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.
-
+### :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 @@
+#
+
+## Nordic nRF52840 Dongle
+
+
+
+### 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.
+
+### 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:
+
+ 
+
+1. You can use the retainer clip if you have one to avoid maintaining pressure
+ between the board and the cable:
+
+ 
+
+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 @@
+#
+
+## 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 @@
+#
+
+## 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 @@
+#
+
+## Nordic nRF52840-DK board
+
+
+
+### 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 @@
+#
+
+## 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 @@
+#
+
+## 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 @@
-
+#
-# 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:
-
-
-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.)
-
-
-
-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:
-
- 
-
-1. You can use the retainer clip if you have one to avoid maintaining pressure
- between the board and the cable:
-
- 
-
-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
-```