Giter Club home page Giter Club logo

u2f-token's Introduction

GitHub Workflow Status (with event) GitHub all releases Latest Release License: GPL v3

U2F-TOKEN firmware for STM32F103 and EFM32HG boards

Turns your cheap STM32F103 or EFM32HG board into U2F token.

Supported boards

U2F-TOKEN is known to work on:

  • Tomu board (EFM32HG) is an excellent device to use for U2F as it can sit entirely inside of your USB port (and it is opensource)
  • Blue pill (STM32F103) as well as Black pill
  • Countless ST32F103 based Chinese St-Link V2 clones can be turned into U2F devices with U2F-TOKEN
  • Variety of Maple Mini clones which can be found on Aliexpress

Udev rules

On Linux you need to add the following rules to be able to use your device as non root user. Create the file /etc/udev/rules.d/10-u2f-token.rules (as root) and paste in the following lines:

ACTION=="add|change", KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0e90", TAG+="uaccess"
ACTION=="add|change", SUBSYSTEM=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0e90", TAG+="uaccess"

Using webauthn from snap packages

Snap has additional security measures so that you will need to add a tag to the hidraw rule for each snap app that you want to have access to the token.

For Chromium and Firefox (snap since ubuntu 21.10) this then reads:

ACTION=="add|change", KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0e90", TAG+="uaccess", TAG+="snap_firefox_firefox", TAG+="snap_chromium_chromedriver"

Installing using prebuilt release binaries

Requirements

Python 3.6 or later and pip are needed. You will also need the hidapi library:

  • To install on OS X run brew install hidapi
  • To install on Ubuntu run sudo apt install libhidapi-hidraw0 python3-hid
  • To install on Archlinux, run pacman -Sy hidapi

If you are on Linux, you will also need to install the aforementioned Udev rules.

Flash binary

Download the binary suitable for your board at releases page.

Binaries for Tomu are built with bootloader support, use the following command to flash the firmware:

dfu-util -d 1209:70b1 -D u2f-TOMU.bin

Binaries for STM32 boards are built without bootloader support, you need to flash the firmware using SWD or JTAG interface. Example using OpenOCD and STLINK-V2:

openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c 'init' -c 'halt' -c 'flash write_image erase unlock u2f-BLUE_PILL.bin  0x08000000' -c 'exit'

(replace BLUE_PILL with appropriate board name)

Initialize device

After flashing device with binary it requires to be initialized. Release binaries come with readout protection enabled and without attestation certificate provisioned. To initialize the device, clone this repository and run (Python 3.6+ and the hidapi library are required):

pip3 install -r requirements.txt --user
cd src/cert
python3 certtool init

You will see something similar to:

Trying to initialize device HIDDevice:
    USB_16d0_0e90_14100000 | 16d0:e90 | unknown | U2F-token (STM32) | 1.00
    release_number: 256
    usage_page: 61904
    usage: 1
    interface_number: -1
Success

The above command will upload pre-generated attestaion.der from this repository to the device. If for whatever reason you want to use your own certificate, tweak and run ./gen.sh to generate it.

Test your key with latest Chrome or Firefox browser using this page.

Building and flashing

Requirements

Build tools

Install and setup Command Line tools for Xcode on macOS.

Install build-essentials package on Debian/Ubuntu:

sudo apt install build-essential

GNU Toolchain for ARM Embedded Processors

Installing on macOS with homebrew:

brew tap osx-cross/arm
brew install arm-gcc-bin

Installing on Debian/Ubuntu:

sudo apt-add-repository ppa:team-gcc-arm-embedded/ppa
sudo apt update
sudo apt install gcc-arm-embedded

For Kali Linux:

apt install gcc-arm-none-eabi

OpenSSL

MacOS comes with openssl/libressl installed out of the box.

Installing on Debian/Ubuntu:

sudo apt install openssl

asn1crypto

There is a tiny python script used to convert certificates generated by OpenSSL from DER format into C-array. It depends on asn1crypto package.

To install with pip:

pip install --user --upgrade asn1crypto

OpenOCD

Installing on macOS with homebrew:

brew install open-ocd

Installing on Debian/Ubuntu:

sudo apt install openocd

Building

git clone https://github.com/gl-sergei/u2f-token.git
cd u2f-token
git submodule update --init
cd src
make TARGET=<target>

will produce firmware file build/u2f.bin.

Supported targets are:

Use BLUE_PILL or BLACK_PILL for generic STM32F103 board without push button.

If build was unsuccessful for whatever reason and you want to start from scratch you may want to run

make clean

to remove all object files, or

make certclean

to remove generated certificates, or

make distclean

to remove board.h symlink, or even all of the above.

Readout protection

Make sure to enable readout protection if you are going to use your device as 2FA for your accounts. Build firmware with ENFORCE_DEBUG_LOCK=1:

make clean
make TARGET=<target> ENFORCE_DEBUG_LOCK=1

Injecting private key

