 Let's give Daniel and Daniel a big round of applause and hear about some uh crypto stuff. Have a great time boys. Have fun. Thanks everybody. They were nice enough to give me a shot too even though I've spoken before so. Although I didn't, I didn't expect it to be room temperature Jack Daniels about body temperature. Sorry, body temperature Jack Daniels so. Um so uh so I'm Daniel Crowley. Um I run research at X-Force Red. Um I'm a cryptography nerd. If you've ever heard of the tool Featherduster, that's my work. Uh also I am C-Landic nobility. Um and I'd like to clarify that crypto does not mean either cryptocurrency or cryptography. Crypto means crypto zoology so please get that right. Yeah so it's my first time speaking here and uh I thought I would start out strong with a uh quality meme. Um so that you know that's just for you guys. Um but I just graduated from Georgia Tech. Um I'm also C-Landic nobility whereas he's a baron I am a lord. Um and yeah so I'm working with him doing our crypto stuff. Yeah. Uh I'd also like to point out that Team Celand here is dangerously close to completing the DEF CON infinity gauntlet. Uh we have the speaker stone, the contest stone and the goon stone and a human stone as well. So for the sake of DEF CON Spider-Man please. Uh don't get a press badge near us. Um anyway sorry. So that there is um there is a problem that we were trying to solve here um and as as any good uh solution should have a problem that is trying to solve. Um so there's this whole big thing made about hash cracking. Hash cracking is a huge thing in the hacker community um and in information security in general and this is for good reason. Um there's lots of practical applications uh for hash cracking um uh in in penetration testing and things like that in strength testing password strength. There's a long history of it um but it's even a sport and a business. You know there's a competition here at DEF CON called crack me if you can. Which is all based around password hash cracking. Um now something that is not quite as big by a long shot is cracking encryption keys. Um there's examples of this that are that are being done um sort of uh on a regular basis. So WPA2 cracking um is cracking symmetric encryption keys. Um but then you also have a lot of stuff that's being done in terms of side channel analysis. So analysis of power or timing or heat or something like that in order to recover encryption keys without uh any sort of uh key search attack. Any sort of brute force. So it's not really brute force it's not really cracking it's more of key recovery. And if you can recover a partial key then you can brute force the rest. Um and then we see algorithm specific attacks. So for instance uh there's been a lot of work in cracking DES keys because DES has a pittifully short key length. Uh and so that makes it practical to do an exhaustive key search without any sort of optimization and it works. Um the EFF has built a DSS uh the most recent DES cracker that I'm aware of. And it's it's just DES is dead. Uh single DES is dead. Um but this is sort of um what we see in the community on encryption key cracking so far. Um but as far as general uh cracking of encryption keys there's not a whole lot going on. Um nobody has really talked about how in general you take encrypted data and try to guess the key in a meaningful way in a practical way. This is really what we're going to be discussing here today. Um but first let's talk about why the traditional wisdom is that symmetric key cracking should fail in theory. Um when you know we've seen with like WPA2 key cracking that it really does work in practice at least with some applications. So the first big thing is key validation. When you take the wrong key and try to use it to decrypt some encrypted data, decryption can't fail. It's it's it's basically an equation. You're you're just running through a set uh a series of steps. Um and it can't it can't fail really. Uh it just produces a different output. Um because you're really just permuting data from one one thing to another. Um so you just get a different pseudo randomized output instead of the correct output. Now in theory, academically speaking uh the the common wisdom is that it should be impossible to guess encryption keys because you can't tell when you've got the correct key because you don't know anything about the message. Now we'll talk about why this is a bad uh assumption why the theory doesn't match the practice, why the real world is different. Um but then you also have the problem of key space. Now um the when you don't when you're not talking about like an export strength cipher cipher which is specifically weakened to have a key length that can be exhaustively searched where we can guess every key with modern hardware. Um you you know when you're talking about like 8 ES 128 for instance you're talking about 16 bytes of key material or 128 bits of key material and to guess every single key with all of the computing resources on planet earth right now it should take longer than we will take to reach the heat death of the universe. So that is another reason why in theory what we're doing practically should fail. Um so let's talk about the solution to validating our guesses. Um so in the real world there is an easy distinction that we can make in most cases between the pseudo random output that we get from using the wrong key to the structured meaningful data that we get from decrypting data using the correct key. In the real world we can we do have some information about what the message is supposed to be and we'll dive deeper into that but you know like if you're seeing English words in a decrypted uh uh in decrypted data if you're seeing meaningful looking data uh if you're seeing uh formats like XML or JSON that that that's you know statistically it's possible that you can come out with that but it's unlikely and we'll talk about just how unlikely uh later on. Um but knowing or guessing part of the plain text is often very easy. We can make a lot of good general assumptions about what data we're going to get and we'll talk about that a little bit more later. Um but if we can validate the data we can validate that the key is correct. Um so uh with electronic code book mode um as an example um there are certain so there are certain considerations that we need to make. So AES by itself is just a black box that takes 16 bytes and a key and turns those 16 bytes into some other 16 bytes and back. Um so it's sort of like a um it's it's a pseudo random permutation. Right? Um now in order to process data with AES it needs to be exactly 16 bytes in length. Um and electronic code book mode is the most naive construction is the simplest construction and this is just for demonstration purposes. We won't get into the all the the problems with ECB. Um but the the thing is that if we have data that is longer than 16 bytes we need to split it up into chunks and do something with those chunks process them individually with AES or whatever block cipher we're using. Um now the thing is if we don't have enough data we need to add what's called padding. So we add at the very end we add a little bit of padding or junk data to the end that is recognizable uh in our crypto system as junk data so that it can be removed so that we can take data that's 15 bytes or 30 bytes or something that doesn't evenly fit into 16 byte chunks and process it with AES which is a function that processes 16 bytes and no more and no less. And what this means for us because padding is required to use AES in a useful way it means we have data that we can validate. So we need padding. We need to apply padding to messages and when we decrypt it we can see that padding and in fact many common encryption libraries when decrypting will check the padding and if it does not uh uh look correct it will actually fail. So while encryption you know while decryption cannot really fail with the wrong key if you were to use the wrong key in decryption your library would probably fail. So this is a way that we can easily validate. Now it is possible for padding to be on a random output just by chance just by random chance but let's talk about how feasible it is let let's talk about how much of a problem that is. So let's talk about uh one of the most common padding schemes in the world this is called pkcs5 or pkcs7 padding and the trivia there is that this was originally released in a standards document uh called pkcs number five and then they they defined it for eight byte block ciphers 64 bit block ciphers and then later on um they said well actually this scheme works for any block size so it works for any block size so just use it like that and it's fine and that was in pkcs number seven so um if a cryptographer uh which we cryptographers are notoriously pedantic um ever is like eh that's actually pkcs seven. Now you know why. Um so uh but if you the way it works is basically like this however many bytes you need to get to the next block boundary uh you just take the that number and and make that the the byte value of every byte that you add so you have five open bytes to get to the next block boundary you add five or two twos and the beauty of this scheme is that if you have for instance four spots empty four bytes that you need to pad and you have a ASCII value four byte at the end of your plain text um a well written pkcs seven padding uh removal routine we'll just take a look at the last byte and say okay is the number four are there four fours at the end there are great I'll remove them so this is totally unambiguous um this is one of the this is very simple padding and it's very commonly used it's very well uh supported um but we can validate this right so um any message that ends in a uh uh a byte with the value one is padded correctly under pkcs five slash seven um which means that we have a one in 256 chance uh of getting a message that is padded correctly under pkcs five slash seven padding so padding alone produces too many false positives but we also have the the assumption that we can make that our data will be printable so we can say you know if we decrypt some piece of data with a can with a key that we're guessing we don't know if it's the correct key or not we can validate the padding and we can also most of the time make the assumption that the data that we're that's coming out is printable now there are a hundred printable characters in the ASCII character set out of 256 so our chances of getting seven characters assuming like an uh eight byte block um is one in a hundred and seven twenty uh uh sorry one in one in seven twenty um so if we have longer blocks more characters we have an even lower chance of a false positive so this in this eight byte scenario we have approximately a one in two hundred and fifty thousand false positive chance now that's not great when we're guessing a large volume of keys but it's also not that bad and we'll talk about how we can improve that further um one of the things to remember here is that it's way more likely for the last byte to be one particular value out of 256 possible values than uh two bytes being one particular value out of 256 possible values or three bytes or four bytes so when we have a false positive on the padding it's overwhelmingly likely to be just one byte value one uh at the end um so keep that in mind. In our worst case scenario we have a single block of cipher text um and this this is you know this this checking for printable characters is something that we can apply across multiple blocks um if we have only a single block of sixty four bit block uh uh of sixty four bit uh block cipher cipher text and we don't know anything about the plain text we are only checking on padding and printable characters we get about four thousand false positives every billion guest keys. Now that's not that bad and we can actually use character analysis frequency analysis um as is used in a lot of cracking of classical ciphers in order to narrow down what the best candidate keys are. So if we have one key that uh comes out you know allows us to decrypt two printable characters but it's a complete jumble and then we have another key that looks that that prints out uh an English word a word in English followed by multiple bytes of pkcs7 padding that's a much better result that is much more likely to be the correct key. And using these factors we can score the output so yes maybe we have four thousand false positives for a billion keys in the worst case scenario but we can score them and like Google results the first page is gonna be a lot more useful than the seventh. If we have more samples and this again is we're talking about worst case scenario eight bytes of cipher text uh per cipher text and multiple samples if we have two suddenly our false positive rate drops dramatically. We have one in sixty two point five billion false positives. So every sixty two point five billion keys we guess we get one false positive. And with three worst case cipher texts this is an obscene number it's like I think quadrillion it's in the quadrillions so this becomes a terribly practical attack when you have even two worst case cipher texts. Alright I uh I talk you know I'm not gonna be silent the whole presentation don't worry. Um so the next part of our solution is uh the key space. So basically um there is the way that developers should be doing this and then there's what actually happens. So how they should be choosing their keys at least is through actual random number generators um true random number generators or um also slightly worse but still uh valid is to kind of take a password and then basically you want to run it through a computationally expensive function uh like those shown and uh basically that that is a decent way of generating a key whereas you don't want your key to be say looking like these. Um so these are some keys that we have actually seen in the wild uh in some like real production code. So yeah I mean you can obviously see how how easy that would be to guess. Um and uh sometimes developers try to do uh like homebrew crypto and that's never a good good thing to try um so uh very common is to just you know choose your password and then just pad nulls null bytes until you hit sixteen bytes um or just repeat your chosen password over and over until you hit that sixteen bytes and then also um I talked about like computationally expensive password derivation functions um running it through MD5 is really really really computationally cheap so uh that's basically nothing if I know that you're using MD5 to generate your keys then I can run all of my password lists through MD5 and that's nothing um it it would be very easy to do. Um so yeah and it's kind of weird but um if you look at the first result of Google as a Java developer for how to do AES encryption they actually tell you the incorrect way of generating your key um either you know just running it through MD5 or SHA-1 or even just hard coding the bytes into your code which is terrible um so yeah um so this is just a basic usage of SHA-1 to generate the uh key. Um uh this is actually the exact code that they give you in the first result in Google. Yeah yeah this is from from their example um and yeah so so this is bad obviously um and uh so sometimes you know developers think oh you know I can just add a little bit more onto it and it'll be a little bit more secure. Ah XOR. Just take the SHA-1 and run it through a couple XORs which is easily reversible um this is no problem for for uh us to attack um because it's and and this is open source code right like this is real code that uh exists unfortunately. Um so then if you're going to not you know just hard code it or use a hash function um some people like to you know use random number generators and there are inherent issues with this uh depending on both how you seed it and how you the actual random number generator that you choose. Um so two common ones are right libcs rand probably all of us have used that and also java utl random um so yeah um the descracker that EFF released has uh 56 des have it's 56 bits of security and that right you can run that off of a laptop and crack deskeys right so these reduce your key space to 32 bit seeds uh seed space um or 48 and that's almost child's play like I I could crack this stuff on a raspberry pi right like this is a joke almost um and so that's a poor random number generator choice assuming that you have truly you know like perfect seeding of your random number generator um but what if you use uh you know a secure random number generator but then you're you go to seed it and uh yeah we've seen developers use time stamps in their seeds easily guessable um and then that allows us to you know you can just guess the time that they probably uh created or generated the key and then you're you can start guessing keys um so both of those things are not very ideal um so yeah we've seen all of these different problems and how we've uh have these techniques to kind of bypass what developers are doing with with uh their encryption um so there's ways that we can optimize a uh basically keycracker for this and we can abuse uh a lot of different techniques to make this insanely fast um so one thing we can do is use parallelization um obviously you know if you want to write up any form of brute forcing you're gonna have to parallelize your workload um but we can actually parallelize in multiple ways here um so we're trying right a bunch of keys you can you know do all of those in parallel against your cipher text but you can also um uh AES itself in in certain modes um block modes are is parallelizable within the actual operation that you're doing um so we saw like ECB had all those you know like no um it wasn't like streamed together and that means that we can even parallelize there um so that leads to massive speed up um and also for uh block these block modes uh you can also introduce this technique where right we're we're looking for checking things that we know to be there to validate whether our key guess is correct and for something like PKCS padding um we that padding is only on the last block so if we had like a 40 block message I can throw away 39 of those blocks and just decrypt the last block in these certain modes and I can check the padding um and then if it ends up being you know an interesting result then you can go back and decrypt it fully um but for the purpose of just finding our our keys that are probable real keys that the developer used uh you can use that um and we can see that here uh CBC itself is actually you're able to do this um last block decryption because you just need um right the last block of the cipher text your guess key and then you can see at the end we're X orring the second to last cipher text uh block uh into that decrypted result um so that cuts out the whole rest of the chain before um and ECB mode yeah it's there's no nothing complicated about just doing the last block there um another optimization we can do for our tool is early exit so these are just the block modes for a stream or for a symmetric cipher but there can be uh basically streaming modes basically uh that don't allow us to that last block decryption um but with this we can do an early exit right uh so if we know we're looking for ASCII we're no we know we're looking for uh say JSON uh we can exit early once we don't satisfy any of our parameters so we're basically doing block by block until something is invalid just throw it away and continue cracking with the next uh key and um yeah another thing we can do that's uh pretty interesting is uh AES uses uh has internally the block cipher has many different rounds and it has these sub keys that it derives from your guest key so if you were to pre compute all of these sub keys um it's possible you know like that you can uh save on space performance etcetera by pre computing um and so for optimization right we're we're wanting this basically to run as as fast as possible um so there's a lot of different choices of hardware uh basically you know CPU GPU FPGA ASICS where do we start really um so with CPUs um they're they're good um they support SIMD instructions uh which basically allows you to handle more data than you normally would um but uh for AES it's unfortunate SIMD instructions don't actually apply uh cause AES is a little bit longer than those instructions the data internally is a little bit longer than those instructions um so CPUs can definitely do it um but yeah we'll I'll get back to CPUs later um and then so graphics cards everybody knows graphics cards for pat for password cracking hash cracking all of this stuff yes they are really fast for that and highly parallelizable um and they have that great advantage but um there's kind of been back and forth which is better CPU GPU um so I will settle that debate after I explain uh FPGAs and ASICS um so FPGAs we looked into it um basically uh you can program your FPGA to basically do the like at the gate level you're programming uh like uh yeah you're programming gates and then you can create specialized hardware whereas you know on CPUs you're running actual instructions where here we could have specialized logic that is at the gate level and then obviously ASICS I mean it's the fastest you can get it you can manufacture a chip that's dedicated just to doing this uh decryption um but we don't have that kind of money or time yet um so it was kind of interesting to choose but there's a twist right I was holding off in the CPU versus GPU debate because actually in 2008 Intel introduced dedicated AES instructions um so basically right where you know SIMD wasn't quite enough to to support AES very quickly at a hardware level um AES and I uh basically is specialized hardware in probably most of your CPUs that does this very common encryption incredibly fast um and it's great for parallelizable workloads and that's exactly what we have um so we can basically just flood our AES and I instructions and just just go all out into this and crack insanely fast um and GPUs are still valid um if you have a password cracking rig or know someone who does they're still valid for this um but in this case AES and I is such a widespread thing um that it's it's perfect for this application um so we can see some benchmarks here basically we can see with the 8 cores um it's uh beating out the GPU at higher ends so like somehow you know an 8 core CPU is destroying this GPU um and so in this test uh this was not done by us but in this test um basically there's also the consideration of price when you're building these and the GPU is before the sale and after the sale um more expensive than the CPU that they used um so CPUs are way more cost effective for this and actually there's yeah and the the GPU is actually refurbished too so and the CPU is new in this case um so CPUs are definitely the best in as far as cost effectiveness and uh so then there's this the atomic pi which has a CPU with AES and I and it's 50 bucks so theoretically you could just rig like as many of these as you want together create a computing cluster and just deploy uh like basically run all of those AES and I instructions across all of those relatively cheap devices um so yeah AES and I provides a good speed up um but uh we need to utilize it effectively um and and we can do that with our tool. Yeah. So I know this slide says limitations um and as I was writing it it really should have been limitation um but the great news is that as I was writing this and having conversations with people about this and doing dry runs with uh friends and colleagues and and and whatnot um what I came to realize is that this wasn't actually that big a limitation so this is this slide is a bit of a misnomer uh from the get go so this is the limitation um one thing that because we are talking about real world we do need to take real world uh uh design choices into consideration something that developers who don't really understand cryptography which is most of them let's be let's be honest um what they will do is take the IV and say I don't know what to do with this uh they'll look at the documentation and say this needs to be they see this needs to be a random uh value of 16 bytes or whatever it is. So they will choose a random value and then hard code it and use it for every single operation um which is not how an IV is supposed to use uh to be used it's supposed to be different per operation but what's really common is the developer doesn't understand what an IV is for they just know it has to be some value and so they will pick a random value and keep it secret because normally you're you know if you don't understand cryptography you're thinking well I have to keep the key secret I probably have to keep this secret too so they just have these two different hard coded values and so if you have a single block of cipher text in CBC mode and you have your IV kept secret the best that you can get without the IV you know even guessing keys is a value that is the real plain text of the message X word with the initialization vector um and this basically boils down to the one time pad problem as long as you've chosen your IV correctly there's really no information that you can get with this there's nowhere you can go from here but because developers generally choose a single fixed IV and keep it secret if we can get more than one message uh we can do something with this so this is you know uh CBC decryption enhance um and so when we look at the first block the decryption starts out with a block cipher operation in decrypt mode and continues on with an X or unmasking step so we take this sort of halfway decrypted block and we X or it um and we get about here so we have you know we have the IV X word with the plain text now if we have two or more cipher texts that are using the same IV and their single block messages that had this limitation um we can actually do something here so all printable ASCII characters start with a bit zero so we know that the first byte of a message is always data uh anything after that could be data could be padding up to the last byte so we can look at the first bit of the uh the first byte and it shouldn't change between messages because the IV is always going to be the same so the first bit of the IV is always going to be the same and so we have something that is zero X word with the first bit of the IV in the case that we're dealing with printable data which is a generally a strong assumption to make um so we know that if that first bit changes between encrypted message uh between between sort of half decrypted messages we'll call them with any given key we know that it's not the correct key because we can make a strong assumption that that first bit is always going to be a zero and whether that's flipped or not because of the the first bit of the IV it's always going to be the same so the other thing that we know is that the last byte of the message can only be between certain values um if we're doing dealing with an 8 byte block cipher the largest value that we can have is 8 if we're dealing with a 16 byte block cipher uh the largest value that we can have is 16 so for uh for any given message we know that the last byte is always going to be padding and therefore will always be at maximum 16 or 8 depending on what we're dealing with so for a 16 byte block cipher an 8 128 bit block cipher like AES we know that the first three bits are always going to be zeros so we can check the last the first three bits of the last byte of any given message and be uh and throw out any key that doesn't produce the same first three bits in that last byte um so that's pretty rad um we can also uh because we're assuming ASCII printable data and either null byte or pkcs7 style padding we can assume that every single byte is going to start with zero whether it's a padding byte or a data byte now for 64 bit block ciphers this means we get 7 bits of data at the one at the start of each byte that isn't the last that we can reliably say should be the same across all messages and for the last byte we can say we get uh 4 bits because the maximum value is 8 so it should start with 0 0 0 0 regardless of the value of the padding byte at the end that gives us 11 bits and what this means is we have 2 2 to the 11 times n uh uh possibilities um and only one of those possibilities is a false positive so for two samples that's a false positive chance of 1 in about 4 million uh and with 3 samples that's about 8.5 billion um and this is if we have secret fixed IV single block cbc cipher text which is you know not always the situation we're going to end up in anyway but we can deal with this and it as it turns out if we just have 2 samples we already have an incredibly practical attack still and for 16 for 128 bit block ciphers like 8 es it gets even better at 2 samples we have a 68.7 uh uh 1 in 68.7 billion false positive chance which is insanely practical um and so once we get to 3 samples it's like I'm not even going to bother trying to like read that member aloud because that's you know it's a phenomenally good chance. So let's talk about the tool. Alright so basically we wanted to actually make this practical um so we had to show build a tool to show it's legit um so we came up with AES first um yeah. So basically right now it just sports ecb cbc and ctr modes um and it has a couple of those optimizations that I was talking about um it does use AES and I currently and it's fully multi threaded um so uh basically what you can do with the tool is you you find uh some sort of encryption scheme that's vulnerable to what we've talked about and you can use your own word lists whatever you want um and we provide a conversion tool the word list will use different approaches to convert that uh word list into uh possible keys um and then uh you can run it and we get some very good uh performance out of this um so the blue here is uh is um uh our first implementation which was in python um and it you know it was a single thread performed well um and we're getting like 125 uh thousand um keys per second so pretty decent and the multi threaded one that I produced uh was uh basically double the speed so um we're getting amazing uh performance optimization here and the thing about this is this is all running off of just a laptop um so I'm getting like 250 thousand keys per second off a single laptop you know um and you can imagine how this would be in a computing cluster made up of all of those atomic pies that I was showing earlier um so yeah and and that that was for ECB mode CBC mode very similar results um because of the optimizations like last block decryption and all of that we get very similar similar results to ECB from a more complex thing like CBC um yeah so unfortunately no demo today I'm sorry um but yeah future work so um the unfortunately we had uh some AV issues that prevent us from showing it to you but the code is available um we probably uh what can you can you give everybody the URL where you can get the tool um so it will be on my github ghost pep um and the tool is AES burst so you should be able to find it just by typing AES burst into github and yeah so we talked a lot about uh about um various techniques that we we we can use to do practical key cracking attacks um but not every one of them is built into AES burst um so the plain text scoring the uh that that could be used to sort the results and it isn't currently um we can add more key derivation methods um currently we support only a few of them um we can uh you know I as I mentioned that limitation section late on was when I realized that this technique could work so uh that's not in there um we could add distributed computing support possibly via kubernetes uh so we can just tie a bunch of existing computers uh uh together um we could you know throw a bunch of atomic pies together and create the cracking cluster that we we talked about um I think that that the final word is not necessarily out on GPUs versus CPUs because at some point there might be a workload large enough and so uh so to be massively parallel parallelizable uh such that we might be able to get slightly more uh performance out of GPU versus CPU but we get so much great performance out of the average CPU and this is across Intel uh CPUs AMD CPUs you know like if if it's in your laptop and you've got your laptop with you right now I would bet uh that your laptop probably supports the AES and I instruction set um right now we only support AES 128 uh AES and I instructions that support AES 128 and 256 um but we can also like this this technique is not specific to AES it it are the techniques that we presented today should work with any blocks try cipher or stream cipher uh it is a a an algorithm independent set of techniques um we'd love to work with established pass password cracking groups like uh Core Logic or Hash Cat or who really whoever wants to work with us to be honest um because you know it's one thing to produce a tool that implements this and it's another to produce work for some group that already has wide adoption where they can just roll out an update and suddenly your favorite password cracking tool can do AES key cracking or whatever else as well um and it's something that they're not currently doing today um we can also add support for AEAD cipher mode so this is something where when you get the correct key you know it because you already have um sort of an uh an authentication uh built into your cipher mode so that is another way that we didn't even discuss that you can validate your key guesses so but we're not doing that currently so there's a lot of room for future work here and this is sort of uh where we want to call everybody to action like this is obviously we've shown we've done the calculations it's an incredibly practical attack we've built a practical tool that implements this on a basic level and it still works we've you know uh um this this this is a practical technique and now what we would love to see is for you to take this and run with it to go as far as you know the hash cracking community has gone with password hash uh cracking uh and do the same with encryption keys and that's that's really what I personally hope to see and I think I speak for the other Daniel as well. He does. Yeah. So confirmation we have confirmation and um I I'm sorry but I haven't been able to see if we are uh good uh five minutes okay thank you I can finally see you the lights are fantastic but you know a little blinding so at this point we'd like to open it up to questions um does anybody have does anybody have questions I see I see somebody raising their hand back there uh do we have microphones for questions or we okay um can you just shut your question really loud and then I'll repeat it into the mic for the recording. So um the question is um one of the the the big things that we've done here is uh validate the padding on block ciphers to check whether or not we've got the correct key uh and do we uh is there a padding method that has been standardized that uh randomizes the padding so there is there is a padding scheme which is referred to as like a cipher text stealing padding scheme which so for instance in cbc mode um you take whatever the cipher text is of the second to last block and you use bytes from that uh after a fixed byte to say you know here's the you know here's the um here's the uh the the bytes. Now while this does prevent against certain attacks like padding oracle attacks this does not actually make a meaningful difference for our attack because any padding scheme that you can validate which really should be all of them based on what padding is used for um we can validate it. So you know even if you're um even if you're stealing cipher text from the second to last block um it needs to be something that you can validate during decryption. So we will by design always be able to use this regardless of the padding scheme unless it's a really shit padding scheme. So great question thank you. Are there other questions? Go ahead. Uh so our our results in benchmarking uh would actually I'll I'll I'll I'll give this to Daniel since he was the one who did the the coding and the benchmarking. Uh oh yeah repeat the question. Um so the question is basically uh for hard limits on like the multi-threaded uh version and uh basically saw that it was linear um so in this case linear is as as far as like complexity time complexity of the of what we're doing it linear is best case right. Anything other than that would just be wasteful um and you can't go below linear if you're doing you know n keys against one cipher text that's you know O of n. Um so we want linear it's just can we can we get it faster and you know changing it from oh you can decrypt this single threaded in in a week versus can you do it in in a weekend right? Um yes. Yes so that was on for a four core and in that case so ASNI is actually uh on its own dye in your CPU. So then you're limited by what your CPU technically has um in this case on the test machine it was uh I had four I was able to run four at at a time um so you're limited not by necessarily your cores you're actually limited by the AES hardware that you have um which is why uh the atomic pies are so interesting is because yeah the CPU itself right from a traditional standpoint pretty crap but it's it's fifty dollars right but it has the exact same AESNI instructions and for for us that's that's already our our bottleneck so that's why those are so attractive really um because it's mega cheap for a specific part of that CPU that we're targeting. Okay it looks like we're out of time so uh if you have additional questions uh do we uh sorry do we have a like a an after room or we do not have an after room okay uh find our attractive beautiful faces that are unmistakable and ask us any questions that you might have that you are not able to later on um we will be around the conference. So uh thank you for coming uh uh have a good Def Con.