# Solo 2 Getting Started Monorepo: https://github.com/solokeys/solo2 Hardware: https://github.com/solokeys/solo2-hw **Feel free to edit or comment on this getting started page directly** Shortlink: https://solo2.dev This documentation is [CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/) licensed. ![](https://i.imgur.com/GxDcBpU.png) ![](https://i.imgur.com/1ZdaODG.jpg) #### Contact - tech talk synchronous: https://matrix.to/#/#solokeys-dev:matrix.org - tech talk asynchronous: https://github.com/solokeys/solo2/discussions - getting started: edit here directly (don't PR README.md in solo2 repo) - Issues / PR: **please NO at this time** Other chat rooms of interest: - Trussed® framework: https://matrix.to/#/#trussed:matrix.org - Rust Embedded: https://matrix.to/#/#rust-embedded:matrix.org - RTIC: https://matrix.to/#/#rtic:matrix.org - LPC55 chips: https://matrix.to/#/#lpc55:matrix.org ## Overview - [setup machine](#Initial-Setup) with Rust + dependencies - `cargo install flip-link` - get an [NXP LPC55 devkit](https://www.nxp.com/design/development-boards/lpcxpresso-boards/lpcxpresso55s69-development-board:LPC55S69-EVK) - flash JLink debugger firmware ([guide](https://www.nxp.com/docs/en/supporting-information/Debug_Probe_Firmware_Programming.pdf) – if you figure out how to use probe.rs instead, please share!) - run `JLinkGDBServer -strict -device LPC55S69 -if SWD -vd` in one terminal - run `netcat localhost 19021` in another terminal (for [delog](docs.rs/delog) logs via RTT) - checkout [github/solokeys/solo2](github.com/solokeys/solo2) and run `make run-dev` This descends into `runners/lpc55` and calls ```bash cargo run --release --features board-lpcxpresso55,develop ``` using `arm-none-eabi-gdb` as runner as configured in [.cargo/config](https://github.com/solokeys/solo2/blob/main/runners/lpc55/.cargo/config). The feature `develop` activates useful features during development - no PRINCE encryption of data section (so no need for PUF enrolment, secure boot, etc.) - silent authentication (buttons are "pressed" without pressing them) - disables the FIDO app's reset time window See [runners/lpc55/Cargo.toml](https://github.com/solokeys/solo2/blob/main/runners/lpc55/Cargo.toml) for all features. To just build: `make build-dev` Helpful during development: `cargo install bacon; cd runners/lpc55; bacon -j check-dev` Very basic test: - `pip install 'fido2~=0.9'` - `python tests/basic.py` ## Bootloader ### `lpc55-host` TODO: How to flash unsigned firmware via [lpc55](https://github.com/lpc55/lpc55-host) host utility. ### `mboot` Install [`cargo-binutils`](https://github.com/rust-embedded/cargo-binutils): ``` $ cargo install cargo-binutils $ rustup component add llvm-tools-preview ``` Install [`mboot`](https://github.com/molejar/pyMBoot), for example using `pip` and a virtual environemnt: ``` $ python3 -m venv mboot $ source mboot/bin/activate $ pip install mboot ``` If you want to perform the following steps without superuser rights, install [these UDEV rules](https://raw.githubusercontent.com/molejar/pyIMX/master/udev/90-imx-sdp.rules): ``` $ curl https://raw.githubusercontent.com/molejar/pyIMX/master/udev/90-imx-sdp.rules | sudo tee /etc/udev/rules.d/90-imx-sdp.rules $ sudo udevadm control --reload-rules ``` Check that the device is connected and in bootloader mode: ``` $ mboot info DEVICE: USB COMPOSITE DEVICE (0x1FC9, 0x0021) ... ``` Compile the firmware and prepare a binary image (see the Overview section for information about the features): ``` $ cargo objcopy --release --features board-lpcxpresso55,develop -- -O binary firmware.bin ``` Flash the firmware image to the MCU: ``` $ mboot erase --mass $ mboot write firmware.bin ``` ## Initial Setup Install Rust/Cargo from rustup.rs: https://www.rust-lang.org/tools/install Then perform OS/distro specific steps listed below. Both VS Code + neovim (nightly 0.5 preview) work well with [rust-analyzer](https://rust-analyzer.github.io/). If you want to use a J-Link, install the [J-Link Software and Documentation Pack](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack) providing `JLinkGDBServer`. ### Debian/Ubuntu ``` sudo apt-get install llvm clang libclang-dev gcc-arm-none-eabi libc6-dev-i386 ``` On Debian, you need to use the `gdb-multiarch` executable instead of `arm-none-eabi-gdb`, so either create a symlink or update `.cargo/config`. ### Arch Linux ``` yay clang llvm arm-none-eabi-gdb ``` ### NixOS You can use the following `mkShell` expression inside a `flake.nix` or `shell.nix`, as long as you provide `nixpkgs` and `nixpkgs-mozilla`. ```nix { nixpkgs, mozilla }: let rust-overlay = import "${mozilla}/rust-overlay.nix"; pkgs = import nixpkgs { overlays = [ rust-overlay ]; }; rust_stable = pkgs.latest.rustChannels.stable.rust; rust_thumbv8m = rust_stable.override { targets = [ "thumbv8m.main-none-eabi" ]; }; pkgs_cross = pkgs.pkgsCross.arm-embedded; gcc = pkgs_cross.buildPackages.gcc; libc_include = "${gcc.libc}/${gcc.libc.incdir}"; gcc-unwrapped = pkgs_cross.buildPackages.gcc-unwrapped; gcc_include = "${gcc-unwrapped}/lib/gcc/${gcc-unwrapped.targetConfig}/${gcc-unwrapped.version}/include"; in pkgs.mkShell { nativeBuildInputs = [ gcc rust_thumbv8m # Is being added to nixpkgs: https://github.com/NixOS/nixpkgs/pull/121184 #pkgs.flip-link pkgs.llvm pkgs.wget ]; LIBCLANG_PATH = "${pkgs.llvmPackages.libclang}/lib"; TARGET_CC = "${gcc.targetPrefix}cc"; TARGET_AR = "${gcc.targetPrefix}ar"; TARGET_CFLAGS = "-I${libc_include}"; BINDGEN_EXTRA_CLANG_ARGS = "-I${libc_include} -I${gcc_include}"; }; ``` ### macOS TODO ### Win10 TODO ## Application-specific Setup ### `fido-authenticator` `fido-authenticator` needs an attestation key and certificate, both with the ID 0. These can be generated using [`solo2-cli`](https://github.com/solokeys/solo2-cli) (requires the `dev-pki` feature): ``` $ solo2-cli dev-pki fido fido.key fido.cert ``` These files (or any other files in the required format) can then be written to the device using the provisioner app. First, run the provisioner app on the prototype: ``` $ cd runners/lpc55 && make run-pro ``` Then use `solo2-cli` to write the key and the certificate to the device: ``` $ solo2-cli app provisioner write-file fido.cert fido/x5c/00 $ solo2-cli app provisioner write-file fido.key fido/sec/00 ``` (Make sure that there is no other pcsc smartcard connected to the device becuase currently, solo2-cli can’t handle multiple available smartcards.)