Firmware generates EC private key on its first boot and erases it when it enters the bootloader. You may want to backup your private key and make it survive firmware upgrade. To achieve this, generate the key on your host machine and inject it into the firmware binary.

Generate your private key:

openssl ecparam -name prime256v1 -genkey -noout -outform der -out key.der

You may want to encrypt your key.der and back it up.

Check device's authentication counter if you are going to perform the firmware upgrade. You can see it in Yubikey demo site output. For the new device, you can skip ctr parameter all together or set it to 1. Let's say the current counter value is 1000.

Use this command to patch firmware binary:

./inject_key.py --key key.der --ctr 1001

Flashing

To STMF103 board using ST-LINK/V2 and OpenOCD

Start OpenOCD:

openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

On other terminal run:

telnet localhost 4444
> reset halt
> stm32f1x unlock 0
> reset halt
> program build/u2f.elf verify reset
> shutdown

To EFM32HG (Tomu) board using DFU

Providing you have Toboot installed:

dfu-util -v -d 1209:70b1 -D build/u2f.bin

After flashing device you still need to initialize device as described in Initialize device

Security considerations

Random number generator (RNG)

U2F-TOKEN is using Neug to generate high quality random numbers. The source of entropy is built-in Analog to Digital Converter (both STM32F103 and EFM32HG have ones). 32-bit ADC output is passed through CRC32 35 times to get 1120 bit input for SHA256-based whitening element.

I ran this suite on 1.7M of raw RNG output from Tomu board.

SUMMARY
-------
monobit_test                             0.119269669219     PASS
frequency_within_block_test              0.11518538339      PASS
runs_test                                0.0626194973829    PASS
longest_run_ones_in_a_block_test         0.585067135452     PASS
binary_matrix_rank_test                  0.862015222632     PASS
dft_test                                 0.965404804209     PASS
non_overlapping_template_matching_test   1.00000631693      PASS
overlapping_template_matching_test       0.35076924588      PASS
maurers_universal_test                   0.999954925686     PASS
linear_complexity_test                   0.906328320146     PASS
serial_test                              0.159775233458     PASS
approximate_entropy_test                 0.15960828003      PASS
cumulative_sums_test                     0.0774471722878    PASS
random_excursion_test                    0.251774950817     PASS
random_excursion_variant_test            0.0871834280054    PASS

Device Key

Device key is a private key for ECDSA p256r1. Any 256 bits are valid key. It is generated using RNG on first run and stored in device's flash memory. It should not leave the device. You must protect your device's flash from readout to protect device key (see below).

Key handles

U2F protocol specifies two actions - register and authenticate.

Register takes appID and challenge from the caller and returns key handle, public key corresponding to that key handle and attestation certificate. No one usually verify the validity of attestation certificate.

Authenticate takes the key handle, appID and another challenge, then it signs both with the private key corresponding to the key handle. Caller then able to check if signature has been made by the same device using a public key from register step. Device in turn has to make sure to refuse signing requests for unknown key handles and don't mess private keys corresponding to different key handles.

If embedded devices would have unlimited storage, the best would be to store all pairs of key handle and private key on the device. But it is not the case, so the private key actually computed based on key handle and device key.

Here is how it is done by U2F-TOKEN firmware:

