diff --git a/README.md b/README.md index 1467bd1..51a6e51 100644 --- a/README.md +++ b/README.md @@ -10,180 +10,70 @@ This repository contains a Rust implementation of a [FIDO2](https://fidoalliance.org/fido2/) authenticator. +We developed OpenSK as a [Tock OS](https://tockos.org) application. -We developed this as a [Tock OS](https://tockos.org) application and it has been -successfully tested on the following boards: +We intend to bring a full open source experience to security keys, from +application to operating system. You can even 3D print your own open source +enclosure! +You can see OpenSK in action in this +[video on YouTube](https://www.youtube.com/watch?v=klEozvpw0xg)! -* [Nordic nRF52840-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) -* [Nordic nRF52840-dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) - -## Disclaimer - -This project is **proof-of-concept and a research platform**. It is **NOT** -meant for a daily usage. It's still under development and as such comes with a -few limitations: +You are viewing the branch for developers. New features are developed here +before they are stabilized. If you instead want to use the FIDO certified +firmware, please go back to the +[stable branch](https://github.com/google/OpenSK). ### FIDO2 -The stable branch implements the published -[CTAP2.0 specifications](https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html) -and is FIDO certified. +The develop branch implements the +[CTAP2.1 specification](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html). +This branch is not FIDO certified. The implementation is backwards compatible +to CTAP2.0. Additionally, OpenSK supports U2F, and non-discoverable credentials +created with either protocol are compatible with the other. -FIDO2 certified L1 +### :warning: Disclaimer -It already contains some preview features of 2.1, that you can try by adding the -flag `--ctap2.1` to the deploy command. The full -[CTAP2.1 specification](https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html) -is work in progress in the develop branch and is tested less thoroughly. +This project is **proof-of-concept and a research platform**. It is **NOT** +meant for a daily usage. It comes with a few limitations: + +* This branch is under development, and therefore less rigorously tested than the stable branch. +* The cryptography implementations are not resistent against side-channel attacks. -### Cryptography - -We're currently still in the process on making the +We're still in the process of integrating the [ARM® CryptoCell-310](https://developer.arm.com/ip-products/security-ip/cryptocell-300-family) embedded in the [Nordic nRF52840 chip](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fcryptocell.html) -work to get hardware-accelerated cryptography. In the meantime we implemented -the required cryptography algorithms (ECDSA, ECC secp256r1, HMAC-SHA256 and -AES256) in Rust as a placeholder. Those implementations are research-quality -code and haven't been reviewed. They don't provide constant-time guarantees and -are not designed to be resistant against side-channel attacks. +to enable hardware-accelerated cryptography. Our placeholder implementations of required +cryptography algorithms (ECDSA, ECC secp256r1, HMAC-SHA256 and AES256) in Rust are research-quality +code. They haven't been reviewed and don't provide constant-time guarantees. + +## Hardware + +You will need one the following supported boards: + +* [Nordic nRF52840-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) + development kit. This board is more convenient for development and debug + scenarios as the JTAG probe is already on the board. +* [Nordic nRF52840 Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle) + to have a more practical form factor. +* [Makerdiary nRF52840-MDK USB dongle](https://wiki.makerdiary.com/nrf52840-mdk/). +* [Feitian OpenSK dongle](https://feitiantech.github.io/OpenSK_USB/). ## Installation -For a more detailed guide, please refer to our -[installation guide](docs/install.md). +To install OpenSK, +1. follow the [general setup steps](docs/install.md), +1. then continue with the instructions for your specific hardware: + * [Nordic nRF52840-DK](docs/boards/nrf52840dk.md) + * [Nordic nRF52840 Dongle](docs/boards/nrf52840_dongle.md) + * [Makerdiary nRF52840-MDK USB dongle](docs/boards/nrf52840_mdk.md) + * [Feitian OpenSK dongle](docs/boards/nrf52840_feitian.md) -1. If you just cloned this repository, run the following script (**Note**: you - only need to do this once): - - ```shell - ./setup.sh - ``` - -1. Next step is to install Tock OS as well as the OpenSK application on your - board. Run: - - ```shell - # Nordic nRF52840-DK board - ./deploy.py --board=nrf52840dk_opensk --opensk - # Nordic nRF52840-Dongle - ./deploy.py --board=nrf52840_dongle_opensk --opensk - ``` - -1. Finally you need to inject the cryptographic material if you enabled - batch attestation or CTAP1/U2F compatibility (which is the case by - default): - - ```shell - ./tools/configure.py \ - --certificate=crypto_data/opensk_cert.pem \ - --private-key=crypto_data/opensk.key - ``` - -1. On Linux, you may want to avoid the need for `root` privileges to interact - with the key. For that purpose we provide a udev rule file that can be - installed with the following command: - - ```shell - sudo cp rules.d/55-opensk.rules /etc/udev/rules.d/ && - sudo udevadm control --reload - ``` - -### Customization - -If you build your own security key, depending on the hardware you use, there are -a few things you can personalize: - -1. If you have multiple buttons, choose the buttons responsible for user - presence in `src/main.rs`. -1. If you have colored LEDs, like different blinking patterns and want to play - around with the code in `src/main.rs` more, take a look at e.g. `wink_leds`. -1. You find more options and documentation in `src/ctap/customization.rs`, - including: - - The default level for the credProtect extension. - - The default minimum PIN length, and what relying parties can set it. - - Whether you want to enforce alwaysUv. - - Settings for enterprise attestation. - - The maximum PIN retries. - - Whether you want to use batch attestation. - - Whether you want to use signature counters. - - Various constants to adapt to different hardware. - -### 3D printed enclosure - -To protect and carry your key, we partnered with a professional designer and we -are providing a custom enclosure that can be printed on both professional 3D -printers and hobbyist models. - -All the required files can be downloaded from -[Thingiverse](https://www.thingiverse.com/thing:4132768) including the STEP -file, allowing you to easily make the modifications you need to further -customize it. - -## Development and testing - -### Printing panic messages to the console - -By default, libtock-rs blinks some LEDs when the userspace application panicks. -This is not always convenient as the panic message is lost. In order to enable -a custom panic handler that first writes the panic message via Tock's console -driver, before faulting the app, you can use the `--panic-console` flag of the -`deploy.py` script. - -```shell -# Example on Nordic nRF52840-DK board -./deploy.py --board=nrf52840dk_opensk --opensk --panic-console -``` - -### Debugging memory allocations - -You may want to track memory allocations to understand the heap usage of -OpenSK. This can be useful if you plan to port it to a board with fewer -available RAM for example. To do so, you can enable the `--debug-allocations` -flag of the `deploy.py` script. This enables a custom (userspace) allocator -that prints a message to the console for each allocation and deallocation -operation. - -The additional output looks like the following. - -```text -# Allocation of 256 byte(s), aligned on 1 byte(s). The allocated address is -# 0x2002401c. After this operation, 2 pointers have been allocated, totalling -# 384 bytes (the total heap usage may be larger, due to alignment and -# fragmentation of allocations within the heap). -alloc[256, 1] = 0x2002401c (2 ptrs, 384 bytes) -# Deallocation of 64 byte(s), aligned on 1 byte(s), from address 0x2002410c. -# After this operation, 1 pointers are allocated, totalling 512 bytes. -dealloc[64, 1] = 0x2002410c (1 ptrs, 512 bytes) -``` - -A tool is provided to analyze such reports, in `tools/heapviz`. This tool -parses the console output, identifies the lines corresponding to (de)allocation -operations, and first computes some statistics: - -* Address range used by the heap over this run of the program, -* Peak heap usage (how many useful bytes are allocated), -* Peak heap consumption (how many bytes are used by the heap, including - unavailable bytes between allocated blocks, due to alignment constraints and - memory fragmentation), -* Fragmentation overhead (difference between heap consumption and usage). - -Then, the `heapviz` tool displays an animated "movie" of the allocated bytes in -heap memory. Each frame in this "movie" shows bytes that are currently -allocated, that were allocated but are now freed, and that have never been -allocated. A new frame is generated for each (de)allocation operation. This tool -uses the `ncurses` library, that you may have to install beforehand. - -You can control the tool with the following parameters: - -* `--logfile` (required) to provide the file which contains the console output - to parse, -* `--fps` (optional) to customize the number of frames per second in the movie - animation. - -```shell -cargo run --manifest-path tools/heapviz/Cargo.toml -- --logfile console.log --fps 50 -``` +To test whether the installation was successful, visit a +[demo website](https://webauthn.io/) and try to register and login. +Please check our [Troubleshooting and Debugging](docs/debugging.md) section if you +have problems with the installation process or during development. To find out what +else you can do with your OpenSK, see [Customization](docs/customization.md). ## Contributing diff --git a/docs/boards/nrf52840_dongle.md b/docs/boards/nrf52840_dongle.md new file mode 100644 index 0000000..e88104b --- /dev/null +++ b/docs/boards/nrf52840_dongle.md @@ -0,0 +1,85 @@ +# OpenSK logo + +## Nordic nRF52840 Dongle + +![Nordic dongle](../img/dongle_front.jpg) + +### 3D printed enclosure + +To protect and carry your key, we partnered with a professional designer and we +are providing a custom enclosure that can be printed on both professional 3D +printers and hobbyist models. + +![OpenSK Enclosure](img/enclosure.jpg) + +All the required files can be downloaded from +[Thingiverse](https://www.thingiverse.com/thing:4132768) including the STEP +file, allowing you to easily make the modifications you need to further +customize it. + +### Flashing using DFU (preferred method) + +To flash the firmware, run: + +```shell +./deploy.py --board=nrf52840_dongle_dfu --opensk --programmer=nordicdfu +``` + +The script will ask you to switch to DFU mode. To activate that on your dongle, +keep the button pressed while inserting the device into your USB port. You may +additionally need to press the tiny, sideways facing reset button. The device +indicates DFU mode with a slowly blinking red LED. + +### Flashing with an external programmer (JLink, OpenOCD, etc.) + +If you want to use JTAG with the dongle, you need additional hardware. + +* a [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) JTAG + probe. +* a + [TC2050 Tag-Connect programming cable](https://www.tag-connect.com/product/tc2050-idc-nl-10-pin-no-legs-cable-with-ribbon-connector). +* a [Tag-Connect TC2050 ARM2010](http://www.tag-connect.com/TC2050-ARM2010) + adaptor +* optionally a + [Tag-Connect TC2050 retainer clip](http://www.tag-connect.com/TC2050-CLIP) + to keep the spring loaded connector pressed to the PCB. + +Follow these steps: + +1. The JTAG probe used for programming won't provide power to the board. + Therefore you will need to use a USB-A extension cable to power the dongle + through its USB port. + +1. Connect the TC2050 cable to the pads below the PCB: + + ![Nordic dongle pads](../img/dongle_pads.jpg) + +1. You can use the retainer clip if you have one to avoid maintaining pressure + between the board and the cable: + + ![Nordic dongle retainer clip](../img/dongle_clip.jpg) + +1. Depending on the programmer you're using, you may have to adapt the next + command line. Run our script for compiling/flashing Tock OS on your device: + + ```shell + $ ./deploy.py --board=nrf52840_dongle_opensk --programmer=jlink + ``` + +1. Remove the programming cable and the USB-A extension cable. + +### Buttons and LEDs + +The bigger, white button conveys user presence to the application. Some actions +like register and login will make the dongle blink, asking you to confirm the +transaction with a button press. The small, sideways pointing buttong next to it +restarts the dongle. + +The 2 LEDs show the state of the app. There are different patterns: + +| Pattern | Cause | +|------------------------------------|------------------------| +| all LEDs and colors | app panic | +| green and blue blinking | asking for touch | +| all LEDs and colors for 5s | wink (just saying Hi!) | +| red slow blink | DFU mode | diff --git a/docs/boards/nrf52840_feitian.md b/docs/boards/nrf52840_feitian.md new file mode 100644 index 0000000..664df7b --- /dev/null +++ b/docs/boards/nrf52840_feitian.md @@ -0,0 +1,23 @@ +# OpenSK logo + +## Feitian OpenSK USB Dongle + +### Flashing using DFU + +This board is similar in hardware to the Nordic nRF52840 Dongle. You can use DFU +to flash it, instructions to enter DFU mode depend on the version of your +hardware. See +[Feitian's instructions](https://feitiantech.github.io/OpenSK_USB/). In short: + +* In V1, use a paperclip to press the Reset button through the tiny hole. +* In V2, push and hold the user button for more than 10 seconds after + connecting your device. + +Afterwards, you can flash your Feitian OpenSK using DFU following the +[instructions for the Nordic nRF52840 Dongle](nrf52840_dongle.md#Flashing-using-DFU). + +### Buttons and LEDs + +For both hardware versions, the buttons and LEDs are described in detail in the +[hardware section](https://feitiantech.github.io/OpenSK_USB/hardware/) of +Feitian's website. diff --git a/docs/boards/nrf52840_mdk.md b/docs/boards/nrf52840_mdk.md new file mode 100644 index 0000000..30d74b5 --- /dev/null +++ b/docs/boards/nrf52840_mdk.md @@ -0,0 +1,47 @@ +# OpenSK logo + +## Nordic nRF52840 MDK + +Makerdiary has instructions on their [website](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/opensk/). They use a custom script to deploy via DFU. + +After general setup, you still need these steps: + +1. Create the hexfile with the firmware. + + ```shell + ./deploy.py --board=nrf52840_mdk_dfu --opensk --programmer=none + ``` + +1. Download the + [script](https://github.com/makerdiary/nrf52840-mdk-usb-dongle/blob/master/tools/uf2conv.py) + from Makerdiary's GitHub into the OpenSK repository. + +1. Run the script: + + ```shell + python3 uf2conv.py -c -f 0xada52840 -o target/opensk.uf2 target/nrf52840_mdk_dfu_merged.hex + ``` + +1. Boot into DFU mode. Keep the user button pressed on your hardware while + inserting it into a USB slot. You should see a bit of red blinking, and then + a constant green light. + +1. Your dongle should appear in your normal file browser like other USB sticks. + Copy the file `target/opensk.uf2` over. + +1. Replug to reboot. + +### Buttons and LEDs + +The big, white button conveys user presence to the application. Some actions +like register and login will make the device blink, asking you to confirm the +transaction with a button press. + +The LED shows the state of the app. There are different patterns: + +| Pattern | Cause | +|------------------------------------|------------------------| +| red glow | busy | +| red and blue blinking | asking for touch | +| red, green, white pattern for 5s | wink (just saying Hi!) | +| constant green | DFU mode | diff --git a/docs/boards/nrf52840dk.md b/docs/boards/nrf52840dk.md new file mode 100644 index 0000000..5be25b3 --- /dev/null +++ b/docs/boards/nrf52840dk.md @@ -0,0 +1,50 @@ +# OpenSK logo + +## Nordic nRF52840-DK board + +![Nordic development kit](../img/devkit_annotated.jpg) + +### Flashing using JTAG + +The development board comes with its own JTAG port, so the default programmer +is the easiest and most convenient. You can flash OpenSK with these steps: + +1. Connect a micro USB cable to the JTAG USB port. + +1. Run our script for compiling/flashing Tock OS and OpenSK on your device: + + ```shell + ./deploy.py --board=nrf52840dk_opensk --opensk + ``` + +1. Connect a micro USB cable to the device USB port. + +**Note**: Due to current limitations of our implementation and Tock, you may +have to press the `BOOT/RESET` button, located next to the device USB port on +the board in order to see your OpenSK device on your system. + +### Buttons and LEDs + +Out of the 5 buttons, the group of 4 behaves identically. They all convey user +presence to the application. Some actions like register and login will make the +board blink, asking you to confirm the transaction with a button press. The +remaining fifth button restarts the board. + +The group of 4 LEDs on the right show the state of the app. There are different +patterns: + +| Pattern | Cause | +|------------------------------------|------------------------| +| LED1 slow blink | kernel panic | +| all LEDs blinking together | app panic | +| LED1+4 and LED2+3 fast alternating | asking for touch | +| fast swirling | wink (just saying Hi!) | +| circle | allocator panic | + +The LEDs closer to the JTAG port indicates the power and debugging state. + +There are 3 switches that need to be in the correct position: + +* Power (bottom left): On +* nRF power source (center left): VDD +* SW6 (top right): DEFAULT diff --git a/docs/customization.md b/docs/customization.md new file mode 100644 index 0000000..be3a6bc --- /dev/null +++ b/docs/customization.md @@ -0,0 +1,66 @@ +# OpenSK logo + +## Customization + +### Cryptographic material + +All the generated certificates and private keys are stored in the directory +`crypto_data/`. The expected content after running our `setup.sh` script is: + +File | Purpose +------------------------ | -------------------------------------------------------- +`aaguid.txt` | Text file containaing the AAGUID value +`opensk_ca.csr` | Certificate sign request for the Root CA +`opensk_ca.key` | ECC secp256r1 private key used for the Root CA +`opensk_ca.pem` | PEM encoded certificate of the Root CA +`opensk_ca.srl` | File generated by OpenSSL +`opensk_cert.csr` | Certificate sign request for the attestation certificate +`opensk_cert.pem` | PEM encoded certificate used for the authenticator +`opensk.key` | ECC secp256r1 private key used for the autenticator +`opensk_upgrade.key` | Private key for signing upgrades through CTAP +`opensk_upgrade_pub.pem` | Public key added to the firmware for verifying upgrades + +If you want to use your own attestation certificate and private key, +replace the `opensk_cert.pem` and `opensk.key` files. The script at +`tools/configure.py` customizes an OpenSK device with the correct certificate +and private key. + +Our build script `build.rs` is responsible for converting the `aaguid.txt` file +into raw data that is then used by the Rust file `src/ctap/key_material.rs`. + +Please make sure to safely store all private key material before calling +`reset.sh`, or the files will be lost. + +#### Certificate considerations + +The certificate on OpenSK is used for attestation. That means, whenever you +register OpenSK on a website, you attest the legitimacy of your hardware. For +self-generated certificates, this claim is rather trivial. Still, it is required +by some websites and to use U2F. + +Usually, the attestation private key is shared between a batch of at least +100,000 security keys of the same model. If you build your own OpenSK, your +private key is unique to you. This makes you identifiable across registrations: +Two websites could collaborate to track if registrations were attested with the +same key material. If you use OpenSK beyond experimentation, please consider +carefully if you want to take this privacy risk. + +### Software personalization + +If you build your own security key, depending on the hardware you use, there are +a few things you can personalize: + +1. If you have multiple buttons, choose the buttons responsible for user + presence in `src/main.rs`. +1. If you have colored LEDs, like different blinking patterns and want to play + around with the code in `src/main.rs` more, take a look at e.g. `wink_leds`. +1. You find more options and documentation in `src/ctap/customization.rs`, + including: + * The default level for the credProtect extension. + * The default minimum PIN length, and what relying parties can set it. + * Whether you want to enforce alwaysUv. + * Settings for enterprise attestation. + * The maximum PIN retries. + * Whether you want to use batch attestation. + * Whether you want to use signature counters. + * Various constants to adapt to different hardware. diff --git a/docs/debugging.md b/docs/debugging.md new file mode 100644 index 0000000..9414e91 --- /dev/null +++ b/docs/debugging.md @@ -0,0 +1,137 @@ +# OpenSK logo + +## Troubleshooting and Debugging + +### Inspecting USB + +The following commands should help you identify whether your operating system +identifies OpenSK over USB. + +#### Linux + +When plugging in the USB key, the following line should appear in `lsusb`. + +```shell +$ lsusb +... +Bus XXX Device YYY: ID 1915:521f Nordic Semiconductor ASA OpenSK +``` + +You should also see lines similar to the following in `dmesg`. + +```shell +$ dmesg +... +[XXX] usb A-BB: new full-speed USB device number 00 using xhci_hcd +[XXX] usb A-BB: New USB device found, idVendor=1915, idProduct=521f, bcdDevice= 0.01 +[XXX] usb A-BB: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[XXX] usb A-BB: Product: OpenSK +[XXX] usb A-BB: Manufacturer: Nordic Semiconductor ASA +[XXX] usb A-BB: SerialNumber: v0.1 +[XXX] hid-generic 0000:0000:0000.0000: hiddev0,hidraw0: USB HID v1.10 Device [Nordic Semiconductor ASA OpenSK] on usb-0000:00:00.0-00/input0 +``` + +#### Mac OS X + +When plugging in the USB key, you should see a similar line by using the `ioreg` +tool: + +```shell +$ ioreg -p IOUSB ++-o Root +... + +-o AppleUSBXHCI Root Hub Simulation@14000000 + +-o OpenSK@14400000 +``` + +### Debug console + +On the dev board, you can read the debug messages using JLink. Use one terminal +for the server and one for the client: + +```shell +# Terminal 1 +JLinkExe -device nrf52 -if swd -speed 1000 -autoconnect 1 +# Terminal 2 +JLinkRTTClient +``` + +You can enhance the debug output by adding flags to the deploy command (see +below for details): + +* `--debug`: more debug messages +* `--panic-console`: add panic messages +* `--debug-allocations`: print information about the used heap + +Adding debugging to your firmware increases resource usage, including + +* USB communication speed +* RAM usage +* binary size + +Depending on your choice of board, you may have to increase the available stack +for kernel or app, or disable features so that the binary fits the flash. Also +expect more packet loss. + +### App panic messages + +By default, libtock-rs blinks some LEDs when the userspace application panics. +This is not always convenient as the panic message is lost. In order to enable +a custom panic handler that first writes the panic message via Tock's console +driver, before faulting the app, you can use the `--panic-console` flag of the +`deploy.py` script. + +```shell +# Example on Nordic nRF52840-DK board +./deploy.py --board=nrf52840dk_opensk --opensk --panic-console +``` + +### Memory allocations + +You may want to track memory allocations to understand the heap usage of +OpenSK. This can be useful if you plan to port it to a board with fewer +available RAM for example. To do so, you can enable the `--debug-allocations` +flag of the `deploy.py` script. This enables a custom (userspace) allocator +that prints a message to the console for each allocation and deallocation +operation. + +The additional output looks like the following. + +```text +# Allocation of 256 byte(s), aligned on 1 byte(s). The allocated address is +# 0x2002401c. After this operation, 2 pointers have been allocated, totalling +# 384 bytes (the total heap usage may be larger, due to alignment and +# fragmentation of allocations within the heap). +alloc[256, 1] = 0x2002401c (2 ptrs, 384 bytes) +# Deallocation of 64 byte(s), aligned on 1 byte(s), from address 0x2002410c. +# After this operation, 1 pointers are allocated, totalling 512 bytes. +dealloc[64, 1] = 0x2002410c (1 ptrs, 512 bytes) +``` + +A tool is provided to analyze such reports, in `tools/heapviz`. This tool +parses the console output, identifies the lines corresponding to (de)allocation +operations, and first computes some statistics: + +* Address range used by the heap over this run of the program, +* Peak heap usage (how many useful bytes are allocated), +* Peak heap consumption (how many bytes are used by the heap, including + unavailable bytes between allocated blocks, due to alignment constraints and + memory fragmentation), +* Fragmentation overhead (difference between heap consumption and usage). + +Then, the `heapviz` tool displays an animated "movie" of the allocated bytes in +heap memory. Each frame in this "movie" shows bytes that are currently +allocated, that were allocated but are now freed, and that have never been +allocated. A new frame is generated for each (de)allocation operation. This tool +uses the `ncurses` library, that you may have to install beforehand. + +You can control the tool with the following parameters: + +* `--logfile` (required) to provide the file which contains the console output + to parse, +* `--fps` (optional) to customize the number of frames per second in the movie + animation. + +```shell +cargo run --manifest-path tools/heapviz/Cargo.toml -- --logfile console.log --fps 50 +``` diff --git a/docs/img/enclosure.jpg b/docs/img/enclosure.jpg new file mode 100644 index 0000000..ed5ef95 Binary files /dev/null and b/docs/img/enclosure.jpg differ diff --git a/docs/install.md b/docs/install.md index ca888ba..c7183bb 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,51 +1,22 @@ -OpenSK logo +# OpenSK logo -# Installation guide +## Installation guide -This document describes in details how to turn a Nordic nRF52840 board into a -working FIDO2 security key. +This document lists required steps to start build your own OpenSK. -## Pre-requisite +### Programmers -### Hardware +OpenSK supports different ways to flash your board: -You will need one the following supported boards: - -* [Nordic nRF52840-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) - development kit. This board is more convenient for development and debug - scenarios as the JTAG probe is already on the board. -* [Nordic nRF52840 Dongle](https://www.nordicsemi.com/Software-and-tools/Development-Kits/nRF52840-Dongle) - to have a more practical form factor. -* [Makerdiary nRF52840-MDK USB dongle](https://wiki.makerdiary.com/nrf52840-mdk/). -* [Feitian OpenSK dongle](https://feitiantech.github.io/OpenSK_USB/). - -In the case of the Nordic USB dongle, you may also need the following extra -hardware: - -* a [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) JTAG - probe. -* a - [TC2050 Tag-Connect programming cable](https://www.tag-connect.com/product/tc2050-idc-nl-10-pin-no-legs-cable-with-ribbon-connector). -* a [Tag-Connect TC2050 ARM2010](http://www.tag-connect.com/TC2050-ARM2010) - adaptor -* optionally a - [Tag-Connect TC2050 retainer clip](http://www.tag-connect.com/TC2050-CLIP) - to keep the spring loaded connector pressed to the PCB. - -Additionnaly, OpenSK supports other ways to flash your board: - -* [OpenOCD](http://openocd.org/). * [Segger J-Link](https://www.segger.com/products/debug-probes/j-link/) (default method). +* [OpenOCD](http://openocd.org/). * [pyOCD](https://pypi.org/project/pyocd/). * [nrfutil](https://pypi.org/project/nrfutil/) for the USB dongle boards that - supports it, which allows you to directly flash a working board over USB + support it, which allows you to directly flash a working board over USB without additional hardware. -This guide **does not** cover how to setup the JTAG probe and their related -tools on your system. - -### Software +### Software requirements In order to compile and flash a working OpenSK firmware, you will need the following: @@ -54,221 +25,121 @@ following: * python3 and pip (can be installed with the `python3-pip` package on Debian) * the OpenSSL command line tool (can be installed and configured with the `libssl-dev` and `pkg-config` packages on Debian) +* `nrfutil` (can be installed using `pip3 install nrfutil`) if you want to flash + a device with DFU +* `uuid-runtime` if you are missing the `uuidgen` command. + +The proprietary software to use the default programmer can be found on the +[Segger website](https://www.segger.com/downloads/jlink). Please follow their +instructions to appropriate binaries for your system. The scripts provided in this project have been tested under Linux and OS X. We haven't tested them on Windows and other platforms. -## Compiling the firmware +### Compiling the firmware -### Initial setup +If this is your first time installing OpenSK, please skip directly to +[Initial setup](#Initial-setup). Else, see +[Updating your setup](#Updating-your-setup) below. -If you just cloned this repository, you need to run the following script -(_output may differ_): +#### Updating your setup + +Depending on the difference to your last state, you may need some of the +following steps: + +* If you are not just testing minor changes, reset and redo the setup. This + will delete all uncommited changes. + + ```shell + ./reset.sh + ./setup.sh + ``` + +* Flash your board according to the + [flashing instructions below](#Flashing-a-firmware]. If you come from an + OpenSK version before the 2.0 certified one, your credential storage is not + backwards compatible and you have to reset it. :warning: You will lose + logins to all websites that you registered with OpenSK. To erase your + persistent storage, run the deploy script twice: Once with the application + parameter `--erase_storage`, and once with `--opensk` as usual. + + This reset also clears the certificate. For a privacy discussion, see the + [certificate section in Customization](customization.md#Certificate-considerations). + If you want to reinstall it, you also need to rerun: + + ```shell + ./tools/configure.py \ + --certificate=crypto_data/opensk_cert.pem \ + --private-key=crypto_data/opensk.key + ``` + +#### Initial setup + +To clone and setup the repository for the develop branch, run the following +commands: ```shell -$ ./setup.sh -[-] Applying patch "01-persistent-storage.patch"... DONE. -[-] Applying patch "02-usb.patch"... DONE. -[-] Applying patch "03-app-memory.patch"... DONE. -[-] Applying patch "04-rtt.patch"... DONE. -[-] Applying patch "01-linked_list_allocator.patch"... DONE. -[-] Applying patch "02-panic_console.patch"... DONE. -[-] Applying patch "03-timer.patch"... DONE. -[-] Applying patch "04-public_syscalls.patch"... DONE. -[-] Applying patch "05-bigger_heap.patch"... DONE. -[-] Applying patch "06-no_spin_allocator.patch"... DONE. -Signature ok -subject=CN = Google OpenSK CA -Getting Private key -Signature ok -subject=CN = Google OpenSK Hacker Edition -Getting CA Private Key -info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu' - - nightly-2020-02-03-x86_64-unknown-linux-gnu unchanged - rustc 1.42.0-nightly (f43c34a13 2020-02-02) - -Requirement already up-to-date: tockloader in /usr/lib/python3/dist-packages/tockloader-1.4.0.dev0-py3.7.egg (1.4.0.dev0) -Requirement already satisfied, skipping upgrade: argcomplete>=1.8.2 in /usr/lib/python3/dist-packages (from tockloader) (1.10.0) -Requirement already satisfied, skipping upgrade: colorama>=0.3.7 in /usr/lib/python3/dist-packages (from tockloader) (0.3.7) -Requirement already satisfied, skipping upgrade: crcmod>=1.7 in /usr/lib/python3/dist-packages (from tockloader) (1.7) -Requirement already satisfied, skipping upgrade: pyserial>=3.0.1 in /usr/lib/python3/dist-packages (from tockloader) (3.4) -Requirement already satisfied, skipping upgrade: pytoml>=0.1.11 in /usr/lib/python3/dist-packages (from tockloader) (0.1.21) -info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date - Updating crates.io index - Ignored package `elf2tab v0.4.0` is already installed, use --force to override +git clone -b develop https://github.com/google/OpenSK.git +cd OpenSK +./setup.sh ``` -The script performs the following steps: +The setup script performs the following steps: -1. Make sure that the git submodules are checked out +1. Make sure that the git submodules are checked out. 1. Apply our patches that haven't yet been merged upstream to both [Tock](https://github.com/tock/tock) and - [libtock-rs](https://github.com/tock/libtock-rs) + [libtock-rs](https://github.com/tock/libtock-rs). -1. Generate a self-signed certificate authority as well as a private key and a - corresponding certificate for your OpenSK key signed by this CA. You will be - able to replace them with your own certificate and private key. +1. Generate crypto material, see [Customization](customization.md) for details. -1. Ensure that your Rust toolchain is using the same version that we tested - OpenSK with. +1. Install the correct Rust toolchain for ARM devices. 1. Install [tockloader](https://github.com/tock/tockloader). -1. Ensure that the Rust toolchain can compile code for ARM devices. +Additionally on Linux, you need to install a `udev` rule file to allow non-root +users to interact with OpenSK devices. To install it, execute: -### Replacing the certificates +```shell +sudo cp rules.d/55-opensk.rules /etc/udev/rules.d/ +sudo udevadm control --reload +``` -All the generated certificates and private keys are stored in the directory -`crypto_data/`. +Then, you need and replug the device for the rule to trigger. -This is the expected content after running our `setup.sh` script: +Last, if you want to use U2F or attestation, configure the certificate. If your +client does not support FIDO2 yet, this step is mandatory for your OpenSK to +work. OpenSK is incompatible with some browsers without a certificate. Please +read the +[certificate section in Customization](customization.md#Certificate-considerations) +for understand privacy tradeoffs. -File | Purpose ------------------------- | -------------------------------------------------------- -`aaguid.txt` | Text file containaing the AAGUID value -`opensk_ca.csr` | Certificate sign request for the Root CA -`opensk_ca.key` | ECC secp256r1 private key used for the Root CA -`opensk_ca.pem` | PEM encoded certificate of the Root CA -`opensk_ca.srl` | File generated by OpenSSL -`opensk_cert.csr` | Certificate sign request for the attestation certificate -`opensk_cert.pem` | PEM encoded certificate used for the authenticator -`opensk.key` | ECC secp256r1 private key used for the autenticator -`opensk_upgrade.key` | Private key for signing upgrades through CTAP -`opensk_upgrade_pub.pem` | Public key added to the firmware for verifying upgrades - -If you want to use your own attestation certificate and private key, simply -replace `opensk_cert.pem` and `opensk.key` files. - -Our build script `build.rs` is responsible for converting the `aaguid.txt` file -into raw data that is then used by the Rust file `src/ctap/key_material.rs`. - -Our configuration script `tools/configure.py` is responsible for configuring -an OpenSK device with the correct certificate and private key. +```shell +./tools/configure.py \ + --certificate=crypto_data/opensk_cert.pem \ + --private-key=crypto_data/opensk.key +``` ### Flashing a firmware -#### Nordic nRF52840-DK board +From here on, please follow the instructions for your hardware: -![Nordic development kit](img/devkit_annotated.jpg) - -1. Connect a micro USB cable to the JTAG USB port. - -1. Run our script for compiling/flashing Tock OS and OpenSK on your device - (_output may differ_): - - ```shell - $ ./deploy.py --board=nrf52840dk_opensk --opensk - info: Updating rust toolchain to nightly-2020-02-03 - info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu' - info: checking for self-updates - info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date - info: Rust toolchain up-to-date - info: Building Tock OS for board nrf52840dk_opensk - Compiling tock-registers v0.5.0 (./third_party/tock/libraries/tock-register-interface) - Compiling tock-cells v0.1.0 (./third_party/tock/libraries/tock-cells) - Compiling enum_primitive v0.1.0 (./third_party/tock/libraries/enum_primitive) - Compiling tock_rt0 v0.1.0 (./third_party/tock/libraries/tock-rt0) - Compiling nrf52840dk_opensk v0.1.0 (./third_party/tock/boards/nordic/nrf52840dk_opensk) - Compiling kernel v0.1.0 (./third_party/tock/kernel) - Compiling cortexm v0.1.0 (./third_party/tock/arch/cortex-m) - Compiling nrf5x v0.1.0 (./third_party/tock/chips/nrf5x) - Compiling capsules v0.1.0 (./third_party/tock/capsules) - Compiling cortexm4 v0.1.0 (./third_party/tock/arch/cortex-m4) - Compiling nrf52 v0.1.0 (./third_party/tock/chips/nrf52) - Compiling nrf52840 v0.1.0 (./third_party/tock/chips/nrf52840) - Compiling components v0.1.0 (./third_party/tock/boards/components) - Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base) - Finished release [optimized + debuginfo] target(s) in 13.15s - info: Converting Tock OS file into a binary - info: Building OpenSK application - Finished release [optimized] target(s) in 0.02s - info: Generating Tock TAB file for application/example ctap2 - info: Erasing all installed applications - All apps have been erased. - info: Flashing file third_party/tock/boards/nordic/nrf52840dk_opensk/target/thumbv7em-none-eabi/release/nrf52840dk_opensk.bin. - info: Flashing padding application - info: Installing Tock application ctap2 - info: You're all set! - ``` - -1. Connect a micro USB cable to the device USB port. - -**Note**: Due to current limitations of our implementation and Tock, you may -have to press the `BOOT/RESET` button, located next to the device USB port on -the board in order to see your OpenSK device on your system. - -#### Nordic nRF52840 Dongle - -##### Using external programmer (JLink, OpenOCD, etc.) - -![Nordic dongle](img/dongle_front.jpg) - -1. The JTAG probe used for programming won't provide power to the board. - Therefore you will need to use a USB-A extension cable to power the dongle - through its USB port. - -1. Connect the TC2050 cable to the pads below the PCB: - - ![Nordic dongle pads](img/dongle_pads.jpg) - -1. You can use the retainer clip if you have one to avoid maintaining pressure - between the board and the cable: - - ![Nordic dongle retainer clip](img/dongle_clip.jpg) - -1. Depending on the programmer you're using, you may have to adapt the next - command line. Run our script for compiling/flashing Tock OS on your device - (_output may differ_): - - ```shell - $ ./deploy.py os --board=nrf52840_dongle_opensk --programmer=jlink - info: Updating rust toolchain to nightly-2020-02-03 - info: syncing channel updates for 'nightly-2020-02-03-x86_64-unknown-linux-gnu' - info: checking for self-updates - info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date - info: Rust toolchain up-to-date - info: Building Tock OS for board nrf52840_dongle - Compiling tock-cells v0.1.0 (./third_party/tock/libraries/tock-cells) - Compiling tock-registers v0.5.0 (./third_party/tock/libraries/tock-register-interface) - Compiling enum_primitive v0.1.0 (./third_party/tock/libraries/enum_primitive) - Compiling tock_rt0 v0.1.0 (./third_party/tock/libraries/tock-rt0) - Compiling nrf52840_dongle v0.1.0 (./third_party/tock/boards/nordic/nrf52840_dongle) - Compiling kernel v0.1.0 (./third_party/tock/kernel) - Compiling cortexm v0.1.0 (./third_party/tock/arch/cortex-m) - Compiling nrf5x v0.1.0 (./third_party/tock/chips/nrf5x) - Compiling capsules v0.1.0 (./third_party/tock/capsules) - Compiling cortexm4 v0.1.0 (./third_party/tock/arch/cortex-m4) - Compiling nrf52 v0.1.0 (./third_party/tock/chips/nrf52) - Compiling nrf52840 v0.1.0 (./third_party/tock/chips/nrf52840) - Compiling components v0.1.0 (./third_party/tock/boards/components) - Compiling nrf52dk_base v0.1.0 (./third_party/tock/boards/nordic/nrf52dk_base) - Finished release [optimized + debuginfo] target(s) in 11.72s - info: Converting Tock OS file into a binary - info: Building OpenSK application - Finished release [optimized] target(s) in 0.02s - info: Generating Tock TAB file for application/example ctap2 - info: Erasing all installed applications - All apps have been erased. - info: Flashing file third_party/tock/boards/nordic/nrf52840_dongle/target/thumbv7em-none-eabi/release/nrf52840_dongle.bin. - info: Flashing padding application - info: Installing Tock application ctap2 - info: You're all set! - ``` - -1. Remove the programming cable and the USB-A extension cable. +* [Nordic nRF52840-DK](boards/nrf52840dk.md) +* [Nordic nRF52840 Dongle](boards/nrf52840_dongle.md) +* [Makerdiary nRF52840-MDK USB dongle](boards/nrf52840_mdk.md) +* [Feitian OpenSK dongle](boards/nrf52840_feitian.md) ### Advanced installation -Although flashing using a Segger JLink probe is the officially supported way, -our tool, `deploy.py` also supports other methods: +We recommend that you flash your development board with JTAG and dongles with +DFU, as described in the [board documentation](#Flashing-a-firmware) linked +above. However, we support other programmers: * OpenOCD: `./deploy.py --board=nrf52840_dongle_opensk --opensk --programmer=openocd` * pyOCD: `./deploy.py --board=nrf52840_dongle_opensk --opensk --programmer=pyocd` -* Nordic DFU: `./deploy.py --board=nrf52840_dongle_dfu --opensk - --programmer=nordicdfu` * Custom: `./deploy.py --board=nrf52840_dongle_opensk --opensk --programmer=none`. In this case, an IntelHex file will be created and how to program a board is left to the user. @@ -278,67 +149,3 @@ If your board is already flashed with Tock OS, you may skip installing it: For more options, we invite you to read the help of our `deploy.py` script by running `./deploy.py --help`. - -### Installing the udev rule (Linux only) - -By default on Linux, a USB device will require root privilege in order interact -with it. As it is not recommended to run your web browser with such a high -privileged account, we made a `udev` rule file to allow regular users to -interact with OpenSK authenticators. - -To install it, you need to execute the following commands: - -```shell -sudo cp rules.d/55-opensk.rules /etc/udev/rules.d/ -sudo udevadm control --reload -``` - -Then, you will need to unplug and replug the key for the rule to trigger. - -## Troubleshooting - -To test whether the installation was successful, visit a -[demo website](https://webauthn.io/) and try to register and login. - -### Linux - -If you have issues with the demo website, the following commands should help you -understand whether OpenSK was installed properly. - -When plugging in the USB key, the following line should appear in `lsusb`. - -```shell -$ lsusb -... -Bus XXX Device YYY: ID 1915:521f Nordic Semiconductor ASA OpenSK -``` - -You should also see lines similar to the following in `dmesg`. - -```shell -$ dmesg -... -[XXX] usb A-BB: new full-speed USB device number 00 using xhci_hcd -[XXX] usb A-BB: New USB device found, idVendor=1915, idProduct=521f, bcdDevice= 0.01 -[XXX] usb A-BB: New USB device strings: Mfr=1, Product=2, SerialNumber=3 -[XXX] usb A-BB: Product: OpenSK -[XXX] usb A-BB: Manufacturer: Nordic Semiconductor ASA -[XXX] usb A-BB: SerialNumber: v0.1 -[XXX] hid-generic 0000:0000:0000.0000: hiddev0,hidraw0: USB HID v1.10 Device [Nordic Semiconductor ASA OpenSK] on usb-0000:00:00.0-00/input0 -``` - -### Mac OS X - -If you have issues with the demo website, the following commands should help you -understand whether OpenSK was installed properly. - -When plugging in the USB key, you should see a similar line by using the `ioreg` -tool: - -```shell -$ ioreg -p IOUSB -+-o Root -... - +-o AppleUSBXHCI Root Hub Simulation@14000000 - +-o OpenSK@14400000 -```