Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to export firmware properly #83

Open
muellermartin opened this issue Jan 13, 2019 · 16 comments
Open

Unable to export firmware properly #83

muellermartin opened this issue Jan 13, 2019 · 16 comments
Assignees
Labels
bug prio:high Makes the device difficult to use, or insecure.
Milestone

Comments

@muellermartin
Copy link

  • Application version: v1.3.2
  • Operating system: macOS 10.13.6 (64-bit)
  • Device model and firmware version: Storage v0.53
  • Connected USB port type: 3.0
  • Issue occurrency: sometimes

Expected behaviour

Firmware can be exported into a file and this file can be successfully matched against the original release of the same version.

Current behaviour

Mostly the exported firmware.bin file is not listed in the file system of the USB storage although the notification says it was successfully exported.

When the Nitrokey Storage is remounted several times and/or the firmware export is repeated (not sure what helps there), the file appears, but is somewhat faulty. For example, if the file is copied to disk, the Finder shows following error message (German):

Der Finder konnte diesen Vorgang nicht abschließen, da einige Daten in „firmware.bin“ nicht gelesen oder geschrieben werden konnten.
(Fehler: -36)

Nevertheless, the file gets copied – at least it seems so (there is a copy and it contains data). Because when using nkcompare.sh from Nitrokey/nitrokey-storage-firmware /tools to compare the exported binary with the original one from GitHub, the binaries do not match ("Firmware binaries mismatch"). This is likely because the exported firmware.bin contains very few data (only exact 4096 bytes!) and the rest is filled with zeros (see attached firmware.bin).

When using cp instead of Finder for coyping the firmware.bin file from the USB storage to the disk, following error is shown:

$ cp /Volumes/Nitrokey/firmware.bin .
cp: /Volumes/Nitrokey/firmware.bin: Input/output error

And the resulting copy is an empty file (0 bytes).

Deleting the file from the Nitrokey storage works, though.

Directly reading the file from the USB storage (e.g. xxd /Volumes/Nitrokey/firmware.bin | less also gives an Input/output error).

Steps for reproduction

Preconditions

Nothing special.

Steps

  1. Insert Nitrokey Storage
  2. Start Nitrokey App
  3. Select tray icon > Configure > Export firmware to file and wait until notification signals completed export.
  4. Repeat 1-3 several times until firmware.bin is visible in the filesystem of the USB storage.
  5. Try to copy or read the firmware.bin (e.g. for comparison with original firmware)

Logs

Logs attached:

Faulty firmware dump

firmware.bin.zip

@szszszsz
Copy link
Member

Hi!
Thank you for the report. From the attached logs it seems, that the direct cause is the Unencrypted Volume set to read-only, which prevents the firmware write. We have missed that case, while implementing the export, and it was shown, when the UV was started to be set read-only by default (earlier firmwares had it read-write).

Nitrokey App v1.4 is planned to warn user about that. Firmware fix is already prepared, but it confused the App v1.3 (potentially making more harm than good), hence not merged yet.

Please retest the export, with making sure before that the UV is set to read-write.

Log excerpt:

 (int) ReadWriteFlagUncryptedVolume_u8:	0

To do:

  • Update firmware verification guide

cc: @alex-nitrokey

@szszszsz
Copy link
Member

Actually, I got confused, sorry. Just checked, and 0 means read-write set in this case (due to inverted logic values write).
I will look closer into it.

@muellermartin
Copy link
Author

muellermartin commented Jan 14, 2019

I'm quite sure this issue is not caused by the unencrypted volume being read-only as I've set it to r/w and the described steps for reproduction sometimes work in part, but it never fully works. Maybe some component falsely thinks that it is read-only and fails, but that doesn't explain why the exported firmware binary is broken in cases where it does work.

Until there is no solution to this, I consider my Nitrokey as compromised, because the firmware can not be verified.

@jans23
Copy link
Member

jans23 commented Jan 14, 2019

@muellermartin Please elaborate "broken". Did you follow these instructions to verify and compare the firmware?

@szszszsz
Copy link
Member

@muellermartin Here are the updated instructions for macOS:
https://github.com/Nitrokey/nitrokey-storage-firmware/tree/master/tools#macos

