This is the firmware for the [passkey v2](https://git.cuvoodoo.info/kingkevin/board/src/tag/passkey_v2) hardware.

purpose
=======

passkey is a USB dongle to paste credentials.
It appears as a serial port to enter the credentials, and HID keyboard to paste them.

Usage:

- insert the passkey dongle in the USB port, with "passkey" text facing up
- it will appear as serial port to enter the credentials, and HID keyboard to paste them
- the red light will blink, indicating no credentials have been entered yet
- connect to it using your favourite serial terminal (e.g. [putty](https://putty.org/) or [picocom](https://github.com/npat-efault/picocom)) using any baud rate
- press 'c' to enter your credentials to paste (username and password)
- the light will remain on
- press one button of the dongle for it to just paste the password
- press the other button to paste the username and password (tab separated)

You can configure passkey over the serial terminal:

- press 'h' to list all available options
- press 'b' to swap the buttons, changing which is for the password or username and password
- press 'l' to set which keyboard layout should be used: use the same are configured in your OS, else some letter in the pasted credentials might be different
- by default the credentials will be cleared 12 hours after they have been entered. Press 'g' to change this time, up to 12 hours
- by default the credentials will be cleared 3 hours after the last time they have been pasted. Press 'r' to change this time, up to 3 hours
- press 'a' to authenticate the device. Enter a random word, and it will provide an URL and a corresponding result. Click on the link, and if the response is the same, the device is running the original firmware.
- press 'k' to enter your own key, which you need to remember. You can then authenticate the device locally (without using the link), using any SHA256 calculator.

security
========

Since the device stores credentials to paste them, it is quite security sensitive.
You can see if credentials are stored using the light.
If it blinks, no credentials are stored.
If it is on, credentials are stored.
Do not leave the dongle unattended in this case, as someone could just press on the button to display the credentials.

The credentials are only stored in volatile memory (i.e. RAM).
As soon as the device is unplugged, the power is removed and the credentials will be cleared.

You can clear the credentials by:

- unplugging the dongle
- pressing both buttons at the same time
- pressing 4 times CapsLock or NumLock within 2 seconds on your keyboard

The credentials will be cleared up to 12 hours after they have been entered.
The credentials will be cleared up to 3 hours after the last time they have been pasted.
This decreases the risk of having them leaked if the dongle is left unattended for too long.
These timeouts can be configured over the serial port.

The dongle can be locked after been programmed.
This prevents from:

- using the SWD interface to attach a debugger on the test points and dump the credentials from the running system
- using the bootloader to flash a new malicious firmware (e.g. that could store the credentials on non-volatile memory and reveal them later)
- mass erase the device, to re-enable debugging and flashing

The flash memory can also write protected.
Only the last 4 kB of flash are re-writable, as they are used to store the configuration set over serial.
This makes it very hard from exploiting the runtime firmware and overwriting it.

To verify if the firmware is original, use the authentication menu.
If you get the passkey from CuVoodoo, you will also has received it's ID per email.
This ID should the prefix of the authentication token.
Each device has been programmed with an individual key before being locked.
Matching the result with the website ensures the key is the same.
To avoid using the website, you can set a user key, and perform the authentication locally using any SHA256 calculator.

risks
-----

The [STM32F042F6P](https://www.st.com/en/microcontrollers-microprocessors/stm32f042f6.html) micro-controller does not have security certifications.
If the device locking mechanism can be circumvented (e.g. using fault injection), a malicious firmware could be installed.
Because of that, it is not recommended to leave the dongle unattended.
It has a hole to pass a string through and attach it to a key-chain you keep with you.
This string also allows to easily unplug the device from the computer.
It is also recommended to draw on the back of the device, so it becomes unique and hard to tamper with unnoticed.

Obermaier and Tatschner [showed in 20179(https://www.usenix.org/system/files/conference/woot17/woot17-paper-obermaier.pdf) how to degrade the readout protection.
This involved decapsulating the chip, which would make it easy to see that the device has been tampered with once you added a drawing onto it.
Other side channel or fault injection attacks could exist to retrieve the key in a less destructive way.
Since the passkey is inexpensive, just toss it away and get a new one if you suspect it has been tampered with.
The other possibility would be for and attacker to intercept the device on the shipping way, extract the ID and corresponding manufacturer key, and programming them on a new chip, along with a malicious firmware.
This malicious device could still pass authentication.
To prevent this attack, you can manufacturer the passkey yourself.
The board design files and firmware source code are open and available.
The bill of material in around $2, and the parts can be hand soldered with little experience.

firmware
========

The devices is based on a [STM32F042F6P](https://www.st.com/en/microcontrollers-microprocessors/stm32f042f6.html) micro-controller.
The firmware uses the [TinyUSB](https://github.com/hathach/tinyusb) USB stack.

If you got the passkey from CuVoodoo, it comes configured with a manufacturer key and locked.
You can also request for a blank devices, and manufacturer it and flash the firmware yourself.

To compile the firmware, you will need and ARM GCC toolchain and run these commands:

~~~
git clone https://git.cuvoodoo.info/kingkevin/passkey_fw
cd passkey_fw/
git checkout passkey
cd examples/device/hid_cdc_passkey
make BOARD=stm32f042passkey get-deps
make BOARD=stm32f042passkey
~~~

When no firmware has been programmed on the passkey, the STM32 bootloader will allow to flash the firmware over USB using dfu-util:

~~~
make dfu
~~~

Re-plug the dongle in the USB port and the passkey will boot the flashed firmware.

Using the serial terminal you can then enter the manufacturer key by pressing 'K'.
Finally, you can lock the firmware by pressing 'L'.
This it not revocable.
Once locked, you can re-flash the device, change de manufacturer key, or debug the device.

Before it is locked, you can erase the firmware using 'E'.
Re-plugging the dongle will start the bootloader again, allowing to re-flash a firmware.
You can also connect an SWD programmer, such as a DAPlink, on the test points.
The pinout is a follow:

- G: ground
- C: SWCLK
- D: SWDIO
- T: the UART TX used to print debug messages

You can then flash and debug the firmware.

~~~
make flash
make debug
~~~
