forked from Nitrokey/chopstx
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Support toboot API 2.0 - Allow injecting private key into firmware
- Loading branch information
Showing
9 changed files
with
281 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,24 @@ | ||
language: c | ||
sudo: required | ||
dist: trusty | ||
|
||
addons: | ||
apt: | ||
packages: | ||
- gcc-arm-none-eabi | ||
- libnewlib-arm-none-eabi | ||
- python-pip | ||
- openssl | ||
|
||
install: | ||
- pip install asn1crypto --user | ||
- sudo apt-add-repository -y ppa:team-gcc-arm-embedded/ppa | ||
- sudo apt-get update | ||
- sudo apt-get install -yy gcc-arm-embedded | ||
|
||
script: | ||
- 'cd u2f && make && cd ..' | ||
- 'cd u2f && make clean certclean && cd ..' | ||
- 'cd u2f && make ENFORCE_DEBUG_LOCK=1 && cd ..' | ||
- 'cd u2f' | ||
- 'make' | ||
- 'make clean certclean' | ||
- 'make ENFORCE_DEBUG_LOCK=1' | ||
- 'openssl ecparam -name prime256v1 -genkey -noout -outform der -out key.der' | ||
- './inject_key.py --key key.der --ctr 1001' | ||
- 'cd ..' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#!/usr/bin/env python | ||
|
||
# | ||
# Use this script to inject your own private key and authentication counter | ||
# into U2F binary. Might be useful if you want keys to survive firmware updates. | ||
# | ||
# Example: | ||
# | ||
# Generate EC private key with openssl: | ||
# > openssl ecparam -name prime256v1 -genkey -noout -outform der > key.der | ||
# | ||
# Inject generated key into u2f.bin and set auth counter to 100: | ||
# > python3 inject_key.py --key key.der --ctr 100 | ||
# | ||
|
||
from __future__ import print_function | ||
from asn1crypto.keys import ECPrivateKey | ||
import hashlib | ||
import argparse | ||
import sys | ||
import struct | ||
import os | ||
import tempfile | ||
import subprocess | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument("--elf", default="build/u2f.elf", | ||
help=".elf file to inject keys into") | ||
parser.add_argument("--key", help="EC private key in DER format") | ||
parser.add_argument("--ctr", default=1, type=int, help="value of auth counter") | ||
args = parser.parse_args() | ||
|
||
# load and parse private key | ||
if args.key: | ||
with open(args.key, "rb") as f: | ||
der = f.read() | ||
else: | ||
stdin = sys.stdin.buffer if hasattr(sys.stdin, "buffer") else sys.stdin | ||
der = stdin.read() | ||
key = ECPrivateKey.load(der) | ||
|
||
# convert key into raw bytes and calculate it's sha256 | ||
key_bytes = bytearray.fromhex(format(key["private_key"].native, '064x')) | ||
key_hash = hashlib.sha256(key_bytes).digest() | ||
|
||
# fill authentication counter | ||
ctr_bytes = struct.pack("<I", args.ctr) * 256 | ||
|
||
# pad key and append ctr to produce 2k output blob | ||
blob = (key_bytes + key_hash).ljust(1024, b"\x00") + ctr_bytes | ||
|
||
assert len(blob) == 2048 | ||
fname, fext = os.path.splitext(args.elf) | ||
assert fext == ".elf" | ||
|
||
with tempfile.NamedTemporaryFile(delete=True) as f: | ||
f.write(blob) | ||
f.flush() | ||
# replace contents of .flash_storage section with desired key and counter | ||
ret = subprocess.call(["arm-none-eabi-objcopy", "--update-section", | ||
".flash_storage=" + f.name, args.elf]) | ||
if ret != 0: | ||
raise Exception("Failed to patch .elf file!") | ||
# generate binary for bootloader | ||
ret = subprocess.call(["arm-none-eabi-objcopy", "-O", "binary", | ||
args.elf, fname + ".bin"]) | ||
if ret != 0: | ||
raise Exception("Failed to create .bin file!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.