Live data from Hacker News

X86 is a high-level language

blog.erratasec.com

51–60 of 125 posts

Re: X86 is a high-level language

#51
post #36
post #20

Earlier quoted context omitted.

I think that's the author's point: x86 is now a significant abstraction from the actual details of execution.

That's true of all superscalar machines. That's what killed RISC. The original idea of RISC was one instruction per clock and a very simple CPU control section. Early MIPS CPUs realized that. Then superscalar came to microprocessors with the Pentium Pro. It took 3000 engineers at Intel to design that CPU, but it did much better than one instruction per clock while still handling all the weird cases in x86 instruction…

x86 encoding is not that compact, especially if you're using some of the odder addressing modes or instructions. (the packing functions, xmm operations, etc) It wastes a fair number of single byte encodings on infrequently used instructions, like BCD arithmetic. An instruction set designed for space efficiency could be smaller without foregoing too much rational and orthogonal opcode design.

It's definitely more compact than a simplistic orthogonal opcode design with a generous allocation of registers, for sure.

Re: X86 is a high-level language

#52

I'm not sure what the takeaway from this is. Don't implement crypto in software, only hardware? Does that cut out algorithm-writers who won't have FPGAs and fabrication available to them?...

I don't think it would - what you implement might have more side channel attacks in, but if it's more of a PoC it shouldn't matter.

On the other hand, even if it did, FPGAs are quite cheap ($100-ish for a suitable one) and if you're a serious cryptographer you're almost certainly going to be based at a university or an agency of some kind which will be able to afford one (or have a whole bunch lying around).

Re: X86 is a high-level language

#53
post #28

The author's conclusion that side channel attacks are unpreventable because x86 instructions execute in a variable amount of time does not follow. Side channel attacks that rely on variable instruction timing rely on _content-dependent_ timing. For example, the time spent for a mov from a memory location does not depend on the contents of the memory, but it does depend on the address of that memory. If that address i…

Something interesting to note is that at least in the Pentium 4, the number of cycles spent on integer division instructions varies depending on the values of the operands [1].

[1] https://gmplib.org/~tege/x86-timing.pdf (pages 4 & 6)

Re: X86 is a high-level language

#54
post #10
post #6

I wonder if introducing a sleep that is longer than the computation could conceivably take would work to solve (or at least make it a lot harder to defeat) the actual problem. The failure case where the computation actually is slow enough to matter could be detected and thrown away. This of course would require a fully async crypto lib..

The timing is a signal, and you're proposing to mask that signal by adding noise. This does work, but you can work around it by gathering more samples and averaging out the noise. You increase the work required from an attacker, but it's not insurmountable.

What if you use random noise from a Cauchy distribution? It (interestingly enough) has no mean, so the amount of time the attacker thinks she has to subtract from her average depends on the number of samples that she takes, and does not converge as she increases the number of samples.

Re: X86 is a high-level language

#55

Earlier quoted context omitted.

That's not an effective technique, unfortunately. You still end up leaking timing information. Lets say you add a small, random sleep after each operation – this still leaks information, as the delay can be averaged out over multiple runs. A fixed sleep after each operation is no use either, for obvious reasons. One approach I've seen is to break time into discrete quanta – for example, you could guarantee that every…

The solution i've seen is: sleep(float(hash(request_content)) % n) this assumes that the attacker cannot control any non-relevant part of request_content.

This seems like it's insecure if the attacker can predict request_content, too.

Re: X86 is a high-level language

#56
post #46

Earlier quoted context omitted.

There's a lot of fear surrounding in-hardware crypto primitives. See for example: http://arstechnica.com/security/2013/12/we-cannot-trust-inte... I personally would be very leery of OpenSSL relying on RdRand or AES-NI.

I think that you have extrapolated the legitimate concern around hardware random number generators to AES-NI, where it is not a legitimate concern. With random numbers, the point is that there's no good way to tell exactly how random something is, and it's quite easy to generate deterministic stuff that looks random. Furthermore, by changing a couple of transistors, you can destroy the randomness of Intel's generator…

That's actually very reassuring. Thanks!

Re: X86 is a high-level language

#57
post #28

The author's conclusion that side channel attacks are unpreventable because x86 instructions execute in a variable amount of time does not follow. Side channel attacks that rely on variable instruction timing rely on _content-dependent_ timing. For example, the time spent for a mov from a memory location does not depend on the contents of the memory, but it does depend on the address of that memory. If that address i…

> The author's conclusion that side channel attacks are unpreventable

The author never said anything about "unpreventable".

> None of the author's various examples have anything to do with side channel attacks.

I think the author was trying to point more directly toward the stackoverflow post that was linked, using the examples to point out that it was based on some faulty assumptions.

Re: X86 is a high-level language

#58
post #48
post #41

Earlier quoted context omitted.

