Nitrokey / nitrokey-start-firmware

A mirror of Gnuk's 1.0.x and 1.2.x branches.
56 stars 15 forks source link

Nitrokey Start firmware is not read protected #14

Closed rot42 closed 5 years ago

rot42 commented 5 years ago

I've recently bought a Nitrokey Start and noticed that the firmware is not read protected.

Your documentation for the old Nitrokey Pro and this tutorial about an earlier version of the Nitrokey Start state that the firmware is supposed to be read protected.

For reference, the Nitrokey Start I received is using the Nitrokey Pro v2 board (without the smartcard socket). Maybe you forgot to read protect the firmware when you switched to hardware version 2?

I think it would make sense to leave the firmware readable on the Nitrokey Pro for auditability, as the key material is stored on the smartcard (assuming the smartcard itself does the PIN verification, I didn't look if this is the case). But for the Nitrokey Start, not read protecting the firmware makes it trivial to extract the key material and bruteforce the PIN.

szszszsz commented 5 years ago

Hi!

Our intention is to enable the read protection on all Pro, HSM and Start devices. Looks like an error in production. Will look into it.

jans23 commented 5 years ago

@rot42 could you provide the serial number of your STM32?

rot42 commented 5 years ago

@jans23 34ff6c064e55373226332443

szszszsz commented 5 years ago

From my side, could you post the USB serial number of the affected Nitrokey Start device? You can send it by email (szcze***pan@nitrokey.com; please remove ``), if you prefer.

jans23 commented 5 years ago

@szszszsz it's there already.

@jans23 34ff6c064e55373226332443

szszszsz commented 5 years ago

I meant the part starting with FSIJ, e.g.: FSIJ-1.2.10-43144852. It should be shown in the gnupg --card-status, as well as in lsusb -d 20a0: -v | grep Serial.

rot42 commented 5 years ago

@szszszsz The serial number is initialized with the last 4 bytes of the above posted STM32 UID in little-endian order -> FSIJ-1.2.10-43243326

szszszsz commented 5 years ago

@rot42 Thank you. Will check this specific sample in logs. Our current production environment locks Start samples. That does not mean of course there was no error earlier. Could you also share the testing method/command, and attach the first lines of the hexdump/ihex of dumped firmware just to make sure we are on the same page?

rot42 commented 5 years ago

Reading the STM32 unique device ID using openocd

$ cat st32uid.cfg
source [find interface/stlink-v2.cfg]
source [find target/stm32f1x.cfg]
init
stm32f1x.cpu mdb 0x1FFFF7E8 12
exit

$ openocd -f stm32uid.cfg
...
0x1ffff7e8 34 ff 6c 06 4e 55 37 32 26 33 24 43             4.l.NU72&3$C

Extracting the firmware:

$ st-flash read nitro-start.bin 0x8000000 0x20000
2019-04-13T01:42:30 INFO common.c: Loading device parameters....
2019-04-13T01:42:30 INFO common.c: Device connected is: F1 Medium-density device, id 0x20036410
2019-04-13T01:42:30 INFO common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes

$ hexdump -C nitro-start.bin | head -n 20
00000000  00 50 00 20 71 02 00 08  1d 01 00 08 51 01 00 08  |.P. q.......Q...|
00000010  81 01 00 08 b9 01 00 08  f5 01 00 08 ad 02 00 08  |................|
00000020  fd 02 00 08 0d 02 00 08  61 03 00 08 31 01 00 08  |........a...1...|
00000030  55 02 00 08 5d 00 00 08  d9 00 00 08 00 00 00 00  |U...]...........|
00000040  08 03 33 00 2e 00 30 00  bd 7e 1e ad 4e 49 54 52  |..3...0..~..NITR|
00000050  4f 4b 45 59 2d 53 54 41  52 54 00 00 1b 4b 1a 68  |OKEY-START...K.h|
00000060  42 f0 01 02 1a 60 19 68  18 4a 89 07 fb d5 11 68  |B....`.h.J.....h|
00000070  01 f0 f9 01 11 60 00 21  51 60 5a 68 13 49 12 f0  |.....`.!Q`Zh.I..|
00000080  0c 0f fa d1 0a 68 42 f4  80 32 0a 60 19 68 0f 4a  |.....hB..2.`.h.J|
00000090  88 03 fb d5 51 68 41 f4  88 11 51 60 11 68 41 f0  |....QhA...Q`.hA.|
000000a0  80 71 11 60 19 68 09 4a  89 01 fb d5 08 49 12 20  |.q.`.h.J.....I. |
000000b0  51 60 08 49 08 60 51 68  41 f0 02 01 51 60 5a 68  |Q`.I.`QhA...Q`Zh|
000000c0  02 f0 0c 02 08 2a fa d1  70 47 00 bf 00 10 02 40  |.....*..pG.....@|
000000d0  00 84 11 00 00 20 02 40  0b 4b 9a 69 42 f0 0d 02  |..... .@.K.iB...|
000000e0  9a 61 0d 22 da 60 00 22  da 60 08 4a 53 68 43 f0  |.a.".`.".`.JShC.|
000000f0  00 73 53 60 06 4b 6f f4  c4 52 da 60 05 4a 5a 60  |.sS`.Ko..R.`.JZ`|
00000100  05 4a 1a 60 70 47 00 bf  00 10 02 40 00 00 01 40  |.J.`pG.....@...@|
00000110  00 08 01 40 44 14 81 38  88 44 44 34 03 4b 80 22  |...@D..8.DD4.K."|
00000120  08 b1 1a 61 70 47 5a 61  70 47 00 bf 00 08 01 40  |...apGZapG.....@|
00000130  06 4b da 69 22 f4 00 02  da 61 4f f4 00 02 1a 61  |.K.i"....aO....a|

I've also extracted the firmware using openocd instead of st-flash and their checksums match.

The extracted firmware match exactly the prebuilt RTM.6 version from this repo. The only differences are, the serial number flashed on 1st start, and the key material and data objects at the end of the firmware.

szszszsz commented 5 years ago

Updating firmware to the latest release RTM.7 solves the issue - ./upgrade_by_passwd.py tool will lock the flash memory if it was not done before, without a need to connect the debugger. In the future the flash memory will be checked and locked in the firmware itself as well, on the very first device initialization.

Regarding your specific sample, I could not find it in our current logs - perhaps it was flashed more than 3 months ago. Nevertheless I will make sure read-protection is double-checked. I hope this will answer your concerns.

Thank you for reporting!

rot42 commented 5 years ago

Updating firmware to the latest release RTM.7 solves the issue - ./upgrade_by_passwd.py tool will lock the flash memory if it was not done before, without a need to connect the debugger. In the future the flash memory will be checked and locked in the firmware itself as well, on the very first device initialization.

I've tested the upgrade_by_passwd.py script and everything worked as expected, the flash read protection is now enabled. Thanks a lot for the new release! Enabling the read protection during the first device initialization seems like a great idea.

Regarding your specific sample, I could not find it in our current logs - perhaps it was flashed more than 3 months ago. Nevertheless I will make sure read-protection is double-checked.

I bought it around 2 months ago so it might very well have been flashed more than 3 months ago.

I hope this will answer your concerns.

Thank you for reporting!

That perfectly answers my concerns, thanks a lot!

szszszsz commented 5 years ago

Great! Will track self-locking in a separate issue. Closing this one as solved.

rot42 commented 5 years ago

If someone else is interested in checking if their Nitrokey Start is correctly locked, I've just released a tool to extract the PGP private keys from a dumped Gnuk / Nitrokey Start firmware. The README explains how to check if the STM32 read protection is correctly enabled.