Page MenuHomePhabricator

TCP ISNs and Temperature induced clock skews
Open, NormalPublic

Description

Attack summary:

QoS acts as a countermeasure by preventing flows on an anonymity-network node from interfering with each other. However, an inevitable result is that when a flow is running at less than its reserved capacity, CPU load on the node will be reduced. This induces a temperature decrease, which affects the frequency of the crystal oscillator driving the system clock. This effect can be measured remotely by requesting timestamps and deriving clock skew. This vector is not low hanging fruit [2] but it would be good to shut down for those who need higher assurance.

(The NFQUEUE-based fix for the latency is great beause this was a more practical real world attack)

TCP ISNs are not possible to block and needed for security anyway. Are a part of all modern OSs.

The only practical solution listed in the paper/slides [1]

23C3 Slide 30:

Run CPU at full load - Inefficient and must be done with care since different types of tasks can have varying temperature effects

Deployment: on host out of reach of malicious code in vm.


Considerations:

Can disabling c-states accomplish the same?

Yes.

Ethan:

However, the suggestion of disabling c-states more or less obsolesces this suggestion, as the stress solution could easily decrease battery life by 2-3x, whereas I've never seen wattage even double from disabling c-states.


[1] https://events.ccc.de/congress/2006/Fahrplan/attachments/1211-23c3hotornotpres.pdf

[2]

Another option with Linux is to use TCP sequence numbers, which are the sum of a cryptographic result and a 1 MHz clock. Over short periods, the high h gives good results, but as the cryptographic function is re-keyed every 5 minutes, maintaining long term clock skew figures is non-trivial.


Details

Impact
Normal

Event Timeline

Patrick added a project: security.
Patrick added subscribers: marmarek, ethanwhite.

Rewriting ISNs idea: https://phabricator.whonix.org/T530#10027

I think that rewriting TCP ISNs is something we definitely want to do.

Yes.

Should we reach out to Steven first and see if he can give us code?

I think that rewriting TCP ISNs is something we definitely want to do. The precise formula for this could be debated; but I'd suggest E(t + H(localhost | localport | remotehost | remoteport)), where E is a 32-bit block cipher under a secret key, and H(x) is the first 32 bits of the digest of x using a MAC with a secret key (I'd suggest HMAC-SHA256 or similar). A choice of E is arguable; I'd suggest a balanced Feistel network based on RC2, or RC5 (has the patent on that expired yet?).

If we don't care about decryption then the RC family is OK however lots of recent cryptanalysis and evidence from Snowden shows how badly broken RC is. Some of it has to do with the overall design of the cipher.

This answer proposes using better ciphers in stream mode:
https://stackoverflow.com/a/1971766

Collision Attacks Against 64-Bit Block Ciphers:

https://www.schneier.com/blog/archives/2016/08/collision_attac.html
https://twitter.com/julianor/status/768431064964558848

That means goodbye 3DES and BlowFish. Nushu uses 3DES unfortunately.

Should we reach out to Steven first and see if he can give us code?

We're not trying to transmit data ourselves, so we probably don't need his code. In fact, we don't even need to try to blend in with normal Linux ISNs. All we need to do is make it impossible for someone who doesn't know the secret key to get timing data from the ISNs.

If we don't care about decryption then the RC family is OK however lots of recent cryptanalysis and evidence from Snowden shows how badly broken RC is.

That means goodbye 3DES and BlowFish. Nushu uses 3DES unfortunately.

The reason I suggested a 32-bit block cipher was simply to use it as a 32-bit secret permutation, in order to prevent repetitions of TCP ISNs (which RFC 6528 suggests are bad). At the end of the day, the block cipher we use doesn't have to be particularly strong; it just needs to make it difficult to see the value of the four microsecond clock that RFC 6528 suggests we use in the ISN generation process. (The RFC also outlines reasons that the 4 microsecond clock is required).

I also read through the other answers on the StackOverflow thread linked above, and one of them suggested a block cipher I'd completely forgotten about, Speck. I don't really trust the key schedule, though, and it uses a 64-bit key anyway (which is way to small), so we'd likely want to swap out the key schedule for a hash function in OFB or CTR mode, and increase the number of rounds.

We're not trying to transmit data ourselves, so we probably don't need his code. In fact, we don't even need to try to blend in with normal Linux ISNs. All we need to do is make it impossible for someone who doesn't know the secret key to get timing data from the ISNs.

I see. Very well then, makes things easier.

I also read through the other answers on the StackOverflow thread linked above, and one of them suggested a block cipher I'd completely forgotten about, Speck. I don't really trust the key schedule, though, and it uses a 64-bit key anyway (which is way to small)

Better to stick with something else. I'm iffy about anything made by Fort Meade. Although I'm sure with sufficient analysis there could be assurance I don't see much cryptanalysis on Speck.

A similar designed cipher is DJB's Salsa20/ChaCha20. Very fast and recently RFC'd. He's known for making crypto libs that are dead easy to use by software programmers to avoid fudged implementations. I think its a better and safer choice:

https://en.wikipedia.org/wiki/Salsa20

A similar designed cipher is DJB's Salsa20/ChaCha20. Very fast and recently RFC'd. He's known for making crypto libs that are dead easy to use by software programmers to avoid fudged implementations.