Register request (app_id is given):

  1. Generate random nonce (32 bytes)
  2. Compute HMAC_SHA265(app_id + nonce) using device key. Result becomes a private key (32 bytes)
  3. Compute HMAC_SHA256(private_k + app_id) + nonce. Result becomes a key handle (64 bytes)
  4. Compute public key for the private key (it's a nice feature of ECC that public key can be easily computed for given private key, but it is not that easy to do vice versa) and hand it out to the caller along with the key handle

Authenticate request (app_id and key handle are given):

  1. Extract nonce (last 32 bytes of key handle)
  2. Compute HMAC_SHA256(app_id + nonce) using device key. This is a private key
  3. Compute HMAC_SHA256(private_k) and compare it to the first 32 bytes of key handle, they should match. If they don't, return key not found error.

Key handle should look random for casual observer and it does. I ran the same suite on 200K of key handle data generated on Tomu board:

SUMMARY
-------
monobit_test                             0.228183190471     PASS
frequency_within_block_test              0.226128174333     PASS
runs_test                                0.0567490131255    PASS
longest_run_ones_in_a_block_test         0.748631279961     PASS
binary_matrix_rank_test                  0.612219673314     PASS
dft_test                                 0.553339041027     PASS
non_overlapping_template_matching_test   1.00000008312      PASS
overlapping_template_matching_test       0.932591232105     PASS
maurers_universal_test                   0.999315334632     PASS
linear_complexity_test                   0.335268833847     PASS
serial_test                              0.201711285468     PASS
approximate_entropy_test                 0.20129897411      PASS
cumulative_sums_test                     0.11790756896      PASS
random_excursion_test                    0.199118786038     PASS
random_excursion_variant_test            0.157445636324     PASS

Tamper resistance

STM32F103 and EFM32HG devices are not tamper resistant. Highly skilled hacker with the right equipment will be able to read the contents of device's flash and get the device key. Then he will be able to clone your device and use it as second factor to log into your account providing that he knows your passwords as well.

However, they are resistant enough for daily use as second factor authentication device, because:

  1. Firmware does not allow to read flash contents by USB, neither does it disclose device key
  2. Both STM32F103 and EFM32HG have "flash readout protection" feature. Once enabled, this feature protecting flash from being read via debug interface. See this post for EFM32, and this question for STM32F103. See also efm32 debuglock and stm32f1x lock commands in OpenOCD manual.

License

Chopstx is a threading library for Cortex-M0 and Cortex-M3 processors written by Niibe Yutaka.

ECC is taken from Gnuk project by Niibe Yutaka.

Some constants and memory layout structures were taken from EFM32 platform libraries by Silicon Laboratories.

Copyright © 2017 Sergei Glushchenko

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

As additional permission under GNU GPL version 3 section 7, you may distribute non-source form of the Program without the copy of the GNU GPL normally required by section 4, provided you inform the recipients of GNU GPL by a written offer.

u2f-token's People

Contributors

albymor avatar assasinfil avatar asymmetric avatar azrdev avatar dsseng avatar eliotb avatar gl-sergei avatar i8-pi avatar max-nextcloud avatar sotpapathe avatar szszszsz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

u2f-token's Issues

no x.509v3 U2F attestation certificate

Hi,

I made a BluePill U2F device and tried it on the following webauthn demo sites:
yubico.com
webauthn.io
webauthn.org

When registering at webauthn.org I got the following error message:

Error: registration failed: expected U2F attestation certificate to be x.509v3
Registration error: Error: registration failed: expected U2F attestation certificate to be x.509v3

Below is the whole debug output:

WEBAUTHN DEBUG TERMINAL
-----------------------
REGISTER START:

Sending Message to Server:
>>>>>>>>>>>>>>>>
{"username":"test1234","displayName":"test1234"}
>>>>>>>>>>>>>>>>

Received Message from Server:
<<<<<<<< [ STATUS 200 ] <<<<<<<<
{"status":"ok","errorMessage":"","rp":{"name":"WebAuthn.org"},"user":{"name":"test1234","id":"JVBq7f5oIwpbrRU0bTxvlg","displayName":"test1234"},"challenge":"h8vscUKHr-QQvln7YaEoeIe691IuIFbgyLlWeEsA_FewJ-iLc0tuq81pPvIJtxFEgiG7daloLN4LJ-rV8BWK9A","pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"timeout":60000,"attestation":"direct"}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

WebAuthn navigator.credentials.create() options:
[CreateOptions] {
    rp: {
        name: "WebAuthn.org",
    },
    user: {
        name: "test1234",
        id: [ArrayBuffer] (16 bytes)
            25 50 6A ED FE 68 23 0A 5B AD 15 34 6D 3C 6F 96,
        displayName: "test1234",
    },
    challenge: [ArrayBuffer] (64 bytes)
        87 CB EC 71 42 87 AF E4 10 BE 59 FB 61 A1 28 78
        87 BA F7 52 2E 20 56 E0 C8 B9 56 78 4B 00 FC 57
        B0 27 E8 8B 73 4B 6E AB CD 69 3E F2 09 B7 11 44
        82 21 BB 75 A9 68 2C DE 0B 27 EA D5 F0 15 8A F4,
    pubKeyCredParams: [
        {
            type: "public-key",
            alg: -7,
        },
        {
            type: "public-key",
            alg: -257,
        },
    ],
    timeout: 60000,
    attestation: "direct",
}
WAITING FOR USER PRESENCE...
USER PRESENCE DONE.
WebAuthn navigator.credentials.create() result:
[CredentialAttestation] {
    rawId: [ArrayBuffer] (64 bytes)
        D5 12 7C 54 27 26 82 E9 1F 56 6E 74 F9 97 52 1B
        5A A7 DF 7C B2 D7 03 2E 68 60 B3 08 D8 26 4E 23
        77 6C 2B D8 60 91 BB 15 13 DF 0F 38 8E 21 68 47
        7F 51 3E 8F F2 BB 17 48 DC D8 1C 1C 7F BA 0F A2,
    id: [ArrayBuffer] (64 bytes)
        D5 12 7C 54 27 26 82 E9 1F 56 6E 74 F9 97 52 1B
        5A A7 DF 7C B2 D7 03 2E 68 60 B3 08 D8 26 4E 23
        77 6C 2B D8 60 91 BB 15 13 DF 0F 38 8E 21 68 47
        7F 51 3E 8F F2 BB 17 48 DC D8 1C 1C 7F BA 0F A2,
    response: {
        clientDataJSON: [ArrayBuffer] (159 bytes)
            7B 22 63 68 61 6C 6C 65 6E 67 65 22 3A 22 68 38
            76 73 63 55 4B 48 72 2D 51 51 76 6C 6E 37 59 61
            45 6F 65 49 65 36 39 31 49 75 49 46 62 67 79 4C
            6C 57 65 45 73 41 5F 46 65 77 4A 2D 69 4C 63 30
            74 75 71 38 31 70 50 76 49 4A 74 78 46 45 67 69
            47 37 64 61 6C 6F 4C 4E 34 4C 4A 2D 72 56 38 42
            57 4B 39 41 22 2C 22 6F 72 69 67 69 6E 22 3A 22
            68 74 74 70 73 3A 2F 2F 77 65 62 61 75 74 68 6E
            2E 6F 72 67 22 2C 22 74 79 70 65 22 3A 22 77 65
            62 61 75 74 68 6E 2E 63 72 65 61 74 65 22 7D,
        attestationObject: [ArrayBuffer] (611 bytes)
            A3 63 66 6D 74 68 66 69 64 6F 2D 75 32 66 67 61
            74 74 53 74 6D 74 A2 63 73 69 67 58 48 30 46 02
            21 00 C8 27 7D 02 24 F1 66 FF D9 23 54 86 A1 23
            63 38 91 82 E0 DD 38 FE F2 51 F9 FF 3C 46 51 41
            7A 91 02 21 00 F3 39 29 7F DD 25 B9 A5 2C EC AF
            0E 22 DF 32 1D 77 6A 13 E8 A5 5A F6 C0 DB 41 1C
            D0 04 F4 D4 7C 63 78 35 63 81 59 01 27 30 82 01
            23 30 81 C9 02 14 6C F9 0C 9E 22 BD DF 03 66 B5
            B9 63 29 EC 86 CF 80 D2 13 50 30 0A 06 08 2A 86
            48 CE 3D 04 03 02 30 14 31 12 30 10 06 03 55 04
            03 0C 09 55 32 46 20 54 6F 6B 65 6E 30 1E 17 0D
            31 39 30 33 30 37 32 30 31 32 32 39 5A 17 0D 32
            39 30 33 30 34 32 30 31 32 32 39 5A 30 14 31 12
            30 10 06 03 55 04 03 0C 09 55 32 46 20 54 6F 6B
            65 6E 30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06
            08 2A 86 48 CE 3D 03 01 07 03 42 00 04 E4 EA 69
            5E A7 36 D6 EC FF F9 9B 2B B1 F0 39 91 CB 11 97
            29 5B E4 30 08 28 DA 17 FF CC F4 D0 5B 05 93 82
            1A 1E 2F 57 30 9A 2A C1 56 37 0D 6A 95 BE 62 39
            55 3A 7A C7 55 FB F9 B5 5D 2A B8 AA 87 30 0A 06
            08 2A 86 48 CE 3D 04 03 02 03 49 00 30 46 02 21
            00 CD EA 3B 6D 2E 03 78 A1 2A E4 B2 B2 F7 4C 50
            2E B4 86 CC A3 6B 8E 10 2B 64 8A 84 4D 4E E9 FD
            89 02 21 00 94 B7 20 3E E7 EB 5C D8 7F 74 E5 35
            20 A4 F0 45 0D 87 93 F6 3F CE 8F CD 88 10 E6 45
            C7 B0 76 EB 68 61 75 74 68 44 61 74 61 58 C4 95
            69 08 8F 1E CE E3 23 29 54 03 5D BD 10 D7 CA E3
            91 30 5A 27 51 B5 59 BB 8F D7 CB B2 29 BD D4 41
            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            00 00 00 00 00 40 D5 12 7C 54 27 26 82 E9 1F 56
            6E 74 F9 97 52 1B 5A A7 DF 7C B2 D7 03 2E 68 60
            B3 08 D8 26 4E 23 77 6C 2B D8 60 91 BB 15 13 DF
            0F 38 8E 21 68 47 7F 51 3E 8F F2 BB 17 48 DC D8
            1C 1C 7F BA 0F A2 A5 01 02 03 26 20 01 21 58 20
            32 F4 4C 31 A2 AC 13 A5 68 6D 00 3A 29 8C 02 19
            AD 65 B8 2F 74 CB B9 FE 2D 4D BE 3C 1C 3D 71 0E
            22 58 20 D1 C8 23 59 24 FD DA D0 8C 32 32 75 49
            F3 F4 7E 51 C0 17 CD 74 7D B5 2E CB 44 6A F7 FD
            AF 04 64,
    },
}

Sending Message to Server:
>>>>>>>>>>>>>>>>
{"rawId":"1RJ8VCcmgukfVm50-ZdSG1qn33yy1wMuaGCzCNgmTiN3bCvYYJG7FRPfDziOIWhHf1E-j_K7F0jc2Bwcf7oPog","id":"1RJ8VCcmgukfVm50-ZdSG1qn33yy1wMuaGCzCNgmTiN3bCvYYJG7FRPfDziOIWhHf1E-j_K7F0jc2Bwcf7oPog","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJoOHZzY1VLSHItUVF2bG43WWFFb2VJZTY5MUl1SUZiZ3lMbFdlRXNBX0Zld0otaUxjMHR1cTgxcFB2SUp0eEZFZ2lHN2RhbG9MTjRMSi1yVjhCV0s5QSIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4ub3JnIiwidHlwZSI6IndlYmF1dGhuLmNyZWF0ZSJ9","attestationObject":"o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEgwRgIhAMgnfQIk8Wb_2SNUhqEjYziRguDdOP7yUfn_PEZRQXqRAiEA8zkpf90luaUs7K8OIt8yHXdqE-ilWvbA20Ec0AT01HxjeDVjgVkBJzCCASMwgckCFGz5DJ4ivd8DZrW5Yynshs-A0hNQMAoGCCqGSM49BAMCMBQxEjAQBgNVBAMMCVUyRiBUb2tlbjAeFw0xOTAzMDcyMDEyMjlaFw0yOTAzMDQyMDEyMjlaMBQxEjAQBgNVBAMMCVUyRiBUb2tlbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOTqaV6nNtbs__mbK7HwOZHLEZcpW-QwCCjaF__M9NBbBZOCGh4vVzCaKsFWNw1qlb5iOVU6esdV-_m1XSq4qocwCgYIKoZIzj0EAwIDSQAwRgIhAM3qO20uA3ihKuSysvdMUC60hsyja44QK2SKhE1O6f2JAiEAlLcgPufrXNh_dOU1IKTwRQ2Hk_Y_zo_NiBDmRcewdutoYXV0aERhdGFYxJVpCI8ezuMjKVQDXb0Q18rjkTBaJ1G1WbuP18uyKb3UQQAAAAAAAAAAAAAAAAAAAAAAAAAAAEDVEnxUJyaC6R9WbnT5l1IbWqfffLLXAy5oYLMI2CZOI3dsK9hgkbsVE98POI4haEd_UT6P8rsXSNzYHBx_ug-ipQECAyYgASFYIDL0TDGirBOlaG0AOimMAhmtZbgvdMu5_i1NvjwcPXEOIlgg0cgjWST92tCMMjJ1SfP0flHAF810fbUuy0Rq9_2vBGQ"}}
>>>>>>>>>>>>>>>>

Received Message from Server:
<<<<<<<< [ STATUS 400 ] <<<<<<<<
{"status":"failed","errorMessage":"registration failed: expected U2F attestation certificate to be x.509v3"}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Error: registration failed: expected U2F attestation certificate to be x.509v3
Registration error: Error: registration failed: expected U2F attestation certificate to be x.509v3
REGISTER DONE.

Unable to boot properly with TOMU inserted

With my tomu (using u2f-token fw) inserted into a USB port I'm unable to properly boot my Linux laptop untill I remove the token. The error logged in dmesg is:

[   16.923942] usb 1-7: device descriptor read/64, error -110

Linux version: (K)Ubuntu 19.04 with custom compiled kernel 5.1.10. I might miss some specific USB module compiled in, but once booted the token works flawless nonetheless:

[  646.417952] usb 1-7: new full-speed USB device number 6 using xhci_hcd
[  646.576314] hid-generic 0003:16D0:0E90.0003: hiddev96,hidraw0: USB HID v1.10 Device [unknown U2F-token (EFM32)] on usb-0000:00:14.0-7/input0

Able to build & flash blue pill, but no usb device when connected to PC

Hi, thanks for writing a cool firmware. I'm trying to build and flash a blue pill board. I can build fine (bins.zip containing .elf and .bin attached).
I can't exactly follow your instructions as if I telnet to my localhost, openocd drops the connection, so I opted to use openocd -f openocd.txt.
If I use program build/u2f.bin 0x08000000 verify reset to flash, when I connect the board to my PC I don't get anything in dmesg. If I use program build/u2f.elf verify reset exit to flash, I get:

** Programming Started
auto erase enabled
Info : device id = 0x20036410
Info : flash size = 64kbytes
Warn : no flash bank found for address 0x07ff0000
Info : Flash write discontinued at 0x08007dac, next section at 0x0800f800
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000003a msp: 0x20005000
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000003a msp: 0x20005000
wrote 30720 bytes from file build/u2f.elf in 1.764730s (17.000 KiB/s)
** Programming Finished **
** Verify Started **
Error: timed out while waiting for target halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x81000003 pc: 0x08000150 msp: 0x20004fe0
Error: error executing cortex_m crc algorithm
** Verify Failed **

Both BOOT pins set to 0, which has seemed to work fine so thus far.
Any idea what's going wrong? Happy to provide any additional info.

openocd.txt
bins.zip

Problems with dfu-utils flashing tomu on MacOS - dfu-util: Cannot set alternate interface

Hi, thank you for this project. I tried to follow the instructions to flash a tomu with your firmware but had no look with that.

I'm running

  • MacOS 10.14.6
  • dfu-util 0.9

The first error I'm running into is uploading the binary to the tomu:

 $ dfu-util -d 1209:70b1 -D u2f-TOMU.bin

> dfu-util 0.9
> Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
> Copyright 2010-2016 Tormod Volden and Stefan Schmidt
> This program is Free Software and has ABSOLUTELY NO WARRANTY
> Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
> 
> dfu-util: Invalid DFU suffix signature
> dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
> Opening DFU capable USB device...
> ID 1209:70b1
> Run-time device DFU version 0101
> Claiming USB DFU Interface...
> Setting Alternate Setting #0 ...
> dfu-util: Cannot set alternate interface

I tried with the prebuilt binary and a self compiled one and I get the same error.
Any hints what might be wrong?

blue pill switch?

I flashed the prebuilt to my blue pill and it seems reset button works as the auth button
and it cycles usb disconnect/connect in kernel messages, and it works on demo.yubico.com as you'd expect it should normally work...

is the reset button really intended to be the auth button or is this unexpected?

otherwise, where should a button go?

Signed tags

Hi!

Would it be possible to sign future tags? I would make verifying the authenticity of tags much easier and isn't really much more work for you.

Thanks :)

