newaetech / chipwhisperer

ChipWhisperer - the complete open-source toolchain for side-channel power analysis and glitching attacks
http://chipwhisperer.com
Other
1.12k stars 285 forks source link

CW305: `fpga_write` not working for payloads longer than 47 bytes #373

Closed jonnykl closed 3 years ago

jonnykl commented 3 years ago

fpga_write() is not working for me when using payloads longer than 47 bytes.

Used version: develop branch, latest commit (15ff86cbede5d7ab5ce9595021c827c02e70c48d) SAM3U FW version after upgrade_firmware(): 0.51

On the FPGA a part of the address space is mapped to a memory, so I should be able to read the data previously written. This works fine when writing 47 bytes (or less) but stops working when trying to write 48 or more bytes. This seems to trigger a single write operation:

>>> import chipwhisperer as cw
>>> target = cw.target(None, cw.targets.CW305, bsfile="/path/to/bitfile.bit", slurp=False)
>>> target.bytecount_size = 0
>>> target.fpga_write(128, [0xFF]*47)  # fill memory with 0xFF
>>> [hex(x) for x in target.fpga_read(128, 16)]
['0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff']
>>> target.fpga_write(128, [a, b] + [0xAA]*48)  # write more than 47 bytes ...
# writes b to address 128+(a & 0x07), example:
>>> target.fpga_write(128, [0x19, 0xCC] + [0xAA]*48)  # write more than 47 bytes ...
>>> [hex(x) for x in target.fpga_read(128, 16)]
['0xff', '0xcc', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff', '0xff']

Side note: I also noticed that the FPGA was programmed much faster before using the develop branch (SAM3U FW version 0.32).

alex-dewar commented 3 years ago

Hi

Thanks for the report on this. For the write, I don't think the bulk transfer code took the address into account. The reason you see that at 48 bytes is because that's when we switch from USB control transfers to USB bulk transfers. I've made a new firmware (0.53) that I think fixes this, though I'm not sure since I don't think we have a CW305 bitstream that accepts writes that long. If you don't mind uploading your bitstream, I can test this for you.

For the FPGA programming speed, you're probably right regarding the programming speed. I think when I merged all the SAM3U code bases together, we ended up using the CWLite programming speed instead of the faster CW305 one. Firmware 0.52 and newer has the ability to set the fpga programming speed. This now defaults to 10MHz, so if you upgrade again you should see a big speedup.

Alex

jonnykl commented 3 years ago

Thanks for the report on this. For the write, I don't think the bulk transfer code took the address into account. The reason you see that at 48 bytes is because that's when we switch from USB control transfers to USB bulk transfers. I've made a new firmware (0.53) that I think fixes this, though I'm not sure since I don't think we have a CW305 bitstream that accepts writes that long. If you don't mind uploading your bitstream, I can test this for you.

Thanks, seems to work now!

But there is one more thing I noticed: fpga_write returns the written data for payloads shorter than 48 bytes. In the other case it returns the number of written bytes. Though the documentation does not specify what is returned, no one would expect this behaviour ...

For the FPGA programming speed, you're probably right regarding the programming speed. I think when I merged all the SAM3U code bases together, we ended up using the CWLite programming speed instead of the faster CW305 one. Firmware 0.52 and newer has the ability to set the fpga programming speed. This now defaults to 10MHz, so if you upgrade again you should see a big speedup.

Yes it's now fast again.

alex-dewar commented 3 years ago

Good to hear it works!

But there is one more thing I noticed: fpga_write returns the written data for payloads shorter than 48 bytes. In the other case it returns the number of written bytes. Though the documentation does not specify what is returned, no one would expect this behaviour ...

I'll get this fixed up so that it returns None. Let us know if you find any other functions that don't specify a return value and return something other than None.

Alex