summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Heller <hellerda@us.ibm.com>2017-07-29 12:50:00 -0400
committerDave Heller <hellerda@us.ibm.com>2017-07-29 12:50:00 -0400
commit8706c1ec90a2fec4cb79fea1973374ba37a26d36 (patch)
tree8051bc06276834d72c0f87c507bb4897663d854e
parent0144ed1f3ba0faae7d0c9047c02ebd75ea5f9215 (diff)
downloadsb-signing-utils-8706c1ec90a2fec4cb79fea1973374ba37a26d36.tar.gz
sb-signing-utils-8706c1ec90a2fec4cb79fea1973374ba37a26d36.zip
Add --validate and --verify options to crtSignedContainer.sh
-rw-r--r--container.c18
-rw-r--r--create-container.c21
-rwxr-xr-xcrtSignedContainer.sh34
-rw-r--r--print-container.c49
4 files changed, 93 insertions, 29 deletions
diff --git a/container.c b/container.c
index ba42234..1f180a5 100644
--- a/container.c
+++ b/container.c
@@ -28,7 +28,7 @@
extern char *progname;
-extern bool verbose;
+extern bool verbose, debug;
extern int wrap;
#define die(status, msg, ...) \
@@ -43,10 +43,8 @@ extern int wrap;
if (verbose) fprintf(stdout, "--> %s: " msg "\n", progname, \
__VA_ARGS__);
-void verbose_print(char *lead, unsigned char *buffer, size_t buflen)
+void hex_print(char *lead, unsigned char *buffer, size_t buflen)
{
- if (!verbose)
- return;
unsigned int i, indent = 4;
char prelead[100];
snprintf(prelead, 100, "--> %s: ", progname);
@@ -66,6 +64,18 @@ void verbose_print(char *lead, unsigned char *buffer, size_t buflen)
fprintf(stdout, "\n");
}
+void verbose_print(char *lead, unsigned char *buffer, size_t buflen)
+{
+ if (verbose)
+ hex_print(lead, buffer, buflen);
+}
+
+void debug_print(char *lead, unsigned char *buffer, size_t buflen)
+{
+ if (debug)
+ hex_print(lead, buffer, buflen);
+}
+
int isValidHex(char *input, int len) {
int r;
size_t maxlen = 512; // sane limit
diff --git a/create-container.c b/create-container.c
index 75106d6..65c5fc2 100644
--- a/create-container.c
+++ b/create-container.c
@@ -442,6 +442,8 @@ int main(int argc, char* argv[])
ph->ver_alg.version = cpu_to_be16(1);
ph->ver_alg.hash_alg = 1;
ph->ver_alg.sig_alg = 1;
+
+ // Set code-start-offset.
if (params.hw_cs_offset) {
if (!isValidHex(params.hw_cs_offset, 4))
die(EX_DATAERR, "%s",
@@ -454,6 +456,8 @@ int main(int argc, char* argv[])
ph->code_start_offset = 0;
}
ph->reserved = 0;
+
+ // Set flags.
if (params.hw_flags) {
if (!isValidHex(params.hw_flags, 4))
die(EX_DATAERR, "%s",
@@ -472,6 +476,8 @@ int main(int argc, char* argv[])
memset(pd->hw_sig_a, 0, sizeof(ecc_signature_t));
memset(pd->hw_sig_b, 0, sizeof(ecc_signature_t));
memset(pd->hw_sig_c, 0, sizeof(ecc_signature_t));
+
+ // Write the HW signatures.
if (params.hw_sigfn_a) {
getSigRaw(&sigraw, params.hw_sigfn_a);
verbose_print((char *) "signature A = ", sigraw, sizeof(sigraw));
@@ -490,6 +496,8 @@ int main(int argc, char* argv[])
memset(pd->sw_pkey_p, 0, sizeof(ecc_key_t));
memset(pd->sw_pkey_q, 0, sizeof(ecc_key_t));
memset(pd->sw_pkey_r, 0, sizeof(ecc_key_t));
+
+ // Write the FW keys.
if (params.sw_keyfn_p) {
getPublicKeyRaw(&pubkeyraw, params.sw_keyfn_p);
verbose_print((char *) "pubkey P = ", pubkeyraw, sizeof(pubkeyraw) - 1);
@@ -510,12 +518,15 @@ int main(int argc, char* argv[])
}
debug_msg("sw_key_count = %u", ph->sw_key_count);
ph->payload_size = cpu_to_be64(ph->sw_key_count * sizeof(ecc_key_t));
+
+ // Calculate the SW keys hash.
p = SHA512(pd->sw_pkey_p, sizeof(ecc_key_t) * ph->sw_key_count, md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
memcpy(ph->payload_hash, md, sizeof(sha2_hash_t));
verbose_print((char *) "SW keys hash = ", md, sizeof(md));
+ // Dump the Prefix header.
if (params.prhdrfn)
writeHdr((void *) ph, params.prhdrfn, PREFIX_HDR);
@@ -524,6 +535,8 @@ int main(int argc, char* argv[])
swh->ver_alg.version = cpu_to_be16(1);
swh->ver_alg.hash_alg = 1;
swh->ver_alg.sig_alg = 1;
+
+ // Set code-start-offset.
if (params.sw_cs_offset) {
if (!isValidHex(params.sw_cs_offset, 4))
die(EX_DATAERR, "%s",
@@ -536,6 +549,8 @@ int main(int argc, char* argv[])
swh->code_start_offset = 0;
}
swh->reserved = 0;
+
+ // Set flags.
if (params.sw_flags) {
if (!isValidHex(params.sw_flags, 4))
die(EX_DATAERR, "%s",
@@ -549,12 +564,15 @@ int main(int argc, char* argv[])
}
swh->reserved_0 = 0;
swh->payload_size = cpu_to_be64(payload_st.st_size);
+
+ // Calculate the payload hash.
p = SHA512(infile, payload_st.st_size, md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
memcpy(swh->payload_hash, md, sizeof(sha2_hash_t));
verbose_print((char *) "Payload hash = ", md, sizeof(md));
+ // Dump the Software header.
if (params.swhdrfn)
writeHdr((void *) swh, params.swhdrfn, SOFTWARE_HDR);
@@ -562,6 +580,8 @@ int main(int argc, char* argv[])
memset(ssig->sw_sig_p, 0, sizeof(ecc_signature_t));
memset(ssig->sw_sig_q, 0, sizeof(ecc_signature_t));
memset(ssig->sw_sig_r, 0, sizeof(ecc_signature_t));
+
+ // Write the HW signatures.
if (params.sw_sigfn_p) {
getSigRaw(&sigraw, params.sw_sigfn_p);
verbose_print((char *) "signature P = ", sigraw, sizeof(sigraw));
@@ -578,6 +598,7 @@ int main(int argc, char* argv[])
memcpy(ssig->sw_sig_r, sigraw, sizeof(ecc_key_t));
}
+ // Print container stats.
size = (uint8_t*) ph - (uint8_t *) c;
offset = (uint8_t*) c - (uint8_t *) c;
verbose_msg("HW header size = %4u (%#06x) at offset %4u (%#06x)",
diff --git a/crtSignedContainer.sh b/crtSignedContainer.sh
index b84a030..39d2c9b 100755
--- a/crtSignedContainer.sh
+++ b/crtSignedContainer.sh
@@ -4,6 +4,7 @@
VERBOSE=""
DEBUG=""
WRAP=""
+RC=0
P=${0##*/}
@@ -26,6 +27,9 @@ usage () {
echo " -o, --code-start-offset code start offset for software header in hex"
echo " -f, --flags prefix header flags in hex"
echo " -e, --eyeCatch name or identifier of the module being built"
+ echo " --validate validate the container after build"
+ echo " --verify verify the container after build, against the provided"
+ echo " value, or filename containing value, of the HW Keys hash"
echo ""
exit 1
}
@@ -97,12 +101,14 @@ for arg in "$@"; do
"--protectedPayload") set -- "$@" "-l" ;;
"--out") set -- "$@" "-i" ;;
"--eyeCatch") set -- "$@" "-e" ;;
+ "--validate") set -- "$@" "-8" ;;
+ "--verify") set -- "$@" "-9" ;;
*) set -- "$@" "$arg"
esac
done
# Process command-line arguments
-while getopts ?dvw:a:b:c:p:q:r:f:o:l:i:e: opt
+while getopts ?dvw:a:b:c:p:q:r:f:o:l:i:e:89: opt
do
case "$opt" in
v) VERBOSE="TRUE";;
@@ -119,6 +125,8 @@ do
l) PAYLOAD="`echo $OPTARG`";;
i) OUTPUT="`echo $OPTARG`";;
e) eyeCatch="`echo $OPTARG`";;
+ 8) VALIDATE="TRUE";;
+ 9) VERIFY="`echo $OPTARG`";;
h|\?) usage;;
esac
done
@@ -176,6 +184,8 @@ HW_KEY_ARGS=""
SW_KEY_ARGS=""
HW_SIG_ARGS=""
SW_SIG_ARGS=""
+VERIFY_ARGS=""
+DEBUG_ARGS=""
ADDL_ARGS=""
[ -n "$HW_KEY_A" ] && HW_KEY_ARGS="$HW_KEY_ARGS -a $HW_KEY_A"
@@ -185,17 +195,21 @@ ADDL_ARGS=""
[ -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"
+[ -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"
-[ -n "$VERBOSE" ] && ADDL_ARGS="$ADDL_ARGS -v"
-[ -n "$DEBUG" ] && ADDL_ARGS="$ADDL_ARGS -d"
-[ -n "$WRAP" ] && ADDL_ARGS="$ADDL_ARGS -w $WRAP"
+
+[ -n "$VALIDATE" ] && VERIFY_ARGS="$VERIFY_ARGS --validate"
+[ -n "$VERIFY" ] && VERIFY_ARGS="$VERIFY_ARGS --verify $VERIFY"
# Build enough of the container to create the Prefix and Software headers
echo "--> $P: Generating signing requests..."
create-container $HW_KEY_ARGS $SW_KEY_ARGS \
--payload $PAYLOAD --imagefile $OUTPUT \
--dumpPrefixHdr $T/prefix_hdr --dumpSwHdr $T/software_hdr \
+ $DEBUG_ARGS \
$ADDL_ARGS
# Sign the Prefix header (all 3 HW keys are required)
@@ -264,12 +278,20 @@ if [ -n "$HW_SIG_ARGS" -o -n "$SW_SIG_ARGS" ]; then
create-container $HW_KEY_ARGS $SW_KEY_ARGS \
$HW_SIG_ARGS $SW_SIG_ARGS \
--payload $PAYLOAD --imagefile $OUTPUT \
+ $DEBUG_ARGS \
$ADDL_ARGS
else
echo "--> $P: No signatures available."
fi
-echo "--> $P: Done."
+echo "--> $P: Container build completed."
+
+# Validate, verify the container.
+if [ -n "$VALIDATE" -o -n "$VERIFY" ]; then
+ echo
+ print-container --imagefile $OUTPUT --no-print $VERIFY_ARGS $DEBUG_ARGS
+ RC=$?
+fi
# Cleanup
if [ $KEEP_CACHE == false ]; then
@@ -283,3 +305,5 @@ if [ $KEEP_CACHE == false ]; then
echo "--> $P: Not removing cache dir: $T"
fi
fi
+
+exit $RC
diff --git a/print-container.c b/print-container.c
index 7fb088a..d692705 100644
--- a/print-container.c
+++ b/print-container.c
@@ -162,6 +162,7 @@ static void display_container(struct parsed_stb_container c)
sizeof(c.c->hw_pkey_b));
print_bytes((char *) "hw_pkey_c: ", (uint8_t *) c.c->hw_pkey_c,
sizeof(c.c->hw_pkey_c));
+
p = SHA512(c.c->hw_pkey_a, sizeof(ecc_key_t) * 3, md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
@@ -246,7 +247,7 @@ static bool validate_container(struct parsed_stb_container c, int fdin)
p = SHA512((uint8_t *) c.ph, sizeof(ROM_prefix_header_raw), md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
- print_bytes((char *) "PR header hash = ", (uint8_t *) md,
+ if (verbose) print_bytes((char *) "PR header hash = ", (uint8_t *) md,
SHA512_DIGEST_LENGTH);
// Verify HW key sigs.
@@ -256,13 +257,13 @@ static bool validate_container(struct parsed_stb_container c, int fdin)
c.pd->hw_sig_b, c.c->hw_pkey_b) && status;
status = verify_signature("HW sig C", md, SHA512_DIGEST_LENGTH,
c.pd->hw_sig_c, c.c->hw_pkey_c) && status;
- printf("\n");
+ if (verbose) printf("\n");
// Get SW header hash.
p = SHA512((uint8_t *) c.sh, sizeof(ROM_sw_header_raw), md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
- print_bytes((char *) "SW header hash = ", (uint8_t *) md,
+ if (verbose) print_bytes((char *) "SW header hash = ", (uint8_t *) md,
SHA512_DIGEST_LENGTH);
// Verify SW key sigs.
@@ -275,36 +276,41 @@ static bool validate_container(struct parsed_stb_container c, int fdin)
if (c.ph->sw_key_count >= 3)
status = verify_signature("SW sig R", md, SHA512_DIGEST_LENGTH,
c.ssig->sw_sig_r, c.pd->sw_pkey_r) && status;
- printf("\n");
+ if (verbose) printf("\n");
// Verify Payload hash.
status = getPayloadHash(fdin, md) && status;
- print_bytes((char *) "Payload hash = ", (uint8_t *) md,
+ if (verbose) print_bytes((char *) "Payload hash = ", (uint8_t *) md,
SHA512_DIGEST_LENGTH);
if (memcmp((uint8_t *) c.sh->payload_hash, md, SHA512_DIGEST_LENGTH)) {
- printf("Payload hash does not agree with value in SW header: MISMATCH\n");
+ if (verbose)
+ printf("Payload hash does not agree with value in SW header: MISMATCH\n");
status = false;
} else {
- printf("Payload hash agrees with value in SW header: VERIFIED ./\n");
+ if (verbose)
+ printf("Payload hash agrees with value in SW header: VERIFIED ./\n");
status = status && true;
}
- printf("\n");
+ if (verbose) printf("\n");
// Verify SW keys hash.
p = SHA512(c.pd->sw_pkey_p, sizeof(ecc_key_t) * c.ph->sw_key_count, md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
- print_bytes((char *) "SW keys hash = ", (uint8_t *) md,
+ if (verbose) print_bytes((char *) "SW keys hash = ", (uint8_t *) md,
SHA512_DIGEST_LENGTH);
if (memcmp((uint8_t *) c.ph->payload_hash, md, SHA512_DIGEST_LENGTH)) {
- printf("SW keys hash does not agree with value in Prefix header: MISMATCH\n");
+ if (verbose)
+ printf("SW keys hash does not agree with value in Prefix header: MISMATCH\n");
status = false;
} else {
- printf("SW keys hash agrees with value in Prefix header: VERIFIED ./\n");
+ if (verbose)
+ printf("SW keys hash agrees with value in Prefix header: VERIFIED ./\n");
status = status && true;
}
+ if (verbose) printf("\n");
return status;
}
@@ -314,23 +320,25 @@ static bool verify_container(struct parsed_stb_container c, char * verify)
void *md = alloca(SHA512_DIGEST_LENGTH);
void *p;
- printf("\n");
p = SHA512(c.c->hw_pkey_a, sizeof(ecc_key_t) * 3, md);
if (!p)
die(EX_SOFTWARE, "%s", "Cannot get SHA512");
- print_bytes((char *) "HW keys hash = ", (uint8_t *) md,
+ if (verbose) print_bytes((char *) "HW keys hash = ", (uint8_t *) md,
SHA512_DIGEST_LENGTH);
void *md_verify = alloca(SHA512_DIGEST_LENGTH);
getVerificationHash(verify, md_verify, SHA512_DIGEST_LENGTH);
if (memcmp((uint8_t *) md_verify, md, SHA512_DIGEST_LENGTH )) {
- printf("HW keys hash does not agree with provided value: MISMATCH\n");
+ if (verbose)
+ printf("HW keys hash does not agree with provided value: MISMATCH\n");
} else {
- printf("HW keys hash agrees with provided value: VERIFIED ./\n");
+ if (verbose)
+ printf("HW keys hash agrees with provided value: VERIFIED ./\n");
status = true;
}
+ if (verbose) printf("\n");
return status;
}
@@ -341,7 +349,7 @@ static bool verify_signature(const char *moniker, const unsigned char *dgst,
bool status = false;
// Convert the raw sig to a structure that can be handled by openssl.
- verbose_print((char *) "Raw sig = ", (uint8_t *) sig_raw,
+ debug_print((char *) "Raw sig = ", (uint8_t *) sig_raw,
sizeof(ecc_signature_t));
BIGNUM *r_bn = BN_new();
@@ -360,7 +368,7 @@ static bool verify_signature(const char *moniker, const unsigned char *dgst,
#endif
// Convert the raw key to a structure that can be handled by openssl.
- verbose_print((char *) "Raw key = ", (uint8_t *) key_raw,
+ debug_print((char *) "Raw key = ", (uint8_t *) key_raw,
sizeof(ecc_key_t));
EC_KEY *ec_key = EC_KEY_new();
@@ -394,10 +402,10 @@ static bool verify_signature(const char *moniker, const unsigned char *dgst,
// Verify the signature.
r = ECDSA_do_verify(dgst, dgst_len, ecdsa_sig, ec_key);
if (r == 1) {
- printf("%s is good: VERIFIED ./\n", moniker);
+ if (verbose) printf("%s is good: VERIFIED ./\n", moniker);
status = true;
} else if (r == 0) {
- printf("%s FAILED to verify.\n", moniker);
+ if (verbose) printf("%s FAILED to verify.\n", moniker);
status = false;
} else {
die(EX_SOFTWARE, "%s", "Cannot ECDSA_do_verify");
@@ -578,6 +586,7 @@ int main(int argc, char* argv[])
break;
case 'w':
wrap = atoi(optarg);
+ wrap = (wrap < 2) ? INT_MAX : wrap;
break;
case 's':
print_stats = true;
@@ -634,7 +643,7 @@ int main(int argc, char* argv[])
if ((validate_status != UNATTEMPTED) || (verify_status != UNATTEMPTED)) {
- printf("\nContainer validity check %s. Container verification check %s.\n\n",
+ printf("Container validity check %s. Container verification check %s.\n\n",
(validate_status == UNATTEMPTED) ?
"not attempted" :
((validate_status == PASSED) ? "PASSED" : "FAILED"),
OpenPOWER on IntegriCloud