summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/2lib/include/2api.h12
-rw-r--r--firmware/2lib/include/2return_codes.h3
-rw-r--r--firmware/lib20/api.c14
-rw-r--r--tests/vb20_api_tests.c33
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");