Read Out Protection (RDP) is not set

The Read Out Protection is a global Flash memory read protection allowing the embedded
firmware code to be protected against copy, reverse engineering, dumping using debug
tools or other means of intrusive attack. This protection should be set by the user after the
binary code is loaded to the embedded Flash memory.

When the read protection level 1 is activated, no access (read, erase, and program) to Flash
memory or backup SRAM can be performed via debug features such as Serial Wire or
JTAG, even while booting from SRAM or system memory bootloader.
However, when booting from Flash memory, accesses to this memory and to backup SRAM
from user code are allowed.
Any read request to the protected Flash memory generates a bus error.
Disabling RDP level 1 protection by re-programming RDP option byte to level 0 leads to a
mass erase.

RDP must be set to Level 1 right after flashing firmware or on the first run.
I think that verify&fix RDP at firmware level is more error-free. We can set OptionBits in the following way at first run (STM32 HAL used)

void TurnOnRDP() {
    FLASH_OBProgramInitTypeDef obConfig;
 
    HAL_FLASHEx_OBGetConfig(&obConfig);
 
    if (obConfig.RDPLevel == OB_RDP_LEVEL_0) {
        // this is first time we run mcu after flashing firmware
        obConfig.RDPLevel = OB_RDP_LEVEL_1;
        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();
        HAL_FLASHEx_OBProgram(&obConfig);
        HAL_FLASH_OB_Launch();
    }
}

