google / OpenSK

OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.
Apache License 2.0
2.93k stars 287 forks source link

OpenOCD can't work for the Nordic nRF52840-dongle #405

Open Lostsite opened 2 years ago

Lostsite commented 2 years ago

Expected Behavior

run the program with OpenOCD

Actual Behavior

run ./deploy.py --board=nrf52840_dongle --programmer=openocd --opensk (--programmer=openocd must ad, otherwise will try to run with Jlink)

shows: fatal: Couldn't install Tock OS: ERROR: Cannot find the board configuration file. You may need to update OpenOCD to the version in latest git master.

Steps to Reproduce the Problem

1.git clone and run './setup.sh' currectly 2.installed all other responses needed ( tockloader==1.5.0, rust (nightly-2020-06-10-x86_64), libssl-dev, uuid-runtime )

  1. installed OpenOCD 0.11.0 (which is the newest one)

Specifications

jmichelp commented 2 years ago

Thanks for reporting.

Your issue is a lack of documentation on our side. OpenOCD requires to manually specify the programmer interface you use. Which means that the user must create a configuration file for their use case.

The file should be named nordic_nrf52840_dongle.cfg and needs to contain the interface definition as well as the chip. Here is an example, which IIRC was using an LPC-Link2 board as a programmer:

interface cmsis-dap
transport select swd
set CHIPNAME nrf52840
source [find target/nrf52.cfg]

The file should be located in ${HOME}/.local/share/openocd/scripts/board/.

The last 3 lines should be there all the time, only the first one needs to be changed based on the programmer you're using.

Lostsite commented 2 years ago

(Sorry, I might be asking a very basic question...) Is there any way to let OpenOCD write directly through the nrf52840 dongle's USB port? If it does, how can I config the interface part?

jmichelp commented 2 years ago

OpenOCD, pyOCD as well as JLink are JTAG/SWD programmers which one must manually wire to the dongle by either using the castellations on the side of the PCB or the TagConnect pads on the bottom of the PCB.

In order to flash over USB, please use the nordicdfu programmer. We added support (with the help of external contributors) to allow flashing Nordic dongles without requiring any external hardware.

kaczmarczyck commented 2 years ago

We need to document OpenOCD and pyOCD better, or remove support.

foopub commented 2 years ago

Supporting openocd is definitely helpful, due to its reliability and availability of cheap interfaces like the st-link.

(feel free to skip these next 2 paragraphs) Using nrfutil is limited and can be a huge pain - firstly since the required version doesn't support python 3.10 so pyenv is needed, secondly since one of its dependencies, pc_ble_driver_py, cannot be installed on a musl. Cloning the nrfutil repo locally and removing pc_ble_driver_py from the requirements before installing seemed to give a partly successful flash. The leds were working as documented, but the actual key functionality seemed broken - i.e. cat /dev/hidraw8 showed the dongle responds with a single o on pressing the button... re-flashing didn't fix it, and I suspect the inability to clear storage was the main issue.

Using jlink goes is contrary to the spirit of open source which has obvious security implications - god knows what the firmware is doing. It's also expensive.

Openocd has one issue - for me it doesn't search in ${HOME}/.local/share/openocd/scripts/ by default, and even copying the file to /usr/share/openocd/scripts/board doesn't seem to work. My solution was to edit ~/.local/lib/python3.9/site-packages/tockloader/openocd.py line 116:

openocd_command = '{openocd_cmd} -c "{prefix} {source} {cmd_prefix} {cmd} {cmd_suffix} exit"'.format(

to insert the search path:

openocd_command = '{openocd_cmd} -s /home/foo/.local/share/openocd/scripts/ -c "{prefix} {source} {cmd_prefix} {cmd} {cmd_suffix} exit"'.format(

No soldering or retainer clip are needed either - inserting regular jumper pins into the side channels/grooves of the dongle, against a breadboard or even just blu tack does the job.

Flashing this way seems to work. This is obviously very hacky and far from streamlined and part of the issue lies in tock being unable to pass flags such as -s ... to openocd as far as I can tell?

Either way, I'll be happy to contribute my notes to the documentation once I find a neater way. Hope this comment is helps for anyone in my position.

kaczmarczyck commented 2 years ago

Thanks for taking the time to explain! I'd be more than happy to merge a PR with documentation for OpenOCD, if you can make it work.

jmichelp commented 2 years ago

As a side note, have you tried to use PyOCD instead? It's a pure python implementation for Cortex-M devices which from my experience provides better support than OpenOCD. I think we support it on OpenSK (mainly because when we started the project, OpenOCD support for the Nordic chip was broken IIRC)

foopub commented 2 years ago

The problem with PyOCD is that one of the wheels it depends on doesn't want to build on musl by default:

error: cannot produce cdylib for `cmsis-cffi v0.3.0 (/tmp/pip-install-xp4dna45/cmsis-pack-manager_8aacfcf601e643d7970bb9ec0baa7dcf/rust/cmsis-cffi)` as the target `x86_64-unknown-linux-musl` does not support these crate types

On Alpine at least (which links musl dynamically), this can be solved with RUSTFLAGS='-C target-feature=-crt-static' pip install ..., not sure about other musl targets. Obviously for anyone on a glibc distro (large majority of people), this shouldn't be an issue. Still, installing openocd (or any other package in the distro's repo) is generally much easier than fiddling with python packages as pip is not a good package manager.

There's another concerning message:

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. nrfutil 5.2.0 requires pyyaml~=4.2b1, but you have pyyaml 6.0 which is incompatible.

but it seems pyocd has installed fine. I will assume that it works normally once installed, although I haven't tried actually flashing with it. Anyway, I think the issue has been resolved with the merge?