> The fact that xor eax,eax is just a register operation doesn't mean it can leak sensitive information. AIUI tfa's point is that you can't assume that xor eax,eax and xor eax,ebx take the same amount of time, because "x86 is a high level language". Similarly for his other examples. This, he claims, makes it difficult to write code that resists timing attacks, if you ever want to have a branch that does nothing. Thus…

The point of the grandparent's post is that timing information is only leaked if the CPU's timing is data dependent. It's not enough to show that different instructions take unpredictable amounts of time. If the sequence of CPU instructions that get executed are the same for varying data, then the unpredictability of the individual instructions doesn't create a timing attack. xor eax,eax scans, to an x86 assembly pro…

Division on some processors takes a data-dependent amount of time. See riscy's comment.

Re: X86 is a high-level language

#59
post #35

"Inside the CPU, the results always appear as if the processor executed everything in-order, but outside the CPU, things happen in strange order." I think the words 'outside' and 'inside' have been swaped

Nope.

Look at load/store ordering, for instance. To your thread (i.e. inside the CPU you're running on), things look normal. But outside your CPU, the order may be different than expected.

Re: X86 is a high-level language

#60
post #57
post #28

The author's conclusion that side channel attacks are unpreventable because x86 instructions execute in a variable amount of time does not follow. Side channel attacks that rely on variable instruction timing rely on _content-dependent_ timing. For example, the time spent for a mov from a memory location does not depend on the contents of the memory, but it does depend on the address of that memory. If that address i…

> The author's conclusion that side channel attacks are unpreventable The author never said anything about "unpreventable". > None of the author's various examples have anything to do with side channel attacks. I think the author was trying to point more directly toward the stackoverflow post that was linked, using the examples to point out that it was based on some faulty assumptions.

I wrote the StackOverflow post, and I don't see anything in the article that points faulty assumptions.

Don't get me wrong, I am glad that someone wrote that article. I was going to write a similar one myself within a few days with all the details I didn't need to expand on in the StackOverflow question because anyone who could answer didn't need them.

If you see any specific assumption that the article points out as faulty, I would be delighted to know which. The article does not even specifically answer the specific question of whether memory-dependence-speculative execution is always canceled when a write occurs that goes to the location that was read, or it is can sometimes not be canceled when the written value coincides with the previous value. It's either one or the other. This is one assumption that we could make, or not, (we'll try not to make it if it's faulty!). But no help there. The article doesn't say.

____________

Something I should clarify and that may be the cause of the misunderstanding (here, or in the article if the article really points out faulty assumptions—I'm not sure it does):

It is called “constant-time programming” by tradition, but it is really “secret-independent-time-programming”, which does not roll off the tongue in the same way. Certainly, the execution time of the crucial instructions that directly handle cryptographic secrets depends on the state in which the previous instructions have left the processor. This is no big deal, because we are not trying to prove that this execution time is constant! We are only trying to prove that it does not depend on the secrets.

And we do this by proving

* that each instruction's execution time does not depend on the secret (this is what ctgrind does, with a basic but adequate set of assumptions on what the execution time of an instruction depends on. The time taken by xor eax, eax does not depend on the previous value of eax, and it doesn't matter that it is different from the time taken by xor eax, ebx. The time taken by xor eax, ebx does not depend on the values of these registers either. And so on. The only arguable chink in the ctgrind armor is integer division, which I don't know whether Adam Langley remembered to count as having an execution time that possibly depends on the value of its arguments—as pointed out in another thread). This works super well for symmetric cryptography. Seriously, problem solved! Now we just need to replace AES with a cipher implemented according to the new rules (the rules predate AES and the reference AES implementation does not follow them. And it would apparently be very difficult to build an AES implementation that would be efficient and that would follow the rules).

* that we can subdivide the code into subgroups of instructions such that each subgroup's execution time does not depend on the secret. This is obviously going to be necessary for perfect “constant-time” asymmetric cryptography. Most subgroups are only one instruction (phew! for these the problem is no harder than above) but a few subgroups need to have more than one. The StackOverflow question is about one such subgroup. Another subgroup is going to be the instructions that access tables in a secret-dependent way. These two non-unitary subgroups of instructions are already written in a very careful way by crypto implementers, who have been aware of the issues for some time. I am only doing a second check, questioning assumptions, and perhaps building an automatic tool for checking that an implementation does not leak information through timing when executed on current, relatively well-understood micro-architectures (better than future micro-architectures that haven't been imagined yet anyway).

“BUT THE ARTICLE SAYS ‘EXECUTION TIME’ IS A ABSTRACTION”, I hear you scream.

Yes. Define “execution time(s)” of an instruction/a group of instructions as “any observable number of cycles in the interaction between the instruction(s) and any other instructions that could be placed around it. The goal is to make all execution times independent of all secrets. It is easy, because currently, apart from memory accesses, conditional jumps, and possibly division, all the execution times of an instruction are independent of the data it handles.

Post reply on HN