Issue with counters?

I've tried it on a few websites (e.g. Gitlab on invent.kde.org, my own Gitea/forgejo instance, github.com) and authentication only works once. I have STLINK token without buttons.

Any ideas how this can be debugged?

Update: hmm, https://demo.yubico.com/playground seems to work more than once.

Windows + Firefox support

When trying to use my Tomu device flashed with the current HEAD on Windows 10 (Build 18362.356), Firefox 69.0.1 the device is recognized but the communication immediately fails.

Windows fails communication

I see the Initialize device section - does this also apply to locally built firmware?

Update the token with USB

I don't know if it's hard to do, but when i update the token , i need to connect many wires to my st dongle and that's quite hard to do everytime. So i thought it could be a good idea to make an "updater" like reGnual ( gnuk project ) https://salsa.debian.org/gnuk-team/gnuk/gnuk/tree/master/regnual and described as :

How to run the script: ::
$ cd tool
$ ./upgrade_by_passwd.py ../regnual/regnual.bin ../src/build/gnuk.bin

Then, the script on your host PC invoke the steps described above, and
you will get new version

Packaging into Debian

Hi!

I would like to package u2f-token to Debian. I've already packaged the Tomu bootlader (it's waiting in the Debian NEW queue). My goal is to make using the Tomu with U2F as easy as possible.

