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

nk3: SPSDKConnectionError during nitropy nk3 update (with udev rules in place!) #601

Closed
farblos opened this issue Dec 12, 2024 · 8 comments · Fixed by #602
Closed

nk3: SPSDKConnectionError during nitropy nk3 update (with udev rules in place!) #601

farblos opened this issue Dec 12, 2024 · 8 comments · Fixed by #602

Comments

@farblos
Copy link

farblos commented Dec 12, 2024

I'm on an up-to-date Debian testing on Linux x86_64 with kernel

Linux host01 6.11.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.11.10-1 (2024-11-23) x86_64 GNU/Linux

nitropy should be up-to-date as well:

[~]$ nitropy version
Command line tool to interact with Nitrokey devices 0.7.0
0.7.0

I have package libnitrokey3 installed (the i prefix in the aptitude output), the udev rules are in place, and should be active through reboot:

[~]$ aptitude search libnitrokey 
i A libnitrokey-common              - architecture independent files for libnitr
p   libnitrokey-dev                 - library to communicate with Nitrokey stick
i   libnitrokey3                    - library to communicate with Nitrokey stick
[~]$ ls -al /usr/lib/udev/rules.d/41-nitrokey.rules
-rw-r--r-- 1 root root 2852 Apr 27  2022 /usr/lib/udev/rules.d/41-nitrokey.rules
[~]$ grep 42dd /usr/lib/udev/rules.d/41-nitrokey.rules
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42dd", TAG+="uaccess"

Finally, I have Nitrokey 3A NFC:

[~]$ nitropy nk3 list
Command line tool to interact with Nitrokey devices 0.7.0
:: 'NK3' keys
/dev/hidraw8: Nitrokey 3 8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXF

Here is what happens in the journal when I plug the device:

[ 1157.164379] host01 kernel: usb 3-3: new full-speed USB device number 15 using xhci_hcd
[ 1157.316164] host01 kernel: usb 3-3: New USB device found, idVendor=20a0, idProduct=42b2, bcdDevice= 1.06
[ 1157.322100] host01 kernel: usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1157.322341] host01 kernel: usb 3-3: Product: Nitrokey 3
[ 1157.322509] host01 kernel: usb 3-3: Manufacturer: Nitrokey
[ 1157.322672] host01 kernel: hid-generic 0003:20A0:42B2.0012: hiddev3,hidraw8: USB HID v1.11 Device [Nitrokey Nitrokey 3] on usb-0000:00:14.0-3/input1
[ 1157.322972] host01 kernel: cdc_acm 3-3:1.2: ttyACM0: USB ACM device
[ 1157.327525] host01 systemd[1698]: Reached target smartcard.target - Smart Card.
[ 1157.327550] host01 systemd[1]: Reached target smartcard.target - Smart Card.
[ 1165.008208] host01 kernel: usb usb2-port2: attempt power cycle
[ 1173.500152] host01 kernel: usb usb2-port2: unable to enumerate USB device

(Not sure whether the messages related to usb2-port2 are relevant here.)

After a nitropy nk3 reboot --bootloader plus a button press I get in the journal:

[ 1203.840171] host01 kernel: usb 3-3: USB disconnect, device number 15
[ 1204.220363] host01 kernel: usb 3-3: new high-speed USB device number 16 using xhci_hcd
[ 1204.368172] host01 kernel: usb 3-3: New USB device found, idVendor=20a0, idProduct=42dd, bcdDevice= 3.00
[ 1204.373524] host01 kernel: usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1204.373905] host01 kernel: usb 3-3: Product: USB COMPOSITE DEVICE
[ 1204.374167] host01 kernel: usb 3-3: Manufacturer: NXP SEMICONDUCTOR INC.
[ 1204.374376] host01 kernel: hid-generic 0003:20A0:42DD.0013: hiddev3,hidraw8: USB HID v1.00 Device [NXP SEMICONDUCTOR INC. USB COMPOSITE DEVICE] on usb-0000:00:14.0-3/input0
[ 1204.380434] host01 systemd[1698]: Stopped target smartcard.target - Smart Card.
[ 1204.381064] host01 systemd[1]: Stopped target smartcard.target - Smart Card.

The ACLs on /dev/hidraw8 look sane:

[~]$ getfacl /dev/hidraw8
getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw8
# owner: root
# group: root
user::rw-
user:farblos:rw-
group::---
mask::rw-
other::---

Now I replug the NK3 and try:

