[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.10,0:00:16.00,Default,,0000,0000,0000,,{\i1}34c3 preroll music{\i0}\NHerald Angel: Today we have our speaker Dialogue: 0,0:00:16.00,0:00:21.92,Default,,0000,0000,0000,,Filippo Valsorda. He is a crypto-engineer\Nand he is specialized in Go. He is some Dialogue: 0,0:00:21.92,0:00:29.03,Default,,0000,0000,0000,,kind of Go wizard so to say and used to\Nwork at CloudFlare. He actually shows now Dialogue: 0,0:00:29.03,0:00:35.47,Default,,0000,0000,0000,,today in the talk how he made an attack to\Nexploit a bug in the implementation of the Dialogue: 0,0:00:35.47,0:00:41.64,Default,,0000,0000,0000,,elliptic curve P256 in Go, that's why he's\Na Go wizard. The reason is actually due to Dialogue: 0,0:00:41.64,0:00:48.21,Default,,0000,0000,0000,,a misplaced bit on the assembler level,\Njust due to the curves implementation. The Dialogue: 0,0:00:48.21,0:00:53.77,Default,,0000,0000,0000,,result is that in certain cases you can\Nretrieve the private key in the elliptic Dialogue: 0,0:00:53.77,0:00:58.44,Default,,0000,0000,0000,,curve Diffie-Hellman encryption scheme.\NPlease welcome Filippo Valsorda to his Dialogue: 0,0:00:58.44,0:01:03.44,Default,,0000,0000,0000,,talk, give him a round of applause. Thank\Nyou very much. Dialogue: 0,0:01:03.44,0:01:05.71,Default,,0000,0000,0000,,Filippo Valsorda: Thank you.\N{\i1}applause{\i0} Dialogue: 0,0:01:05.71,0:01:11.39,Default,,0000,0000,0000,,Thanks. I love the term crypto-golfer. Tony\Ncame up with it and I just want business Dialogue: 0,0:01:11.39,0:01:17.35,Default,,0000,0000,0000,,cards with that on it. Anyway, okay, I'm\NFilippo. As you heard I worked on Internet Dialogue: 0,0:01:17.35,0:01:22.34,Default,,0000,0000,0000,,infrastructure, I work on Go, I work on\Ncryptography. But this is a collaboration Dialogue: 0,0:01:22.34,0:01:28.23,Default,,0000,0000,0000,,with Sean Devlin, you might know him as\None of the authors of the Cryptopals or Dialogue: 0,0:01:28.23,0:01:35.11,Default,,0000,0000,0000,,the matasano crypto challenges. A few\Nmonths ago earlier this year a bug.. a Dialogue: 0,0:01:35.11,0:01:46.36,Default,,0000,0000,0000,,CloudFlare engineer was scanning CT logs.\NCT logs are big logs of TLS certificates Dialogue: 0,0:01:46.36,0:01:52.09,Default,,0000,0000,0000,,and he was checking the ECDSA signatures\Non these certificates and one of the Dialogue: 0,0:01:52.09,0:01:58.51,Default,,0000,0000,0000,,signatures was not verifying. Which is\Nweird, because CT logs check the Dialogue: 0,0:01:58.51,0:02:04.13,Default,,0000,0000,0000,,certificates before adding them to the\Nlog. It turned out that the bug was in the Dialogue: 0,0:02:04.13,0:02:09.25,Default,,0000,0000,0000,,code that CloudFlare was using to verify\Nthe certificates. And more specifically it Dialogue: 0,0:02:09.25,0:02:17.69,Default,,0000,0000,0000,,was in the Go standard library. It was in the\Nimplementation of the NIST P256 curve, Dialogue: 0,0:02:17.69,0:02:24.36,Default,,0000,0000,0000,,which is a popular, very hard to implement,\Nelliptic curve that is used for example Dialogue: 0,0:02:24.36,0:02:31.80,Default,,0000,0000,0000,,for ECDSA TLS certificates. This curve has\Nan assembly implementation in the Go Dialogue: 0,0:02:31.80,0:02:40.67,Default,,0000,0000,0000,,standard library, of course, to squeeze\Nevery bit of performance out of it, and Dialogue: 0,0:02:40.67,0:02:47.42,Default,,0000,0000,0000,,it's specifically optimized for x86-64\Narchitecture. So that's where the bug was. Dialogue: 0,0:02:47.42,0:02:53.43,Default,,0000,0000,0000,,There was a carry propagation bug. It was\Nreported upstream and everyone agreed that Dialogue: 0,0:02:53.43,0:03:00.42,Default,,0000,0000,0000,,this was not obviously exploitable.\NBut Adam Langley also said that it would Dialogue: 0,0:03:00.42,0:03:08.24,Default,,0000,0000,0000,,be a cool paper though. And well I mean,\Nhow do you pass on that? So Sean and I met Dialogue: 0,0:03:08.24,0:03:13.62,Default,,0000,0000,0000,,in Paris and spend a weekend and then some\Neating Thai food and staring at this Dialogue: 0,0:03:13.62,0:03:20.44,Default,,0000,0000,0000,,assembly code to try to understand what is\Nit doing. And one month later we have a Dialogue: 0,0:03:20.44,0:03:30.63,Default,,0000,0000,0000,,CVE and two Go security releases. We found\Na way to go from this single carry bit bug Dialogue: 0,0:03:30.63,0:03:36.29,Default,,0000,0000,0000,,to a full key recovery against protocols\Nthat use elliptic curve Diffie-Hellman Dialogue: 0,0:03:36.29,0:03:42.52,Default,,0000,0000,0000,,within ephemeral static way. If this means\Nnothing to you, it's okay, I will try to Dialogue: 0,0:03:42.52,0:03:51.17,Default,,0000,0000,0000,,go over it. One of these protocols for\Nexample is JWT. Jozy, or however you want Dialogue: 0,0:03:51.17,0:03:58.21,Default,,0000,0000,0000,,to call it - it has 15 different acronyms.\NAnd it's often implemented in Go, so this Dialogue: 0,0:03:58.21,0:04:05.85,Default,,0000,0000,0000,,was exploitable against real-world\Nservices. So, let's start by looking at Dialogue: 0,0:04:05.85,0:04:11.90,Default,,0000,0000,0000,,the code with the bug. Let's take it from\Nthe beginning. This is the short assembly Dialogue: 0,0:04:11.90,0:04:19.76,Default,,0000,0000,0000,,function that does subtraction. When you\Ndo elliptic curve math, you usually work Dialogue: 0,0:04:19.76,0:04:27.98,Default,,0000,0000,0000,,on a field, you work on math modulo some\Nprime p. So if it was subtraction you do a Dialogue: 0,0:04:27.98,0:04:35.68,Default,,0000,0000,0000,,minus b modulo p and this is what this\Nassembly snippet does. It sets a to a Dialogue: 0,0:04:35.68,0:04:44.03,Default,,0000,0000,0000,,minus b. Of course these are numbers way\Ntoo big to fit into a single register. So Dialogue: 0,0:04:44.03,0:04:49.60,Default,,0000,0000,0000,,how do you do math, when you can't fit\Ninto a single register? You do multi- Dialogue: 0,0:04:49.60,0:04:55.73,Default,,0000,0000,0000,,precision math. And the thing is, you all\Nknow how to do multi-precision math, you Dialogue: 0,0:04:55.73,0:05:01.36,Default,,0000,0000,0000,,learned that in elementary school. When\Nyou would write numbers in columns and you Dialogue: 0,0:05:01.36,0:05:06.62,Default,,0000,0000,0000,,do math with register size of 10, because\Nfor every digit you would subtract two Dialogue: 0,0:05:06.62,0:05:13.11,Default,,0000,0000,0000,,digits and carry the minus one if it went\Nnegative and then subtract with the carry Dialogue: 0,0:05:13.11,0:05:17.50,Default,,0000,0000,0000,,and then carry the minus one. That's\Nexactly what this is doing, but it's doing Dialogue: 0,0:05:17.50,0:05:23.44,Default,,0000,0000,0000,,it instead with digits with 64-bit registers,\Nbecause this is a 64-bit architecture Dialogue: 0,0:05:23.44,0:05:27.68,Default,,0000,0000,0000,,. So we look at the first\Nlines: the first lines is nothing else Dialogue: 0,0:05:27.68,0:05:32.87,Default,,0000,0000,0000,,than subtract, subtract, subtract with\Ncarry. And then the carry is finally Dialogue: 0,0:05:32.87,0:05:40.83,Default,,0000,0000,0000,,stored in that mul0 accumulator. But then\Nwhat do we do if it goes negative? Dialogue: 0,0:05:40.83,0:05:47.55,Default,,0000,0000,0000,,We said that this is modulo p so we can't\Njust let it wrap around modulo 2^256, Dialogue: 0,0:05:47.55,0:05:53.27,Default,,0000,0000,0000,,because that's how wide, you know, 4\Nregisters are. But since we're doing Dialogue: 0,0:05:53.27,0:05:57.68,Default,,0000,0000,0000,,arithmetic modulo a number, we can just\Nadd that number and the result is the Dialogue: 0,0:05:57.68,0:06:03.72,Default,,0000,0000,0000,,same, right? Adding p modulo p is a no-op\Nin the result. So that's what this code Dialogue: 0,0:06:03.72,0:06:11.31,Default,,0000,0000,0000,,does: It does a equal a minus b, it takes\Na copy of the result and it adds p. And Dialogue: 0,0:06:11.31,0:06:17.62,Default,,0000,0000,0000,,then in constant time, it uses that final\Ncarry to check, if it went negative or not Dialogue: 0,0:06:17.62,0:06:23.34,Default,,0000,0000,0000,,to decide in constant time, which one to\Nuse. The one with b , so a minus b plus p Dialogue: 0,0:06:23.34,0:06:30.17,Default,,0000,0000,0000,,or a minus B - and that's subtraction.\NStraightforward enough. Now the problem Dialogue: 0,0:06:30.17,0:06:35.76,Default,,0000,0000,0000,,with this code is that if you look closely\Nyou can see something that might be weird Dialogue: 0,0:06:35.76,0:06:40.86,Default,,0000,0000,0000,,if you're not familiar with assembly. It\Nstill trips me over. To use a condition Dialogue: 0,0:06:40.86,0:06:45.15,Default,,0000,0000,0000,,like these constant time conditionals\Nthere. Which have to be constant time, Dialogue: 0,0:06:45.15,0:06:50.19,Default,,0000,0000,0000,,because you don't want to leak timings\Nbased on the size of number. You have to Dialogue: 0,0:06:50.19,0:06:56.54,Default,,0000,0000,0000,,first operate on mul0, so that you set the\Nflags, the zero flag. So normally what you Dialogue: 0,0:06:56.54,0:07:06.92,Default,,0000,0000,0000,,do is either add 0 and 1 to your mul0\Nto check if to set the flags. But that's Dialogue: 0,0:07:06.92,0:07:13.24,Default,,0000,0000,0000,,not that's not an add, that's an add with\Ncarry. It means that it's adding zero to Dialogue: 0,0:07:13.24,0:07:20.92,Default,,0000,0000,0000,,mul0 and the carry bit from this addition\Nhere, which has nothing to do with it, Dialogue: 0,0:07:20.92,0:07:25.93,Default,,0000,0000,0000,,it's not supposed to be there. Like this\Nis adding p, but it doesn't matter, if it Dialogue: 0,0:07:25.93,0:07:31.57,Default,,0000,0000,0000,,overflows, because if it does, it wasn't\Ngoing to be picked here anyway. So it's Dialogue: 0,0:07:31.57,0:07:35.64,Default,,0000,0000,0000,,adding another bit into the operation that\Nwasn't supposed to be there. So it's Dialogue: 0,0:07:35.64,0:07:41.40,Default,,0000,0000,0000,,flipping the result, but then also the\Nconditions here are flipped, so Dialogue: 0,0:07:41.40,0:07:50.99,Default,,0000,0000,0000,,essentially it evens itself out. Except:\Nwhen that carry bit happens not to be set, Dialogue: 0,0:07:50.99,0:07:54.52,Default,,0000,0000,0000,,because the number a minus b is small\Nenough, that if you add P, you don't wrap Dialogue: 0,0:07:54.52,0:08:00.84,Default,,0000,0000,0000,,around. That happens once every 2^32\Ntimes, which is why it's so rare that Dialogue: 0,0:08:00.84,0:08:06.54,Default,,0000,0000,0000,,nobody had noticed so far.\NSo the code went in and nobody noticed for Dialogue: 0,0:08:06.54,0:08:09.95,Default,,0000,0000,0000,,a long time, until CloudFlare first\Nstarted scanning CT logs and had this Dialogue: 0,0:08:09.95,0:08:16.12,Default,,0000,0000,0000,,weird one signature that wasn't verifying\Nand they were lucky enough to actually Dialogue: 0,0:08:16.12,0:08:21.14,Default,,0000,0000,0000,,have it in the logs because you know if it\Nhappens transiently you might just think.. Dialogue: 0,0:08:21.14,0:08:27.97,Default,,0000,0000,0000,,I don't know, the connection broke, right?\NSo this is what we call a carry Dialogue: 0,0:08:27.97,0:08:32.83,Default,,0000,0000,0000,,propagation bug. Carry propagation is the\Nactivity of making sure that you carry the Dialogue: 0,0:08:32.83,0:08:43.46,Default,,0000,0000,0000,,1. And here it's a bit weird, we didn't\Nforget to carry it, but we carried a bit Dialogue: 0,0:08:43.46,0:08:49.12,Default,,0000,0000,0000,,that we weren't supposed to carry into a\Nresult. Most of the times that goes well, Dialogue: 0,0:08:49.12,0:08:55.49,Default,,0000,0000,0000,,sometimes that breaks. When that breaks:\Nwrong result! Wrong result, wrong point Dialogue: 0,0:08:55.49,0:09:02.89,Default,,0000,0000,0000,,computation and wrong point computation,\Nso what? Like how does forgetting to carry Dialogue: 0,0:09:02.89,0:09:09.21,Default,,0000,0000,0000,,the one lead to a full key recovery? This\Nis not one of those bugs, where like Dialogue: 0,0:09:09.21,0:09:13.48,Default,,0000,0000,0000,,buffer overflow you know what you're\Ntrying to do even if you might have to Dialogue: 0,0:09:13.48,0:09:18.68,Default,,0000,0000,0000,,jump through so many hoops, because there\Nmight be all these protections, you know Dialogue: 0,0:09:18.68,0:09:23.46,Default,,0000,0000,0000,,what your capabilities are, you can\Noverwrite some memory. Here instead it's Dialogue: 0,0:09:23.46,0:09:29.54,Default,,0000,0000,0000,,not clear what your capability is. So\Ntoday I'm going to try to explain that. Dialogue: 0,0:09:29.54,0:09:36.01,Default,,0000,0000,0000,,How we turn this very rare failed\Ncomputation into a complete key recovery Dialogue: 0,0:09:36.01,0:09:44.40,Default,,0000,0000,0000,,attack. But first I apologize that I have\Nto give a elliptic curve cryptography Dialogue: 0,0:09:44.40,0:09:55.45,Default,,0000,0000,0000,,crash course here at CCC. So we've seen\Nthe field is nothing else than operations Dialogue: 0,0:09:55.45,0:10:03.27,Default,,0000,0000,0000,,modulo p, then there are the points: the\Npoints are x and y, the coordinates. They Dialogue: 0,0:10:03.27,0:10:07.97,Default,,0000,0000,0000,,fit an equation, which we don't care\Nabout, they just fit an equation. They are Dialogue: 0,0:10:07.97,0:10:13.50,Default,,0000,0000,0000,,integers, so we can work with them, and we\Ncan use them to build a group. A group is Dialogue: 0,0:10:13.50,0:10:21.39,Default,,0000,0000,0000,,one of the core structures in modern\Ncryptography. To build a group we need a Dialogue: 0,0:10:21.39,0:10:26.93,Default,,0000,0000,0000,,zero point, a generator point, and an\Naddition over the group, over the Dialogue: 0,0:10:26.93,0:10:29.93,Default,,0000,0000,0000,,points. So we define an addition, Dialogue: 0,0:10:29.93,0:10:34.65,Default,,0000,0000,0000,,again, we don't care about how addition\Nworks. It's just: you take two points, you Dialogue: 0,0:10:34.65,0:10:38.12,Default,,0000,0000,0000,,add them together, you get a result.\NIt has all the properties that you Dialogue: 0,0:10:38.12,0:10:45.26,Default,,0000,0000,0000,,remember from elementary school addition:\Nit's commutative, it's associative. And Dialogue: 0,0:10:45.26,0:10:50.24,Default,,0000,0000,0000,,then you have multiplication: You don't\Nactually define how to multiply a point, Dialogue: 0,0:10:50.24,0:10:55.40,Default,,0000,0000,0000,,but if I tell you that you have an\Naddition operation and I want five times Dialogue: 0,0:10:55.40,0:11:00.69,Default,,0000,0000,0000,,this point, what do you do? You take the\Npoint and you add the point and you add Dialogue: 0,0:11:00.69,0:11:06.79,Default,,0000,0000,0000,,the point and you add the point,... so\Nthis is called scalar multiplication: Dialogue: 0,0:11:06.79,0:11:11.100,Default,,0000,0000,0000,,doing multiplication by adding repeatedly\Na certain point. Dialogue: 0,0:11:11.100,0:11:19.14,Default,,0000,0000,0000,,So now we have a group, which is given by\Nmultiplying the point, a generator point, a Dialogue: 0,0:11:19.14,0:11:25.11,Default,,0000,0000,0000,,certain number of times and we have a\Nmultiplication operation. So how do we Dialogue: 0,0:11:25.11,0:11:31.19,Default,,0000,0000,0000,,build cryptography out of it? This is all\Nawfully abstract so far? So we build Dialogue: 0,0:11:31.19,0:11:35.18,Default,,0000,0000,0000,,elliptic curve Diffie-Hellman. If you're\Nfamiliar with normal Diffie-Hellman, you Dialogue: 0,0:11:35.18,0:11:41.15,Default,,0000,0000,0000,,will see something snap at some point. The\Nprivate key is a giant number, this is Dialogue: 0,0:11:41.15,0:11:50.47,Default,,0000,0000,0000,,important. The private key in ECDH is just\Na random giant 256 bit number. And then we Dialogue: 0,0:11:50.47,0:11:56.25,Default,,0000,0000,0000,,have a public key. A public key is that\Ngiant number multiplied, the scalar Dialogue: 0,0:11:56.25,0:12:03.32,Default,,0000,0000,0000,,multiplication we just talked about, by a\Ngenerator point. If you know normal Dialogue: 0,0:12:03.32,0:12:08.88,Default,,0000,0000,0000,,Diffie-Hellman, this is like doing g to\Nthe a. If you don't, it's okay, this is Dialogue: 0,0:12:08.88,0:12:17.32,Default,,0000,0000,0000,,just multiplying private key by a point.\NAnd then, when I have my private key and Dialogue: 0,0:12:17.32,0:12:23.23,Default,,0000,0000,0000,,my public key, you send me your public\Nkey. We need to agree on a shared secret, Dialogue: 0,0:12:23.23,0:12:29.68,Default,,0000,0000,0000,,how we do that, is that I take your public\Nkey, which is a point. I take this and I Dialogue: 0,0:12:29.68,0:12:36.30,Default,,0000,0000,0000,,multiply it by my private key, here, so\Nagain: it's my giant number private key Dialogue: 0,0:12:36.30,0:12:41.75,Default,,0000,0000,0000,,multiplied by your point. That comes\Ntogether: The two results are the same, Dialogue: 0,0:12:41.75,0:12:48.68,Default,,0000,0000,0000,,because if we do my private key times your\Nprivate key times g it's the same as your Dialogue: 0,0:12:48.68,0:12:54.57,Default,,0000,0000,0000,,private key times my private key times g,\Nbecause that's commutative. And we land on Dialogue: 0,0:12:54.57,0:13:03.01,Default,,0000,0000,0000,,a shared secret. And that's all we need to\Nknow about elliptic curve cartography to Dialogue: 0,0:13:03.01,0:13:10.63,Default,,0000,0000,0000,,exploit this. However, there's one thing\Nthat I glossed over: It's easy to multiply Dialogue: 0,0:13:10.63,0:13:18.00,Default,,0000,0000,0000,,by five, you add five times.\NBut if I'm asking you to multiply by a 256 Dialogue: 0,0:13:18.00,0:13:26.75,Default,,0000,0000,0000,,bit number, you can't add 2 to the 256\Ntimes a point, right? So what do we do Dialogue: 0,0:13:26.75,0:13:31.40,Default,,0000,0000,0000,,there? Remember that here, what we're\Ntrying to do is the multiplication: The Dialogue: 0,0:13:31.40,0:13:38.08,Default,,0000,0000,0000,,private key times the public key, the\Npoint. We do something called double and Dialogue: 0,0:13:38.08,0:13:44.49,Default,,0000,0000,0000,,add: We take our private key and we string\Nit out like bits. We start from the most Dialogue: 0,0:13:44.49,0:13:49.94,Default,,0000,0000,0000,,significant bit. This is little endian,\Nbecause I have gotten this slide wrong the Dialogue: 0,0:13:49.94,0:13:54.85,Default,,0000,0000,0000,,first time. But, you know, you just claim\Nthat you meant it to be the opposite Dialogue: 0,0:13:54.85,0:14:00.51,Default,,0000,0000,0000,,endianness. Anyway, that's the most\Nsignificant bit, the one that is two to Dialogue: 0,0:14:00.51,0:14:08.30,Default,,0000,0000,0000,,the 256, no, two to the 255. If you flip\Nit, you're adding or removing two to the Dialogue: 0,0:14:08.30,0:14:14.45,Default,,0000,0000,0000,,255. So you start with 0, that's zed, 0,\Nnothing, and you check the first bit, the Dialogue: 0,0:14:14.45,0:14:20.97,Default,,0000,0000,0000,,most important bit: Is that set, yes or\Nno? Yes, so you add the point Q, which is Dialogue: 0,0:14:20.97,0:14:26.13,Default,,0000,0000,0000,,the point we're trying to multiply by this\Ngiant e. So we add the point and then we Dialogue: 0,0:14:26.13,0:14:33.03,Default,,0000,0000,0000,,move down one by doubling. Can you imagine\Nhow we double something? Remember we only Dialogue: 0,0:14:33.03,0:14:39.71,Default,,0000,0000,0000,,have addition. We add it to itself, of\Ncourse. So we use addition to double the Dialogue: 0,0:14:39.71,0:14:45.80,Default,,0000,0000,0000,,point. And you might see, where we're\Ngoing with this. We double every time we Dialogue: 0,0:14:45.80,0:14:50.40,Default,,0000,0000,0000,,slide down one bit.\NBy the time we arrive at the end, how many Dialogue: 0,0:14:50.40,0:14:56.56,Default,,0000,0000,0000,,times did we double that first point that\Nwe added, because the first bit was one? Dialogue: 0,0:14:56.56,0:15:04.32,Default,,0000,0000,0000,,255 times! That bit was worth 2 to the\N255, so at the end that will have the Dialogue: 0,0:15:04.32,0:15:10.56,Default,,0000,0000,0000,,value it was supposed to have. And we keep\Ngoing, we check if this bit is 1: Is it 1? Dialogue: 0,0:15:10.56,0:15:16.13,Default,,0000,0000,0000,,No. So we do nothing, we double again to\Nmove down one. We check if this bit is Dialogue: 0,0:15:16.13,0:15:23.83,Default,,0000,0000,0000,,one. This bit is 1: so we add the point.\NSo we did add the point, double, double, Dialogue: 0,0:15:23.83,0:15:30.83,Default,,0000,0000,0000,,add the point, double, moving down one and\Nwe keep going like this. We keep going Dialogue: 0,0:15:30.83,0:15:38.29,Default,,0000,0000,0000,,like this, until we reach the least\Nsignificant bit. At the least significant Dialogue: 0,0:15:38.29,0:15:42.90,Default,,0000,0000,0000,,bit, if it's one, we add the point, if\Nit's not, we don't add the point. And at Dialogue: 0,0:15:42.90,0:15:49.08,Default,,0000,0000,0000,,the end we have the correct result and the\Nresult comes from this sequence of Dialogue: 0,0:15:49.08,0:15:56.32,Default,,0000,0000,0000,,operations which at most are twice 255\Noperations, which is something that we can Dialogue: 0,0:15:56.32,0:16:07.40,Default,,0000,0000,0000,,do concretely. Now why did I explain this\Nvery specific algorithm to you. Because to Dialogue: 0,0:16:07.40,0:16:12.20,Default,,0000,0000,0000,,understand this attack, you have to\Nrecognize that each key, so each string of Dialogue: 0,0:16:12.20,0:16:19.84,Default,,0000,0000,0000,,bits here, converts into a very specific\Nsequence of operations. Okay, if you Dialogue: 0,0:16:19.84,0:16:26.96,Default,,0000,0000,0000,,change one bit, there will be an one more\Naddition one less addition and each key Dialogue: 0,0:16:26.96,0:16:33.26,Default,,0000,0000,0000,,has a very specific sequence. In this case\Nit's add, double, double, add, double, Dialogue: 0,0:16:33.26,0:16:44.23,Default,,0000,0000,0000,,add, double, double, and it keeps going.\NSo back to our bug. If you spaced out, Dialogue: 0,0:16:44.23,0:16:53.29,Default,,0000,0000,0000,,because we took a lot of crypto, I saw\Nyou! But the two things you should take Dialogue: 0,0:16:53.29,0:16:59.30,Default,,0000,0000,0000,,away are: There's a giant number, it's the\Nprivate key, we want to multiply the giant Dialogue: 0,0:16:59.30,0:17:06.59,Default,,0000,0000,0000,,number by a point and we do that by doing\Nadditions and doubles in an order that is Dialogue: 0,0:17:06.59,0:17:12.50,Default,,0000,0000,0000,,specified by the bits of the giant number.\NThat's what you need to have clear, the Dialogue: 0,0:17:12.50,0:17:20.30,Default,,0000,0000,0000,,only thing. So let's go back to see how we\Nuse that to turn our very small carry bug Dialogue: 0,0:17:20.30,0:17:26.52,Default,,0000,0000,0000,,into a complete key recovery attack. First\Nthing we do is we bubble it up. That Dialogue: 0,0:17:26.52,0:17:30.82,Default,,0000,0000,0000,,function that breaks is called P256\Nsubinternal. That's the function I showed Dialogue: 0,0:17:30.82,0:17:39.77,Default,,0000,0000,0000,,you earlier. P256 subinternal is used by P256\Npoint add, which is what we spoke about Dialogue: 0,0:17:39.77,0:17:45.93,Default,,0000,0000,0000,,adding two points, the only important\Noperation. And adding two points, we've Dialogue: 0,0:17:45.93,0:17:51.95,Default,,0000,0000,0000,,seen, we use when we're multiplying, when\Nwe're doing that scalar multiplication, Dialogue: 0,0:17:51.95,0:17:59.27,Default,,0000,0000,0000,,which is d times q, d times the point. And\Nhow is scalar mult used? Here we finally Dialogue: 0,0:17:59.27,0:18:04.31,Default,,0000,0000,0000,,surfaced to a level that if you work with\Ncryptographic protocols you might start Dialogue: 0,0:18:04.31,0:18:09.84,Default,,0000,0000,0000,,recognizing pieces of. Scalar\Nmultiplication is the operation that the Dialogue: 0,0:18:09.84,0:18:15.45,Default,,0000,0000,0000,,peer does in elliptic curve Diffie-\NHellman. There's a scalar, which is the Dialogue: 0,0:18:15.45,0:18:20.02,Default,,0000,0000,0000,,secret, which is the private key. There's\Na point, which is the public key of the Dialogue: 0,0:18:20.02,0:18:26.00,Default,,0000,0000,0000,,other person, which might be the attacker.\NSo the scalar multiplication here, Dialogue: 0,0:18:26.00,0:18:34.09,Default,,0000,0000,0000,,speaking in InfoSec terms, has an attacker\Nsupplied point and a secret scalar and the Dialogue: 0,0:18:34.09,0:18:41.35,Default,,0000,0000,0000,,result, the shared secret, is the session\Nkey. For example: TLS, when you open a Dialogue: 0,0:18:41.35,0:18:47.02,Default,,0000,0000,0000,,connection with TLS and you're using\Nelliptic curve Diffie-Hellman, then you Dialogue: 0,0:18:47.02,0:18:53.36,Default,,0000,0000,0000,,will do this dance to agree on a session\Nkey. If the session key is correct, the Dialogue: 0,0:18:53.36,0:18:59.32,Default,,0000,0000,0000,,connection will open and you will be able\Nto, I don't know, get send HTTP request. Dialogue: 0,0:18:59.32,0:19:06.11,Default,,0000,0000,0000,,If the bug is hit and the result is wrong,\Nso the result bubbles up into a wrong Dialogue: 0,0:19:06.11,0:19:14.37,Default,,0000,0000,0000,,shared secret, the session key is wrong.\NAnd the session key is wrong you notice, Dialogue: 0,0:19:14.37,0:19:21.86,Default,,0000,0000,0000,,how do you notice? The connection breaks.\NSo this is what in cryptography we call an Dialogue: 0,0:19:21.86,0:19:25.23,Default,,0000,0000,0000,,oracle.\NYou have an oracle that you can call and Dialogue: 0,0:19:25.23,0:19:33.06,Default,,0000,0000,0000,,send a point, because that's your public\Nkey, you're the attacker, and you send Dialogue: 0,0:19:33.06,0:19:39.93,Default,,0000,0000,0000,,that point and it gets multiplied by the\Nprivate key. And it gives you one bit of Dialogue: 0,0:19:39.93,0:19:46.22,Default,,0000,0000,0000,,information, did the bug trigger or did it\Nnot? Most of the times it won't, because Dialogue: 0,0:19:46.22,0:19:54.16,Default,,0000,0000,0000,,remember, this is an extremely rare bug.\NSo you have an oracle that tells you: Bug Dialogue: 0,0:19:54.16,0:19:58.90,Default,,0000,0000,0000,,happen, bug didn't happen, based on the\Npoint you sent. And let's assume that the Dialogue: 0,0:19:58.90,0:20:04.92,Default,,0000,0000,0000,,key stays the same, we'll talk about that.\NCan you imagine how we use that to start Dialogue: 0,0:20:04.92,0:20:13.47,Default,,0000,0000,0000,,learning things about the key? Well, let's\Nsay, that we can magically conjure a point Dialogue: 0,0:20:13.47,0:20:17.22,Default,,0000,0000,0000,,that in that sequence of operation, that's\Nwhy I told you the sequence of operation Dialogue: 0,0:20:17.22,0:20:25.38,Default,,0000,0000,0000,,was important, the bug happens very\Nspecifically at that addition and we find Dialogue: 0,0:20:25.38,0:20:32.95,Default,,0000,0000,0000,,another point where the bug happens very\Nspecifically at that double. If we know Dialogue: 0,0:20:32.95,0:20:39.21,Default,,0000,0000,0000,,already these bits of the key, and we\Naren't sure about this one, what can we do Dialogue: 0,0:20:39.21,0:20:48.82,Default,,0000,0000,0000,,with these two points? We send them both,\None of them will break the TLS connection, Dialogue: 0,0:20:48.82,0:20:55.69,Default,,0000,0000,0000,,the other one will succeed. That means\Nthat the one that broke triggered the bug, Dialogue: 0,0:20:55.69,0:21:01.68,Default,,0000,0000,0000,,the one that didn't break, didn't trigger\Nthe bug. And we know which one corresponds Dialogue: 0,0:21:01.68,0:21:08.08,Default,,0000,0000,0000,,to which key. Because we magically made\Nspecial points that only break very Dialogue: 0,0:21:08.08,0:21:13.82,Default,,0000,0000,0000,,precisely at that point of the\Ncomputation. Okay, so we learned a bit of Dialogue: 0,0:21:13.82,0:21:19.24,Default,,0000,0000,0000,,the key. In cryptography as soon as you\Nlearn one bit of the key, there's probably Dialogue: 0,0:21:19.24,0:21:28.14,Default,,0000,0000,0000,,a way all the way down. So we build what's\Ncalled an adaptive attack. Let's say we Dialogue: 0,0:21:28.14,0:21:34.07,Default,,0000,0000,0000,,have these bits, but we want to learn\Nthese, too. We compute two points, one Dialogue: 0,0:21:34.07,0:21:40.11,Default,,0000,0000,0000,,that breaks, when the addition happens\Nexactly at that point in the double and Dialogue: 0,0:21:40.11,0:21:46.99,Default,,0000,0000,0000,,add a procedure, and one that triggers\Nonly when the add doesn't happen at the Dialogue: 0,0:21:46.99,0:21:52.93,Default,,0000,0000,0000,,specific point in the double and add\Nsequence. We send them both, only one of Dialogue: 0,0:21:52.93,0:22:00.95,Default,,0000,0000,0000,,them breaks the TLS connection, well, then\Nwe know a bit! We go back to our magic Dialogue: 0,0:22:00.95,0:22:05.67,Default,,0000,0000,0000,,point generator and we generate two new\Npoints. Dialogue: 0,0:22:05.67,0:22:10.52,Default,,0000,0000,0000,,This time we don't look for things that\Nbreak here, we look for things that break Dialogue: 0,0:22:10.52,0:22:17.10,Default,,0000,0000,0000,,here. We make two points, we send them\Nboth. One of them breaks the connection, Dialogue: 0,0:22:17.10,0:22:21.07,Default,,0000,0000,0000,,the other doesn't break the connection. We\Nlearned one more bit of the key. We go Dialogue: 0,0:22:21.07,0:22:26.94,Default,,0000,0000,0000,,back, we make two points, we send them\Nboth: One breaks the connection, one Dialogue: 0,0:22:26.94,0:22:31.41,Default,,0000,0000,0000,,doesn't. We keep going like that, once for\Neach bit. Every time we go back and we Dialogue: 0,0:22:31.41,0:22:36.11,Default,,0000,0000,0000,,adapt to what we learned so far. That's\Nwhy it's called an adaptive attack, we Dialogue: 0,0:22:36.11,0:22:41.27,Default,,0000,0000,0000,,can't pre-compute all these points. We\Nhave to come up with them while we learn Dialogue: 0,0:22:41.27,0:22:47.94,Default,,0000,0000,0000,,the key. And the beautiful thing about\Nadaptive attacks is that they look exactly Dialogue: 0,0:22:47.94,0:22:53.92,Default,,0000,0000,0000,,like Hollywood, it's beautiful! Because\Nyou see them flipping and going through Dialogue: 0,0:22:53.92,0:22:58.54,Default,,0000,0000,0000,,values, getting it right and moving to the\Nnext one, which you all told it was fake, Dialogue: 0,0:22:58.54,0:23:16.01,Default,,0000,0000,0000,,it was not! Everything else is fake. Okay,\Nso, this attack we came up with that, we Dialogue: 0,0:23:16.01,0:23:21.73,Default,,0000,0000,0000,,told we had something extremely novel, we\Nwent to the literature and everyone that Dialogue: 0,0:23:21.73,0:23:27.86,Default,,0000,0000,0000,,had picked an academic career in the\Naudience knows exactly what happened: We Dialogue: 0,0:23:27.86,0:23:33.66,Default,,0000,0000,0000,,found a paper that was doing exactly this.\NHowever, you know, it was a little Dialogue: 0,0:23:33.66,0:23:44.11,Default,,0000,0000,0000,,different. It was still P256 and it was\Nstill ECDH and, hmm.. okay it's really Dialogue: 0,0:23:44.11,0:23:50.74,Default,,0000,0000,0000,,similar. But it's an attack that depends a\Nlot on the implementation details, how you Dialogue: 0,0:23:50.74,0:23:55.63,Default,,0000,0000,0000,,pull it off. You can't suddenly just\Nrepurpose the code, but the idea so far: Dialogue: 0,0:23:55.63,0:23:59.68,Default,,0000,0000,0000,,an adaptive attack where you send two\Npoints and you check which one breaks is Dialogue: 0,0:23:59.68,0:24:05.58,Default,,0000,0000,0000,,the same as a BBB paper from a few years\Nago when it worked against open SSL Dialogue: 0,0:24:05.58,0:24:13.53,Default,,0000,0000,0000,,instead. Instead of against this bug in\Nthe Go standard library. So instead from Dialogue: 0,0:24:13.53,0:24:20.79,Default,,0000,0000,0000,,now on we're going to talk about how\Nexactly we implemented this against Go, Dialogue: 0,0:24:20.79,0:24:26.19,Default,,0000,0000,0000,,because this changes a lot based on the\Nimplementation details of the library Dialogue: 0,0:24:26.19,0:24:31.45,Default,,0000,0000,0000,,you're working with. So this was the\Ngeneral idea of how the attack works. All Dialogue: 0,0:24:31.45,0:24:35.92,Default,,0000,0000,0000,,that: You find points that break at the\Nright time, you send them both, and that Dialogue: 0,0:24:35.92,0:24:40.39,Default,,0000,0000,0000,,way you learn a bit of the key,\Nexcept I lied to you. Dialogue: 0,0:24:40.39,0:24:46.05,Default,,0000,0000,0000,,I lied to you, because I lied to you on a\Nlot of things: The first one is that Go Dialogue: 0,0:24:46.05,0:24:51.57,Default,,0000,0000,0000,,doesn't do double and add one bit at a\Ntime, it does it five bits at a time! It's Dialogue: 0,0:24:51.57,0:24:57.73,Default,,0000,0000,0000,,called Booth multiplication, it took us\Nforever to figure it out. It's an 1980s Dialogue: 0,0:24:57.73,0:25:13.57,Default,,0000,0000,0000,,paper. Instead of adding one point or zero\Npoints and then doubling, it adds between Dialogue: 0,0:25:13.57,0:25:20.06,Default,,0000,0000,0000,,minus 16 and plus 16 points and then\Ndoubles five times moving down. It just Dialogue: 0,0:25:20.06,0:25:27.15,Default,,0000,0000,0000,,does it in blocks of five. So it splits up\Nthe key and then looks at each block of Dialogue: 0,0:25:27.15,0:25:33.47,Default,,0000,0000,0000,,bits, picks a value from a pre-computed\Ntable, which is just all the values from Dialogue: 0,0:25:33.47,0:25:40.62,Default,,0000,0000,0000,,one times the point to 16 times the point\Nand in the loop it doubles five times, Dialogue: 0,0:25:40.62,0:25:47.90,Default,,0000,0000,0000,,because it moved five bits down. And then\Nit chooses, which point between zero and Dialogue: 0,0:25:47.90,0:25:55.59,Default,,0000,0000,0000,,16 to use from the table and it adds that\Nto the rolling result, instead of adding 1 Dialogue: 0,0:25:55.59,0:26:02.34,Default,,0000,0000,0000,,or 0. There's also a bit of constant time\Narithmetic there, because the other thing Dialogue: 0,0:26:02.34,0:26:08.26,Default,,0000,0000,0000,,I lied to you on is that there's no such\Nthing as at 0 point. It's an imaginary Dialogue: 0,0:26:08.26,0:26:12.80,Default,,0000,0000,0000,,point that we add to make the math work,\Nbut when you try to tell the code to Dialogue: 0,0:26:12.80,0:26:17.28,Default,,0000,0000,0000,,actually add the zero point it's like\Nasking you to divide by 0. It just won't Dialogue: 0,0:26:17.28,0:26:25.54,Default,,0000,0000,0000,,do it! But you know how you add 0, right?\NYou do nothing! So there's some constant Dialogue: 0,0:26:25.54,0:26:30.82,Default,,0000,0000,0000,,time code here that looks at it and if\Nit's 0, it does nothing. If it's not 0, it Dialogue: 0,0:26:30.82,0:26:39.67,Default,,0000,0000,0000,,adds the value.\NSo the first thing we had to do to adapt Dialogue: 0,0:26:39.67,0:26:46.69,Default,,0000,0000,0000,,to this format is that we worked in limbs.\NWhen you hear me say limb, it just means Dialogue: 0,0:26:46.69,0:26:53.85,Default,,0000,0000,0000,,that we will look at each five bit block\Non its own as it is zero to sixteen and a Dialogue: 0,0:26:53.85,0:27:01.02,Default,,0000,0000,0000,,sign value. That's much easier, because\Nit's actually kind of weird how the five Dialogue: 0,0:27:01.02,0:27:05.57,Default,,0000,0000,0000,,bits are extracted and I don't want to\Nbore you with it. So let's just consider Dialogue: 0,0:27:05.57,0:27:12.12,Default,,0000,0000,0000,,that we look at each group of five bits\Nconverted into a value from zero to Dialogue: 0,0:27:12.12,0:27:18.85,Default,,0000,0000,0000,,sixteen and a one and a sign or plus minus\Nsixteen. So when you hear me talk about Dialogue: 0,0:27:18.85,0:27:24.53,Default,,0000,0000,0000,,limbs you just know that it means the five\Nbit value from the key. This is still the Dialogue: 0,0:27:24.53,0:27:34.73,Default,,0000,0000,0000,,giant d key that's the multiplier. So how\Ndoes the attack change? Not that much! Dialogue: 0,0:27:34.73,0:27:39.30,Default,,0000,0000,0000,,Instead of attacking one bit at a time,\Nyou know two points - one that breaks for Dialogue: 0,0:27:39.30,0:27:45.18,Default,,0000,0000,0000,,zero, one that breaks for one - we attack\None limb at a time, one that breaks for Dialogue: 0,0:27:45.18,0:27:49.02,Default,,0000,0000,0000,,one, one that breaks for two, one that\Nbreaks for three, sixteen, minus one, Dialogue: 0,0:27:49.02,0:27:57.72,Default,,0000,0000,0000,,minus two, minus 16. So, to recover five\Nbits of the key, we'll need on average Dialogue: 0,0:27:57.72,0:28:04.43,Default,,0000,0000,0000,,half the space: seventeen points, which is\Na little less efficient than the bit-by- Dialogue: 0,0:28:04.43,0:28:15.95,Default,,0000,0000,0000,,bit one, because that would be five points\Nfor five bits. So, however, how the attack Dialogue: 0,0:28:15.95,0:28:23.06,Default,,0000,0000,0000,,triggers is the same: We're looking for a\Nbug that happens in the five doubles at Dialogue: 0,0:28:23.06,0:28:33.70,Default,,0000,0000,0000,,the very right time or that happens at the\Naddition at the very right time. Now Dialogue: 0,0:28:33.70,0:28:38.65,Default,,0000,0000,0000,,that's still the high level of how we're\Ngoing to do it, but in practice I didn't Dialogue: 0,0:28:38.65,0:28:43.87,Default,,0000,0000,0000,,tell you how we're going to magically\Ngenerate these magic points that break Dialogue: 0,0:28:43.87,0:28:51.38,Default,,0000,0000,0000,,just at the right time. And I didn't tell\Nyou because it's fuzzing. There is there's Dialogue: 0,0:28:51.38,0:28:58.83,Default,,0000,0000,0000,,no specific way to generate them\Nalgebraically, so instead we just hooked Dialogue: 0,0:28:58.83,0:29:03.50,Default,,0000,0000,0000,,the assembly code with something that\Nwould just set a boolean, you know, true, Dialogue: 0,0:29:03.50,0:29:08.59,Default,,0000,0000,0000,,false, if the conditions for the bug are\Nmet. And then we run through a lot of Dialogue: 0,0:29:08.59,0:29:14.93,Default,,0000,0000,0000,,points. And if for each point we run it\Nthrough the limbs we already know, Dialogue: 0,0:29:14.93,0:29:19.52,Default,,0000,0000,0000,,remember this is an adaptive attack, so\Nwe want to learn the next limb. Dialogue: 0,0:29:19.52,0:29:24.24,Default,,0000,0000,0000,,We learned a few limbs, we want to learn\Nthe next one. We run through the ones we Dialogue: 0,0:29:24.24,0:29:30.63,Default,,0000,0000,0000,,know and then we try all the possible\Nvalues for ones that we don't know. If one Dialogue: 0,0:29:30.63,0:29:36.61,Default,,0000,0000,0000,,of them and only one of them breaks,\Nthat's a useful point. Because if we send Dialogue: 0,0:29:36.61,0:29:46.39,Default,,0000,0000,0000,,that point and it breaks, we know exactly\Nwhat the value of the next limb is. Okay, Dialogue: 0,0:29:46.39,0:29:53.68,Default,,0000,0000,0000,,so this is going even more low-level. If\Nyou're interested in optimizations, we had Dialogue: 0,0:29:53.68,0:29:57.86,Default,,0000,0000,0000,,to run through a lot of candidate points\Nand for each point we needed to know the d Dialogue: 0,0:29:57.86,0:30:02.85,Default,,0000,0000,0000,,value. Because we can find a magic point,\Nbut if we don't know the private key, we Dialogue: 0,0:30:02.85,0:30:10.05,Default,,0000,0000,0000,,don't know if the entire protocol works\Nand our oracle doesn't work anymore. So to Dialogue: 0,0:30:10.05,0:30:15.08,Default,,0000,0000,0000,,work with that instead of multiplying a\Nnew random private key every time we just Dialogue: 0,0:30:15.08,0:30:23.79,Default,,0000,0000,0000,,add that one to the private key and added\Nthe point to the public key, this is just Dialogue: 0,0:30:23.79,0:30:32.77,Default,,0000,0000,0000,,an optimization. We called into the\Nvarious assembly of the standard library. Dialogue: 0,0:30:32.77,0:30:37.84,Default,,0000,0000,0000,,Don't do this, but it's beautiful. You can\Ngo call all the unexported functions in Dialogue: 0,0:30:37.84,0:30:45.00,Default,,0000,0000,0000,,the standard library. I will never approve\Nit on code review, but I love it. And then Dialogue: 0,0:30:45.00,0:30:51.21,Default,,0000,0000,0000,,there's some post-processing to make sure\Nthat the bug is actually there, because Dialogue: 0,0:30:51.21,0:30:55.97,Default,,0000,0000,0000,,sometimes there are false positives. So we\Njust run it through the broken code, the Dialogue: 0,0:30:55.97,0:30:59.74,Default,,0000,0000,0000,,fixed code, is the result the same?\NWell, false positive, is it Dialogue: 0,0:30:59.74,0:31:10.69,Default,,0000,0000,0000,,different, good. Okay, so we have a way to\Nmove through the attack. The only thing we Dialogue: 0,0:31:10.69,0:31:15.09,Default,,0000,0000,0000,,don't have yet is: How we figure out the\Nfirst limb. The first one, the most Dialogue: 0,0:31:15.09,0:31:19.10,Default,,0000,0000,0000,,important, the most significant one, when\Nwe still don't know anything about the Dialogue: 0,0:31:19.10,0:31:27.21,Default,,0000,0000,0000,,key. The problem with this one is: It's\Nlike this, so let's pick three, it's an Dialogue: 0,0:31:27.21,0:31:32.83,Default,,0000,0000,0000,,example okay, let's pretend that the limb\Nis three. So we do our usual thing, we do Dialogue: 0,0:31:32.83,0:31:40.33,Default,,0000,0000,0000,,our fuzzing and we find something that\Nbreaks at the fifth doubling and we send Dialogue: 0,0:31:40.33,0:31:47.02,Default,,0000,0000,0000,,it and it breaks. It means that the first\Nlimb is three, right? Wrong. Sadly, it Dialogue: 0,0:31:47.02,0:31:55.06,Default,,0000,0000,0000,,might mean that the limb is also 6 or 12.\NBecause how six is selected for example is Dialogue: 0,0:31:55.06,0:32:01.77,Default,,0000,0000,0000,,that three is taken, it's doubled and\Nsaved in the precomputation table as six, Dialogue: 0,0:32:01.77,0:32:06.08,Default,,0000,0000,0000,,then it's taken out of the table, doubled\Nfive times, but what happens after you Dialogue: 0,0:32:06.08,0:32:13.03,Default,,0000,0000,0000,,double six four times? What's the value?\NThe exact same as doubling three five Dialogue: 0,0:32:13.03,0:32:19.39,Default,,0000,0000,0000,,times, and the sequence is the exact same!\NSo we don't know, which one it is, because Dialogue: 0,0:32:19.39,0:32:23.85,Default,,0000,0000,0000,,we only know that that's the sequence but\Nthat doesn't tell us anything. And the Dialogue: 0,0:32:23.85,0:32:29.74,Default,,0000,0000,0000,,same happens for 12, 12 is nothing else\Nthan 3 double double. So if we double it Dialogue: 0,0:32:29.74,0:32:36.78,Default,,0000,0000,0000,,five times, at the third double it breaks\Nand we only know if it breaks or not. So Dialogue: 0,0:32:36.78,0:32:42.68,Default,,0000,0000,0000,,we can't move, so instead what we do is\Nthat we find three points: one that breaks Dialogue: 0,0:32:42.68,0:32:48.35,Default,,0000,0000,0000,,after doubling three five times, one that\Nbreaks doubling it six times, and one that Dialogue: 0,0:32:48.35,0:32:54.02,Default,,0000,0000,0000,,breaks after doubling it seven times. We\Nsend them all and we look at which ones Dialogue: 0,0:32:54.02,0:33:01.11,Default,,0000,0000,0000,,break. Only this one? It's a three! The\Nfirst and the second but not the third Dialogue: 0,0:33:01.11,0:33:07.67,Default,,0000,0000,0000,,point? It's a six! All three? It's a 12!\NThis took me forever to wrap my head Dialogue: 0,0:33:07.67,0:33:17.25,Default,,0000,0000,0000,,around, this is like pure shaman insight.\NOkay now I can feel that you're getting Dialogue: 0,0:33:17.25,0:33:25.87,Default,,0000,0000,0000,,bit tired, this is intensive, it's a lot\Nof math, so let's go for a change of pace Dialogue: 0,0:33:25.87,0:33:32.66,Default,,0000,0000,0000,,and let's talk about kangaroos instead.\NI'm gonna tell you something that I Dialogue: 0,0:33:32.66,0:33:40.91,Default,,0000,0000,0000,,learned from a cryptographic paper, I\Nswear. And it's about how kangaroos jump. Dialogue: 0,0:33:40.91,0:33:48.73,Default,,0000,0000,0000,,Apparently kangaroos jump depending on how\Nthe terrain on which they are jumping from Dialogue: 0,0:33:48.73,0:33:54.37,Default,,0000,0000,0000,,is. Depending on that terrain, if you put\Ntwo kangaroos on the exact same spot, they Dialogue: 0,0:33:54.37,0:33:59.77,Default,,0000,0000,0000,,will jump the same distance and\Napproximately the same direction. I don't Dialogue: 0,0:33:59.77,0:34:05.47,Default,,0000,0000,0000,,know, if this is true, but Pollard said so\Nin a paper and I am NOT arguing with Dialogue: 0,0:34:05.47,0:34:13.54,Default,,0000,0000,0000,,Pollard. So now, why is this useful? Well,\Nthis makes for an extremely cool way to Dialogue: 0,0:34:13.54,0:34:22.31,Default,,0000,0000,0000,,catch kangaroos! I mean, did you expect\Nsome math or crypto? I know, we're Dialogue: 0,0:34:22.31,0:34:27.92,Default,,0000,0000,0000,,catching kangaroos here! So you take a\Nkangaroo that you have on hand, because Dialogue: 0,0:34:27.92,0:34:34.22,Default,,0000,0000,0000,,you all have a kangaroo on hand. And you\Nput a GPS tracker on it and you let it Dialogue: 0,0:34:34.22,0:34:43.25,Default,,0000,0000,0000,,loose. This kangaroo jumps and it roams it\Nenjoys a brief stint of freedom and it Dialogue: 0,0:34:43.25,0:34:48.44,Default,,0000,0000,0000,,runs and at some point you go pick it up\Nand because you know where it is and you Dialogue: 0,0:34:48.44,0:34:54.68,Default,,0000,0000,0000,,place a trap there exactly where you find\Nit. What happens to the kangaroo that is Dialogue: 0,0:34:54.68,0:35:04.63,Default,,0000,0000,0000,,just passing by? If it steps at any point\Non one of the points, where the other Dialogue: 0,0:35:04.63,0:35:10.82,Default,,0000,0000,0000,,kangaroo jumped from there on it will\Nfollow the same path. Because each jump Dialogue: 0,0:35:10.82,0:35:20.75,Default,,0000,0000,0000,,depends on the ground. So this way if the\Nwild kangaroo lands on any of the prints Dialogue: 0,0:35:20.75,0:35:25.65,Default,,0000,0000,0000,,of the previous kangaroo you're catching\Nit because eventually it will end up in Dialogue: 0,0:35:25.65,0:35:30.94,Default,,0000,0000,0000,,the trap. Okay, this had nothing to do\Nwith the talk, I just wanted to share Dialogue: 0,0:35:30.94,0:35:38.35,Default,,0000,0000,0000,,this!\NNow, okay, so here is how this converts to Dialogue: 0,0:35:38.35,0:35:44.95,Default,,0000,0000,0000,,crypto. We can make elliptic curve points\Njump like kangaroos, we just have to make Dialogue: 0,0:35:44.95,0:35:53.67,Default,,0000,0000,0000,,the jump deterministic based on the input,\Nbased on the starting point. For example Dialogue: 0,0:35:53.67,0:35:59.77,Default,,0000,0000,0000,,we can take a hash, any hash, you design\Nthe hash. Apparently that's popular in Dialogue: 0,0:35:59.77,0:36:01.74,Default,,0000,0000,0000,,cryptocurrencies to design your own hash\N.. Dialogue: 0,0:36:01.74,0:36:13.09,Default,,0000,0000,0000,,{\i1}laughter{\i0}\NAnd you hash a point to another point and Dialogue: 0,0:36:13.09,0:36:19.87,Default,,0000,0000,0000,,when you want to do a jump you take the\Npoint and you add it to its own hash, so Dialogue: 0,0:36:19.87,0:36:27.63,Default,,0000,0000,0000,,Q_N+1 depends only on QN, and this is just\Nlike the kangaroo jump. How do you use Dialogue: 0,0:36:27.63,0:36:35.81,Default,,0000,0000,0000,,this for what we're doing? We want to\Nrecover d, right? We want to recover the Dialogue: 0,0:36:35.81,0:36:43.93,Default,,0000,0000,0000,,multiplier, the discrete log it's often\Ncalled, of the public key. How we work Dialogue: 0,0:36:43.93,0:36:50.81,Default,,0000,0000,0000,,with this is that we take a tame kangaroo,\Na point that we know the d off, and we Dialogue: 0,0:36:50.81,0:36:58.66,Default,,0000,0000,0000,,make it jump a lot. It keeps jumping and\Nwe remember what the value is at the end. Dialogue: 0,0:36:58.66,0:37:02.90,Default,,0000,0000,0000,,We take that value at the end and we save\Nit. No need to keep all the points in Dialogue: 0,0:37:02.90,0:37:09.81,Default,,0000,0000,0000,,between, so we don't need some giant\Nmemory construction and then we take the Dialogue: 0,0:37:09.81,0:37:16.74,Default,,0000,0000,0000,,point that we don't know the d of and we\Nmake it jump a lot. What happens is that Dialogue: 0,0:37:16.74,0:37:23.17,Default,,0000,0000,0000,,it has much higher probability to\Nintersect one of the various prints of the Dialogue: 0,0:37:23.17,0:37:28.57,Default,,0000,0000,0000,,previous point. When it does, it will\Neventually end up in our trap, it will end Dialogue: 0,0:37:28.57,0:37:36.95,Default,,0000,0000,0000,,up having the same value as the one we\Ncalculated earlier. When that happens, we Dialogue: 0,0:37:36.95,0:37:43.70,Default,,0000,0000,0000,,know how far the wild point traveled,\Nbecause we were the ones making it jump. Dialogue: 0,0:37:43.70,0:37:49.49,Default,,0000,0000,0000,,So we can just walk backwards to the\Nstarting point. It turns out that this is Dialogue: 0,0:37:49.49,0:37:55.88,Default,,0000,0000,0000,,extremely efficient to find the d value\Nwhen you know the interval of the d value. Dialogue: 0,0:37:55.88,0:38:01.88,Default,,0000,0000,0000,,The intuition there is that if the\Nkangaroo starts in a small area: You know Dialogue: 0,0:38:01.88,0:38:07.19,Default,,0000,0000,0000,,when it's been too much time that it\Nprobably travelled past your trap. So you Dialogue: 0,0:38:07.19,0:38:14.68,Default,,0000,0000,0000,,have to rewind time, which in crypto you\Ncan, and try again, because it went past Dialogue: 0,0:38:14.68,0:38:18.36,Default,,0000,0000,0000,,your trap. So the smaller the interval,\Nthe more precise you can be, the more Dialogue: 0,0:38:18.36,0:38:26.41,Default,,0000,0000,0000,,efficient attack. This is called the\NPollard-kangaroo attack. It's described in Dialogue: 0,0:38:26.41,0:38:30.79,Default,,0000,0000,0000,,original paper from the 1980s, it was\Ndescribed on Diffie-Hellman first, but it Dialogue: 0,0:38:30.79,0:38:34.68,Default,,0000,0000,0000,,works on any group, so it works on\Nelliptic curves. And the elliptic curve Dialogue: 0,0:38:34.68,0:38:44.43,Default,,0000,0000,0000,,version is then improved by a few papers\Nlater and there is a chapter in the Dialogue: 0,0:38:44.43,0:38:50.31,Default,,0000,0000,0000,,elliptic and hyperelliptic handbook\Nthat describes it. Dialogue: 0,0:38:50.31,0:38:55.61,Default,,0000,0000,0000,,So we have it all, we have how to start,\Nwe have how to run through the attack and Dialogue: 0,0:38:55.61,0:39:03.94,Default,,0000,0000,0000,,we have a how to end. So now let's get\Nconcrete, let's pick a target, as I said Dialogue: 0,0:39:03.94,0:39:15.66,Default,,0000,0000,0000,,this attack works against JWT. JWT made\N... a lot of questionable choices. One of Dialogue: 0,0:39:15.66,0:39:21.02,Default,,0000,0000,0000,,them is to include as one of the public\Nkey algorithms elliptic curve Diffie- Dialogue: 0,0:39:21.02,0:39:25.03,Default,,0000,0000,0000,,Hellman but not the version of Diffie-\NHellman you and I are familiar with. The Dialogue: 0,0:39:25.03,0:39:30.90,Default,,0000,0000,0000,,one where we both generate a new private\Nkey every time, which makes this attack Dialogue: 0,0:39:30.90,0:39:35.16,Default,,0000,0000,0000,,impossible. Remember that this is an\Nadaptive attack. We need to query the Dialogue: 0,0:39:35.16,0:39:40.73,Default,,0000,0000,0000,,orcale for the same private key over and\Nover and over again. Instead there's a Dialogue: 0,0:39:40.73,0:39:48.45,Default,,0000,0000,0000,,variant called ephemeral static Diffie-\NHellman, where one of the two sides is Dialogue: 0,0:39:48.45,0:39:54.69,Default,,0000,0000,0000,,always the same. This is sometimes done as\Nan optimization, don't do that. OpenSSL Dialogue: 0,0:39:54.69,0:40:02.02,Default,,0000,0000,0000,,was doing that and it stopped doing that\Nafter a bunch of attacks came from that. Dialogue: 0,0:40:02.02,0:40:06.96,Default,,0000,0000,0000,,So in TLS that usually doesn't happen and\Nthe Go TLS stack thankfully never did Dialogue: 0,0:40:06.96,0:40:14.00,Default,,0000,0000,0000,,that, so the attack doesn't work against\NTLS. But JWT is encoded it straight into Dialogue: 0,0:40:14.00,0:40:20.80,Default,,0000,0000,0000,,the standard, because if your public key\Nis fixed, so is your private key, always Dialogue: 0,0:40:20.80,0:40:30.61,Default,,0000,0000,0000,,the same. So if we have a service that\Naccepts things encrypted with a ECDHES Dialogue: 0,0:40:30.61,0:40:36.74,Default,,0000,0000,0000,,algorithm, we can use this attack. For\Nexample against the popular implementation Dialogue: 0,0:40:36.74,0:40:46.37,Default,,0000,0000,0000,,Go-Jose, it's not Go-Jose's fault and Go\N1.8.1.1, the latest vulnerable version, Dialogue: 0,0:40:46.37,0:40:52.84,Default,,0000,0000,0000,,and we can just check if the service can\Ndecrypt what we're sending it. It can, Dialogue: 0,0:40:52.84,0:40:58.43,Default,,0000,0000,0000,,because it throws HTTP error when it\Ncan't, because of different timings. This Dialogue: 0,0:40:58.43,0:41:03.30,Default,,0000,0000,0000,,changes in any case, but what you need is\Nthe Oracle that tells you: did it work did Dialogue: 0,0:41:03.30,0:41:08.28,Default,,0000,0000,0000,,it not work? Did the bug trigger, so are\Nyou right about your prediction of the Dialogue: 0,0:41:08.28,0:41:13.37,Default,,0000,0000,0000,,limb or are you not?\NThen of course we need to do a lot of Dialogue: 0,0:41:13.37,0:41:22.43,Default,,0000,0000,0000,,work. If you don't have the resources of a\Nbig corporation of where to spin up Dialogue: 0,0:41:22.43,0:41:27.94,Default,,0000,0000,0000,,things, you can just use EC2 spot\Ninstances. How we architected that, is Dialogue: 0,0:41:27.94,0:41:33.94,Default,,0000,0000,0000,,that there will be a small piece of code\Nthat do nothing intensive on your laptop Dialogue: 0,0:41:33.94,0:41:43.54,Default,,0000,0000,0000,,or anything. It would accept HTTP requests\Nfrom the workers. The beautiful thing Dialogue: 0,0:41:43.54,0:41:48.36,Default,,0000,0000,0000,,about this infrastructure is that you can\Nhorizontally scale the workers, spin up as Dialogue: 0,0:41:48.36,0:41:58.84,Default,,0000,0000,0000,,many as you want on node.js platforms,\Nbecause the only thing that they need to Dialogue: 0,0:41:58.84,0:42:04.04,Default,,0000,0000,0000,,be able to do: they don't need to have\Nports open, you don't have to worry about Dialogue: 0,0:42:04.04,0:42:07.99,Default,,0000,0000,0000,,NAT, you can even run it on your botnet,\Nbecause the only thing they have to do is Dialogue: 0,0:42:07.99,0:42:14.23,Default,,0000,0000,0000,,connect back and ask for work and then\Nafter 30 cycles or when they find the Dialogue: 0,0:42:14.23,0:42:18.18,Default,,0000,0000,0000,,point, connect back and say I found\Nsomething, I didn't find anything, give me Dialogue: 0,0:42:18.18,0:42:26.50,Default,,0000,0000,0000,,some more work and send the result. This\Nwas also useful, because if you get the Dialogue: 0,0:42:26.50,0:42:31.21,Default,,0000,0000,0000,,worker code wrong or if you want to change\Nthe deployment, you can just redeploy the Dialogue: 0,0:42:31.21,0:42:36.62,Default,,0000,0000,0000,,workers without losing state on the\Ndispatcher. Because the dispatcher just Dialogue: 0,0:42:36.62,0:42:44.93,Default,,0000,0000,0000,,keeps running and it will just wait for\Nworkers to come and ask. Specifically we Dialogue: 0,0:42:44.93,0:42:51.80,Default,,0000,0000,0000,,built this just with the small script that\Nyou can start an EC2 machine with, because Dialogue: 0,0:42:51.80,0:42:59.37,Default,,0000,0000,0000,,we didn't even need to make a custom\Nimage. So a few figures, a few numbers. Dialogue: 0,0:42:59.37,0:43:05.26,Default,,0000,0000,0000,,Each Key has 52 limbs, it will take a bit\Nless than that, because we have kangaroos. Dialogue: 0,0:43:05.26,0:43:14.10,Default,,0000,0000,0000,,But let's say approximately 52. Each limb\Nis 16 points on average. It would be 17, Dialogue: 0,0:43:14.10,0:43:18.75,Default,,0000,0000,0000,,but two of the points are faster to find,\Nso let's say 16. Each point takes Dialogue: 0,0:43:18.75,0:43:30.57,Default,,0000,0000,0000,,approximately 2 to the 26 candidate\Npoints, before we find one that triggers Dialogue: 0,0:43:30.57,0:43:41.01,Default,,0000,0000,0000,,the bug at the right point. Since we need\N16 candidate points and each takes 2 to Dialogue: 0,0:43:41.01,0:43:49.74,Default,,0000,0000,0000,,the 26 candidate points, that takes\Napproximately 85 CPU hours. That's like Dialogue: 0,0:43:49.74,0:43:57.52,Default,,0000,0000,0000,,one CPU running for an hour, 1 core. Turns\Nout that you can get 85 CPU hours from Dialogue: 0,0:43:57.52,0:44:04.44,Default,,0000,0000,0000,,spot instances for about a dollar and a\Nquarter, which makes the total cost of the Dialogue: 0,0:44:04.44,0:44:10.58,Default,,0000,0000,0000,,attack something like 60 bucks.\NWhich was a relief, because I had done the Dialogue: 0,0:44:10.58,0:44:16.78,Default,,0000,0000,0000,,math wrong first and the it came out as at\N1000 and I run the demo tonight and I Dialogue: 0,0:44:16.78,0:44:26.42,Default,,0000,0000,0000,,didn't check the bill, yeah.. Anyway, it's\Ncheap. Now, I am not brave enough to run Dialogue: 0,0:44:26.42,0:44:31.81,Default,,0000,0000,0000,,the attack live, because, yes, it's a nice\Ninfrastructure, but no, I don't trust it Dialogue: 0,0:44:31.81,0:44:38.39,Default,,0000,0000,0000,,that much. But also, because it takes a\Nwhile. If you don't want to spin up Dialogue: 0,0:44:38.39,0:44:46.62,Default,,0000,0000,0000,,infinite number of EC2 machines, you have\Nto accept that it would take about, I Dialogue: 0,0:44:46.62,0:44:53.52,Default,,0000,0000,0000,,think, our attack run in 12 hours. So\Nwe're gonna look at a sped-up version of a Dialogue: 0,0:44:53.52,0:44:58.18,Default,,0000,0000,0000,,one-hour video in the next 45 minutes, you\Nhave time, right? Dialogue: 0,0:44:58.18,0:45:02.65,Default,,0000,0000,0000,,{\i1}laughter{\i0}\NNo, it's a couple of minutes. So this is Dialogue: 0,0:45:02.65,0:45:09.81,Default,,0000,0000,0000,,the UI. It shouldn't be too confusing and\Nif anyone works at Hollywood and wants to Dialogue: 0,0:45:09.81,0:45:17.10,Default,,0000,0000,0000,,license it, we can talk. What you're\Nseeing is that the red values are the ones Dialogue: 0,0:45:17.10,0:45:23.06,Default,,0000,0000,0000,,that we found a point for from the workers\Nand we submitted. And when we submitted Dialogue: 0,0:45:23.06,0:45:28.99,Default,,0000,0000,0000,,that it resulted not to be the right limb\Nand the green ones are the ones that Dialogue: 0,0:45:28.99,0:45:35.52,Default,,0000,0000,0000,,instead broke, so they're the right limb.\NRemember that here the target is a JWT Dialogue: 0,0:45:35.52,0:45:42.86,Default,,0000,0000,0000,,receiving application. And then you can\Nsee the key slowly flipping from the Dialogue: 0,0:45:42.86,0:45:51.65,Default,,0000,0000,0000,,bottom and it's exactly like Hollywood, I\Nlove that. So you can see the limbs Dialogue: 0,0:45:51.65,0:45:57.08,Default,,0000,0000,0000,,filling up as we find them and that\Napproximately there's 30 bits, so 2 to the Dialogue: 0,0:45:57.08,0:46:07.00,Default,,0000,0000,0000,,30 rounds, so 30 candidates work for each\Nround for each limb that we find. It Dialogue: 0,0:46:07.00,0:46:16.93,Default,,0000,0000,0000,,obviously depends on luck and yes the the\Nthing will probably keep running for a Dialogue: 0,0:46:16.93,0:46:23.79,Default,,0000,0000,0000,,little while, but this is already at limb\Nnine, it has to get to 52 and you don't Dialogue: 0,0:46:23.79,0:46:34.51,Default,,0000,0000,0000,,have that patience. So this was the attack\Nthe code will be open-source soon. Leave Dialogue: 0,0:46:34.51,0:46:40.12,Default,,0000,0000,0000,,the limbs you lost, they belong to us now.\NAnd: any questions? Dialogue: 0,0:46:40.12,0:46:56.33,Default,,0000,0000,0000,,{\i1}applause{\i0}\NHerald: Valsorda, thank you very much for Dialogue: 0,0:46:56.33,0:47:02.42,Default,,0000,0000,0000,,a lovely talk and the kangaroos. So, we\Nhave a question from the signal angel, go Dialogue: 0,0:47:02.42,0:47:05.35,Default,,0000,0000,0000,,ahead, please.\NSignal Angel: Actually the internet wants Dialogue: 0,0:47:05.35,0:47:10.06,Default,,0000,0000,0000,,to know: Did you compare this bug to\Nimplementation in other libraries. Dialogue: 0,0:47:10.06,0:47:14.56,Default,,0000,0000,0000,,Filippo: So I guess that means, if I\Nlooked for similar bugs in other Dialogue: 0,0:47:14.56,0:47:21.29,Default,,0000,0000,0000,,implementations. We did not, because each\Nimplementation is a bit different. Hanno Dialogue: 0,0:47:21.29,0:47:27.52,Default,,0000,0000,0000,,works on a lot of fuzzing of bigint\Nimplementations and at one point he asked Dialogue: 0,0:47:27.52,0:47:33.30,Default,,0000,0000,0000,,me, like on Twitter just today, if I tried\Nfuzzing the Go implementation for example. Dialogue: 0,0:47:33.30,0:47:41.19,Default,,0000,0000,0000,,And sadly this is constant time code that\Nis specific to P256, so the answer is, Dialogue: 0,0:47:41.19,0:47:45.78,Default,,0000,0000,0000,,there's a lot of them and the bug can be\Nsmall and anywhere. It's not like you will Dialogue: 0,0:47:45.78,0:47:52.59,Default,,0000,0000,0000,,be looking for another bug in P256\Nsubtraction, it can be anywhere in the Dialogue: 0,0:47:52.59,0:47:57.19,Default,,0000,0000,0000,,underlying math and we can turn that into\Nthe same attack. So, no, we didn't look Dialogue: 0,0:47:57.19,0:48:05.43,Default,,0000,0000,0000,,for this specific one, but I think that\Nfour CVEs in 2017 on open SSL have Dialogue: 0,0:48:05.43,0:48:11.59,Default,,0000,0000,0000,,descriptions that are very similar, but\Nthey're about finite field Diffie-Hellman, Dialogue: 0,0:48:11.59,0:48:21.92,Default,,0000,0000,0000,,like normal DH. If you look for something\Nthat says about it's barely doable, Dialogue: 0,0:48:21.92,0:48:27.56,Default,,0000,0000,0000,,because all the computation can be done\Noffline. That's this kind of attacks on Dialogue: 0,0:48:27.56,0:48:32.89,Default,,0000,0000,0000,,open SSL. Next?\NHerald: Are there any other questions from Dialogue: 0,0:48:32.89,0:48:39.20,Default,,0000,0000,0000,,the Signal Angel? So please line up at the\Nmicrophone. Microphone one please. Dialogue: 0,0:48:39.20,0:48:44.55,Default,,0000,0000,0000,,Mic1: So why can't you determine the\Npoints algebraically? Dialogue: 0,0:48:44.55,0:48:52.30,Default,,0000,0000,0000,,Filippo: Laziness? No, so it's entirely\Nassembly and there's a lot of points where Dialogue: 0,0:48:52.30,0:49:01.26,Default,,0000,0000,0000,,the value is then thrown out or it might\Nget corrected by .. it's essentially we Dialogue: 0,0:49:01.26,0:49:07.50,Default,,0000,0000,0000,,didn't see a clear path to this, and it's\N$65 on ec2, so it doesn't really change Dialogue: 0,0:49:07.50,0:49:14.74,Default,,0000,0000,0000,,the feasibility to just fuzz them, so we\Njust went for the fastest path to the Dialogue: 0,0:49:14.74,0:49:19.00,Default,,0000,0000,0000,,entrance.\NHerald: Are there any other questions? Dialogue: 0,0:49:19.00,0:49:21.83,Default,,0000,0000,0000,,Filippo: No one is asking about kangaroos,\Npeople, I mean.. Dialogue: 0,0:49:21.83,0:49:26.09,Default,,0000,0000,0000,,Herald: Yes, ask about kangaroos, lovely.\Nhave you been to Australia? Dialogue: 0,0:49:26.09,0:49:28.53,Default,,0000,0000,0000,,Filippo: I haven't.\NHerald: Okay, you have to. Dialogue: 0,0:49:28.53,0:49:31.23,Default,,0000,0000,0000,,Filippo: Yep, definitely.\NHerald: I think, there aren't any other Dialogue: 0,0:49:31.23,0:49:36.56,Default,,0000,0000,0000,,questions. So Filippo Valsorda, big round\Nof applause for you. Thank you! Dialogue: 0,0:49:36.56,0:49:40.40,Default,,0000,0000,0000,,{\i1}applause{\i0} Dialogue: 0,0:49:40.40,0:49:45.51,Default,,0000,0000,0000,,{\i1}34c3 outro{\i0} Dialogue: 0,0:49:45.51,0:50:02.00,Default,,0000,0000,0000,,subtitles created by c3subtitles.de\Nin the year 2019. Join, and help us!