sign_official_build.sh revision aa888463b860c2852f3fcb17baf8de395fcca294
137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah#!/bin/bash 237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 39137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Use of this source code is governed by a BSD-style license that can be 537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# found in the LICENSE file. 637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Sign the final build image using the "official" keys. 80c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# 90c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Prerequisite tools needed in the system path: 100c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# 110c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# gbb_utility (from src/platform/vboot_reference) 120c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# vbutil_kernel (from src/platform/vboot_reference) 130c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# cgpt (from src/platform/vboot_reference) 140c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# dump_kernel_config (from src/platform/vboot_reference) 150c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# verity (from src/platform/verity) 161cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# load_kernel_test (from src/platform/vboot_reference) 171a2e6fc765a13b636d3dd75dc7cae709e9e8d218Gaurav Shah# dumpe2fs 18d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah# sha1sum 1937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 2037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Load common constants and variables. 2137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah. "$(dirname "$0")/common.sh" 2237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 231cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Print usage string 241cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahusage() { 2537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah cat <<EOF 268ae7b0e41a1252f98e6662a298efb97624431c44Gaurav ShahUsage: $PROG <type> input_image /path/to/keys/dir [output_image] [version_file] 2737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahwhere <type> is one of: 2837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah ssd (sign an SSD image) 291cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah recovery (sign a USB recovery image) 3022bd8b0c29b485ccdaa4f63e6fdac9f097b60aabMike Frysinger factory (sign a factory install image) 3122bd8b0c29b485ccdaa4f63e6fdac9f097b60aabMike Frysinger install (old alias to "factory") 32283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger update_payload (sign a delta update hash) 339c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah firmware (sign a firmware image) 3464bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson usb (sign an image to boot directly from USB) 351cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah verify (verify an image including rootfs hashes) 361cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 378ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahoutput_image: File name of the signed output image 388ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahversion_file: File name of where to read the kernel and firmware versions. 398ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah 408ae7b0e41a1252f98e6662a298efb97624431c44Gaurav ShahIf you are signing an image, you must specify an [output_image] and 418ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahoptionally, a [version_file]. 428ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah 4337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahEOF 44b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger if [[ $# -gt 0 ]]; then 45b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger error "$*" 46b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger exit 1 47b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger fi 48b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger exit 0 491cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah} 501cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 51b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger# Verify we have as many arguments as we expect, else show usage & quit. 52b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger# Usage: 53b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger# check_argc <number args> <exact number> 54b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger# check_argc <number args> <lower bound> <upper bound> 55b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysingercheck_argc() { 56b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger case $# in 57b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger 2) 58b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger if [[ $1 -ne $2 ]]; then 59b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger usage "command takes exactly $2 args" 60b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger fi 61b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger ;; 62b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger 3) 63b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger if [[ $1 -lt $2 || $1 -gt $3 ]]; then 64b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger usage "command takes $2 to $3 args" 65b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger fi 66b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger ;; 67b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger *) 68b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger die "check_argc: incorrect number of arguments" 69b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger esac 70b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger} 7137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 7237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Abort on errors. 7337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahset -e 7437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 759dc90d36f8f2e2029adbfece0831c1a840e899caGaurav Shah# Add to the path since some tools reside here and may not be in the non-root 769dc90d36f8f2e2029adbfece0831c1a840e899caGaurav Shah# system path. 779dc90d36f8f2e2029adbfece0831c1a840e899caGaurav ShahPATH=$PATH:/usr/sbin:/sbin 789dc90d36f8f2e2029adbfece0831c1a840e899caGaurav Shah 790500524edda44c770690bb942e916522f1eca5cdGaurav Shah# Make sure the tools we need are available. 801cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahfor prereqs in gbb_utility vbutil_kernel cgpt dump_kernel_config verity \ 81ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah load_kernel_test dumpe2fs sha1sum e2fsck; do 820500524edda44c770690bb942e916522f1eca5cdGaurav Shah type -P "${prereqs}" &>/dev/null || \ 830500524edda44c770690bb942e916522f1eca5cdGaurav Shah { echo "${prereqs} tool not found."; exit 1; } 840500524edda44c770690bb942e916522f1eca5cdGaurav Shahdone 850500524edda44c770690bb942e916522f1eca5cdGaurav Shah 8637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahTYPE=$1 8737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahINPUT_IMAGE=$2 8837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahKEY_DIR=$3 8937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahOUTPUT_IMAGE=$4 908ae7b0e41a1252f98e6662a298efb97624431c44Gaurav ShahVERSION_FILE=$5 918ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah 928ae7b0e41a1252f98e6662a298efb97624431c44Gaurav ShahFIRMWARE_VERSION=1 938ae7b0e41a1252f98e6662a298efb97624431c44Gaurav ShahKERNEL_VERSION=1 9437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 951cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Get current rootfs hash and kernel command line 96d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah# ARGS: IMAGE KERNELPART 971cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahgrab_kernel_config() { 981cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local image=$1 99d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah local kernelpart=$2 # Kernel partition number to grab. 1001cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # Grab the existing kernel partition and get the kernel config. 1010c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah temp_kimage=$(make_temp_file) 102d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah extract_image_partition ${image} ${kernelpart} ${temp_kimage} 1031cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah dump_kernel_config ${temp_kimage} 1041cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah} 1051cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 10669b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah# TODO(gauravsh): These are duplicated from chromeos-setimage. We need 10769b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah# to move all signing and rootfs code to one single place where it can be 10869b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah# reused. crosbug.com/19543 10969b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah 11069b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah# get_verity_arg <commandline> <key> -> <value> 11169b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shahget_verity_arg() { 112132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah echo "$1" | sed -n "s/.*\b$2=\([^ \"]*\).*/\1/p" 11369b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah} 11469b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah 11569b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shahis_old_verity_argv() { 11669b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local depth=$(echo "$1" | cut -f7 -d' ') 11769b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah if [ "$depth" = "0" ]; then 11869b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah return 0 11969b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah fi 12069b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah return 1 12169b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah} 12269b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah 123ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah# Get the dmparams parameters from a kernel config. 124ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shahget_dmparams_from_config() { 125ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local kernel_config=$1 12696d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom echo ${kernel_config} | sed -nre 's/.*dm="([^"]*)".*/\1/p' 127ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah} 128c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah# Get the verity root digest hash from a kernel config command line. 129c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shahget_hash_from_config() { 130c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah local kernel_config=$1 131ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local dm_config=$(get_dmparams_from_config "${kernel_config}") 132c8c8dfd90992808a91ce85110218cf1f78fd7f92Paul Taysom local vroot_dev=$(get_dm_slave "${dm_config}" vroot) 13396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom if is_old_verity_argv "${vroot_dev}"; then 13496d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom echo ${vroot_dev} | cut -f9 -d ' ' 135c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah else 13696d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom echo $(get_verity_arg "${vroot_dev}" root_hexdigest) 137c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah fi 138c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah} 139c0911e27b93eae772088ed09d7a41561b7a5b0b6Gaurav Shah 14096d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# Get the slave device and its args 14196d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# get_dm_ags $dm_config [vboot|vroot] 14296d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# Assumes we have only one slave device per device 14396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysomget_dm_slave() { 14496d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local dm=$1 14596d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local device=$2 14696d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom echo $(echo "${dm}" | sed -nre "s/.*${device}[^,]*,([^,]*).*/\1/p") 14796d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom} 14896d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom 14996d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# Set the slave device and its args for a device 15096d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# get_dm_ags $dm_config [vboot|vroot] args 15196d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom# Assumes we have only one slave device per device 15296d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysomset_dm_slave() { 15396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local dm=$1 15496d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local device=$2 15596d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local slave=$3 15696d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom echo $(echo "${dm}" | 157f5c62bd7dc1ef3d76d6e5f9119ad73ec95a926d7Paul Taysom sed -nre "s#(.*${device}[^,]*,)([^,]*)(.*)#\1${slave}\3#p") 15896d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom} 15996d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom 160ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav ShahCALCULATED_KERNEL_CONFIG= 1611cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Calculate rootfs hash of an image 1621cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Args: ROOTFS_IMAGE KERNEL_CONFIG HASH_IMAGE 1631cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# 1641cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# rootfs calculation parameters are grabbed from KERNEL_CONFIG 1651cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# 166ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah# Updated kernel config command line with the new hash is stored in 167ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah# $CALCULATED_KERNEL_CONFIG and the new hash image is written to the file 168ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah# HASH_IMAGE. 1691cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahcalculate_rootfs_hash() { 1701cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local rootfs_image=$1 1711cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local kernel_config=$2 1721cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local hash_image=$3 173ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local dm_config=$(get_dmparams_from_config "${kernel_config}") 1740c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 17533c44fc14f6981601d0f0743d0705587d5f11c56Gaurav Shah if [ -z "${dm_config}" ]; then 176ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "WARNING: Couldn't grab dm_config. Aborting rootfs hash calculation." 177ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah return 1 1780c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah fi 17996d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local vroot_dev=$(get_dm_slave "${dm_config}" vroot) 18069b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah 18169b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local rootfs_sectors 18269b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local verity_depth 18369b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local verity_algorithm 18469b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local root_dev 18569b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah local hash_dev 186132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah local verity_bin="verity" 18796d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom if is_old_verity_argv "${vroot_dev}"; then 18869b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah # dm="0 2097152 verity ROOT_DEV HASH_DEV 2097152 1 \ 18969b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah # sha1 63b7ad16cb9db4b70b28593f825aa6b7825fdcf2" 19096d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom rootfs_sectors=$(echo ${vroot_dev} | cut -f2 -d' ') 19196d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom verity_depth=$(echo ${vroot_dev} | cut -f7 -d' ') 19296d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom verity_algorithm=$(echo ${vroot_dev} | cut -f8 -d' ') 19396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom root_dev=$(echo ${vroot_dev} | cut -f4 -d ' ') 19496d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom hash_dev=$(echo ${vroot_dev} | cut -f5 -d ' ') 195132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah # Hack around the fact that the signer needs to use the old version of 196132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah # verity to generate legacy verity kernel parameters. If we find it, 197132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah # we use it. 198132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah type -P "verity-old" &>/dev/null && verity_bin="verity-old" 19969b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah else 20069b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah # Key-value parameters. 20196d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom rootfs_sectors=$(get_verity_arg "${vroot_dev}" hashstart) 20269b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah verity_depth=0 20396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom verity_algorithm=$(get_verity_arg "${vroot_dev}" alg) 20496d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom root_dev=$(get_verity_arg "${vroot_dev}" payload) 20596d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom hash_dev=$(get_verity_arg "${vroot_dev}" hashtree) 20696d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom salt=$(get_verity_arg "${vroot_dev}" salt) 207132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah fi 208132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah 209132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah local salt_arg 210132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah if [ -n "$salt" ]; then 211132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah salt_arg="salt=$salt" 21269b88dc99b0c3ed12ad66f8df7b65ecc3682204fGaurav Shah fi 2130c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 2141cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # Run the verity tool on the rootfs partition. 21596d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local slave=$(sudo ${verity_bin} mode=create \ 216cba0e83d91b33c3ef9c71fc7dc24c1370e7f3e9aGaurav Shah alg=${verity_algorithm} \ 217cba0e83d91b33c3ef9c71fc7dc24c1370e7f3e9aGaurav Shah payload="${rootfs_image}" \ 218cba0e83d91b33c3ef9c71fc7dc24c1370e7f3e9aGaurav Shah payload_blocks=$((rootfs_sectors / 8)) \ 219132e6e0c8cfa49a470199374e2331e3bb2ea21d6Gaurav Shah hashtree="${hash_image}" ${salt_arg}) 2200c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah # Reconstruct new kernel config command line and replace placeholders. 22196d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom slave="$(echo "${slave}" | 2220c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")" 22396d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom local dm_args=$(set_dm_slave "${dm_config}" vroot "${slave}") 224ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah CALCULATED_KERNEL_CONFIG=$(echo ${kernel_config} | 22596d16de52ebb6785f7d34dcecc030d1b4e3f9c09Paul Taysom sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${dm_args}\3#g") 2261cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah} 2271cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 2281cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Re-calculate rootfs hash, update rootfs and kernel command line. 229d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah# Args: IMAGE KEYBLOCK PRIVATEKEY KERNELPART 2301cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahupdate_rootfs_hash() { 2311cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local image=$1 # Input image. 2321cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local keyblock=$2 # Keyblock for re-generating signed kernel partition 2331cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local signprivate=$3 # Private key to use for signing. 234d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah local kernelpart=$4 # Kernel partition number to update (usually 2 or 4) 235d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 2368ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah echo "Updating rootfs hash and updating config for Kernel partition" \ 237d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah "$kernelpart" 2381cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 239ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # If we can't find dm parameters in the kernel config, bail out now. 240ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local kernel_config=$(grab_kernel_config "${image}" ${kernelpart}) 241ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local dm_config=$(get_dmparams_from_config "${kernel_config}") 242ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah if [ -z "${dm_config}" ]; then 243ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "WARNING: Couldn't grab dm_config from kernel partition ${kernelpart}" 244ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "WARNING: Not performing rootfs hash update!" 245ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah return 246ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah fi 247ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah 24804c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin # check and clear need_to_resign tag 24904c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin local rootfs_dir=$(make_temp_dir) 25004c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin mount_image_partition_ro "${image}" 3 "${rootfs_dir}" 25104c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin if has_needs_to_be_resigned_tag "${rootfs_dir}"; then 25204c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin # remount as RW 253d170a9d542dd4770c25d5ed82429a55391d88218Gaurav Shah sudo umount "${rootfs_dir}" 25404c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin mount_image_partition "${image}" 3 "${rootfs_dir}" 25504c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin sudo rm -f "${rootfs_dir}/${TAG_NEEDS_TO_BE_SIGNED}" 25604c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin fi 257d170a9d542dd4770c25d5ed82429a55391d88218Gaurav Shah sudo umount "${rootfs_dir}" 25804c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin 2591cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local rootfs_image=$(make_temp_file) 2601cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah extract_image_partition ${image} 3 ${rootfs_image} 2611cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local hash_image=$(make_temp_file) 2621cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 263aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry # Disable rw mount support prior to hashing. 264aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry disable_rw_mount "${rootfs_image}" 265aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry 266ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah if ! calculate_rootfs_hash "${rootfs_image}" "${kernel_config}" \ 267ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah "${hash_image}"; then 268ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "calculate_rootfs_hash failed!" 269ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "Aborting rootfs hash update!" 270ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah return 271ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah fi 272ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah 273ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local new_kernel_config=$CALCULATED_KERNEL_CONFIG 274d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah echo "New config for kernel partition $kernelpart is:" 275d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah echo $new_kernel_config 2766bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah echo 2771cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 2781a2e6fc765a13b636d3dd75dc7cae709e9e8d218Gaurav Shah local rootfs_blocks=$(sudo dumpe2fs "${rootfs_image}" 2> /dev/null | 2791cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah grep "Block count" | 2801cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah tr -d ' ' | 2811cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah cut -f2 -d:) 2821cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local rootfs_sectors=$((rootfs_blocks * 8)) 2830c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 2840c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah # Overwrite the appended hashes in the rootfs 2850c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah local temp_config=$(make_temp_file) 2861cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo ${new_kernel_config} >${temp_config} 2871cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah dd if=${hash_image} of=${rootfs_image} bs=512 \ 2886bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah seek=${rootfs_sectors} conv=notrunc 2>/dev/null 2890c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 2901cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local temp_kimage=$(make_temp_file) 291d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah extract_image_partition ${image} ${kernelpart} ${temp_kimage} 2920c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah # Re-calculate kernel partition signature and command line. 2930c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah local updated_kimage=$(make_temp_file) 2940c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah vbutil_kernel --repack ${updated_kimage} \ 2950c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah --keyblock ${keyblock} \ 2960c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah --signprivate ${signprivate} \ 2978ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah --version "${KERNEL_VERSION}" \ 2980c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah --oldblob ${temp_kimage} \ 2990c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah --config ${temp_config} 30033c44fc14f6981601d0f0743d0705587d5f11c56Gaurav Shah 301d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah replace_image_partition ${image} ${kernelpart} ${updated_kimage} 3021cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah replace_image_partition ${image} 3 ${rootfs_image} 3030c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah} 3040c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 3055f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah# Do a sanity check on the image's rootfs 3065f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah# ARGS: Image 3075f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shahverify_image_rootfs() { 3085f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah local image=$1 3095f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah local rootfs_image=$(make_temp_file) 3105f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah extract_image_partition ${image} 3 ${rootfs_image} 3115f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah # This flips the read-only compatibility flag, so that e2fsck does not 3125f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah # complain about unknown file system capabilities. 3135f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah enable_rw_mount ${rootfs_image} 3145f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah echo "Running e2fsck to check root file system for errors" 3155f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah sudo e2fsck -fn "${rootfs_image}" || 3165f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah { echo "Root file system has errors!" && exit 1;} 3175f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah} 3188ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah 3199137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# Extracts a firmware updater bundle (for firmware image binaries) file 3209137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# (generated by src/platform/firmware/pack_firmware.sh). 3219137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# Args: INPUT_FILE OUTPUT_DIR 3229137e8df481906c7de15d92f639a6129adedd892Hung-Te Linextract_firmware_bundle() { 3239137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local input="$(readlink -f "$1")" 3249137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local output_dir="$2" 3259137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin if [ ! -s "${input}" ]; then 3269137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin return 1 3279137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin elif grep -q '^##CUTHERE##' "${input}"; then 3289137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Bundle supports self-extraction. 3299137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin "$input" --sb_extract "${output_dir}" || 3309137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin die "Extracting firmware autoupdate (--sb_extract) failed." 33171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah else 3329137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Legacy bundle - try uudecode. 3339137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin uudecode -o - ${input} | tar -C ${output_dir} -zxf - 2>/dev/null || 3349137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin die "Extracting firmware autoupdate failed." 3359137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin fi 3369137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin} 3379137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin 3389137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# Repacks firmware updater bundle content from given folder. 3399137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin# Args: INPUT_DIR TARGET_SCRIPT 3409137e8df481906c7de15d92f639a6129adedd892Hung-Te Linrepack_firmware_bundle() { 3419137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local input_dir="$1" 3429137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local target="$(readlink -f "$2")" 3439137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin 3449137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin if [ ! -s "${target}" ]; then 34571bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah return 1 3469137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin elif grep -q '^##CUTHERE##' "${target}"; then 3479137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Bundle supports repacking. 3489137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin "$target" --sb_repack "${input_dir}" || 3499137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin die "Updating firmware autoupdate (--sb_repack) failed." 3509137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin else 3519137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Legacy bundle using uuencode + tar.gz. 3529137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Replace MD5 checksum in the firmware update payload. 3539137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local newfd_checksum="$(md5sum ${input_dir}/bios.bin | cut -f 1 -d ' ')" 3549137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local temp_version="$(make_temp_file)" 3559137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin cat ${input_dir}/VERSION | 3569137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin sed -e "s#\(.*\)\ \(.*bios.bin.*\)#${newfd_checksum}\ \2#" > ${temp_version} 3579137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin mv ${temp_version} ${input_dir}/VERSION 3589137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin 3599137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Re-generate firmware_update.tgz and copy over encoded archive in 3609137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # the original shell ball. 3619137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin sed -ine '/^begin .*firmware_package/,/end/D' "$target" 3629137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin tar zcf - -C "${input_dir}" . | 3639137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin uuencode firmware_package.tgz >>"${target}" 36471bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah fi 3650c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah} 3660c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 3679c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah# Sign a firmware in-place with the given keys. 368aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger# Args: FIRMWARE_IMAGE KEY_DIR FIRMWARE_VERSION [LOEM_OUTPUT_DIR] 3699c783ce3c132491e28efe84751b20d82fc571560Gaurav Shahsign_firmware() { 3709c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah local image=$1 3719c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah local key_dir=$2 3729c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah local firmware_version=$3 373aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger local loem_output_dir=${4:-} 3749c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah 3759c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah local temp_firmware=$(make_temp_file) 3769c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah # Resign the firmware with new keys, also replacing the root and recovery 3779c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah # public keys in the GBB. 378aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger "${SCRIPT_DIR}/sign_firmware.sh" "${image}" "${key_dir}" "${temp_firmware}" \ 379aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger "${firmware_version}" "${loem_output_dir}" 3809c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah # Note: Although sign_firmware.sh may correctly handle specifying the same 3819c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah # output file as the input file, we do not want to rely on it correctly 3829c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah # handing that. Hence, the use of a temporary file. 3839c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah mv ${temp_firmware} ${image} 3849c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah echo "Signed firmware image output to ${image}" 3859c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah} 3869c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah 387283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger# Sign a delta update payload (usually created by paygen). 388283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger# Args: INPUT_IMAGE KEY_DIR OUTPUT_IMAGE 389283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysingersign_update_payload() { 390283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger local image=$1 391283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger local key_dir=$2 392283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger local output=$3 393283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger local key_size key_file="${key_dir}/update_key.pem" 394283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger local algo algos=( 395283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger # Maps key size to verified boot's algorithm id (for pad_digest_utility). 396283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger # Hashing algorithm is always SHA-256. 397283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger [1024]=1 398283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger [2048]=4 399283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger [4096]=7 400283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger [8192]=10 401283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger ) 402283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger 403283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger key_size=$(openssl rsa -text -noout -in "${key_file}" | \ 404283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger sed -n -r '1{s/Private-Key: \(([0-9]*) bit\)/\1/p}') 405283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger algo=${algos[${key_size}]} 406283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger if [[ -z ${algo} ]]; then 407283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger die "Unknown algorithm specified by key_size=${key_size}" 408283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger fi 409283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger 410283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger pad_digest_utility ${algo} "${image}" | \ 411283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger openssl rsautl -sign -pkcs -inkey "${key_file}" -out "${output}" 412283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger} 413283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger 4140c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Re-sign the firmware AU payload inside the image rootfs with a new keys. 4150c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Args: IMAGE 4160c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shahresign_firmware_payload() { 4170c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah local image=$1 4180c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 419815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah if [ -n "${NO_FWUPDATE}" ]; then 420815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah echo "Skipping firmware update." 421815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah return 422815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah fi 423815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah 4249137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # Grab firmware image from the autoupdate bundle (shellball). 4250c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah local rootfs_dir=$(make_temp_dir) 4260c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah mount_image_partition ${image} 3 ${rootfs_dir} 42714805f555173cf430902ab415cef9d0d83182578Gaurav Shah # Force unmount of the rootfs on function exit as it is needed later. 428d170a9d542dd4770c25d5ed82429a55391d88218Gaurav Shah trap "sudo umount ${rootfs_dir}" RETURN 4299137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local firmware_bundle="${rootfs_dir}/usr/sbin/chromeos-firmwareupdate" 4300c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah local shellball_dir=$(make_temp_dir) 4319137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin 4329137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin # extract_firmware_bundle can fail if the image has no firmware update. 4339137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin extract_firmware_bundle "${firmware_bundle}" "${shellball_dir}" || 43471bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah { echo "Didn't find a firmware update. Not signing firmware." 43571bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah return; } 43671bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah echo "Found a valid firmware update shellball." 4370c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 438aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger local image_file sign_args=() loem_sfx loem_output_dir 439ca8c372e60d249cc49ecaf1d33ace2d53caadfaeHung-Te Lin for image_file in "${shellball_dir}"/bios*.bin; do 440aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger if [[ -e "${KEY_DIR}/loem.ini" ]]; then 441aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger # Extract the extended details from "bios.bin" and use that in the 442aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger # subdir for the keyset. 443aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger loem_sfx=$(sed -r 's:.*/bios([^/]*)[.]bin$:\1:' <<<"${image_file}") 444aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger loem_output_dir="${shellball_dir}/keyset${loem_sfx}" 445aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger sign_args=( "${loem_output_dir}" ) 446aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger mkdir -p "${loem_output_dir}" 447aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger fi 448aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger sign_firmware "${image_file}" "${KEY_DIR}" "${FIRMWARE_VERSION}" \ 449aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger "${sign_args[@]}" 450ca8c372e60d249cc49ecaf1d33ace2d53caadfaeHung-Te Lin done 45142d23c664dbd1334c82b48b504b7d8499955963dGaurav Shah 4529137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin local signer_notes="${shellball_dir}/VERSION.signer" 4539137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin echo "" >"$signer_notes" 4549137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin echo "Signed with keyset in $(readlink -f "${KEY_DIR}") ." >>"$signer_notes" 4550c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah 4560c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah new_shellball=$(make_temp_file) 4579137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin cp -f "${firmware_bundle}" "${new_shellball}" 458bd3dad01b0c2d934462d70eeabb31abcd0310b3fHung-Te Lin chmod a+rx "${new_shellball}" 4599137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin repack_firmware_bundle "${shellball_dir}" "${new_shellball}" 4609137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin sudo cp -f "${new_shellball}" "${firmware_bundle}" 4619137e8df481906c7de15d92f639a6129adedd892Hung-Te Lin sudo chmod a+rx "${firmware_bundle}" 4620c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah echo "Re-signed firmware AU payload in $image" 4630c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah} 46437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 4651cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Verify an image including rootfs hash using the specified keys. 4661cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahverify_image() { 4671cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local rootfs_image=$(make_temp_file) 4681cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah extract_image_partition ${INPUT_IMAGE} 3 ${rootfs_image} 4691cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 4701cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "Verifying RootFS hash..." 471ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # What we get from image. 472ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local kernel_config 473ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # What we calculate from the rootfs. 474ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local new_kernel_config 475ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # Depending on the type of image, the verity parameters may 476ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # exist in either kernel partition 2 or kernel partition 4 477ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local partnum 478ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah for partnum in 2 4; do 479ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "Considering Kernel partition $partnum" 480ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah kernel_config=$(grab_kernel_config ${INPUT_IMAGE} $partnum) 481ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah local hash_image=$(make_temp_file) 482ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah if ! calculate_rootfs_hash "${rootfs_image}" "${kernel_config}" \ 483ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah "${hash_image}"; then 484ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "Trying next kernel partition." 485ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah continue 486ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah fi 487ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah new_kernel_config="$CALCULATED_KERNEL_CONFIG" 488ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah break 489ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah done 490ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah 491ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # Note: If calculate_rootfs_hash succeeded above, these should 492ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah # be non-empty. 493ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah expected_hash=$(get_hash_from_config "${new_kernel_config}") 494ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah got_hash=$(get_hash_from_config "${kernel_config}") 495ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah 496ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah if [ -z "${expected_hash}" ] || [ -z "${got_hash}" ]; then 497ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah echo "FAILURE: Couldn't verify RootFS hash on the image." 498c3fe59f72c95597a2d5becc8511e9d5eaf97c391Gaurav Shah exit 1 499c3fe59f72c95597a2d5becc8511e9d5eaf97c391Gaurav Shah fi 500ce6649250583a8f3a7aeac78ee3a00679cf6223dGaurav Shah 5011cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah if [ ! "${got_hash}" = "${expected_hash}" ]; then 5021cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah cat <<EOF 5031cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahFAILED: RootFS hash is incorrect. 5041cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahExpected: ${expected_hash} 5051cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahGot: ${got_hash} 5061cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahEOF 507c3fe59f72c95597a2d5becc8511e9d5eaf97c391Gaurav Shah exit 1 5081cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah else 5091cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "PASS: RootFS hash is correct (${expected_hash})" 5101cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah fi 5111cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 5121cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # Now try and verify kernel partition signature. 5131cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah set +e 5141cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah local try_key=${KEY_DIR}/recovery_key.vbpubk 5151cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "Testing key verification..." 5161cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # The recovery key is only used in the recovery mode. 5171cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo -n "With Recovery Key (Recovery Mode ON, Dev Mode OFF): " && \ 5181cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 2 >/dev/null 2>&1 && \ 5191cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "YES"; } || echo "NO" 5201cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo -n "With Recovery Key (Recovery Mode ON, Dev Mode ON): " && \ 5211cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 3 >/dev/null 2>&1 && \ 5221cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "YES"; } || echo "NO" 5231cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 5241cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah try_key=${KEY_DIR}/kernel_subkey.vbpubk 5251cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # The SSD key is only used in non-recovery mode. 5261cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo -n "With SSD Key (Recovery Mode OFF, Dev Mode OFF): " && \ 5271cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 0 >/dev/null 2>&1 && \ 5281cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "YES"; } || echo "NO" 5291cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo -n "With SSD Key (Recovery Mode OFF, Dev Mode ON): " && \ 5301cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 1 >/dev/null 2>&1 && \ 5311cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah echo "YES"; } || echo "NO" 5321cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah set -e 5331cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 5345f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah verify_image_rootfs "${INPUT_IMAGE}" 5355f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah 5361cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah # TODO(gauravsh): Check embedded firmware AU signatures. 5371cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah} 5381cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 539276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Sign the kernel partition on an image using the given keys. Modifications are 540276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# made in-place. 541276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Args: src_bin kernel_datakey kernel_keyblock kernel_version 542276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shahsign_image_inplace() { 543276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah src_bin=$1 544276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah kernel_datakey=$2 545276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah kernel_keyblock=$3 546276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah kernel_version=$4 547276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah 548276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah temp_kimage=$(make_temp_file) 549276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah extract_image_partition ${src_bin} 2 ${temp_kimage} 550276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah updated_kimage=$(make_temp_file) 551276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah 552276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah vbutil_kernel --repack "${updated_kimage}" \ 553276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah --keyblock "${kernel_keyblock}" \ 554276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah --signprivate "${kernel_datakey}" \ 555276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah --version "${kernel_version}" \ 556276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah --oldblob "${temp_kimage}" 557276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah replace_image_partition ${src_bin} 2 ${updated_kimage} 558276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah} 559276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah 56037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the SSD image 561276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Args: image_bin 56237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_ssd() { 563276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah image_bin=$1 564276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_image_inplace ${image_bin} ${KEY_DIR}/kernel_data_key.vbprivk \ 5658ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah ${KEY_DIR}/kernel.keyblock \ 5668ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah "${KERNEL_VERSION}" 567276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah echo "Signed SSD image output to ${image_bin}" 56837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah} 56937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 57064bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson# Generate the USB image (direct boot) 57164bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardsonsign_for_usb() { 572276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah image_bin=$1 573276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_image_inplace ${image_bin} ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 5748ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah ${KEY_DIR}/recovery_kernel.keyblock \ 5758ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah "${KERNEL_VERSION}" 5764b86514d8581315fafc196d47d4412677f193750Bill Richardson 5774b86514d8581315fafc196d47d4412677f193750Bill Richardson # Now generate the installer vblock with the SSD keys. 5784b86514d8581315fafc196d47d4412677f193750Bill Richardson # The installer vblock is for KERN-A on direct boot images. 5794b86514d8581315fafc196d47d4412677f193750Bill Richardson temp_kimagea=$(make_temp_file) 5804b86514d8581315fafc196d47d4412677f193750Bill Richardson temp_out_vb=$(make_temp_file) 581276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah extract_image_partition ${image_bin} 2 ${temp_kimagea} 5824b86514d8581315fafc196d47d4412677f193750Bill Richardson ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimagea} ${temp_out_vb} \ 5834b86514d8581315fafc196d47d4412677f193750Bill Richardson ${KEY_DIR}/kernel_data_key.vbprivk \ 5848ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah ${KEY_DIR}/kernel.keyblock \ 5858ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah "${KERNEL_VERSION}" 5864b86514d8581315fafc196d47d4412677f193750Bill Richardson 5874b86514d8581315fafc196d47d4412677f193750Bill Richardson # Copy the installer vblock to the stateful partition. 5884b86514d8581315fafc196d47d4412677f193750Bill Richardson local stateful_dir=$(make_temp_dir) 589276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah mount_image_partition ${image_bin} 1 ${stateful_dir} 5904b86514d8581315fafc196d47d4412677f193750Bill Richardson sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock 5914b86514d8581315fafc196d47d4412677f193750Bill Richardson 592276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah echo "Signed USB image output to ${image_bin}" 59364bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson} 59464bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson 59537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the USB (recovery + install) image 596276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Args: image_bin 59737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_recovery() { 598276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah image_bin=$1 5996bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah 6006bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # Sign the install kernel with SSD keys. 6016bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local temp_kimageb=$(make_temp_file) 602276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah extract_image_partition ${image_bin} 4 ${temp_kimageb} 6036bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local updated_kimageb=$(make_temp_file) 6046bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah vbutil_kernel --repack ${updated_kimageb} \ 6056bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah --keyblock ${KEY_DIR}/kernel.keyblock \ 6066bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah --signprivate ${KEY_DIR}/kernel_data_key.vbprivk \ 6076bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah --version "${KERNEL_VERSION}" \ 6086bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah --oldblob ${temp_kimageb} 6096bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah 6106bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah replace_image_partition ${image_bin} 4 ${updated_kimageb} 6116bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah 6126bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # Copy the SSD kernel vblock to the stateful partition. 6136bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # TODO(gauravsh): Get rid of this once --skip_vblock is nuked from 6146bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # orbit everywhere. crosbug.com/8378 6156bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local temp_out_vb=$(make_temp_file) 6166bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimageb} ${temp_out_vb} \ 6176bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah ${KEY_DIR}/kernel_data_key.vbprivk \ 6186bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah ${KEY_DIR}/kernel.keyblock \ 6196bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah "${KERNEL_VERSION}" 6206bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local stateful_dir=$(make_temp_dir) 6216bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah mount_image_partition ${image_bin} 1 ${stateful_dir} 6226bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock 623d170a9d542dd4770c25d5ed82429a55391d88218Gaurav Shah sudo umount "${stateful_dir}" 624d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 6256bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # Update the Kernel B hash in Kernel A command line 6266bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local old_kerna_config=$(grab_kernel_config "${image_bin}" 2) 6276bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local new_kernb=$(make_temp_file) 6286bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # Can't use updated_kimageb since the hash is calculated on the 6296bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah # whole partition including the null padding at the end. 6306bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah extract_image_partition ${image_bin} 4 ${new_kernb} 6316bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah local new_kernb_hash=$(sha1sum ${new_kernb} | cut -f1 -d' ') 6326bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah 6336bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah new_kerna_config=$(make_temp_file) 6346bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah echo "$old_kerna_config" | 6356bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah sed -e "s#\(kern_b_hash=\)[a-z0-9]*#\1${new_kernb_hash}#" \ 6366bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah > ${new_kerna_config} 637d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah echo "New config for kernel partition 2 is" 6386bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah cat ${new_kerna_config} 639d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 640d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah local temp_kimagea=$(make_temp_file) 641276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah extract_image_partition ${image_bin} 2 ${temp_kimagea} 6426bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah 643d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah # Re-calculate kernel partition signature and command line. 644d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah local updated_kimagea=$(make_temp_file) 645d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah vbutil_kernel --repack ${updated_kimagea} \ 646d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah --keyblock ${KEY_DIR}/recovery_kernel.keyblock \ 647d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah --signprivate ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 6488ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah --version "${KERNEL_VERSION}" \ 649d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah --oldblob ${temp_kimagea} \ 6506bd03d4a88fa049bd72cf18fec701cec1dfc042bGaurav Shah --config ${new_kerna_config} 6518ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah 652276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah replace_image_partition ${image_bin} 2 ${updated_kimagea} 653276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah echo "Signed recovery image output to ${image_bin}" 65437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah} 65537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 65637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the factory install image. 657276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Args: image_bin 65837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_factory_install() { 659276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah image_bin=$1 660276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_image_inplace ${image_bin} ${KEY_DIR}/installer_kernel_data_key.vbprivk \ 6618ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah ${KEY_DIR}/installer_kernel.keyblock \ 6628ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah "${KERNEL_VERSION}" 663276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah echo "Signed factory install image output to ${image_bin}" 66437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah} 66537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah 6661cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Verification 667b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysingercase ${TYPE} in 668b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysingerdump_config) 669b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger check_argc $# 2 670b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger for partnum in 2 4; do 671b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger echo "kernel config in partition number ${partnum}:" 672b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger grab_kernel_config "${INPUT_IMAGE}" ${partnum} 673b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger echo 674b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger done 675b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger exit 0 676b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger ;; 677b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysingerverify) 678b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger check_argc $# 2 6791cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah verify_image 680527612e3565be00030a082c262204a0562bc0d4aGaurav Shah exit 0 681b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger ;; 682b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger*) 683b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger # All other signing commands take 4 to 5 args. 684b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger if [ -z "${OUTPUT_IMAGE}" ]; then 685b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger # Friendlier message. 686b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger usage "Missing output image name" 687b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger fi 688b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger check_argc $# 4 5 689b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysinger ;; 690b55c538fca8939e58d20c127a9f42ce4eba7282cMike Frysingeresac 6911cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah 6928ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah# If a version file was specified, read the firmware and kernel 6938ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah# versions from there. 6948ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahif [ -n "${VERSION_FILE}" ]; then 6958ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah FIRMWARE_VERSION=$(sed -n 's#^firmware_version=\(.*\)#\1#pg' ${VERSION_FILE}) 6968ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shah KERNEL_VERSION=$(sed -n 's#^kernel_version=\(.*\)#\1#pg' ${VERSION_FILE}) 6978ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahfi 6988ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahecho "Using firmware version: ${FIRMWARE_VERSION}" 6998ae7b0e41a1252f98e6662a298efb97624431c44Gaurav Shahecho "Using kernel version: ${KERNEL_VERSION}" 70071bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah 701276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah# Make all modifications on output copy. 70237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahif [ "${TYPE}" == "ssd" ]; then 703276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah cp ${INPUT_IMAGE} ${OUTPUT_IMAGE} 704276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah resign_firmware_payload ${OUTPUT_IMAGE} 7057a3a4676672525231c38612e6c8a820305d99de5Don Garrett "${SCRIPT_DIR}/strip_boot_from_image.sh" --image "${OUTPUT_IMAGE}" 706276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah update_rootfs_hash ${OUTPUT_IMAGE} \ 7070c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah ${KEY_DIR}/kernel.keyblock \ 708d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah ${KEY_DIR}/kernel_data_key.vbprivk \ 709d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 2 710276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_for_ssd ${OUTPUT_IMAGE} 71164bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardsonelif [ "${TYPE}" == "usb" ]; then 712276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah cp ${INPUT_IMAGE} ${OUTPUT_IMAGE} 713276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah resign_firmware_payload ${OUTPUT_IMAGE} 7147a3a4676672525231c38612e6c8a820305d99de5Don Garrett "${SCRIPT_DIR}/strip_boot_from_image.sh" --image "${OUTPUT_IMAGE}" 715276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah update_rootfs_hash ${OUTPUT_IMAGE} \ 71664bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson ${KEY_DIR}/recovery_kernel.keyblock \ 71764bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 71864bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson 2 719276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_for_usb ${OUTPUT_IMAGE} 72037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahelif [ "${TYPE}" == "recovery" ]; then 721276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah cp ${INPUT_IMAGE} ${OUTPUT_IMAGE} 722276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah resign_firmware_payload ${OUTPUT_IMAGE} 7237a3a4676672525231c38612e6c8a820305d99de5Don Garrett "${SCRIPT_DIR}/strip_boot_from_image.sh" --image "${OUTPUT_IMAGE}" 724d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah # Both kernel command lines must have the correct rootfs hash 725276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah update_rootfs_hash ${OUTPUT_IMAGE} \ 726d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah ${KEY_DIR}/recovery_kernel.keyblock \ 727d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 728d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 4 729276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah update_rootfs_hash ${OUTPUT_IMAGE} \ 7300c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah ${KEY_DIR}/recovery_kernel.keyblock \ 731d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ 732d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 2 733276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_for_recovery ${OUTPUT_IMAGE} 73422bd8b0c29b485ccdaa4f63e6fdac9f097b60aabMike Frysingerelif [ "${TYPE}" == "factory" ] || [ "${TYPE}" == "install" ]; then 735276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah cp ${INPUT_IMAGE} ${OUTPUT_IMAGE} 736276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah resign_firmware_payload ${OUTPUT_IMAGE} 7377a3a4676672525231c38612e6c8a820305d99de5Don Garrett # We do NOT strip /boot for factory, since some factory images need it 7387a3a4676672525231c38612e6c8a820305d99de5Don Garrett # to boot EFI. crosbug.com/260512 would obsolete this requirement. 739276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah update_rootfs_hash ${OUTPUT_IMAGE} \ 7400c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah ${KEY_DIR}/installer_kernel.keyblock \ 741baa09de3a426936de697895b95641254ebf2c01fGaurav Shah ${KEY_DIR}/installer_kernel_data_key.vbprivk \ 742d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah 2 743276f846a142a3c2c7c2c575d4403c71eca18a92aGaurav Shah sign_for_factory_install ${OUTPUT_IMAGE} 7449c783ce3c132491e28efe84751b20d82fc571560Gaurav Shahelif [ "${TYPE}" == "firmware" ]; then 745aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger if [[ -e "${KEY_DIR}/loem.ini" ]]; then 746aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger echo "LOEM signing not implemented yet for firmware images" 747aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger exit 1 748aa888463b860c2852f3fcb17baf8de395fcca294Mike Frysinger fi 7499c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah cp ${INPUT_IMAGE} ${OUTPUT_IMAGE} 7509c783ce3c132491e28efe84751b20d82fc571560Gaurav Shah sign_firmware ${OUTPUT_IMAGE} ${KEY_DIR} ${FIRMWARE_VERSION} 751283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysingerelif [ "${TYPE}" == "update_payload" ]; then 752283cbf89a9893f3a024809eb7d6c84ed353df6b4Mike Frysinger sign_update_payload ${INPUT_IMAGE} ${KEY_DIR} ${OUTPUT_IMAGE} 75337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahelse 75437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah echo "Invalid type ${TYPE}" 75537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah exit 1 75637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahfi 757