[~]$ nitropy nk3 update
Command line tool to interact with Nitrokey devices 0.7.0
Do you want to download the firmware version v1.8.0? [Y/n]: 
Download v1.8.0: 100%|█████████████████████| 1.08M/1.08M [00:00<00:00, 1.85MB/s]
Current firmware version:  v1.6.0
Updated firmware version:  v1.8.0

Please do not remove the Nitrokey 3 or insert any other Nitrokey 3 devices during the update. Doing so may damage the Nitrokey 3.
Do you want to perform the firmware update now? [y/N]: y

Please press the touch button to reboot the device into bootloader mode ...

Critical error:
An unhandled exception occurred
        Exception encountered: SPSDKConnectionError()

--------------------------------------------------------------------------------
Critical error occurred, exiting now
Unexpected? Is this a bug? Would you like to get support/help?
- You can report issues at: https://support.nitrokey.com/
- Writing an e-mail to [email protected] is also possible
- Please attach the log: '/tmp/nitropy.log.er8mz_96' with any support/help request!
- Please check if you have udev rules installed: https://docs.nitrokey.com/nitrokeys/nitrokey3/firmware-update#troubleshooting-linux

For above button press the journal reports:

[ 1311.564133] host01 kernel: usb 3-3: USB disconnect, device number 17
[ 1311.876390] host01 kernel: usb 3-3: new high-speed USB device number 18 using xhci_hcd
[ 1312.024160] host01 kernel: usb 3-3: New USB device found, idVendor=20a0, idProduct=42dd, bcdDevice= 3.00
[ 1312.029334] host01 kernel: usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1312.029991] host01 kernel: usb 3-3: Product: USB COMPOSITE DEVICE
[ 1312.030400] host01 kernel: usb 3-3: Manufacturer: NXP SEMICONDUCTOR INC.
[ 1312.030748] host01 kernel: hid-generic 0003:20A0:42DD.0015: hiddev3,hidraw9: USB HID v1.00 Device [NXP SEMICONDUCTOR INC. USB COMPOSITE DEVICE] on usb-0000:00:14.0-3/input0
[ 1312.036321] host01 systemd[1698]: Stopped target smartcard.target - Smart Card.
[ 1312.036722] host01 systemd[1]: Stopped target smartcard.target - Smart Card.

Again, the ACLs on the device look OK:

[~]$ getfacl /dev/hidraw9
getfacl: Removing leading '/' from absolute path names
# file: dev/hidraw9
# owner: root
# group: root
user::rw-
user:farblos:rw-
group::---
mask::rw-
other::---

I have copied away the log file quoted above. Here is what seems one relevant part to me (it is repeated in multiple variations):

14212     DEBUG nitrokey.nk3.updates Trying to connect to bootloader (try 1 of 3)
14212     DEBUG pynitrokey.cli.trussed Searching NK3 bootloader device (try 1 of 30)
14275      INFO nitrokey.trussed._bootloader.lpc55_upload.mboot.mcuboot Connect: identifier='usb', device= (0x20A0, 0x42DD)path=b'3-3:1.0'
14275     DEBUG nitrokey.trussed._bootloader.lpc55_upload.utils.interfaces.device.usb_device Opening the Interface:  (0x20A0, 0x42DD)path=b'3-3:1.0'
14277    WARNING pynitrokey.cli An unhandled exception occurred
Traceback (most recent call last):
  File "/home/farblos/.local/share/pipx/venvs/pynitrokey/lib/python3.12/site-packages/nitrokey/trussed/_bootloader/lpc55_upload/utils/interfaces/device/usb_device.py", line 78, in open
    self._device.open_path(self.path)
  File "hid.pyx", line 158, in hid.device.open_path
OSError: open failed

Since the error messages were not really helpful I tried an strace, where it became clear (?) that it is actually a file hid.pyx that is missing here (newlines in strace added by me):