My end goal would be to write a GUI that flashes toboot and u2f-token to a Tomu so people that can't use CLI interfaces can still use the Tomu as a U2F token.

To be able to package u2f-token in Debian, I would need to package chopstx as a separate package, since Debian doesn't allow included libraries.

I have a few questions:

  1. Do you have anything against me trying to package this in Debian? It's important for me to have an upstream that's open to the idea :D
  2. Is there a technical reason the patches you made to chopstx haven't been upstreamed (the current upstream is hosted on Debian's Gitlab instance now)? I would be much more comfortable packaging the upstream chopstx instead of the fork you currently maintain at https://github.com/gl-sergei/chopstx. If it's just because you haven't had time, I may be able to help out with doing this.
  3. Would you be open to the idea of signing future git tags? That would make it easier for everyone to verify the integrity of the code.

Thanks a lot for this software, I really enjoy using it!

Port for Raspberry PI Pico?

Raspberry PI pico is based on RP2040 (Cortex M0) Microcontroller.
Thanks to Raspberry Pi Foundation, It is widely available and at a very good price.

It would be great if this project can be ported over to RP2040.

Udev rules for certtool

certtool is using easyhid which in turn is using hidapi-libusb on Linux systems, which requires an access to /sys/bus/usb/devices/.... In order to make it work (on Arch in my case), I had to add following rules:

