Performing CPA on ECB mode with AES-256 on a FPGA-board

Hi,

I have worked all summer with ChipWhisperer, and I am now going to head on to my greatest challenge so far; attack an FPGA-board(CW305) with AES-256. I am able to recover the key with AES-128 utilizing your course “PA_HW_CW305_1-Attacking_AES_on_an_FPGA”.

However, I do not know how to approach the attack with AES-256. To do the AES-128, one attacks the last round. This also work for AES-256, but now this is just half of what one need to recover the master key. And one can not repeat this for round 13, since round 1-13 are done in one clock-cycle. Locating and extracting the round-key for round 13 therefore is impossible this way( I think ).

How would you do this sort of attack?

Best regards
sca_fanatic

1 Like

There is nothing fundamentally different about attacking AES-256 vs AES-128, assuming of course that your AES-256 implementation is similar to our AES-128 implementation. Whichever round key you are attacking, just follow the key expansion to get back to the initial key.

Jean-Pierre

1 Like

Hi,

I believe you will run into an issue trying to repeat the attack across round 13, since there’s a mix columns operation in round 13 (unlike in round 14) associating each byte stored in the register with 4 bytes of the key.

If you’re able to control the plaintext, you should be able to perform this attack twice to recover the encryption key: https://github.com/newaetech/chipwhisperer-jupyter/blob/master/experiments/MixColumn%20Attack.ipynb. Alternatively, if you have control of the ciphertext, you should be able to modify the attack to go through inv mix columns and do it a single time in addition to the normal last round state diff.

Alex

2 Likes

Would it be possible to change the leakage model “last_round_state_diff” and modify this for AES256 to get the first 16 bytes of 32 byte key on the FPGA board?

I have tried changing the key schedule to use 14 insted og 10 rounds without any success.

image

Fridthoy

Hi again,

The second approach you are proposing Alex, seems like the way for my attack.

My first problem is that I can not get the “PA_HW_CW305_1-Attacking_AES_on_an_FPGA” to work with AES-256, even though it works perfectly fine for AES-128. When I try to run
image

I get this:


  1. I have tried to figure out where the error lies, but have been unsuccessful in my attempts. Do you know how to fix this?

  2. And is it this approach you are refering to(“Side channel power analysis of an AES-256 bootloader” written by Colin)?

image

  1. Why do you have “scope.adc.samples = 3000” instead of = 129? From the tutorial: “We’re only capturing 129 samples (the minimum allowed), and the encryption is completed in less than 60 samples with an x4 ADC clock. This makes sense - as we mentioned above, our AES implementation is computing each round in a single clock cycle”. My traces look like this
    image

  2. When you say “modify the attack to go through inv mix columns”, exactly where and what am I supposed to change?

Thank you so much for your help :slight_smile:
Best regards
sca_fanatic

1 Like

I tried using the code from:https://github.com/newaetech/chipwhisperer-jupyter/blob/master/experiments/MixColumn%20Attack.ipynb , But I do not understand how the traces is generated here? It seems like 4 different projects is saved in one list, why is this the case?

image

1 Like

Hi,

  1. Some of the leakage models present require the key to be known and are more of a a reference than anything useful. Sbox Output Successive is one of those.
  2. Nope, I’m referring to a different paper that targets the bootloader of some Xilinx FPGAs: https://eprint.iacr.org/2016/249.pdf
  3. The attack wasn’t designed for the usual CW305 AES and is instead targeted at another implementation that takes longer to run. That being said, I have run the attack against AES128 on the CW305 and it does work (and should work against AES256 as well).
  4. If I recall the attack correctly, there’s some coefficients used in the attack that come from mixcolumns. You’ll need to change those to ones from inv mixcolumns instead, as well as use the inverse SBox in the attack as well.

Alex

Basically, the attack uses 4 bytes of variable plaintext and 12 bytes of constant plaintext, meaning you’ll only get the 4 key bytes associated with the variable plaintext out. As such, you need to repeat the attack 3 more times with the 4 different variable bytes until you get the full key out

Alex

