diff options
-rw-r--r-- | firmware/2lib/include/2api.h | 12 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 3 | ||||
-rw-r--r-- | firmware/lib20/api.c | 14 | ||||
-rw-r--r-- | tests/vb20_api_tests.c | 33 |
4 files changed, 61 insertions, 1 deletions
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index 56d18d69..bf8f6393 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -497,6 +497,18 @@ int vb2api_extend_hash(struct vb2_context *ctx, int vb2api_check_hash(struct vb2_context *ctx); /** + * Check the hash value started by vb2api_init_hash() while retrieving + * calculated digest. + * + * @param ctx Vboot context + * @param digest_out optional pointer to buffer to store digest + * @param digest_out_size optional size of buffer to store digest + * @return VB2_SUCCESS, or error code on error. + */ +int vb2api_check_hash_get_digest(struct vb2_context *ctx, void *digest_out, + uint32_t digest_out_size); + +/** * Get a PCR digest * * @param ctx Vboot context diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 4201b693..1d1ed531 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -523,6 +523,9 @@ enum vb2_return_code { /* Phase one passing through secdata's request to reboot */ VB2_ERROR_API_PHASE1_SECDATA_REBOOT, + /* Digest buffer passed into vb2api_check_hash incorrect. */ + VB2_ERROR_API_CHECK_DIGEST_SIZE, + /********************************************************************** * Errors which may be generated by implementations of vb2ex functions. * Implementation may also return its own specific errors, which should diff --git a/firmware/lib20/api.c b/firmware/lib20/api.c index bee93285..7c253457 100644 --- a/firmware/lib20/api.c +++ b/firmware/lib20/api.c @@ -129,7 +129,8 @@ int vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size) return vb2_digest_init(dc, key.hash_alg); } -int vb2api_check_hash(struct vb2_context *ctx) +int vb2api_check_hash_get_digest(struct vb2_context *ctx, void *digest_out, + uint32_t digest_out_size) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_digest_context *dc = (struct vb2_digest_context *) @@ -199,5 +200,16 @@ int vb2api_check_hash(struct vb2_context *ctx) if (rv) vb2_fail(ctx, VB2_RECOVERY_FW_BODY, rv); + if (digest_out != NULL) { + if (digest_out_size < digest_size) + return VB2_ERROR_API_CHECK_DIGEST_SIZE; + memcpy(digest_out, digest, digest_size); + } + return rv; } + +int vb2api_check_hash(struct vb2_context *ctx) +{ + return vb2api_check_hash_get_digest(ctx, NULL, 0); +} diff --git a/tests/vb20_api_tests.c b/tests/vb20_api_tests.c index 90141a9b..f0bc98bf 100644 --- a/tests/vb20_api_tests.c +++ b/tests/vb20_api_tests.c @@ -27,6 +27,8 @@ const int mock_body_size = sizeof(mock_body); const int mock_algorithm = VB2_ALG_RSA2048_SHA256; const int mock_hash_alg = VB2_HASH_SHA256; const int mock_sig_size = 64; +static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE]; +static const uint32_t digest_result_size = sizeof(digest_result); /* Mocked function data */ @@ -98,6 +100,9 @@ static void reset_common_data(enum reset_type t) if (t == FOR_CHECK_HASH) vb2api_extend_hash(&cc, mock_body, mock_body_size); + + /* Always clear out the digest result. */ + memset(digest_result, 0, digest_result_size); }; /* Mocked functions */ @@ -153,12 +158,21 @@ int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, return VB2_SUCCESS; } +static void fill_digest(uint8_t *digest, uint32_t digest_size) +{ + /* Set the result to a known value. */ + memset(digest, 0x0a, digest_size); +} + int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size) { if (hwcrypto_state != HWCRYPTO_ENABLED) return VB2_ERROR_UNKNOWN; + if (retval_vb2_digest_finalize == VB2_SUCCESS) + fill_digest(digest, digest_size); + return retval_vb2_digest_finalize; } @@ -194,6 +208,10 @@ int vb2_digest_finalize(struct vb2_digest_context *dc, { if (hwcrypto_state == HWCRYPTO_ENABLED) return VB2_ERROR_UNKNOWN; + + if (retval_vb2_digest_finalize == VB2_SUCCESS) + fill_digest(digest, digest_size); + return retval_vb2_digest_finalize; } @@ -333,11 +351,26 @@ static void extend_hash_tests(void) static void check_hash_tests(void) { struct vb2_fw_preamble *pre; + const uint32_t digest_value = 0x0a0a0a0a; reset_common_data(FOR_CHECK_HASH); TEST_SUCC(vb2api_check_hash(&cc), "check hash good"); reset_common_data(FOR_CHECK_HASH); + TEST_SUCC(vb2api_check_hash_get_digest(&cc, digest_result, + digest_result_size), "check hash good with result"); + /* Check the first 4 bytes to ensure it was copied over. */ + TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)), + "check digest value"); + + reset_common_data(FOR_CHECK_HASH); + TEST_EQ(vb2api_check_hash_get_digest(&cc, digest_result, + digest_result_size - 1), + VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size"); + TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0, + "check digest wrong size"); + + reset_common_data(FOR_CHECK_HASH); sd->workbuf_preamble_size = 0; TEST_EQ(vb2api_check_hash(&cc), VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble"); |