kopia lustrzana https://github.com/solokeys/solo1
initial draft
rodzic
caac9d0cc1
commit
f5794481ae
|
@ -0,0 +1,51 @@
|
|||
# Booting into bootloader mode
|
||||
|
||||
You can put Solo into bootloader mode by holding down the button, and plugging in Solo. After 2 seconds, bootloader mode will activate.
|
||||
You'll see a yellowish flashing light and you can let go of the button.
|
||||
|
||||
Now Solo is ready to accept firmware updates. If the Solo is a secured model, it can only accept signed updates, typically in the `firmware-*.json` format.
|
||||
|
||||
If Solo is running a hacker build, it can be put into bootloader mode on command. This makes it easier for development.
|
||||
|
||||
```bash
|
||||
solo program aux enter-bootloader
|
||||
```
|
||||
|
||||
# The boot stages of Solo
|
||||
|
||||
Solo has 3 boot stages.
|
||||
|
||||
## DFU
|
||||
|
||||
The first stage is the DFU (Device Firmware Update) which is in a ROM on Solo. It is baked into the chip and is not implemented by us.
|
||||
This is what allows the entire firmware of Solo to be programmed. **It's not recommended to develop for Solo using the DFU because
|
||||
if you program broken firmware, you could brick your device**.
|
||||
|
||||
On hacker devices, you can boot into the DFU by holding down the button for 5 seconds, when Solo is already in bootloader mode.
|
||||
|
||||
You can also run this command when Solo is in bootloader mode to put it in DFU mode.
|
||||
|
||||
```bash
|
||||
solo program aux enter-dfu
|
||||
```
|
||||
|
||||
Note it will stay in DFU mode until to tell it to boot again. You can boot it again by running the following.
|
||||
|
||||
```bash
|
||||
solo program aux leave-dfu
|
||||
```
|
||||
|
||||
*Warning*: If you change the firmware to something broken, and you tell the DFU to boot it, you could brick your device.
|
||||
|
||||
## Solo Bootloader
|
||||
|
||||
The next boot stage is the "Solo bootloader". So when we say to put your Solo into bootloader mode, it is this stage.
|
||||
This bootloader is written by us and allows signed firmware updates to be written. On Solo Hackers, there is no signature checking
|
||||
and will allow any firmware updates.
|
||||
|
||||
It is safe to develop for Solo using our Solo bootloader. If broken firmware is uploaded to the device, then the Solo
|
||||
bootloader can always be booted again by holding down the button when plugging in.
|
||||
|
||||
## Solo application
|
||||
|
||||
This is what contains all the important functionality of Solo. FIDO2, U2F, etc. This is what Solo will boot to by default.
|
|
@ -14,12 +14,6 @@ but be warned they might be out of date. Typically it will be called `gcc-arm-n
|
|||
|
||||
Install `solo-python` usually with `pip3 install solo-python`. The `solo` python application may also be used for [programming](#programming).
|
||||
|
||||
To program your build, you'll need one of the following programs.
|
||||
|
||||
- [openocd](http://openocd.org)
|
||||
- [stlink](https://github.com/texane/stlink)
|
||||
- [STM32CubeProg](https://www.st.com/en/development-tools/stm32cubeprog.html)
|
||||
|
||||
## Obtain source code and solo tool
|
||||
|
||||
Source code can be downloaded from:
|
||||
|
@ -54,7 +48,7 @@ enabled, like being able to jump to the bootloader on command. It then merges b
|
|||
and solo builds into the same binary. I.e. it combines `bootloader.hex` and `solo.hex`
|
||||
into `all.hex`.
|
||||
|
||||
If you're just planning to do development, please don't try to reprogram the bootloader,
|
||||
If you're just planning to do development, **please don't try to reprogram the bootloader**,
|
||||
as this can be risky if done often. Just use `solo.hex`.
|
||||
|
||||
### Building with debug messages
|
||||
|
@ -86,6 +80,8 @@ solo monitor <serial-port>
|
|||
|
||||
### Building a Solo release
|
||||
|
||||
To build Solo
|
||||
|
||||
If you want to build a release of Solo, we recommend trying a Hacker build first
|
||||
just to make sure that it's working. Otherwise it may not be as easy or possible to
|
||||
fix any mistakes.
|
||||
|
@ -96,105 +92,6 @@ If you're ready to program a full release, run this recipe to build.
|
|||
make build-release-locked
|
||||
```
|
||||
|
||||
Programming `all.hex` will cause the device to permanently lock itself.
|
||||
Programming `all.hex` will cause the device to permanently lock itself. This means debuggers cannot be used and signature checking
|
||||
will be enforced on all future updates.
|
||||
|
||||
## Programming
|
||||
|
||||
It's recommended to test a debug/hacker build first to make sure Solo is working as expected.
|
||||
Then you can switch to a locked down build, which cannot be reprogrammed as easily (or not at all!).
|
||||
|
||||
We recommend using our `solo` tool to manage programming. It is cross platform. First you must
|
||||
install the prerequisites:
|
||||
|
||||
```
|
||||
pip3 install -r tools/requirements.txt
|
||||
```
|
||||
|
||||
If you're on Windows, you must also install [libusb](https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/).
|
||||
|
||||
### Pre-programmed Solo Hacker
|
||||
|
||||
If your Solo device is already programmed (it flashes green when powered), we recommend
|
||||
programming it using the Solo bootloader.
|
||||
|
||||
```
|
||||
solo program aux enter-bootloader
|
||||
solo program bootloader solo.hex
|
||||
```
|
||||
|
||||
Make sure to program `solo.hex` and not `all.hex`. Nothing bad would happen, but you'd
|
||||
see errors.
|
||||
|
||||
If something bad happens, you can always boot the Solo bootloader by doing the following.
|
||||
|
||||
1. Unplug device.
|
||||
2. Hold down button.
|
||||
3. Plug in device while holding down button.
|
||||
4. Wait about 2 seconds for flashing yellow light. Release button.
|
||||
|
||||
If you hold the button for an additional 5 seconds, it will boot to the ST DFU (device firmware update).
|
||||
Don't use the ST DFU unless you know what you're doing.
|
||||
|
||||
### ST USB DFU
|
||||
|
||||
If your Solo has never been programmed, it will boot the ST USB DFU. The LED is turned
|
||||
off and it enumerates as "STM BOOTLOADER".
|
||||
|
||||
You can program it by running the following.
|
||||
|
||||
```
|
||||
solo program aux enter-bootloader
|
||||
solo program aux enter-dfu
|
||||
# powercycle key
|
||||
solo program dfu all.hex
|
||||
```
|
||||
|
||||
Make sure to program `all.hex`, as this contains both the bootloader and the Solo application.
|
||||
|
||||
If all goes well, you should see a slow-flashing green light.
|
||||
|
||||
### Solo Hacker vs Solo
|
||||
|
||||
A Solo hacker device doesn't need to be in bootloader mode to be programmed, it will automatically switch.
|
||||
|
||||
Solo (locked) needs the button to be held down when plugged in to boot to the bootloader.
|
||||
|
||||
A locked Solo will only accept signed updates.
|
||||
|
||||
### Signed updates
|
||||
|
||||
If this is not a device with a hacker build, you can only program signed updates.
|
||||
|
||||
```
|
||||
solo program bootloader /path/to/firmware.json
|
||||
```
|
||||
|
||||
If you've provisioned the Solo bootloader with your own secp256r1 public key, you can sign your
|
||||
firmware by running the following command.
|
||||
|
||||
```
|
||||
solo sign /path/to/signing-key.pem /path/to/solo.hex /output-path/to/firmware.json
|
||||
```
|
||||
|
||||
If your Solo isn't locked, you can always reprogram it using a debugger connected directly
|
||||
to the token.
|
||||
|
||||
## Permanently locking the device
|
||||
|
||||
If you plan to be using your Solo for real, you should lock it permanently. This prevents
|
||||
someone from connecting a debugger to your token and stealing credentials.
|
||||
|
||||
To do this, build the locked release firmware.
|
||||
```
|
||||
make build-release-locked
|
||||
```
|
||||
|
||||
Now when you program `all.hex`, the device will lock itself when it first boots. You can only update it
|
||||
with signed updates.
|
||||
|
||||
If you'd like to also permanently disable signed updates, plug in your programmed Solo and run the following:
|
||||
|
||||
```
|
||||
# WARNING: No more signed updates.
|
||||
solo program disable-bootloader
|
||||
```
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
# Customization
|
||||
|
||||
If you are interested in customizing parts of your Solo, and you have a Solo Hacker, this page is for you.
|
||||
|
||||
## Custom Attestation key
|
||||
|
||||
The attestation key is used in the FIDO2 *makeCredential* or U2F *register* requests. It signs
|
||||
newly generated credentials. The certification associated with the attestation key is output as well.
|
||||
Platforms or services can use the attestation feature to enforce specific authenticators to be used.
|
||||
This is typically a use case for organizations and isn't seen in the wild for consumer use cases.
|
||||
|
||||
Attestation keys are typically the same for at least 100K units of a particular authenticator model.
|
||||
This is so they don't contribute a significant fingerprint that platforms could use to identify the user.
|
||||
|
||||
If you don't want to use the default attestation key that Solo builds with, you can create your own
|
||||
and program it.
|
||||
|
||||
### Creating your attestation key pair
|
||||
|
||||
Since we are generating keys, it's important to use a good entropy source.
|
||||
You can use your Solo device to generate some good random numbers.
|
||||
|
||||
```
|
||||
# Run for 1 second, then hit control-c
|
||||
solo key rng > seed.bin
|
||||
```
|
||||
|
||||
First we will create a self signed key pair that acts as the root of trust. This
|
||||
won't go on the authenticator, but will sign the keypair that does.
|
||||
|
||||
Please change the root certification information as needed. You may change the ECC curve.
|
||||
|
||||
```
|
||||
curve=prime256v1
|
||||
|
||||
country=US
|
||||
state=Maine
|
||||
organization=OpenSourceSecurity
|
||||
unit=Root CA
|
||||
CN=example.com
|
||||
email=example@example.com
|
||||
|
||||
# generate EC private key
|
||||
openssl ecparam -genkey -name "$curve" -out root_key.pem -rand seed.bin
|
||||
|
||||
# generate a "signing request"
|
||||
openssl req -new -key root_key.pem -out root_key.pem.csr -subj "/C=$country/ST=$state/O=$organization/OU=$unit/CN=example.com/emailAddress=$email"
|
||||
|
||||
# self sign the request
|
||||
openssl x509 -trustout -req -days 18250 -in root_key.pem.csr -signkey root_key.pem -out root_cert.pem -sha256
|
||||
|
||||
# convert to smaller size format DER
|
||||
openssl x509 -in root_cert.pem -outform der -out root_cert.der
|
||||
|
||||
# print out information and verify
|
||||
openssl x509 -in root_cert.pem -text -noout
|
||||
```
|
||||
|
||||
You need to create a extended certificate for the device certificate to work with FIDO2. You need to create this
|
||||
file, `v3.ext`, and add these options to it.
|
||||
|
||||
```
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
|
||||
```
|
||||
|
||||
Now to generate & sign the attestation key pair that will go on your device, or maybe 100,000 devices :).
|
||||
Note you must use a prime256v1 curve for this step, and you must leave the unit/OU as "Authenticator Attestation".
|
||||
|
||||
```
|
||||
country=US
|
||||
state=Maine
|
||||
organization=OpenSourceSecurity
|
||||
unit=Authenticator Attestation
|
||||
CN=example.com
|
||||
email=example@example.com
|
||||
|
||||
# generate EC private key
|
||||
openssl ecparam -genkey -name "$curve" -out device_key.pem -rand seed.bin
|
||||
|
||||
# generate a "signing request"
|
||||
openssl req -new -key device_key.pem -out device_key.pem.csr -subj "/C=$country/ST=$state/O=$organization/OU=$unit/CN=example.com/emailAddress=$email
|
||||
|
||||
# sign the request
|
||||
openssl x509 -req -days 18250 -in device_key.pem.csr -extfile v3.ext -CA root_cert.pem -CAkey root_key.pem -set_serial 01 -out device_cert.pem -sha256
|
||||
|
||||
# convert to smaller size format DER
|
||||
openssl x509 -in device_cert.pem -outform der -out device_cert.der
|
||||
|
||||
# Verify the device certificate details
|
||||
openssl x509 -in device_cert.pem -text -noout
|
||||
```
|
||||
|
||||
Let's verify that the attestation key and certificate are valid, and that they can be verified with the root key pair.
|
||||
|
||||
```
|
||||
echo 'challenge $RANDOM' > chal.txt
|
||||
|
||||
# check that they are valid key pairs
|
||||
openssl dgst -sha256 -sign device_key.pem -out sig.txt chal.txt
|
||||
openssl dgst -sha256 -verify <(openssl x509 -in device_cert.der -pubkey -noout) -signature sig.txt chal.txt
|
||||
|
||||
openssl dgst -sha256 -sign "root_key.pem" -out sig.txt chal.txt
|
||||
openssl dgst -sha256 -verify <(openssl x509 -in root_cert.der -pubkey -noout) -signature sig.txt chal.txt
|
||||
|
||||
# Check they are a chain
|
||||
openssl verify -verbose -CAfile "$rcert" "$icert"
|
||||
```
|
||||
|
||||
If the checks succeed, you are ready to program the device attestation key and certificate.
|
||||
|
||||
### Programming an attestation key and certificate
|
||||
|
||||
Convert the DER format of the device attestation certificate to "C" bytes using our utility script. You may first need to
|
||||
first install prerequisite python modules (pip install -r tools/requirements.txt).
|
||||
|
||||
```
|
||||
python tools/gencert/cbytes.py device_cert.der
|
||||
```
|
||||
|
||||
Copy the byte string portion into the [`attestation.c` source file of Solo](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/attestation.c). Overwrite the development or "default" certificate that is already there.
|
||||
|
||||
Now [build the Solo firmware](/solo/building), either a secure or hacker build. You will need to produce a bootloader.hex file and a solo.hex file.
|
||||
|
||||
Print your attestation key in a hex string format.
|
||||
|
||||
```
|
||||
python tools/print_x_y.py
|
||||
```
|
||||
|
||||
Merge the bootloader.hex, solo.hex, and attestion key into one firmware file.
|
||||
|
||||
```
|
||||
solo merge --attestation-key <attestation-key-hex-string> bootloader.hex solo.hex all.hex
|
||||
```
|
||||
|
||||
Now you have a newly create `all.hex` file with a custom attestation key. You can [program this all.hex file
|
||||
with Solo in DFU mode](/solo/programming#procedure).
|
|
@ -0,0 +1,113 @@
|
|||
# Programming
|
||||
|
||||
This page documents how to update or program your Solo.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To program Solo, you'll likely only need to use our Solo tool.
|
||||
|
||||
```python
|
||||
pip3 install solo-python
|
||||
```
|
||||
|
||||
## Updating the firmware
|
||||
|
||||
If you just want to update the firmware, you can run one of the following commands.
|
||||
Make sure your key [is in bootloader mode](/solo/bootloader-mode#solo-bootloader) first.
|
||||
|
||||
```bash
|
||||
solo key update <--secure | --hacker>
|
||||
```
|
||||
|
||||
You can manually install the [latest release](https://github.com/solokeys/solo/releases), or use a build that you made.
|
||||
|
||||
```bash
|
||||
# If it's a hacker, it will automatically boot into bootloader mode.
|
||||
solo program bootloader <firmware.hex | firmware.json>
|
||||
```
|
||||
|
||||
Note you won't be able to use `all.hex` or the `bundle-*.hex` builds, as these include the solo bootloader. You shouldn't
|
||||
risk changing the Solo bootloader unless you want to make it a secure device, or [make other customizations]().
|
||||
|
||||
## Updating a Hacker to a Secure Solo
|
||||
|
||||
Updating a hacker to be a secure build overwrites the [Solo bootloader](/solo/bootloader-mode#solo-bootloader).
|
||||
So it's important to not mess this up or you may brick your device.
|
||||
|
||||
You can use a firmware build from the [latest release](https://github.com/solokeys/solo/releases) or use
|
||||
a build that you made yourself.
|
||||
|
||||
You need to use a firmware file that has the combined bootloader and application (or at the very least just the bootloader).
|
||||
This means using the `bundle-*.hex` file or the `all.hex` from your build. If you overwrite the Solo flash with a missing bootloader,
|
||||
it will be bricked.
|
||||
|
||||
We provide two types of bundled builds. The `bundle-hacker-*.hex` build is the hacker build. If you update with this,
|
||||
you will update the bootloader and application, but nothing will be secured. The `bundle-secure-non-solokeys.hex`
|
||||
is a secured build that will lock your device and it will behave just like a Secure Solo. The main difference is that
|
||||
it uses a "default" attestation key in the device, rather than the SoloKeys attestation key. There is no security
|
||||
concern with using our default attestation key, aside from a privacy implication that services can distinguish it from Solo Secure.
|
||||
|
||||
### Procedure
|
||||
|
||||
1. Boot into DFU mode.
|
||||
|
||||
# Enter Solo bootloader
|
||||
solo program aux enter-bootloader
|
||||
|
||||
# Enter DFU
|
||||
solo program aux enter-dfu
|
||||
|
||||
The device should be turned off.
|
||||
|
||||
2. Program the device
|
||||
|
||||
solo program dfu <bundle-secure-non-solokeys.hex | all.hex>
|
||||
|
||||
Double check you programmed it with bootloader + application (or just bootloader).
|
||||
If you messed it up, simply don't do the next step and repeat this step correctly.
|
||||
|
||||
3. Boot the device
|
||||
|
||||
Once Solo boots a secure build, it will lock the flash permantly from debugger access. Also the bootloader
|
||||
will only accept signed firmware updates.
|
||||
|
||||
solo program aux leave-dfu
|
||||
|
||||
If you are having problems with solo tool and DFU mode, you could alternatively try booting into DFU
|
||||
by holding down the button while Solo is in bootloader mode. Then try another programming tool that works
|
||||
with ST DFU:
|
||||
|
||||
* STM32CubeProg
|
||||
* openocd
|
||||
* stlink
|
||||
|
||||
Windows users need to install [libusb](https://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/)
|
||||
for solo-python to work with Solo's DFU.
|
||||
|
||||
|
||||
## Programming a Solo that hasn't been programmed
|
||||
|
||||
A Solo that hasn't been programmed will boot into DFU mode. You can program
|
||||
it by following a bootloader, or combined bootloader + application.
|
||||
|
||||
```
|
||||
solo program dfu <bundle-*.hex | all.hex>
|
||||
```
|
||||
|
||||
Then boot the device. Make sure it has a bootloader to boot to.
|
||||
|
||||
```
|
||||
solo program aux leave-dfu
|
||||
```
|
||||
|
||||
## Disable signed firmware updates
|
||||
|
||||
If you'd like to also permanently disable signed updates, plug in your programmed Solo and run the following:
|
||||
|
||||
```bash
|
||||
# WARNING: No more signed updates.
|
||||
solo program disable-bootloader
|
||||
```
|
||||
|
||||
You won't be able to update to any new releases.
|
||||
|
|
@ -38,6 +38,7 @@ build firmware hacker solo
|
|||
build firmware hacker-debug-1 solo
|
||||
build firmware hacker-debug-2 solo
|
||||
build firmware secure solo
|
||||
build firmware secure-non-solokeys solo
|
||||
|
||||
pip install -U pip
|
||||
pip install -U solo-python
|
||||
|
@ -49,3 +50,6 @@ bundle="bundle-hacker-debug-1-${version}"
|
|||
/opt/conda/bin/solo mergehex bootloader-nonverifying-${version}.hex firmware-hacker-debug-1-${version}.hex ${bundle}.hex
|
||||
bundle="bundle-hacker-debug-2-${version}"
|
||||
/opt/conda/bin/solo mergehex bootloader-nonverifying-${version}.hex firmware-hacker-debug-2-${version}.hex ${bundle}.hex
|
||||
bundle="bundle-secure-non-solokeys-${version}"
|
||||
/opt/conda/bin/solo mergehex bootloader-verifying-${version}.hex firmware-secure-non-solokeys-${version}.hex ${bundle}.hex
|
||||
sha256sum ${bundle}.hex > ${bundle}.sha2
|
||||
|
|
|
@ -11,6 +11,9 @@ nav:
|
|||
- FIDO2 Implementation: solo/fido2-impl.md
|
||||
- Metadata Statements: solo/metadata-statements.md
|
||||
- Build instructions: solo/building.md
|
||||
- Programming instructions: solo/programming.md
|
||||
- Bootloader mode: solo/bootloader-mode.md
|
||||
- Customization: solo/customization.md
|
||||
- Running on Nucleo32 board: solo/nucleo32-board.md
|
||||
- Signed update process: solo/signed-updates.md
|
||||
- Code documentation: solo/code-overview.md
|
||||
|
|
Ładowanie…
Reference in New Issue