Merge branch 'master' into python-cleanup
This commit is contained in:
commit
de3d6fd5ba
@ -41,15 +41,14 @@ If you have a Solo for Hacker, here's how you can load your own code on it. You
|
|||||||
git clone --recurse-submodules https://github.com/SoloKeysSec/solo
|
git clone --recurse-submodules https://github.com/SoloKeysSec/solo
|
||||||
cd solo
|
cd solo
|
||||||
|
|
||||||
cd targets/stm32l442
|
cd targets/stm32l432
|
||||||
make cbor
|
make cbor
|
||||||
make all-hacker
|
make all-hacker
|
||||||
python ../../tools/programmer.py solo.hex
|
python ../../tools/programmer.py solo.hex
|
||||||
```
|
```
|
||||||
|
|
||||||
If you forgot the `--recurse-submodules` when cloning, simply `git submodule update --init --recursive`.
|
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/SoloKeysSec/solo/blob/master/targets/stm32l442/src/led.c#L15) and force:
|
|
||||||
```
|
```
|
||||||
uint32_t b = 0;
|
uint32_t b = 0;
|
||||||
```
|
```
|
||||||
|
160
docs/building.md
160
docs/building.md
@ -5,7 +5,7 @@ There exists a development board [NUCLEO-L432KC](https://www.st.com/en/evaluatio
|
|||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
|
|
||||||
Install the [latest ARM compiler toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) for your system.
|
Install the [latest ARM compiler toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) for your system. We recommend getting the latest compilers from ARM.
|
||||||
|
|
||||||
You can also install the ARM toolchain using a package manage like `apt-get` or `pacman`,
|
You can also install the ARM toolchain using a package manage like `apt-get` or `pacman`,
|
||||||
but be warned they might be out of date. Typically it will be called `gcc-arm-none-eabi binutils-arm-none-eabi`.
|
but be warned they might be out of date. Typically it will be called `gcc-arm-none-eabi binutils-arm-none-eabi`.
|
||||||
@ -21,7 +21,7 @@ To program your build, you'll need one of the following programs.
|
|||||||
Enter the `stm32l4xx` target directory.
|
Enter the `stm32l4xx` target directory.
|
||||||
|
|
||||||
```
|
```
|
||||||
cd targets/stm32l442
|
cd targets/stm32l432
|
||||||
```
|
```
|
||||||
|
|
||||||
Build the cbor library.
|
Build the cbor library.
|
||||||
@ -30,117 +30,131 @@ Build the cbor library.
|
|||||||
make cbor
|
make cbor
|
||||||
```
|
```
|
||||||
|
|
||||||
Now build the Solo bootloader.
|
Now build Solo.
|
||||||
|
|
||||||
```
|
```
|
||||||
make clean
|
make build-hacker
|
||||||
make boot
|
|
||||||
# Or to make a Solo Hacker build:
|
|
||||||
# make boot-hacker
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now build the Solo application.
|
The `build-hacker` recipe does a few things. First it builds the bootloader, with
|
||||||
|
signature checking disabled. Then it builds the Solo application with "hacker" features
|
||||||
|
enabled, like being able to jump to the bootloader on command. It then merges bootloader
|
||||||
|
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,
|
||||||
|
as this can be risky if done often. Just use `solo.hex`.
|
||||||
|
|
||||||
|
### Building with debug messages
|
||||||
|
|
||||||
|
If you're developing, you probably want to see debug messages! Solo has a USB
|
||||||
|
Serial port that it will send debug messages through (from `printf`). You can read them using
|
||||||
|
a normal serial terminal like `picocom` or `putty`.
|
||||||
|
|
||||||
|
Just add `DEBUG=1` or `DEBUG=2` to your build recipe, like this.
|
||||||
|
|
||||||
```
|
```
|
||||||
make clean
|
make build-hacker DEBUG=1
|
||||||
make
|
|
||||||
# Or to make a Solo Hacker build:
|
|
||||||
# make all-hacker
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that for hacker builds, the bootloader must be built using the `boot-hacker` recipe.
|
If you use `DEBUG=2`, that means Solo will not boot until something starts reading
|
||||||
|
it's debug messages. So it basically it waits to tether to a serial terminal so that you don't
|
||||||
|
miss any debug messages.
|
||||||
|
|
||||||
Merge the two files together. This script also patches a spot in memory to
|
We recommend using our `solotool.py` as a serial emulator since it will automatically
|
||||||
allow the bootloader to boot the application. This memory spot is later used for
|
reconnect each time you program Solo.
|
||||||
signed firmware updates.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
python merge_hex.py solo.hex bootloader.hex all.hex
|
python tools/solotool.py monitor <serial-port>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can now program Solo with `all.hex`.
|
### Building a Solo release
|
||||||
|
|
||||||
# Solo Hacker
|
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.
|
||||||
|
|
||||||
A Solo Hacker build is more friendly for development. If you just want to test your
|
If you're ready to program a full release, run this recipe to build.
|
||||||
solo build or do any sort of development, you should start with this.
|
|
||||||
|
|
||||||
It is the same build as a production Solo, but it has extra commands available.
|
```
|
||||||
|
make build-release-locked
|
||||||
|
```
|
||||||
|
|
||||||
* Allows updates at any time without pressing button.
|
Programming `all.hex` will cause the device to permanently lock itself.
|
||||||
* Opens a USB emulated serial port for printing.
|
|
||||||
* Doesn't lock the flash or debugger at all.
|
|
||||||
|
|
||||||
You if build with Solo Hacker, you can always completely overwrite it and start over.
|
|
||||||
If it's not a hacker build, you cannot reprogram Solo as easily.
|
|
||||||
|
|
||||||
* `all-hacker`: can be reprogrammed again over USB or via wire with a programmer.
|
|
||||||
* `all`: can be reprogrammed using only signed updates or via wire with a programmer.
|
|
||||||
* `all-locked`: Can only be reprogrammed via signed updates unless they are disabled.
|
|
||||||
|
|
||||||
# Programming
|
# Programming
|
||||||
|
|
||||||
It's recommended to test a debug/hacker build first to make sure Solo is working as expected.
|
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!).
|
Then you can switch to a locked down build, which cannot be reprogrammed as easily (or not at all!).
|
||||||
|
|
||||||
|
We recommend using our `solotool.py` 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.
|
||||||
|
|
||||||
|
```
|
||||||
|
python tools/solotool.py program 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
|
## ST USB DFU
|
||||||
|
|
||||||
If your Solo has never been programmed, it will boot the ST USB DFU. You can program
|
If your Solo has never been programmed, it will boot the ST USB DFU. The LED is turned
|
||||||
it via USB. After you program it, it will still be in ST USB DFU mode. You additionally
|
off and it enumerates as "STM BOOTLOADER".
|
||||||
need to supply a command to tell the DFU program to "detach" and boot the application.
|
|
||||||
|
|
||||||
If you power cycle Solo, it will return to DFU mode so you can reprogram it. If you don't
|
You can program it by running the following.
|
||||||
want it to do this, you must set the option bytes bit `nBOOT0=1`. Now it will always boot the application.
|
|
||||||
|
|
||||||
Example using STM32CubeProg.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# Program all.hex
|
python tools/solotool.py program all.hex --use-dfu --detach
|
||||||
STM32_Programmer_CLI -c port=usb1 -halt -d all.hex
|
|
||||||
|
|
||||||
# If you want it to always boot application, set nBOOT0=1
|
|
||||||
STM32_Programmer_CLI -c port=usb1 -ob nBOOT0=1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If Solo has been programmed with a hacker build, you can return it to ST DFU mode using just USB.
|
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.
|
||||||
# Use our programmer script
|
|
||||||
|
|
||||||
# Makes it boot to ST DFU once
|
## Solo Hacker vs Solo
|
||||||
python tools/programmer.py --st-dfu
|
|
||||||
|
|
||||||
# OR
|
|
||||||
# Make it boot to ST DFU every boot (initial state basically)
|
|
||||||
python tools/programmer.py --enter-bootloader
|
|
||||||
python tools/programmer.py --st-dfu
|
|
||||||
```
|
|
||||||
|
|
||||||
## Solo / Solo Hacker updates
|
|
||||||
|
|
||||||
To program a Solo Hacker device, run the following. Note you should only specify the application
|
|
||||||
firmware, not the combined bootloader+application! I.e. not `all.hex` from above.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python tools/programmer.py target/stm32l442/solo.hex
|
|
||||||
```
|
|
||||||
|
|
||||||
A Solo hacker device doesn't need to be in bootloader mode to be programmed, it will automatically switch.
|
A Solo hacker device doesn't need to be in bootloader mode to be programmed, it will automatically switch.
|
||||||
If the application gets bricked, you can hold down the button for 2 seconds while
|
|
||||||
plugging it in the token make it stay in the bootloader. Holding the button an additional 5 seconds
|
Solo (locked) needs the button to be held down when plugged in to boot to the bootloader.
|
||||||
will return it to the ST DFU.
|
|
||||||
|
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.
|
If this is not a device with a hacker build, you can only program signed updates.
|
||||||
|
|
||||||
```
|
```
|
||||||
python tools/programmer.py /path/to/firmware.json
|
python tools/solotool.py program /path/to/firmware.json
|
||||||
```
|
```
|
||||||
|
|
||||||
If you've provisioned the Solo bootloader with your own secp256r1 public key, you can sign your
|
If you've provisioned the Solo bootloader with your own secp256r1 public key, you can sign your
|
||||||
firmware by running the following command.
|
firmware by running the following command.
|
||||||
|
|
||||||
```
|
```
|
||||||
python tools/sign_firmware.py /path/to/signing-key.pem /path/to/solo.hex /output-path/to/firmware.json
|
python tools/solotool.py 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
|
If your Solo isn't locked, you can always reprogram it using a debugger connected directly
|
||||||
@ -151,13 +165,9 @@ to the token.
|
|||||||
If you plan to be using your Solo for real, you should lock it permanently. This prevents
|
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.
|
someone from connecting a debugger to your token and stealing credentials.
|
||||||
|
|
||||||
To do this, build the non-hacker bootloader and locked version of the firmware.
|
To do this, build the locked release firmware.
|
||||||
```
|
```
|
||||||
make clean
|
make build-release-locked
|
||||||
make boot
|
|
||||||
make clean
|
|
||||||
make all-locked
|
|
||||||
python merge_hex.py solo.hex bootloader.hex all.hex
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now when you program `all.hex`, the device will lock itself when it first boots. You can only update it
|
Now when you program `all.hex`, the device will lock itself when it first boots. You can only update it
|
||||||
@ -166,6 +176,6 @@ with signed updates.
|
|||||||
If you'd like to also permanently disable signed updates, plug in your programmed Solo and run the following:
|
If you'd like to also permanently disable signed updates, plug in your programmed Solo and run the following:
|
||||||
|
|
||||||
```
|
```
|
||||||
# No more signed updates.
|
# WARNING: No more signed updates.
|
||||||
python tools/programmer.py --disable
|
python tools/programmer.py --disable
|
||||||
```
|
```
|
||||||
|
@ -2,11 +2,11 @@ We are very open to contributions!
|
|||||||
|
|
||||||
[Currently](https://github.com/solokeyssec/solo/issues), most work will go towards
|
[Currently](https://github.com/solokeyssec/solo/issues), most work will go towards
|
||||||
|
|
||||||
* implementing STM32L442
|
* implementing STM32L432
|
||||||
* implementing NFC
|
* implementing NFC
|
||||||
* adding documentation and improving accessability of the code
|
* 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 STM32L442 to good use!
|
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/SoloKeysSec/solo/pulls) at any time, we don't currently have a formal contribution process.
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Solo has a bootloader that's fixed in memory to allow for signed firmware updates. It is not a built-in bootloader provided by the chip
|
Solo has a bootloader that's fixed in memory to allow for signed firmware updates. It is not a built-in bootloader provided by the chip
|
||||||
manufacturer, it is our own. We plan to use Ed25519 signatures, which have [efficient constant-time implementations on Cortex-M4 chips](http://www.cs.haifa.ac.il/~orrd/LC17/paper39.pdf).
|
manufacturer, it is our own. We plan to use Ed25519 signatures, which have [efficient constant-time implementations on Cortex-M4 chips](http://www.cs.haifa.ac.il/~orrd/LC17/paper39.pdf).
|
||||||
|
|
||||||
On the STM32L442, there is 256 KB of memory. The first 14 KB of memory is reserved for the bootloader.
|
On the STM32L432, there is 256 KB of memory. The first 14 KB of memory is reserved for the bootloader.
|
||||||
The bootloader is the first thing that boots, and if the button of the device is not held for 2 seconds, the
|
The bootloader is the first thing that boots, and if the button of the device is not held for 2 seconds, the
|
||||||
application is immediately booted.
|
application is immediately booted.
|
||||||
|
|
||||||
|
@ -22,14 +22,29 @@ debugboot-boot:
|
|||||||
LDSCRIPT=linker/bootloader_stm32l4xx_extra.ld EXTRA_DEFINES='-DAPPLICATION_START_PAGE=16 -DSOLO_HACKER'
|
LDSCRIPT=linker/bootloader_stm32l4xx_extra.ld EXTRA_DEFINES='-DAPPLICATION_START_PAGE=16 -DSOLO_HACKER'
|
||||||
|
|
||||||
boot-sig-checking:
|
boot-sig-checking:
|
||||||
$(MAKE) -f bootloader.mk -j8 bootloader.hex
|
$(MAKE) -f bootloader.mk -j8 bootloader.hex DEBUG=0
|
||||||
|
|
||||||
boot-no-sig:
|
boot-no-sig:
|
||||||
$(MAKE) -f bootloader.mk -j8 bootloader.hex EXTRA_DEFINES='-DSOLO_HACKER'
|
$(MAKE) -f bootloader.mk -j8 bootloader.hex EXTRA_DEFINES='-DSOLO_HACKER' DEBUG=0
|
||||||
|
|
||||||
|
build-release-locked: clean2 boot-sig-checking clean all-locked
|
||||||
|
$(merge_hex) solo.hex bootloader.hex all.hex
|
||||||
|
rm -f solo.hex bootloader.hex # don't program solo.hex ...
|
||||||
|
|
||||||
|
build-release: clean2 boot-sig-checking clean all
|
||||||
|
$(merge_hex) solo.hex bootloader.hex all.hex
|
||||||
|
|
||||||
|
build-hacker: clean2 boot-no-sig clean all-hacker
|
||||||
|
$(merge_hex) solo.hex bootloader.hex all.hex
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -f application.mk clean
|
$(MAKE) -f application.mk clean
|
||||||
$(MAKE) -f bootloader.mk clean
|
$(MAKE) -f bootloader.mk clean
|
||||||
|
clean2:
|
||||||
|
rm -f solo.hex bootloader.hex all.hex
|
||||||
|
$(MAKE) -f application.mk clean
|
||||||
|
$(MAKE) -f bootloader.mk clean
|
||||||
|
|
||||||
|
|
||||||
flash: solo.hex bootloader.hex
|
flash: solo.hex bootloader.hex
|
||||||
$(merge_hex) solo.hex bootloader.hex all.hex
|
$(merge_hex) solo.hex bootloader.hex all.hex
|
@ -24,10 +24,8 @@ CFLAGS= $(INC)
|
|||||||
TARGET=solo
|
TARGET=solo
|
||||||
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
||||||
|
|
||||||
# Nucleo board
|
# Solo or Nucleo board
|
||||||
#CHIP=STM32L432xx
|
CHIP=STM32L432xx
|
||||||
# Solo
|
|
||||||
CHIP=STM32L442xx
|
|
||||||
|
|
||||||
DEFINES = -D$(CHIP) -DAES256=1 -DUSE_FULL_LL_DRIVER
|
DEFINES = -D$(CHIP) -DAES256=1 -DUSE_FULL_LL_DRIVER
|
||||||
DEFINES += -DTEST_SOLO_STM32 -DTEST
|
DEFINES += -DTEST_SOLO_STM32 -DTEST
|
@ -36,10 +36,8 @@ CFLAGS= $(INC)
|
|||||||
TARGET=solo
|
TARGET=solo
|
||||||
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
||||||
|
|
||||||
# Nucleo board
|
# Solo or Nucleo board
|
||||||
#CHIP=STM32L432xx
|
CHIP=STM32L432xx
|
||||||
# Solo
|
|
||||||
CHIP=STM32L442xx
|
|
||||||
|
|
||||||
ifndef DEBUG
|
ifndef DEBUG
|
||||||
DEBUG=0
|
DEBUG=0
|
@ -34,10 +34,8 @@ CFLAGS= $(INC)
|
|||||||
TARGET=bootloader
|
TARGET=bootloader
|
||||||
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
|
||||||
|
|
||||||
# Nucleo board
|
# Solo or Nucleo board
|
||||||
#CHIP=STM32L432xx
|
CHIP=STM32L432xx
|
||||||
# Solo
|
|
||||||
CHIP=STM32L442xx
|
|
||||||
|
|
||||||
ifndef DEBUG
|
ifndef DEBUG
|
||||||
DEBUG=0
|
DEBUG=0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user