That may be. I used the wrong leakage-model, I was supposed to run “cwa.leakage_models.last_round_state_diff”. However I get the exactly same error about “list index out of range”. I have checked and the project-object knows the key so that is not the problem. I am confident that the root of the problem lies in the fact that the key is 32 bytes instead of the normal 16. I have tried to find a way around this, but been unsuccessful so far. The simple_PGE function is the one that causes the trouble, but this is for the partial guessing entropy, which is of no interest of mine.

Is it possible to cut this animation of the search out, in hopes that the algorithm will work for the 32-byte key.? If not, do you know how to fix this “list index out of range”-problem?

Best regards

Hey Alex,

We had a difficult time trying to run the code you linked at https://github.com/newaetech/chipwhisperer-jupyter/blob/master/experiments/MixColumn%20Attack.ipynb. Since this git repo is not located inside the “normal” chipwhisperer repo I used anaconda and downloaded the necessary modules, this works fine. I have a issue cased by “import cwtvla”, I have tried importing this library directly from github at “https://github.com/newaetech/chipwhisperer-tvla” with the commands “python setup.py install”, it seems like the libary is only downloaded as pip and not in my conda environment.

Maybe I am making this hard for myself, but do you have any recoomendation on how to run " https://github.com/newaetech/chipwhisperer-jupyter/blob/master/experiments/MixColumn%20Attack.ipynb".

Best regards,
Fridthoy

IIRC you’ll need to add target specific setup, then the notebook should just work. You can just delete the cwtvla line, that was required in the past but is no longer needed.

Alex

You need to break your attack into two parts - one for each half of the key. There’s no way to attack AES256 in a single step.

Alex

I must have been unclear in my previous post, I have always known that the attack must be performed in two steps. The difficulties I have is to run the code. Since this is AES-256, I must use a 32-byte key to encrypt. What I want is to get the roundkey from round 14(I of course need two roundkeys, but I am starting with this). Now I should be able to get the 14th roundkey from just running the same attack as with the AES-128 with the last_round_state_diff leakage-model. My crypto-supervisor has also confirmed this. Therefore the problem lies in the code.

I get it working perfectly fine with AES-128 and a 16-byte key. But when I use a 32-byte key I get this:



This problem arises when the last function gets the bnum value to be 16. So it sounds like an easy fix, just make it so that the bnum never exceeds this limit. But I have not been able to do so.

Do you know how/can figure it out?

Best regards
sca_fanatic

I was also able to get the first 16 bytes of my 32 byte key with the mixcolumns code you earlier referred to! Thanks! You told me to just run the code twice? What exactly should I change when I run it a second time?

-sca_fanatic

Basically, you need to use the key you got from the first round to advance the AES state, then repeat the attack.

Sorry for asking, but could you explain more in depth on how to implement this with with mix columns? We have done the tutorial " Breaking AES-256 Bootloader" and understood that we need to make a new leakage model and use the first 16 bytes of the key for finding the remaining of the key. When using mix columns code it seems like this is not straight forward . Soo… could you help us on how we can implement the attack after finding the first 16 bytes?

Best regards
fridthoy

1 Like

This is what I have currently tried so far:

I have tried to make a new leakage model to find the the last 16 bytes, this unfortunately does not work, the wrong key is found and the correlation is not significant.

Note that I have not used the mixcolumns scripts that you refered to since I was able to find the first 16 bytes with some changes to the “normal” attack. This is also a more preferable approach since we don’t know the plaintext that is sent in.

So, do you know why I get the wrong results and how I can fix this?

With that being said, if you have any recommendations on how to get the last 16 bytes of the key with the mixcolumns script I would gladly take it!

Thanks again

fridthoy

1 Like

I have tried something else in order to get the last 16 bytes

As the leakage-model for getting the first 16 byte is

image

I thought this might work:

but it did not.

  1. Do you spot any mistakes?

  2. Should I not take the hamming-weight of the hamming-distance in the output of the leakage-function? (I have tried both with no success. The file AES256_8bit.py uses this idea, but the leakage-model I just used for the first 16 bytes does not, and that one works.)

  3. If you think it is impossible to find the last 16 bytes this way, why?

Sorry, I’m not sure why your model doesn’t work. If you want to use the MixColumns attack, you need to break both halves of the key from the start of the encryption. You won’t be able to use the half of the key you got from the last round state diff.

Alex