4549  openat(AT_FDCWD, "/home/farblos/.local/share/pipx/venvs/pynitrokey/lib/python3.12/site-packages/nitrokey/trussed/_bootloader/lpc55_upload/utils/interfaces/device/usb_device.py", O_RDONLY|O_CLOEXEC) = 10
4549  fstat(10, {st_mode=S_IFREG|0644, st_size=5994, ...}) = 0
4549  ioctl(10, TCGETS, 0x7ffef2144e40) = -1 ENOTTY (Inappropriate ioctl for device)
4549  lseek(10, 0, SEEK_CUR)            = 0
4549  read(10, "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# Copyright 2023 NXP\n#\n# SPDX-License-Identifier: BSD-3-Clause\n\n\"\"\"Low level Hid device.\"\"\"\nimport logging\nimport warnings\nfrom typing import TYPE_CHECKING, List, Optional\n\nfrom ....exceptions import SPSDKCon"..., 4096) = 4096
4549  read(10, "rror(\"Device is not opened for writing\")\n        try:\n            bytes_written = self._device.write(data)\n        except Exception as e:\n            raise SPSDKConnectionError(str(e)) from e\n        if bytes_written < 0 or bytes_written < len(data):\n     "..., 8192) = 1898
4549  read(10, "", 8192)                = 0
4549  close(10)                         = 0
4549  newfstatat(AT_FDCWD, "/home/farblos/.local/share/pipx/venvs/pynitrokey/lib/python3.12/site-packages/nitrokey/trussed/_bootloader/lpc55_upload/utils/interfaces/device/usb_device.py", {st_mode=S_IFREG|0644, st_size=5994, ...}, 0) = 0


4549  newfstatat(AT_FDCWD, "hid.pyx", 0x7ffef2144cb0, 0) = -1 ENOENT (No such file or directory)


4549  write(3, "22610    WARNING pynitrokey.cli An unhandled exception occurred\nTraceback (most recent call last):\n  File \"/home/farblos/.local/share/pipx/venvs/pynitrokey/lib/python3.12/site-packages/nitrokey/trussed/_bootloader/lpc55_upload/utils/interfaces/device/usb_"..., 4179) = 4179

What am I missing here? I know little about Python.

@robin-nitrokey
Copy link
Member

Thanks for the detailed report! I’m not sure if the hid.pyx error is the cause or just a symptom. I’ll look into it.

Does the following udev rule fix the problem for you?

ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42dd", MODE="666"

@robin-nitrokey
Copy link
Member

Another idea – the hidapi library recently changed its default backend. Can you check which version you are using? The method depends on how you installed pynitrokey – generally, you need to run pip freeze | grep hidapi with the correct pip.

@farblos
Copy link
Author

farblos commented Dec 12, 2024

Like this?

[~]$ /home/farblos/.local/share/pipx/venvs/pynitrokey/bin/python3 -m pip freeze | grep hidapi
hidapi==0.14.0.post4

I probably should add here that I'm one of those preferring not to install the Debian Recommends - meaning that my system may be lacking packages which are "usually" installed. But I'm not sure to what extent that matters when using pipx and venvs...

Will try the 0666 on the hidraw device tomorrow, but my gut feeling rather points to something missing in my Python setup ...

@robin-nitrokey
Copy link
Member

Yes, thank you! I was able to reproduce the problem on my machine. It is caused by a breaking change in a dependency, see trezor/cython-hidapi#191. There are two options to fix the problem:

  • Rollback to hidapi==0.14.0.post2, for example with pipx:
    pipx inject pynitrokey hidapi==0.14.0.post2
    
  • Add a new udev rule:
    ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42dd", MODE="666"
    

@farblos
Copy link
Author

farblos commented Dec 13, 2024

Thanks! So you were right with your 0666 proposal, after all.

I will go for the pipx inject rollback as a work-around and see how you manage to fix this in the long term. Of course, using the uaccess tag is way more elegant ...

Thanks again.

@farblos
Copy link
Author

farblos commented Dec 13, 2024

Completed the firmware update successfully after doing

pipx inject --force pynitrokey hidapi==0.14.0.post2

robin-nitrokey added a commit that referenced this issue Dec 13, 2024
hidapi release v0.14.0-post.4 does not work with our udev rules as it
switches back to the libusb backend instead of using hidraw.  Until we
have rolled out new udev rules or hidapi has migrated to hidraw for
good, this patch restricts hidapi to the versions using the hidraw
backend.

Fixes: #601
@jjakob
Copy link

jjakob commented Dec 31, 2024

I package pynitrokey for gentoo (for my personal overlay), I ran into this issue as gentoo has hidapi 0.14.0_p4 (post4) and no older versions available, a workaround that worked for me personally was to add this local udev rule

ACTION!="add|change", GOTO="nk3_end"
ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42dd", TAG+="uaccess"
LABEL="nk3_end"

Now I wonder how I can make the package work for others too, is it as simple as modifying the udev rule that libnitrokey provides, removing all hidraw match filters?

@robin-nitrokey
Copy link
Member

@jjakob We are preparing a similar change here: Nitrokey/nitrokey-udev-rules#6. It would be great if you could test the updated rules and comment the results in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants