From 8f6a2045e678be01f8b1bf8245d0e862d548ecd9 Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Mon, 25 Jun 2018 17:09:52 +0100 Subject: [PATCH] build: Refactor Docker build --- Dockerfile | 5 ++- build.sh | 75 +++---------------------------------- script/cibuild | 4 +- script/fingerprint | 41 ++++++++++++++++++++ script/fullbuild | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 72 deletions(-) create mode 100755 script/fingerprint create mode 100755 script/fullbuild diff --git a/Dockerfile b/Dockerfile index 4debc36f5..b5a3b7c3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,10 @@ RUN apt-get update && \ ENV PROTOBUF_VERSION=3.4.0 RUN curl -LO "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -RUN unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d /usr + +# use zipfile module to extract files world-readable +RUN python3 -m zipfile -e "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" /usr/local && chmod 755 /usr/local/bin/protoc + RUN pip3 install "protobuf==${PROTOBUF_VERSION}" ecdsa RUN ln -s python3 /usr/bin/python diff --git a/build.sh b/build.sh index 005ec9f88..81dc2a8dc 100755 --- a/build.sh +++ b/build.sh @@ -3,74 +3,9 @@ set -e IMAGE=trezor-mcu-build -BOOTLOADER_TAG=${1:-master} -FIRMWARE_TAG=${2:-master} -REPOSITORY=${3:-trezor} +BOOTLOADER_COMMIT=${1:-HEAD} +FIRMWARE_COMMIT=${2:-HEAD} -if [ "$REPOSITORY" = "local" ]; then - REPOSITORY=file:///local/ -else - REPOSITORY=https://github.com/$REPOSITORY/trezor-mcu.git -fi - -BOOTLOADER_BINFILE=build/bootloader-$BOOTLOADER_TAG.bin -BOOTLOADER_ELFFILE=build/bootloader-$BOOTLOADER_TAG.elf - -FIRMWARE_BINFILE=build/trezor-$FIRMWARE_TAG.bin -FIRMWARE_ELFFILE=build/trezor-$FIRMWARE_TAG.elf - -docker build -t $IMAGE . - -echo -echo "STARTING BUILD:" -echo -echo "Building bootloader '$BOOTLOADER_TAG' + firmware '$FIRMWARE_TAG' from repo: $REPOSITORY" -echo - -docker run -i -t -v $(pwd):/local -v $(pwd)/build:/build:z $IMAGE /bin/sh -c "\ - cd /tmp && \ - git clone $REPOSITORY trezor-mcu-bl && \ - cd trezor-mcu-bl && \ - git checkout $BOOTLOADER_TAG && \ - git submodule update --init --recursive && \ - make -C vendor/libopencm3 && \ - make && \ - make -C bootloader align && \ - cp bootloader/bootloader.bin /$BOOTLOADER_BINFILE && \ - cp bootloader/bootloader.elf /$BOOTLOADER_ELFFILE && \ - cd /tmp && \ - git clone $REPOSITORY trezor-mcu-fw && \ - cd trezor-mcu-fw && \ - git checkout $FIRMWARE_TAG && \ - git submodule update --init --recursive && \ - make -C vendor/libopencm3 && \ - make -C vendor/nanopb/generator/proto && \ - make -C firmware/protob && \ - make && \ - cp /tmp/trezor-mcu-bl/bootloader/bootloader.bin bootloader/bootloader.bin - make -C firmware sign && \ - cp firmware/trezor.bin /$FIRMWARE_BINFILE && \ - cp firmware/trezor.elf /$FIRMWARE_ELFFILE - " - -echo -echo "FINISHED BUILD" -echo - -/usr/bin/env python -c " -from __future__ import print_function -import hashlib -import sys -for arg in sys.argv[1:]: - (fn, fprint_start, hashing, max_size) = arg.split(':') - fprint_start = int(fprint_start) - max_size = int(max_size) - data = open(fn, 'rb').read() - if hashing == 'd': - fprint = hashlib.sha256(hashlib.sha256(data[fprint_start:]).digest()).hexdigest() - else: - fprint = hashlib.sha256(data[fprint_start:]).hexdigest() - print('Filename :', fn) - print('Fingerprint :', fprint) - print('Size : %d bytes (out of %d maximum)' % (len(data), max_size)) -" $BOOTLOADER_BINFILE:0:d:32768 $FIRMWARE_BINFILE:256:s:491520 +docker build -t "$IMAGE" . +docker run -it -v $(pwd):/src:z --user="$(stat -c "%u:%g" .)" "$IMAGE" \ + /src/script/fullbuild "$BOOTLOADER_COMMIT" "$FIRMWARE_COMMIT" diff --git a/script/cibuild b/script/cibuild index 3b13af97f..2c2382a8e 100755 --- a/script/cibuild +++ b/script/cibuild @@ -14,9 +14,11 @@ else fi make + if [ "$EMULATOR" != 1 ]; then - make -C bootloader + make -C bootloader align fi + make -C vendor/nanopb/generator/proto make -C firmware/protob diff --git a/script/fingerprint b/script/fingerprint new file mode 100755 index 000000000..de9d90ed5 --- /dev/null +++ b/script/fingerprint @@ -0,0 +1,41 @@ +#!/usr/bin/env python +from __future__ import print_function + +import binascii +import hashlib + + +def H(x): + return hashlib.sha256(x).digest() + + +def compute_fingerprint(x, double): + digest = H(H(x)) if double else H(x) + return binascii.hexlify(digest).decode() + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser() + + parser.add_argument("file", type=argparse.FileType("rb"), + help="input file") + parser.add_argument("--offset", type=int, default=0, + help="skip bytes at start of input") + parser.add_argument("--max-size", type=int, + help="maximum input file size") + parser.add_argument("--double", action="store_true", + help="use SHA-256d instead of SHA-256") + + args = parser.parse_args() + + data = args.file.read() + size = len(data) + fingerprint = compute_fingerprint(data[args.offset:], args.double) + + print("Filename :", args.file.name) + print("Fingerprint :", fingerprint) + + print("Size : {} bytes (out of {} maximum)" + .format(size, args.max_size)) diff --git a/script/fullbuild b/script/fullbuild new file mode 100755 index 000000000..834d4e253 --- /dev/null +++ b/script/fullbuild @@ -0,0 +1,93 @@ +#!/bin/bash + +# script/build: Build the TREZOR firmware in a clean working tree. +# + +set -eu + +cd "$(dirname "$0")/.." + +readonly ARTIFACT_EXTENSIONS=(bin elf) +readonly BUILD_DIR="$(readlink -f build)" + +readonly BOOTLOADER_DIR="$BUILD_DIR/bootloader" +readonly BOOTLOADER_FILENAME="bootloader/bootloader.bin" +readonly BOOTLOADER_PATH="$BOOTLOADER_DIR/$BOOTLOADER_FILENAME" + +readonly FIRMWARE_DIR="$BUILD_DIR/firmware" +readonly FIRMWARE_FILENAME="firmware/trezor.bin" +readonly FIRMWARE_PATH="$FIRMWARE_DIR/$FIRMWARE_FILENAME" + +worktree_setup() { + local path="$1" + local commit="$2" + + rm -rf "$path" + git clone -n --reference=. . "$path" --recurse-submodules + + # Use `git rev-parse` so that we can use any reference from the working repository. + git -C "$path" checkout "$(git rev-parse "$commit")" + + ( cd "$path" && script/setup ) +} + +worktree_build() { + local path="$1" + + ( cd "$path" && script/cibuild ) +} + +worktree_copy() { + local path="$1" + local filename="$2" + local pattern="$3" + + local describe="$(git -C "$path" describe --tags --match "$pattern")" + + local src="$path/$filename" + + local basename="$(basename "$filename")" + local dest="$BUILD_DIR/${basename%.*}-$describe.${basename##*.}" + + for extension in "${ARTIFACT_EXTENSIONS[@]}"; do + install -Dm0644 \ + "${src%.*}.$extension" \ + "${dest%.*}.$extension" + done + + printf "%s" "$dest" +} + +main() { + local bootloader_commit="$1" + local firmware_commit="$2" + + worktree_setup "$BOOTLOADER_DIR" "$bootloader_commit" + worktree_build "$BOOTLOADER_DIR" + + local bootloader_path="$(worktree_copy \ + "$BOOTLOADER_DIR" \ + "$BOOTLOADER_FILENAME" \ + "bl*")" + + worktree_setup "$FIRMWARE_DIR" "$firmware_commit" + cp "$BOOTLOADER_PATH" "$FIRMWARE_DIR/$BOOTLOADER_FILENAME" + worktree_build "$FIRMWARE_DIR" + + local firmware_path="$(worktree_copy \ + "$FIRMWARE_DIR" \ + "$FIRMWARE_FILENAME" \ + "v*")" + + printf "\n\n"; script/fingerprint \ + "$bootloader_path" \ + --max-size 32768 \ + --double + + printf "\n\n"; script/fingerprint \ + "$firmware_path" \ + --offset 256 \ + --max-size 491520 +} + +main "$@"