@jans23 The problem is, that macOS sees too small file of the exported firmware. We have not seen that on Linux. I have not seen that myself, when tested the firmware verification lately too. Will check.

@muellermartin
Copy link
Author

muellermartin commented Jan 14, 2019

For my definition of broken, see my original post (read/write errors and only 4096 bytes in firmware).

Yes, it did follow the steps. Basically I fail at step 4, because the firmware can not be exported properly (hence the title of this issue).

@muellermartin
Copy link
Author

What's the status of this issue other than havin to wait for version 1.4 of the application? I can't trust my Nitrokey farther than I can throw it unless I'm able to verify the firmware.

@szszszsz
Copy link
Member

@muellermartin I understand your concerns. Actually I plan to take this on this week, specifically tomorrow, and would be best to resolve it asap. The milestone is just an upper time limit for the issue to be solved.

@szszszsz szszszsz self-assigned this Jan 17, 2019
@szszszsz
Copy link
Member

Confirmed firmware export is troublesome under macOS 10.13.6. Investigating further.

szszszsz referenced this issue in Nitrokey/libnitrokey Jan 18, 2019
Export the firmware multiple times, and test its size.
Hardcoded device set to /dev/sde1

Related: https://github.com/Nitrokey/nitrokey-app/issues/399
Signed-off-by: Szczepan Zalega <[email protected]>
@szszszsz szszszsz transferred this issue from Nitrokey/nitrokey-app Jan 18, 2019
@szszszsz
Copy link
Member

Moved to Storage firmware repository.

@szszszsz szszszsz added bug prio:high Makes the device difficult to use, or insecure. labels Jan 18, 2019
@szszszsz szszszsz added this to the v0.54 milestone Jan 18, 2019
@szszszsz
Copy link
Member

szszszsz commented Jan 18, 2019

Retested under Fedora 29 with Nitrokey/libnitrokey@a2b7b9a.

In a stress test it turned out, that overall success rate for export is 3/10 and 5/20.
When before exporting the UV unmount was performed in the host OS, the success rate went up to 9/10 and 20/20.
It seems that the auto-remounting side-effect, introduced in v0.46, highly influences this feature. Probably host access to the UV conflicts with the write by the device, thus failing to finish the export.

Solution:

  1. Fix by removing the direct cause - correctly remove the UV by making its capacity == 0, or using other ways to inform the OS about the block device removal.
  2. Add error codes handling for the firmware exporting procedure, to inform about file creation failure.

Edit: relevant references:

  • src/USER_INTERFACE/html_io.c:452
  • src/USER_INTERFACE/file_io.c:280

@muellermartin
Copy link
Author

muellermartin commented Jan 18, 2019

Thanks for testing this and finding a possible cause!

I even can confirm this under macOS: I've unmounted the unencrypted volume (had to use the workaround in issue Nitrokey/nitrokey-app#337, i.e. use Disk Utility to disable the volume to bypass the automount) and then used the export functionality in Nitrokey App. Funnily, the unencrypted volume was set to read-only and the firmware export worked nevertheless, although according to issue #69 this shouldn't have worked). This worked on the first try. I did not try it several times to test the reproducibility.

And the good news is that the exported firmware also could be successfully verified with the provided script (tools/nkcompare.sh):

$ ./nkcompare.sh v0.53/storage-firmware-V0.53-0-g905976e.hex firmware.bin 
Running ./nkcompare.sh v0.53/storage-firmware-V0.53-0-g905976e.hex firmware.bin
Firmware binaries match
SHA256: aea280a50225b270b980fe81ad873d9418b449916ee1c15a01e280f484ecc80c

@szszszsz
Copy link
Member

Thank you for the feedback!
The firmware verification guide should be updated based on this to provide the workaround, until the issue will be fixed.
cc @alex-nitrokey

Related: #45

@muellermartin
Copy link
Author

Based on your stress test I've added a similar test for macOS (see PR Nitrokey/libnitrokey#151).

The results for me:

  • with unmount 19/20 succeed
  • without unmount 0/20 succeed

@szszszsz
Copy link
Member

@NKelias Could you take a brief look to that, if time would permit?

@szszszsz szszszsz modified the milestones: v0.54, v0.55 Jun 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug prio:high Makes the device difficult to use, or insecure.
Projects
None yet
Development

No branches or pull requests

3 participants