diff options
author | Dave Heller <hellerda@us.ibm.com> | 2017-08-29 14:43:39 -0400 |
---|---|---|
committer | Dave Heller <hellerda@us.ibm.com> | 2017-08-29 14:43:39 -0400 |
commit | 2b37ee3213f6cf9baa093b281de711bbcb55b236 (patch) | |
tree | 7ebeef9b8698a9821b4dd7e257442f9fc712adb2 /crtSignedContainer.sh | |
parent | e807aeee19556974c5041aa862eac70c49a14b8f (diff) | |
download | sb-signing-utils-2b37ee3213f6cf9baa093b281de711bbcb55b236.tar.gz sb-signing-utils-2b37ee3213f6cf9baa093b281de711bbcb55b236.zip |
Add basic support for Production mode in op-build
Signed-off-by: Dave Heller <hellerda@us.ibm.com>
Diffstat (limited to 'crtSignedContainer.sh')
-rwxr-xr-x | crtSignedContainer.sh | 309 |
1 files changed, 231 insertions, 78 deletions
diff --git a/crtSignedContainer.sh b/crtSignedContainer.sh index 00cd180..18b8321 100755 --- a/crtSignedContainer.sh +++ b/crtSignedContainer.sh @@ -1,13 +1,24 @@ #!/bin/bash # Script to create a signed container. Intended for op-build integration. +# Defaults, initial values +P=${0##*/} +MODE=local +PASS_ON_ERR=N + +HW_KEY_ARGS="" +SW_KEY_ARGS="" +HW_SIG_ARGS="" +SW_SIG_ARGS="" +VERIFY_ARGS="" +DEBUG_ARGS="" +ADDL_ARGS="" + VERBOSE="" DEBUG="" WRAP="" RC=0 -P=${0##*/} - # Functions usage () { echo "" @@ -26,6 +37,7 @@ usage () { echo " -i, --out file to write containerized payload" echo " -o, --code-start-offset code start offset for software header in hex" echo " -f, --flags prefix header flags in hex" + echo " -m, --mode signing mode: local, independent or production" echo " -L, --label name or identifier of the module being built (8 char max)" echo " --validate validate the container after build" echo " --verify verify the container after build, against the provided" @@ -47,6 +59,15 @@ is_public_key () { openssl ec -pubin -pubout -in $1 &>/dev/null } +is_raw_key () { + test $(stat -c%s "$K") -eq 133 -a \ + $(dd if="$K" bs=1 count=1 2>/dev/null | xxd -p) == "04" +} + +to_upper () { + echo $1 | tr a-z A-Z +} + checkKey () { # The variable name KEY_NAME=$1 @@ -56,10 +77,13 @@ checkKey () { PUBKEYS=0 if [ -n "$K" ]; then - if [ -f $K ]; then - if is_private_key $K; then + if [ -f "$K" ]; then + if is_private_key "$K"; then + KEYS=1 + elif is_public_key "$K"; then KEYS=1 - elif is_public_key $K; then + PUBKEYS=1 + elif is_raw_key "$K"; then KEYS=1 PUBKEYS=1 else @@ -100,6 +124,7 @@ for arg in "$@"; do "--code-start-offset") set -- "$@" "-o" ;; "--protectedPayload") set -- "$@" "-l" ;; "--out") set -- "$@" "-i" ;; + "--mode") set -- "$@" "-m" ;; "--label ") set -- "$@" "-L" ;; "--sign-project-FW-token") set -- "$@" "-L" ;; "--validate") set -- "$@" "-8" ;; @@ -109,7 +134,7 @@ for arg in "$@"; do done # Process command-line arguments -while getopts ?dvw:a:b:c:p:q:r:f:o:l:i:L:89: opt +while getopts ?dvw:a:b:c:p:q:r:f:o:l:i:m:L:89: opt do case "$opt" in v) VERBOSE="TRUE";; @@ -125,6 +150,7 @@ do o) CS_OFFSET="`echo $OPTARG | tr A-Z a-z`";; l) PAYLOAD="`echo $OPTARG`";; i) OUTPUT="`echo $OPTARG`";; + m) MODE="`echo $OPTARG`";; L) LABEL="`echo $OPTARG`";; 8) VALIDATE="TRUE";; 9) VERIFY="`echo $OPTARG`";; @@ -181,30 +207,111 @@ else fi # Set arguments for (program) execution -HW_KEY_ARGS="" -SW_KEY_ARGS="" -HW_SIG_ARGS="" -SW_SIG_ARGS="" -VERIFY_ARGS="" -DEBUG_ARGS="" -ADDL_ARGS="" +test -n "$VERBOSE" && DEBUG_ARGS="$DEBUG_ARGS -v" +test -n "$DEBUG" && DEBUG_ARGS="$DEBUG_ARGS -d" +test -n "$WRAP" && DEBUG_ARGS="$DEBUG_ARGS -w $WRAP" +test -n "$HW_FLAGS" && ADDL_ARGS="$ADDL_ARGS --hw-flags $HW_FLAGS" +test -n "$CS_OFFSET" && ADDL_ARGS="$ADDL_ARGS --sw-cs-offset $CS_OFFSET" +test -n "$LABEL" && ADDL_ARGS="$ADDL_ARGS --label $LABEL" + +# Determine if validate or verify has been requested +test -n "$BR2_CONFIG" && source $BR2_CONFIG &> /dev/null +test -n "$BR2_OPENPOWER_SECUREBOOT_PASS_ON_VALIDATION_ERROR" && PASS_ON_ERR=Y + +if [ -z "$VALIDATE" -a -n "$BR2_OPENPOWER_SECUREBOOT_CONTAINER_VALIDATE" ] +then + VALIDATE="$BR2_OPENPOWER_SECUREBOOT_CONTAINER_VALIDATE" +fi + +if [ -z "$VERIFY" -a -n "$BR2_OPENPOWER_SECUREBOOT_CONTAINER_VERIFY" ] +then + VERIFY="$BR2_OPENPOWER_SECUREBOOT_CONTAINER_VERIFY" +fi -[ -n "$HW_KEY_A" ] && HW_KEY_ARGS="$HW_KEY_ARGS -a $HW_KEY_A" -[ -n "$HW_KEY_B" ] && HW_KEY_ARGS="$HW_KEY_ARGS -b $HW_KEY_B" -[ -n "$HW_KEY_C" ] && HW_KEY_ARGS="$HW_KEY_ARGS -c $HW_KEY_C" -[ -n "$SW_KEY_P" ] && SW_KEY_ARGS="$SW_KEY_ARGS -p $SW_KEY_P" -[ -n "$SW_KEY_Q" ] && SW_KEY_ARGS="$SW_KEY_ARGS -q $SW_KEY_Q" -[ -n "$SW_KEY_R" ] && SW_KEY_ARGS="$SW_KEY_ARGS -r $SW_KEY_R" +test -n "$VALIDATE" && VERIFY_ARGS="$VERIFY_ARGS --validate" +test -n "$VERIFY" && VERIFY_ARGS="$VERIFY_ARGS --verify $VERIFY" -[ -n "$VERBOSE" ] && DEBUG_ARGS="$DEBUG_ARGS -v" -[ -n "$DEBUG" ] && DEBUG_ARGS="$DEBUG_ARGS -d" -[ -n "$WRAP" ] && DEBUG_ARGS="$DEBUG_ARGS -w $WRAP" -[ -n "$HW_FLAGS" ] && ADDL_ARGS="$ADDL_ARGS --hw-flags $HW_FLAGS" -[ -n "$CS_OFFSET" ] && ADDL_ARGS="$ADDL_ARGS --sw-cs-offset $CS_OFFSET" +# Get the public keys +SF_EPWD=/path/to/epwd.txt +SF_SSHKEY=/path/to/id_rsa.sign +SF_USER=sf_user +SF_SERVER=server.mydomain.com -[ -n "$VALIDATE" ] && VERIFY_ARGS="$VERIFY_ARGS --validate" -[ -n "$VERIFY" ] && VERIFY_ARGS="$VERIFY_ARGS --verify $VERIFY" -[ -n "$LABEL" ] && ADDL_ARGS="$ADDL_ARGS --label $LABEL" +if [ "$MODE" == "local" ] +then + # Set args from cmdline params + test -n "$HW_KEY_A" && HW_KEY_ARGS="$HW_KEY_ARGS -a $HW_KEY_A" + test -n "$HW_KEY_B" && HW_KEY_ARGS="$HW_KEY_ARGS -b $HW_KEY_B" + test -n "$HW_KEY_C" && HW_KEY_ARGS="$HW_KEY_ARGS -c $HW_KEY_C" + test -n "$SW_KEY_P" && SW_KEY_ARGS="$SW_KEY_ARGS -p $SW_KEY_P" + test -n "$SW_KEY_Q" && SW_KEY_ARGS="$SW_KEY_ARGS -q $SW_KEY_Q" + test -n "$SW_KEY_R" && SW_KEY_ARGS="$SW_KEY_ARGS -r $SW_KEY_R" + +elif [ "$MODE" == "production" ] +then + SF_PROJECT_BASE=sign_ecc_pwr_hw_key + for KEY in a b c; do + SF_PROJECT=${SF_PROJECT_BASE}_${KEY} + KEYFILE=project.$SF_PROJECT.HW_key_$KEY.raw + + # If no keyfile in the current dir, try to find one. + # If no keyfile found, try to get one. + if [ -f "$T/$KEYFILE" ] + then + echo "--> $P: Found key for HW key $(to_upper $KEY)." + else + KEYFOUND=$(find $TOPDIR -name $KEYFILE | head -1) + + if [ -n "$KEYFOUND" ] + then + echo "--> $P: Found key for HW key $(to_upper $KEY)." + cp -p $KEYFOUND $T/ + else + echo "--> $P: Requesting public key for HW key $(to_upper $KEY)..." + sf_client -stdout -project getpubkeyecc -param "-signproject $SF_PROJECT" \ + -epwd $SF_EPWD -comments "Requesting $SF_PROJECT" \ + -url sftp://$SF_USER@$SF_SERVER -pkey $SF_SSHKEY -o $T/$KEYFILE + # TODO Check return code, fail on error... + echo "--> $P: Retrieved public key for HW key $(to_upper $KEY)." + fi + fi + + # Set args from project files + HW_KEY_ARGS="$HW_KEY_ARGS -$KEY $T/$KEYFILE" + done + + SF_PROJECT_BASE=sign_ecc_pwr_fw_key_op_bld + for KEY in p; do + SF_PROJECT=${SF_PROJECT_BASE}_${KEY} + KEYFILE=project.$SF_PROJECT.SW_key_$KEY.raw + + if [ -f "$T/$KEYFILE" ] + then + echo "--> $P: Found key for SW key $(to_upper $KEY)." + else + KEYFOUND=$(find $TOPDIR -name $KEYFILE | head -1) + + if [ -n "$KEYFOUND" ] + then + echo "--> $P: Found key for SW key $(to_upper $KEY)." + cp -p $KEYFOUND $T/ + else + echo "--> $P: Requesting public key for SW key $(to_upper $KEY)..." + sf_client -stdout -project getpubkeyecc -param "-signproject $SF_PROJECT" \ + -epwd $SF_EPWD -comments "Requesting $SF_PROJECT" \ + -url sftp://$SF_USER@$SF_SERVER -pkey $SF_SSHKEY -o $T/$KEYFILE + # TODO Check return code, fail on error... + echo "--> $P: Retrieved public key for SW key $(to_upper $KEY)." + fi + fi + + SW_KEY_ARGS="$SW_KEY_ARGS -$KEY $T/$KEYFILE" + done + +elif [ -n "$MODE" ] +then + die "Unsupported mode: $MODE" +fi # Build enough of the container to create the Prefix and Software headers echo "--> $P: Generating signing requests..." @@ -214,64 +321,110 @@ create-container $HW_KEY_ARGS $SW_KEY_ARGS \ $DEBUG_ARGS \ $ADDL_ARGS -# Sign the Prefix header (all 3 HW keys are required) -if [ "$HW_KEY_COUNT" -eq "3" -a "$HW_KEY_PUBKEY_COUNT" -eq "0" ] -then - echo "--> $P: Executing signing request for HW keys A,B,C..." - openssl dgst -SHA512 -sign $HW_KEY_A $T/prefix_hdr > $T/hw_key_a.sig - openssl dgst -SHA512 -sign $HW_KEY_B $T/prefix_hdr > $T/hw_key_b.sig - openssl dgst -SHA512 -sign $HW_KEY_C $T/prefix_hdr > $T/hw_key_c.sig -fi +# Prepare the HW and SW key signatures +FOUND="" -# Sign the Software header (at least one SW key is required) -if [ "$SW_KEY_COUNT" -gt "0" -a "$SW_KEY_PUBKEY_COUNT" -eq "0" ] +if [ "$MODE" == "local" ] then - if [ -n "$SW_KEY_P" ]; then - echo "--> $P: Executing signing request for SW key P..." - openssl dgst -SHA512 -sign $SW_KEY_P $T/software_hdr > $T/sw_key_p.sig - fi + for KEY in a b c; do + SIGFILE=HW_key_$KEY.sig + name=HW_KEY_$(to_upper $KEY); eval KEYFILE=\$$name; + + # If no signature found, try to generate one. + if [ -f "$T/$SIGFILE" ] + then + echo "--> $P: Found signature for HW key $(to_upper $KEY)." + elif test -f $KEYFILE && is_private_key $KEYFILE + then + echo "--> $P: Generating signature for HW key $(to_upper $KEY)..." + openssl dgst -SHA512 -sign $KEYFILE $T/prefix_hdr > $T/$SIGFILE + else + echo "--> $P: No signature found and no private key available for HW key $(to_upper $KEY), skipping." + continue + fi - if [ -n "$SW_KEY_Q" ]; then - echo "--> $P: Executing signing request for SW key Q..." - openssl dgst -SHA512 -sign $SW_KEY_Q $T/software_hdr > $T/sw_key_q.sig - fi + FOUND="${FOUND}$(to_upper $KEY)," + HW_SIG_ARGS="$HW_SIG_ARGS -$(to_upper $KEY) $T/$SIGFILE" + done + + for KEY in p q r; do + SIGFILE=SW_key_$KEY.sig + name=SW_KEY_$(to_upper $KEY); eval KEYFILE=\$$name; + + # If no signature found, try to generate one. + if [ -f "$T/$SIGFILE" ] + then + echo "--> $P: Found signature for SW key $(to_upper $KEY)." + elif test -f $KEYFILE && is_private_key $KEYFILE + then + echo "--> $P: Generating signature for SW key $(to_upper $KEY)..." + openssl dgst -SHA512 -sign $KEYFILE $T/software_hdr > $T/$SIGFILE + else + echo "--> $P: No signature found and no private key available for SW key $(to_upper $KEY), skipping." + continue + fi - if [ -n "$SW_KEY_R" ]; then - echo "--> $P: Executing signing request for SW key R..." - openssl dgst -SHA512 -sign $SW_KEY_R $T/software_hdr > $T/sw_key_r.sig - fi -fi + FOUND="${FOUND}$(to_upper $KEY)," + SW_SIG_ARGS="$SW_SIG_ARGS -$(to_upper $KEY) $T/$SIGFILE" + done -# Find signatures -FOUND="" -if [ -f $T/hw_key_a.sig ]; then - FOUND="${FOUND}A," - HW_SIG_ARGS="$HW_SIG_ARGS -A $T/hw_key_a.sig" -fi +elif [ "$MODE" == "production" ] +then + SF_PROJECT_BASE=sign_ecc_pwr_hw_key + for KEY in a b c; do + SF_PROJECT=${SF_PROJECT_BASE}_${KEY} + SIGFILE=project.$SF_PROJECT.HW_sig_$KEY.raw + + # If no signature in the current dir, try to find one. + # If no signature found, request one. + if [ -f "$T/$SIGFILE" ] + then + echo "--> $P: Found signature for HW key $(to_upper $KEY)." + else + SIGFOUND=$(find $TOPDIR -name $SIGFILE | head -1) -if [ -f $T/hw_key_b.sig ]; then - FOUND="${FOUND}B," - HW_SIG_ARGS="$HW_SIG_ARGS -B $T/hw_key_b.sig" -fi + if [ -n "$SIGFOUND" ] + then + echo "--> $P: Found signature for HW key $(to_upper $KEY)." + cp -p $SIGFOUND $T/ + else + echo "--> $P: Requesting signature for HW key $(to_upper $KEY)..." + sf_client -stdout -project $SF_PROJECT -epwd $SF_EPWD \ + -comments "Requesting sig for $SF_PROJECT" \ + -url sftp://$SF_USER@$SF_SERVER -pkey $SF_SSHKEY \ + -payload $T/prefix_hdr -o $T/$SIGFILE + # TODO Check return code, fail on error... + echo "--> $P: Retrieved signature for HW key $(to_upper $KEY)." + fi + fi -if [ -f $T/hw_key_c.sig ]; then - FOUND="${FOUND}C," - HW_SIG_ARGS="$HW_SIG_ARGS -C $T/hw_key_c.sig" -fi + FOUND="${FOUND}$(to_upper $KEY)," + HW_SIG_ARGS="$HW_SIG_ARGS -$(to_upper $KEY) $T/$SIGFILE" + done -if [ -f $T/sw_key_p.sig ]; then - FOUND="${FOUND}P," - SW_SIG_ARGS="$SW_SIG_ARGS -P $T/sw_key_p.sig" -fi + SF_PROJECT_BASE=sign_ecc_pwr_fw_key_op_bld + for KEY in p; do + SF_PROJECT=${SF_PROJECT_BASE}_${KEY} + SIGFILE=project.$SF_PROJECT.SW_sig_$KEY.raw -if [ -f $T/sw_key_q.sig ]; then - FOUND="${FOUND}Q," - SW_SIG_ARGS="$SW_SIG_ARGS -Q $T/sw_key_q.sig" -fi + # If no signature in the current dir, request one. + if [ -f "$T/$SIGFILE" ] + then + echo "--> $P: Found signature for SW key $(to_upper $KEY)." + else + echo "--> $P: Requesting signature for SW key $(to_upper $KEY)..." + sha512sum $T/software_hdr | cut -d' ' -f1 | xxd -p -r > $T/software_hdr.sha512.bin + sf_client -stdout -project $SF_PROJECT -epwd $SF_EPWD \ + -comments "Requesting sig for $LABEL from $SF_PROJECT" \ + -url sftp://$SF_USER@$SF_SERVER -pkey $SF_SSHKEY \ + -payload $T/software_hdr.sha512.bin -o $T/$SIGFILE + # TODO Check return code, fail on error... + echo "--> $P: Retrieved signature for SW key $(to_upper $KEY)." + fi -if [ -f $T/sw_key_r.sig ]; then - FOUND="${FOUND}R," - SW_SIG_ARGS="$SW_SIG_ARGS -R $T/sw_key_r.sig" + FOUND="${FOUND}$(to_upper $KEY)," + SW_SIG_ARGS="$SW_SIG_ARGS -$(to_upper $KEY) $T/$SIGFILE" + done fi # Build the full container @@ -286,13 +439,13 @@ else echo "--> $P: No signatures available." fi -echo "--> $P: Container build completed." +echo "--> $P: Container $LABEL build completed." -# Validate, verify the container. +# Validate, verify the container if [ -n "$VALIDATE" -o -n "$VERIFY" ]; then echo print-container --imagefile $OUTPUT --no-print $VERIFY_ARGS $DEBUG_ARGS - RC=$? + test $? -ne 0 && test $PASS_ON_ERR == N && RC=1 fi # Cleanup |