diff --git a/.clabot b/.clabot new file mode 100644 index 0000000..76e90a2 --- /dev/null +++ b/.clabot @@ -0,0 +1,4 @@ +{ + "contributors": "https://raw.githubusercontent.com/solokeys/contributors/master/contributors.json", + "message": "We require contributors to sign our Copyright License Agreement, and we don't have {{usersWithoutCLA}} on file. In order for us to review and merge your code, please visit https://solokeys.com/legal/contributors, or contact @nickray, @conorpp or @0x0ece for further information or help." +} diff --git a/.gitmodules b/.gitmodules index 889b2af..05c9e6f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/intel/tinycbor [submodule "python-fido2"] path = python-fido2 - url = https://github.com/SoloKeysSec/python-fido2 + url = https://github.com/solokeys/python-fido2 [submodule "crypto/micro-ecc"] path = crypto/micro-ecc url = https://github.com/kmackay/micro-ecc.git @@ -12,4 +12,4 @@ url = https://github.com/kokke/tiny-AES-c [submodule "targets/stm32l442/dfuse-tool"] path = targets/stm32l442/dfuse-tool - url = https://github.com/SoloKeysSec/dfuse-tool + url = https://github.com/solokeys/dfuse-tool diff --git a/.travis.yml b/.travis.yml index 8d8a18f..72ff11a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -dist: trusty +dist: xenial language: c compiler: gcc addons: @@ -7,6 +7,7 @@ addons: - ubuntu-toolchain-r-test packages: - gcc-7 + - cppcheck script: - export CC=gcc-7 - make test diff --git a/99-solo.rules b/99-solo.rules index e2f9a47..0c6450a 100644 --- a/99-solo.rules +++ b/99-solo.rules @@ -1,6 +1,17 @@ +# Notify ModemManager this device should be ignored +ACTION!="add|change|move", GOTO="mm_usb_device_blacklist_end" +SUBSYSTEM!="usb", GOTO="mm_usb_device_blacklist_end" +ENV{DEVTYPE}!="usb_device", GOTO="mm_usb_device_blacklist_end" + +ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="mm_usb_device_blacklist_end" + # Solo ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey" ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo HACKER (Unlocked)", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solohacker" +SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey-serial" + # U2F Zero KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero" diff --git a/Makefile b/Makefile index d72d90f..99beef4 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,6 @@ cbor: $(LIBCBOR) $(LIBCBOR): tinycbor/Makefile cd tinycbor/ && $(MAKE) clean && $(MAKE) -j8 -test: - $(MAKE) -C . main - .PHONY: efm8prog efm8prog: cd './targets/efm8\Keil 8051 v9.53 - Debug' && $(MAKE) all @@ -92,6 +89,16 @@ wink3: env3 fido2-test: env3 env3/bin/python tools/ctap_test.py +CPPCHECK_FLAGS=--quiet --error-exitcode=2 + +cppcheck: + cppcheck $(CPPCHECK_FLAGS) crypto/aes-gcm + cppcheck $(CPPCHECK_FLAGS) crypto/sha256 + cppcheck $(CPPCHECK_FLAGS) fido2 + cppcheck $(CPPCHECK_FLAGS) pc + +test: main cppcheck + clean: rm -f *.o main.exe main $(obj) rm -rf env2 env3 diff --git a/README.md b/README.md index bc6c090..7633e17 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg) -[![Kickstarter](https://img.shields.io/badge/kickstarter-back%20us-red.svg)](https://solokeys.com/kickstarter) -[![Build Status](https://travis-ci.com/SoloKeysSec/solo.svg?branch=master)](https://travis-ci.com/SoloKeysSec/solo) -[![Discourse Status](https://img.shields.io/discourse/https/meta.discourse.org/status.svg)](https://discourse.solokeys.com) +[![License](https://img.shields.io/github/license/solokeys/solo.svg)](https://github.com/solokeys/solo/blob/master/LICENSE) +[![Build Status](https://travis-ci.com/solokeys/solo.svg?branch=master)](https://travis-ci.com/solokeys/solo) +[![Discourse Users](https://img.shields.io/discourse/https/discourse.solokeys.com/users.svg)](https://discourse.solokeys.com) [![Keybase Chat](https://img.shields.io/badge/chat-on%20keybase-brightgreen.svg)](https://keybase.io/team/solokeys.public) +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo?ref=badge_shield) # Solo @@ -35,20 +35,25 @@ Solo for Hacker is a special version of Solo that let you customize its firmware You can only buy Solo for Hacker at [solokeys.com](https://solokeys.com), as we don't sell it on Amazon and other places to avoid confusing customers. If you buy a Hacker, you can permanently lock it into a regular Solo, but viceversa you can NOT take a regular Solo and turn it a Hacker. -If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://solo.solokeys.io/building/). +If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/). ```bash -git clone --recurse-submodules https://github.com/SoloKeysSec/solo +git clone --recurse-submodules https://github.com/solokeys/solo cd solo cd targets/stm32l432 make cbor make all-hacker -python ../../tools/solotool.py program solo.hex +cd ../.. + +make env3 +source env3/bin/activate +python tools/solotool.py program targets/stm32l432/solo.hex ``` If you forgot the `--recurse-submodules` when cloning, simply `git submodule update --init --recursive`. -For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/SoloKeysSec/solo/blob/master/targets/stm32l432/src/led.c#L15) and force: + +For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/led.c#L15) and force: ``` uint32_t b = 0; ``` @@ -65,7 +70,7 @@ A frequently asked question is whether Solo for Hacker is less secure than regul Clone Solo and build it ```bash -git clone --recurse-submodules https://github.com/SoloKeysSec/solo +git clone --recurse-submodules https://github.com/solokeys/solo cd solo make all ``` @@ -93,12 +98,12 @@ Or any client example such as: python python-fido2/examples/credential.py ``` -You can find more details in our [documentation](https://solo.solokeys.io), including how to build on the the NUCLEO-L432KC development board. +You can find more details in our [documentation](https://docs.solokeys.io/solo/), including how to build on the the NUCLEO-L432KC development board. # Documentation -Check out our [official documentation](https://solo.solokeys.io). +Check out our [official documentation](https://docs.solokeys.io/solo/). # Contributors @@ -117,6 +122,9 @@ All software is licensed under GPLv3, and hardware under CC BY-SA 4.0. Software and hardware are available under licenses for commercial use. Please contact SoloKeys for more information. + +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo?ref=badge_large) + # Where To Buy Solo -You can buy Solo, Solo Tap, and Solo for Hackers at [solokeys.com](https://solokeys.com). +You can buy Solo, Solo Tap, and Solo for Hackers at [solokeys.com](https://solokeys.com). \ No newline at end of file diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index b29e554..0000000 --- a/docs/index.md +++ /dev/null @@ -1,4 +0,0 @@ -Welcome to the technical documentation for [solokeyssec/solo](https://github.com/solokeyssec/solo). - -For now, you can read the repository `README.md`, more documentation to come! - diff --git a/docs/repo-readme.md b/docs/repo-readme.md deleted file mode 120000 index 32d46ee..0000000 --- a/docs/repo-readme.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/docs/building.md b/docs/solo/building.md similarity index 98% rename from docs/building.md rename to docs/solo/building.md index 20740e7..e3f74d0 100644 --- a/docs/building.md +++ b/docs/solo/building.md @@ -68,6 +68,10 @@ reconnect each time you program Solo. python tools/solotool.py monitor ``` +#### Linux Users: + +[See issue 62](https://github.com/solokeys/solo/issues/62). + ### Building a Solo release If you want to build a release of Solo, we recommend trying a Hacker build first diff --git a/docs/code-overview.md b/docs/solo/code-overview.md similarity index 100% rename from docs/code-overview.md rename to docs/solo/code-overview.md diff --git a/docs/contributing.md b/docs/solo/contributing.md similarity index 52% rename from docs/contributing.md rename to docs/solo/contributing.md index a200f01..3c82137 100644 --- a/docs/contributing.md +++ b/docs/solo/contributing.md @@ -1,15 +1,15 @@ We are very open to contributions! -[Currently](https://github.com/solokeyssec/solo/issues), most work will go towards +[Currently](https://github.com/solokeys/solo/issues), most work will go towards -* implementing STM32L432 +* ~~implementing STM32L432~~ * implementing NFC * adding documentation and improving accessability of the code In the future, we would love to see creative plugins/extensions, putting the TRNG and other features of the STM32L432 to good use! -Feel free to send a [pull request](https://github.com/SoloKeysSec/solo/pulls) at any time, we don't currently have a formal contribution process. +Feel free to send a [pull request](https://github.com/solokeys/solo/pulls) at any time, please note that we do require a lightweight copyright license agreement in order to accept contributions. Reason and procedure: . If you want to discuss your plans in quasi-realtime beforehand, you can also join our [solokeys.public](https://keybase.io/team/solokeys.public) Keybase team. -But first: [join our mailing list!](https://solokeys.us19.list-manage.com/subscribe/post?u=cc0c298fb99cd136bdec8294b&id=b9cb3de62d) +But first: [join our mailing list!](https://solokeys.us19.list-manage.com/subscribe/post?u=cc0c298fb99cd136bdec8294b&id=6550fc947a) diff --git a/docs/documenting.md b/docs/solo/documenting.md similarity index 100% rename from docs/documenting.md rename to docs/solo/documenting.md diff --git a/docs/fido2-impl.md b/docs/solo/fido2-impl.md similarity index 95% rename from docs/fido2-impl.md rename to docs/solo/fido2-impl.md index 4747516..a5c8ba4 100644 --- a/docs/fido2-impl.md +++ b/docs/solo/fido2-impl.md @@ -15,6 +15,8 @@ A master secret, `M`, is generated at initialization. This is only used for all key generation and derivation in FIDO2. Solo uses a key wrapping method for FIDO2 operation. +** NOTE: The masked implementation of AES is planned, but not yet implemented. Currently it is normal AES. ** + ## Key wrapping When you register a service with a FIDO2 or U2F authenticator, the @@ -55,6 +57,8 @@ keys which are then used for FIDO2/U2F. --> ## Key derivation +** Planned, but not yet implemented. ** + Master secret `M` consists of 64 bytes, split into equal parts `M1` and `M2`. In theory, we should only need 32 bytes to achieve 256 security, but we also plan to have side channel security hence the added bytes. diff --git a/docs/solo/images/favicon.ico b/docs/solo/images/favicon.ico new file mode 100644 index 0000000..c5dfb60 Binary files /dev/null and b/docs/solo/images/favicon.ico differ diff --git a/docs/images/logo.svg b/docs/solo/images/logo.svg similarity index 100% rename from docs/images/logo.svg rename to docs/solo/images/logo.svg diff --git a/docs/solo/index.md b/docs/solo/index.md new file mode 100644 index 0000000..ab5ffdb --- /dev/null +++ b/docs/solo/index.md @@ -0,0 +1,4 @@ +Welcome to the technical documentation for [solokeys/solo](https://github.com/solokeys/solo). + +For now, you can read the repository `README.md`, more documentation to come! + diff --git a/docs/solo/metadata-statements.md b/docs/solo/metadata-statements.md new file mode 100644 index 0000000..3aea488 --- /dev/null +++ b/docs/solo/metadata-statements.md @@ -0,0 +1,12 @@ +For information on what this is, see the [spec](https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-metadata-statement-v2.0-rd-20180702.html#fido2-example). +## CTAP2 + +``` +{!metadata/solo-FIDO2-CTAP2-Authenticator.json!} +``` + +## U2F + +``` +{!metadata/solo-FIDO2-U2F-Authenticator.json!} +``` diff --git a/docs/solo/repo-readme.md b/docs/solo/repo-readme.md new file mode 120000 index 0000000..fe84005 --- /dev/null +++ b/docs/solo/repo-readme.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/docs/signed-updates.md b/docs/solo/signed-updates.md similarity index 88% rename from docs/signed-updates.md rename to docs/solo/signed-updates.md index 86dba1d..39eae90 100644 --- a/docs/signed-updates.md +++ b/docs/solo/signed-updates.md @@ -22,5 +22,5 @@ In order to boot the application, a valid signature must be provided to the boot signature using a public key stored in the bootloader section, and the data in the application section. If the signature is valid, the boot flag in the data section will be changed to allow boot. -Signature checks and checks to the data section boot flag are made redundantly to make glitching attacks more difficult. Random delays -between redundant checks are also made. +We are working to make the signature checking process redundantly to make glitching attacks more difficult. Also random delays +between redundant checks. diff --git a/docs/udev.md b/docs/solo/udev.md similarity index 89% rename from docs/udev.md rename to docs/solo/udev.md index d8ad228..6bac736 100644 --- a/docs/udev.md +++ b/docs/solo/udev.md @@ -1,6 +1,6 @@ # tl;dr -Create [`/etc/udev/99-solo.rules`](https://github.com/SoloKeysSec/solo/blob/master/99-solo.rules) and add the following (which assumes your user is in group `plugdev`): +Create [`/etc/udev/rules.d/99-solo.rules`](https://github.com/solokeys/solo/blob/master/99-solo.rules) and add the following (which assumes your user is in group `plugdev`): ``` # Solo @@ -13,7 +13,7 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct Then run ``` -udevadm trigger +sudo udevadm control --reload-rules && sudo udevadm trigger ``` # How do udev rules work and why are they needed @@ -65,8 +65,8 @@ udevadm trigger ## What about vendor and product ID for Solo? | Key | Vendor ID | Product ID | | --- | --- | --- | -| Solo | 10c4 | 8acf | -| U2F Zero | 0483 | a2ca | +| Solo | 0483 | a2ca | +| U2F Zero | 10c4 | 8acf | ## You got this all wrong, I can't believe it! -Are you suffering from [us being wrong](https://xkcd.com/386/)? Please, send us a [pull request](https://github.com/SoloKeysSec/solo/pulls) and prove us wrong :D +Are you suffering from [us being wrong](https://xkcd.com/386/)? Please, send us a [pull request](https://github.com/solokeys/solo/pulls) and prove us wrong :D diff --git a/fido2/u2f.c b/fido2/u2f.c index ac84205..5213ea8 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -1,21 +1,21 @@ /* * Copyright (C) 2018 SoloKeys, Inc. - * + * * This file is part of Solo. - * + * * Solo 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. - * + * * Solo 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 Solo. If not, see - * + * * This code is available under licenses for commercial use. * Please contact SoloKeys for more information. */ @@ -125,17 +125,17 @@ void u2f_request_nfc(uint8_t * req, int len, CTAP_RESPONSE * resp) { if (len < 5 || !req) return; - + uint32_t alen = req[4]; - - u2f_request_ex((APDU_HEADER *)req, &req[5], alen, resp, true); + + u2f_request_ex((APDU_HEADER *)req, &req[5], alen, resp, true); } void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) { uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16)); - - u2f_request_ex((APDU_HEADER *)req, req->payload, len, resp, false); + + u2f_request_ex((APDU_HEADER *)req, req->payload, len, resp, false); } int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len) diff --git a/metadata/solo-FIDO2-CTAP2-Authenticator.json b/metadata/solo-FIDO2-CTAP2-Authenticator.json new file mode 100644 index 0000000..9f35933 --- /dev/null +++ b/metadata/solo-FIDO2-CTAP2-Authenticator.json @@ -0,0 +1,39 @@ +{ + "description": "Solo Secp256R1 FIDO2 CTAP2 Authenticator", + "aaguid": "8876631b-d4a0-427f-5773-0ec71c9e0279", + "alternativeDescriptions": { + }, + "protocolFamily": "fido2", + "authenticatorVersion": 2, + "upv": [ + { + "major": 1, + "minor": 0 + } + ], + "assertionScheme": "FIDOV2", + "authenticationAlgorithm": 1, + "publicKeyAlgAndEncoding": 260, + "attestationTypes": [ + 15879, + 15880 + ], + "userVerificationDetails": [ + [ + { + "userVerification": 4 + } + ] + ], + "keyProtection": 2, + "matcherProtection": 4, + "cryptoStrength": 128, + "attachmentHint": 2, + "isSecondFactorOnly": false, + "tcDisplay": 0, + "attestationRootCertificates": [ +"MIIB9DCCAZoCCQDER2OSj/S+jDAKBggqhkjOPQQDAjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMCAXDTE4MTExMTEyNTE0MloYDzIwNjgxMDI5MTI1MTQyWjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWHAN0CCJVZdMs0oktZ5m93uxmB1iyq8ELRLtqVFLSOiHQEab56qRTB/QzrpGAY++Y2mw+vRuQMNhBiU0KzwjBjAKBggqhkjOPQQDAgNIADBFAiEAz9SlrAXIlEu87vra54rICPs+4b0qhp3PdzcTg7rvnP0CIGjxzlteQQx+jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs" + ], + "icon": "data:image/png;base64,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" + +} diff --git a/metadata/solo-FIDO2-U2F-Authenticator.json b/metadata/solo-FIDO2-U2F-Authenticator.json new file mode 100644 index 0000000..71a711f --- /dev/null +++ b/metadata/solo-FIDO2-U2F-Authenticator.json @@ -0,0 +1,37 @@ +{ + "description": "Solo Secp256R1 U2F Authenticator", + "attestationCertificateKeyIdentifiers": ["3be6d2c06ff2e7b07c9d9e28c020b00d07c815c8"], + "alternativeDescriptions": { + }, + "protocolFamily": "u2f", + "authenticatorVersion": 2, + "upv": [ + { + "major": 1, + "minor": 2 + } + ], + "assertionScheme": "U2FV1BIN", + "authenticationAlgorithm": 1, + "publicKeyAlgAndEncoding": 256, + "attestationTypes": [ + 15879 + ], + "userVerificationDetails": [ + [ + { + "userVerification": 1 + } + ] + ], + "keyProtection": 2, + "matcherProtection": 4, + "cryptoStrength": 128, + "attachmentHint": 2, + "isSecondFactorOnly": true, + "tcDisplay": 0, + "attestationRootCertificates": [ +"MIIB9DCCAZoCCQDER2OSj/S+jDAKBggqhkjOPQQDAjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMCAXDTE4MTExMTEyNTE0MloYDzIwNjgxMDI5MTI1MTQyWjCBgDELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1hcnlsYW5kMRIwEAYDVQQKDAlTb2xvIEtleXMxEDAOBgNVBAsMB1Jvb3QgQ0ExFTATBgNVBAMMDHNvbG9rZXlzLmNvbTEhMB8GCSqGSIb3DQEJARYSaGVsbG9Ac29sb2tleXMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWHAN0CCJVZdMs0oktZ5m93uxmB1iyq8ELRLtqVFLSOiHQEab56qRTB/QzrpGAY++Y2mw+vRuQMNhBiU0KzwjBjAKBggqhkjOPQQDAgNIADBFAiEAz9SlrAXIlEu87vra54rICPs+4b0qhp3PdzcTg7rvnP0CIGjxzlteQQx+jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs" + ], + "icon": "data:image/png;base64,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" +} diff --git a/mkdocs.yml b/mkdocs.yml index 508e6ec..b140e92 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,21 +1,27 @@ -site_name: Solo +site_name: Solo Technical Documentation site_author: SoloKeys site_description: 'Documentation for the SoloKeys solo software' -repo_url: 'https://github.com/solokeyssec/solo' -repo_name: 'solokeyssec/solo' -copyright: 'Copyright © 2018 SoloKeys' +site_url: 'https://docs.solokeys.io/solo/' +repo_url: 'https://github.com/solokeys/solo' +repo_name: 'solokeys/solo' +copyright: 'Copyright © 2018 - 2019 SoloKeys' nav: - - Home: index.md - - README.md: repo-readme.md - - FIDO2 Implementation: fido2-impl.md - - Signed update process: signed-updates.md - - Building: building.md - - Code documentation: code-overview.md - - Contributing Code: contributing.md - - Contributing Docs: documenting.md - - What the udev?!: udev.md + - Home: solo/index.md + - FIDO2 Implementation: solo/fido2-impl.md + - Metadata Statements: solo/metadata-statements.md + - Build instructions: solo/building.md + - Signed update process: solo/signed-updates.md + - Code documentation: solo/code-overview.md + - Contributing Code: solo/contributing.md + - Contributing Docs: solo/documenting.md + - udev Rules: solo/udev.md + - About: solo/repo-readme.md theme: name: material - logo: 'images/logo.svg' + logo: 'solo/images/logo.svg' + favicon: 'solo/images/favicon.ico' + +markdown_extensions: + - markdown_include.include diff --git a/pc/device.c b/pc/device.c index 4344ef5..ce915eb 100644 --- a/pc/device.c +++ b/pc/device.c @@ -54,7 +54,11 @@ void device_set_status(int status) int udp_server() { - int fd; + static bool run_already = false; + static int fd = -1; + if (run_already && fd >= 0) return fd; + run_already = true; + if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { perror( "socket failed" ); return 1; diff --git a/targets/stm32l432/README.md b/targets/stm32l432/README.md index be55b7a..58af397 100644 --- a/targets/stm32l432/README.md +++ b/targets/stm32l432/README.md @@ -1,4 +1,4 @@ -# STM32L4xx Solo +# STM32L432 Solo -Check out our [official documentation](https://solo.solokeys.io/building/) +Check out our [official documentation](https://docs.solokeys.io/solo/building/) for instructions on building and programming! diff --git a/targets/stm32l432/lib/usbd/usbd_desc.c b/targets/stm32l432/lib/usbd/usbd_desc.c index 63c8e4a..bd0ed90 100644 --- a/targets/stm32l432/lib/usbd/usbd_desc.c +++ b/targets/stm32l432/lib/usbd/usbd_desc.c @@ -56,12 +56,14 @@ #ifndef SOLO_HACKER #define USBD_MANUFACTURER_STRING "Solo Keys" #define USBD_PRODUCT_FS_STRING "Solo" -#define USBD_SERIAL_NUM "solocafebabe" +#ifndef USBD_SERIAL_NUM +#define USBD_SERIAL_NUM "0123456789ABCDEF" +#endif #else #define USBD_MANUFACTURER_STRING "Solo Keys" #define USBD_PRODUCT_FS_STRING "Solo HACKER (Unlocked)" #ifndef USBD_SERIAL_NUM -#define USBD_SERIAL_NUM "Solo-Keys-Solo" +#define USBD_SERIAL_NUM "0123456789ABCDEF" #endif #endif diff --git a/targets/stm32l432/lib/usbd/usbd_hid.c b/targets/stm32l432/lib/usbd/usbd_hid.c index a1950c3..bf32911 100644 --- a/targets/stm32l432/lib/usbd/usbd_hid.c +++ b/targets/stm32l432/lib/usbd/usbd_hid.c @@ -114,15 +114,10 @@ USBD_ClassTypeDef USBD_HID = NULL, - - NULL, - NULL, - NULL, - NULL, - // USBD_HID_GetFSCfgDesc, - // USBD_HID_GetFSCfgDesc, - // USBD_HID_GetFSCfgDesc, - // USBD_HID_GetDeviceQualifierDesc, + USBD_HID_GetFSCfgDesc, + USBD_HID_GetFSCfgDesc, + USBD_HID_GetFSCfgDesc, + USBD_HID_GetDeviceQualifierDesc, }; #define USBD_HID_CfgHSDesc USBD_HID_OtherSpeedCfgDesc diff --git a/targets/stm32l432/src/init.c b/targets/stm32l432/src/init.c index 3c33c56..5185aeb 100644 --- a/targets/stm32l432/src/init.c +++ b/targets/stm32l432/src/init.c @@ -276,7 +276,7 @@ void init_usb() // Enable USB Clock SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USBFSEN); - +#if DEBUG_LEVEL > 0 USBD_Composite_Set_Classes(&USBD_HID, &USBD_CDC); in_endpoint_to_class[HID_EPIN_ADDR & 0x7F] = 0; out_endpoint_to_class[HID_EPOUT_ADDR & 0x7F] = 0; @@ -290,6 +290,10 @@ void init_usb() // // USBD_RegisterClass(&Solo_USBD_Device, &USBD_CDC); USBD_CDC_RegisterInterface(&Solo_USBD_Device, &USBD_Interface_fops_FS); +#else + USBD_Init(&Solo_USBD_Device, &Solo_Desc, 0); + USBD_RegisterClass(&Solo_USBD_Device, &USBD_HID); +#endif USBD_Start(&Solo_USBD_Device); } diff --git a/tools/solotool.py b/tools/solotool.py index b9f4606..5148b50 100755 --- a/tools/solotool.py +++ b/tools/solotool.py @@ -31,11 +31,17 @@ import tempfile from binascii import hexlify, unhexlify from hashlib import sha256 +from cryptography import x509 +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.backends import default_backend + from fido2.hid import CtapHidDevice, CTAPHID from fido2.client import Fido2Client, ClientError from fido2.ctap import CtapError from fido2.ctap1 import CTAP1, ApduError +from fido2.ctap2 import CTAP2 from fido2.utils import Timeout +from fido2.attestation import Attestation import usb.core import usb.util @@ -119,6 +125,7 @@ class SoloBootloader: class SoloClient: def __init__(self,): self.origin = 'https://example.org' + self.host = 'example.org' self.exchange = self.exchange_hid self.do_reboot = True @@ -145,6 +152,8 @@ class SoloClient: raise RuntimeError('No FIDO device found') self.dev = dev self.ctap1 = CTAP1(dev) + self.ctap2 = CTAP2(dev) + self.client = Fido2Client(dev, self.origin) if self.exchange == self.exchange_hid: self.send_data_hid(CTAPHID.INIT, '\x11\x11\x11\x11\x11\x11\x11\x11') @@ -222,6 +231,32 @@ class SoloClient: def wink(self,): self.send_data_hid(CTAPHID.WINK, b'') + def reset(self,): + self.ctap2.reset() + + def make_credential(self,): + rp = {'id': self.host, 'name': 'example site'} + user = {'id': b'abcdef', 'name': 'example user'} + challenge = 'Y2hhbGxlbmdl' + attest, data = self.client.make_credential( + rp, user, challenge, exclude_list=[] + ) + try: + attest.verify(data.hash) + except AttributeError: + verifier = Attestation.for_type(attest.fmt) + verifier().verify( + attest.att_statement, + attest.auth_data, + data.hash + ) + print('Register valid') + x5c = attest.att_statement['x5c'][0] + cert = x509.load_der_x509_certificate(x5c, default_backend()) + + return cert + + def enter_solo_bootloader(self,): """ If solo is configured as solo hacker or something similar, @@ -560,11 +595,16 @@ def solo_main(): help='Continuously dump random numbers generated from Solo.', ) parser.add_argument("--wink", action="store_true", help='HID Wink command.') + parser.add_argument("--reset", action="store_true", help='Issue a FIDO2 reset command. Warning: your credentials will be lost.') + parser.add_argument("--verify-solo", action="store_true", help='Verify that the Solo firmware is from SoloKeys.') args = parser.parse_args() p = SoloClient() p.find_device() + if args.reset: + p.reset() + if args.rng: while True: r = p.get_rng(255) @@ -575,6 +615,15 @@ def solo_main(): p.wink() sys.exit(0) + if args.verify_solo: + cert = p.make_credential() + solo_fingerprint = b'r\xd5\x831&\xac\xfc\xe9\xa8\xe8&`\x18\xe6AI4\xc8\xbeJ\xb8h_\x91\xb0\x99!\x13\xbb\xd42\x95' + + if (cert.fingerprint(hashes.SHA256()) == solo_fingerprint): + print('Valid firmware from SoloKeys') + else: + print('This is either a Solo Hacker or a invalid Solo.') + def asked_for_help(): for i, v in enumerate(sys.argv): @@ -954,6 +1003,10 @@ def main_mergehex(): if __name__ == '__main__': + if sys.version_info[0] < 3: + print('Sorry, python3 is required.') + sys.exit(1) + if len(sys.argv) < 2 or (len(sys.argv) == 2 and asked_for_help()): print('Diverse command line tool for working with Solo') print('usage: %s [options] [-h]' % sys.argv[0])