The reason I'm proposing a block cipher is because, if we want to use the trivial extension I proposed of RFC 6528, we need an encryption mechanism that produces a secret bijection from the set of vectors of 32 bits to the same set, which is something only a 32-bit block cipher can provide. [1] Speck and Simon are the only 32-bit block ciphers available that have had serious cryptanalysis efforts against them.

With that said, there is another option. I've been working on a construction to use a stream cipher to generate four different 16-bit permutations (adding up to a round 1MB of ram) . We could then use those two permutations in a four-round Feistel network. Although rolling your own cryptography is generally discouraged, in this case it would be relatively safe for two reasons. First off, any attack on the block cipher would have to be spectacular based on the fact that the input is relatively unpredictable, and the volume of ciphertext likely available. Second, my current version of the construction has a reductionist security argument to the security of the stream cipher (if it were possible to distinguish the 16-bit permutations from permutations chosen randomly and uniformly from the set of possible permutations, then it would be possible to leverage that to build a distinguishing attack on the stream cipher). [2]

If we do want to use this, I can properly write up both the construction and the security proof.


  1. Because that's the definition of a 32-bit block cipher: a secret bijection from the set of vectors of 32 bits to the set of vectors of 32 bits, so anything that provided that would be a block cipher.
  2. The reason this isn't used for real-world block ciphers is simply that the memory requirements and key setup time would be somewhat ridiculous for block sizes above 32 bits.

If we do want to use this, I can properly write up both the construction and the security proof.

Yes I think that's the way to go. Can you please use 256 bit keys so we have a post-quantum resistant solution?

I went ahead and implemented the aforementioned 32-bit block cipher, and the implementation is available here. It's relatively performant, getting about a million encryptions per second; that should be enough, especially given that this is only used when a socket is first opened.

Great stuff :) Thanks Ethan!

To make sure, this is for generating the ISNs but we still need some way to overwrite the ISN field in packets?

Dumb question but do the results of this quantum cryptanalysis paper have any effect on using CTR?

https://arxiv.org/pdf/1602.05973v3.pdf

We obtain attacks with very strong implications. First, we show that the most widely used modes of operation for authentication and authenticated encryption (e.g. CBC-MAC, PMAC, GMAC, GCM, and OCB) are completely broken in this security model. Our attacks are also applicable to many CAESAR candidates: CLOC, AEZ, COPA, OTR, POET, OMD, and Minalpher. This is quite surprising compared to the situation with encryption modes: Anand et al. show that standard modes are secure with a quantum-secure PRF.

Some ideas for tools needed to change tcp headers:

https://serverfault.com/questions/318960/easy-way-to-edit-the-traffic-coming-from-a-tcp-host-linux.

netsed uses scapy. Need to be careful about interfaces its set on because raw sockets bypass iptables.

https://packages.debian.org/jessie/netsed

Application similar to netsed uses python-libnetfilter-queue:
https://github.com/rgerganov/nfqsed

nfqsed is a command line utility that transparently modifies network traffic using a predefined set of substitution rules. It runs on Linux and uses the netfilter_queue library. It is similar to netsed but it also allows modifying the network traffic passing through an ethernet bridge. This is especially useful in situations where the source MAC address needs to stay unchanged.

@ethanwhite

I guess I'm trying to figure out if its possible to use the code you wrote to overwrite ISNs without patching the kernel.

I've looked into TCP Option parameters and there doesn't seem to be one that supports altering sequence numbers. If you have any insight on what can be done please let us know.

@Patrick What is the status of integration? Since we have kloak this is also a great defense to have. There is a script on there for packing as a deb:

https://github.com/ethan2-0/nfqueue-packet-delay

@Patrick What is the status of integration?

Build bug from T530#10723 is unresolved. Waiting for @ethanwhite to fix since I don't know how.

An alternative proposal for editing ISNs without involving the kernel:

We can use netsed to edit any arbitrary field of the TCP and UDP protocols. The setup will be done on traffic at the outgoing NIC of Whonix Gateway only, where it is relevant for masking visible traffic connected to a user in the open (User -> Guard node). Netsed is in Debian. Alternatively scapy can be used instead if you prefer (also in Debian). [1]

[0] https://packages.debian.org/buster/netsed
[1] https://stackoverflow.com/questions/10033285/how-to-change-a-packet-data-with-scapy

Netsed preferred because of its compact size and single focus.


Manual for netsed info and how to edit a packet:

http://www.linuxcertif.com/man/1/netsed/

For scapy here is a snippet of code to read seq numbers for sync/ack:

https://networkengineering.stackexchange.com/questions/40420/extremely-large-sequence-and-acknowledge-numbers-when-using-scapy


Proxying outgoing packets thru netsed. This can be done in a couple of ways. 1) Using iptables for transparent proxying of TCP traffic thru a local port that netsed listens on and does its thing then sends the outgoing packets on their way. 2) Using libnetfilter_qu in addition to iptables, is another option to "...[reinject] altered packets to the kernel nfnetlink_queue subsystem." This option gives the most extensibility as it's up to you to code software.

https://serverfault.com/questions/318960/easy-way-to-edit-the-traffic-coming-from-a-tcp-host-linux

Open questions:

  • Will the kernel protest over modified ISNs and start dropping connections?