ACTION=="add|change", SUBSYSTEM=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0e90", TAG+="uaccess"

Would be great to make certtool to use hidraw API on Linux so that hidraw* rule would become sufficient for certtool.

Errors while using u2f-token with tomu

Hello!

I'm trying to use my Tomu (v.0.4) as an U2F-Token
There are few cases which produce different errors:

Case #1
I compile firmware by command:
make TARGET=TOMU ENFORCE_DEBUG_LOCK=0
and than flash it by command:
sudo dfu-util -v -d 1209:70b1 -D build/u2f.bin
BTW: phrase from readme.md

Binaries for Tomu are built with bootloader support, use the following command to flash the firmware:
dfu-util -d 1209:70b1 -D u2f-TOMU.bin

is confusing.

Then I use https://github.com/mdp/u2fcli to test my token.
When I insert dongle I can see in logs:

[ 2483.341307] usb 1-4: USB disconnect, device number 14
[ 2487.385776] usb 1-4: new full-speed USB device number 15 using xhci_hcd
[ 2487.536935] usb 1-4: New USB device found, idVendor=16d0, idProduct=0e90
[ 2487.536941] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2487.536946] usb 1-4: Product: U2F-token (EFM32)
[ 2487.536950] usb 1-4: Manufacturer: unknown
[ 2487.536953] usb 1-4: SerialNumber: 1.00
[ 2487.540344] hid-generic 0003:16D0:0E90.000A: hiddev0,hidraw0: USB HID v1.10 Device [unknown U2F-token (EFM32)] on usb-0000:00:14.0-4/input0

when I run:
./u2fcli reg --challenge complexChallengeGoesHere12345671 --appid https://mdp.im
I have next response:
Registering, press the button on your U2F device #1 [unknown U2F-token (EFM32)]Error registering with device: u2ftoken: unexpected error 27014 during registration

Dongle does not react on command at all.
After some investigations I can see in src/cert/certificates.c

struct attestation_cert  __attribute__ ((section(".attestation.cert")))
attestation_cert = {
  .der_len = (uint32_t) -1,
  .der = NULL,
  .key = NULL
};

I guess it's not expected

Case #2
I compile firmware with next command:
make TARGET=TOMU ENFORCE_DEBUG_LOCK=0
then I generate certificate and inject it to firmware:

openssl ecparam -name prime256v1 -genkey -noout -outform der -out key.der
./inject_key.py --key key.der

then, I flash it .

When insert in logs:

[ 3398.155269] usb 1-4: New USB device found, idVendor=16d0, idProduct=0e90
[ 3398.155275] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3398.155280] usb 1-4: Product: U2F-token (EFM32)
[ 3398.155284] usb 1-4: Manufacturer: unknown
[ 3398.155287] usb 1-4: SerialNumber: 1.00
[ 3398.158837] hid-generic 0003:16D0:0E90.000C: hiddev0,hidraw0: USB HID v1.10 Device [unknown U2F-token (EFM32)] on usb-0000:00:14.0-4/input0

Testing:

./u2fcli reg --challenge complexChallengeGoesHere12345671 --appid https://mdp.im

lengeGoesHere12345671 --appid https://mdp.im
Registering, press the button on your U2F device #1 [unknown U2F-token (EFM32)]

Dongle starts to blink by red led with impulse pattern. When I touch it changes blink by solid red light. In console I can see:
Error registering with device: u2fhid: error reading response, read timed out


I will continue to investigate why there is NULL in certificates.c file and update you as soon as I find something.

Thank you in advance!

Best regards,
Alex

undefined_symbol: hid_enumerate

Trying to run ./certtool init is throwing the following errors:

Traceback (most recent call last):
  File "./certtool", line 139, in <module>
    main()
  File "./certtool", line 136, in main
    args.func(args)
  File "./certtool", line 102, in command_init
    e = easyhid.Enumeration()
  File "/home/server/Dev/venv/lib/python3.7/site-packages/easyhid/easyhid.py", line 358, in __init__
    self.device_list = _hid_enumerate(vid, pid)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/easyhid/easyhid.py", line 420, in _hid_enumerate
    start = hidapi.hid_enumerate(vendor_id, product_id)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 882, in __getattr__
    make_accessor(name)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 878, in make_accessor
    accessors[name](name)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 808, in accessor_function
    value = backendlib.load_function(BType, name)
AttributeError: function/symbol 'hid_enumerate' not found in library '<None>': python: undefined symbol: hid_enumerate
(venv) [server@server cert]$ sudo ./certtool init
Traceback (most recent call last):
  File "./certtool", line 139, in <module>
    main()
  File "./certtool", line 136, in main
    args.func(args)
  File "./certtool", line 102, in command_init
    e = easyhid.Enumeration()
  File "/home/server/Dev/venv/lib/python3.7/site-packages/easyhid/easyhid.py", line 358, in __init__
    self.device_list = _hid_enumerate(vid, pid)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/easyhid/easyhid.py", line 420, in _hid_enumerate
    start = hidapi.hid_enumerate(vendor_id, product_id)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 882, in __getattr__
    make_accessor(name)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 878, in make_accessor
    accessors[name](name)
  File "/home/server/Dev/venv/lib/python3.7/site-packages/cffi/api.py", line 808, in accessor_function
    value = backendlib.load_function(BType, name)
