summaryrefslogtreecommitdiffstats
path: root/crtSignedContainer.sh
diff options
context:
space:
mode:
authorDave Heller <hellerda@us.ibm.com>2017-08-29 14:43:39 -0400
committerDave Heller <hellerda@us.ibm.com>2017-08-29 14:43:39 -0400
commit2b37ee3213f6cf9baa093b281de711bbcb55b236 (patch)
tree7ebeef9b8698a9821b4dd7e257442f9fc712adb2 /crtSignedContainer.sh
parente807aeee19556974c5041aa862eac70c49a14b8f (diff)
downloadsb-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-xcrtSignedContainer.sh309
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
OpenPOWER on IntegriCloud