AttributeError: function/symbol 'hid_enumerate' not found in library '<None>': python: undefined symbol: hid_enumerate

I've tried on both macOS 10.12.6 and a Linux system running kernel 4.20.6. As far as I can tell I've installed all the dependencies required, I've also tried Python 3.6.8 and 3.7.2

Incorrect SET_IDLE handling

It doesn't cause any issues, but still needs to be fixed. The code

u2f-token/u2f/usb-hid.c

Lines 240 to 241 in 871eb2f

case USB_HID_REQ_SET_IDLE:
return usb_lld_ctrl_recv (dev, &hid_idle_rate, 1);

expecting SET_IDLE rate value to come in a data packet, but in fact it comes in a high byte of wValue.

Prebuilt binaries?

Hi

Per my groups post at https://groups.google.com/d/msg/tomu-discuss/qk6oRofL8B0/ae0kj7mXEQAJ I think it'd be really helpful to have a prebuilt firmware binary available as a github "release" here.

That'd greatly lower the bar for basic experimentation and testing. It'd also help with QA - if someone has a problem you can ask them to try the latest prebuilt binary to help isolate build-env / toolchain issues.

I hope the suggestion is OK.

make certclean to solve ATTESTATION_DER_LEN error

This is a documentation issue and can be closed immediately. I hope someone in the future is helped by this closed bug.

If you're not paying attention to the system requirements as you try to build this project, you'll generate a bogus file called src/cert/certificates.c. Then you'll get compilation errors about ATTESTATION_DER_LEN not being defined, and you'll go crazy because it really isn't defined anywhere.

Then you'll install more of the dependencies, and pip install --user --upgrade asn1crypto will enable the system to generate src/cert/certificates.c, which defines ATTESTATION_DER_LEN, but make clean doesn't remove that file, so you'll keep getting the error.

Once you make certclean you'll regenerate the file, and all will be well again.

The key is not initialized

BLACK_PILL
certtool:

Trying to initialize device HIDDevice:
    /dev/hidraw1 | 16d0:e90 | unknown | U2F-token (STM32) | 1.00
    release_number: 256
    usage_page: 14898
    usage: 11825
    interface_number: 0
APDU Error: 6986

dmesg:

[  184.219613] usb 1-2: new full-speed USB device number 6 using xhci_hcd
[  184.368774] usb 1-2: New USB device found, idVendor=16d0, idProduct=0e90, bcdDevice= 1.00
[  184.368778] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  184.368781] usb 1-2: Product: U2F-token (STM32)
[  184.368783] usb 1-2: Manufacturer: unknown
[  184.368785] usb 1-2: SerialNumber: 1.00
[  184.372322] hid-generic 0003:16D0:0E90.0003: hiddev0,hidraw1: USB HID v1.10 Device [unknown U2F-token (STM32)] on usb-0000:00:14.0-2/input0

Add to Wiki

Add a line to the wiki for the kali linux
GNU Toolchain for ARM Embedded Processors for Kali Linux
apt install gcc-arm-none-eabi

Unable to intialize device with injected key

I've tried to use u2f with injected key:

make TARGET=ST_DONGLE
./inject_key.py --key key.der
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg

on step "Initialize device" I've got:

python3 certtool init
Trying to initialize device HIDDevice:
    /dev/hidraw4 | 16d0:e90 | unknown | U2F-token (STM32) | 1.00
    release_number: 256
    usage_page: 14898
    usage: 11825
    interface_number: 0
APDU Error: 6986

After some investigation I found that the problem with attestation certificate - empty-attestation-cert.c conflicts with injected key.
Workaround: rm -f cert/certificates.c && make TARGET=... CUSTOM_ATTESTATION_CERT=1

FIDO2

Hello, does this project support the newer FIDO2 standard?
How hard would it be to implement it?

Thanks!

Alternative to NIST P-256 ?

I try to figure out how to get the token with something else than NIST P-256, which can be considered as unsafe. I already tried with ed25519 , but it blocks with inject_key.py .
Does someone have an idea ?

Different udev rules

The udev rules in the README are different from the ones on the tomu.im homepage:

README:

ACTION=="add|change", KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0e90", TAG+="uaccess"

tomu.im:

ACTION=="add|change", KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="cdab", TAG+="uaccess"

Is this intended? And how does it affect the functioning of the device?

__process6_stack_size__ is not defined in u2f.ld

Following error received while linking

u2f-token/u2f/pbt.c:114: undefined reference to '__process6_stack_size__'

I guess, we need to reserve some space on stack in u2f.ld

board.h -> board-blue-pill.h

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.