diff options
37 files changed, 474 insertions, 486 deletions
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c index 13b3a697..ee63af3c 100644 --- a/firmware/2lib/2api.c +++ b/firmware/2lib/2api.c @@ -148,10 +148,7 @@ vb2_error_t vb2api_extend_hash(struct vb2_context *ctx, sd->hash_remaining_size -= size; - if (dc->using_hwcrypto) - return vb2ex_hwcrypto_digest_extend(buf, size); - else - return vb2_digest_extend(dc, buf, size); + return vb2_digest_extend(dc, buf, size); } vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx, @@ -264,25 +261,8 @@ vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag) sd->hash_tag = tag; sd->hash_remaining_size = pre->body_signature.data_size; - if (vb2_hwcrypto_allowed(ctx)) { - vb2_error_t rv = vb2ex_hwcrypto_digest_init( - key.hash_alg, pre->body_signature.data_size); - if (!rv) { - VB2_DEBUG("Using HW crypto engine for hash_alg %d\n", - key.hash_alg); - dc->hash_alg = key.hash_alg; - dc->using_hwcrypto = 1; - return VB2_SUCCESS; - } - if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) - return rv; - VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n", - key.hash_alg); - } else { - VB2_DEBUG("HW crypto forbidden by TPM flag, using SW\n"); - } - - return vb2_digest_init(dc, key.hash_alg); + return vb2_digest_init(dc, vb2api_hwcrypto_allowed(ctx), + key.hash_alg, pre->body_signature.data_size); } vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx, @@ -321,10 +301,7 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx, return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; /* Finalize the digest */ - if (dc->using_hwcrypto) - VB2_TRY(vb2ex_hwcrypto_digest_finalize(digest, digest_size)); - else - VB2_TRY(vb2_digest_finalize(dc, digest, digest_size)); + VB2_TRY(vb2_digest_finalize(dc, digest, digest_size)); /* The code below is specific to the body signature */ if (sd->hash_tag != VB2_HASH_TAG_FW_BODY) @@ -343,7 +320,7 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx, vb2_member_of(sd, sd->data_key_offset), sd->data_key_size)); - key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx); + key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx); /* * Check digest vs. signature. Note that this destroys the signature. diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c index fa0585e3..d6ee701e 100644 --- a/firmware/2lib/2common.c +++ b/firmware/2lib/2common.c @@ -187,45 +187,15 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size, const struct vb2_public_key *key, const struct vb2_workbuf *wb) { - struct vb2_workbuf wblocal = *wb; - uint8_t *digest; - uint32_t digest_size; - vb2_error_t rv; + struct vb2_hash hash; if (sig->data_size > size) { VB2_DEBUG("Data buffer smaller than length of signed data.\n"); return VB2_ERROR_VDATA_NOT_ENOUGH_DATA; } - /* Digest goes at start of work buffer */ - digest_size = vb2_digest_size(key->hash_alg); - if (!digest_size) - return VB2_ERROR_VDATA_DIGEST_SIZE; + VB2_TRY(vb2_hash_calculate(key->allow_hwcrypto, data, sig->data_size, + key->hash_alg, &hash)); - digest = vb2_workbuf_alloc(&wblocal, digest_size); - if (!digest) - return VB2_ERROR_VDATA_WORKBUF_DIGEST; - - if (key->allow_hwcrypto) { - rv = vb2ex_hwcrypto_digest_init(key->hash_alg, sig->data_size); - if (rv == VB2_SUCCESS) { - VB2_DEBUG("Using HW crypto engine for hash_alg %d\n", key->hash_alg); - VB2_TRY(vb2ex_hwcrypto_digest_extend(data, sig->data_size)); - VB2_TRY(vb2ex_hwcrypto_digest_finalize(digest, digest_size)); - } else if (rv == VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) { - VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n", - key->hash_alg); - VB2_TRY(vb2_digest_buffer(data, sig->data_size, key->hash_alg, - digest, digest_size)); - } else { - VB2_DEBUG("HW crypto init error : %d\n", rv); - return rv; - } - } else { - VB2_DEBUG("HW crypto forbidden by TPM flag, using SW\n"); - VB2_TRY(vb2_digest_buffer(data, sig->data_size, key->hash_alg, - digest, digest_size)); - } - - return vb2_verify_digest(key, sig, digest, &wblocal); + return vb2_verify_digest(key, sig, hash.raw, wb); } diff --git a/firmware/2lib/2firmware.c b/firmware/2lib/2firmware.c index bc708dc5..49566c4f 100644 --- a/firmware/2lib/2firmware.c +++ b/firmware/2lib/2firmware.c @@ -43,7 +43,7 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx) /* Unpack the root key */ VB2_TRY(vb2_unpack_key_buffer(&root_key, key_data, key_size)); - root_key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx); + root_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx); /* Load the firmware keyblock header after the root key */ kb = vb2_workbuf_alloc(&wb, sizeof(*kb)); @@ -149,7 +149,7 @@ vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx) VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size)); - data_key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx); + data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx); /* Load the firmware preamble header */ pre = vb2_workbuf_alloc(&wb, sizeof(*pre)); diff --git a/firmware/2lib/2hmac.c b/firmware/2lib/2hmac.c index d67da42c..70a0d82d 100644 --- a/firmware/2lib/2hmac.c +++ b/firmware/2lib/2hmac.c @@ -33,7 +33,9 @@ int hmac(enum vb2_hash_algorithm alg, return -1; if (key_size > block_size) { - vb2_digest_buffer((uint8_t *)key, key_size, alg, k, block_size); + vb2_digest_init(&dc, false, alg, 0); + vb2_digest_extend(&dc, (uint8_t *)key, key_size); + vb2_digest_finalize(&dc, k, block_size); key_size = digest_size; } else { memcpy(k, key, key_size); @@ -46,12 +48,12 @@ int hmac(enum vb2_hash_algorithm alg, i_pad[i] = 0x36 ^ k[i]; } - vb2_digest_init(&dc, alg); + vb2_digest_init(&dc, false, alg, 0); vb2_digest_extend(&dc, i_pad, block_size); vb2_digest_extend(&dc, msg, msg_size); vb2_digest_finalize(&dc, b, digest_size); - vb2_digest_init(&dc, alg); + vb2_digest_init(&dc, false, alg, 0); vb2_digest_extend(&dc, o_pad, block_size); vb2_digest_extend(&dc, b, digest_size); vb2_digest_finalize(&dc, mac, mac_size); diff --git a/firmware/2lib/2load_kernel.c b/firmware/2lib/2load_kernel.c index 65e40536..35dc5b4b 100644 --- a/firmware/2lib/2load_kernel.c +++ b/firmware/2lib/2load_kernel.c @@ -110,11 +110,11 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash( struct vb2_packed_key *key = &keyblock->data_key; uint8_t *buf = ((uint8_t *)key) + key->key_offset; uint32_t buflen = key->key_size; - uint8_t digest[VB2_SHA256_DIGEST_SIZE]; + struct vb2_hash hash; VB2_DEBUG("Checking developer key hash.\n"); - VB2_TRY(vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256, digest, - sizeof(digest))); + VB2_TRY(vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen, + VB2_HASH_SHA256, &hash)); uint8_t *fwmp_dev_key_hash = vb2_secdata_fwmp_get_dev_key_hash(ctx); @@ -123,8 +123,8 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash( return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH; } - if (vb2_safe_memcmp(digest, fwmp_dev_key_hash, - VB2_SHA256_DIGEST_SIZE)) { + if (vb2_safe_memcmp(hash.sha256, fwmp_dev_key_hash, + sizeof(hash.sha256))) { int i; VB2_DEBUG("Wrong developer key hash.\n"); @@ -134,7 +134,7 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash( VB2_DEBUG_RAW("\n"); VB2_DEBUG("Got: "); for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) - VB2_DEBUG_RAW("%02x ", digest[i]); + VB2_DEBUG_RAW("%02x ", hash.sha256[i]); VB2_DEBUG_RAW("\n"); return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH; @@ -175,8 +175,7 @@ static vb2_error_t vb2_verify_kernel_vblock( key_size = sd->kernel_key_size; VB2_TRY(vb2_unpack_key_buffer(&kernel_key, key_data, key_size)); - if (vb2_hwcrypto_allowed(ctx)) - kernel_key.allow_hwcrypto = 1; + kernel_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx); /* * Clear any previous keyblock-valid flag (for example, from a previous @@ -435,8 +434,7 @@ static vb2_error_t vb2_load_partition( return VB2_ERROR_LOAD_PARTITION_DATA_KEY; } - if (vb2_hwcrypto_allowed(ctx)) - data_key.allow_hwcrypto = 1; + data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx); /* Verify kernel data */ if (vb2_verify_data(kernbuf, kernbuf_size, &preamble->body_signature, diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c index 62a1ab3e..333e8064 100644 --- a/firmware/2lib/2misc.c +++ b/firmware/2lib/2misc.c @@ -577,20 +577,22 @@ int vb2api_use_short_dev_screen_delay(struct vb2_context *ctx) return gbb->flags & VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY; } -static void snprint_sha1_sum(struct vb2_packed_key *key, +static void snprint_sha1_sum(struct vb2_context *ctx, + struct vb2_packed_key *key, char *dest, size_t dest_size) { uint8_t *buf = ((uint8_t *)key) + key->key_offset; uint64_t buflen = key->key_size; - uint8_t digest[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; int32_t used = 0; int i; - vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest)); - for (i = 0; i < sizeof(digest); i++) + vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen, + VB2_HASH_SHA1, &hash); + for (i = 0; i < sizeof(hash.sha1); i++) if (used < dest_size) used += snprintf(dest + used, dest_size - used, - "%02x", digest[i]); + "%02x", hash.sha1[i]); dest[dest_size - 1] = '\0'; } @@ -690,7 +692,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx) struct vb2_workbuf wblocal = wb; rv = vb2_gbb_read_root_key(ctx, &key, NULL, &wblocal); if (rv == VB2_SUCCESS) { - snprint_sha1_sum(key, sha1sum, sizeof(sha1sum)); + snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum)); DEBUG_INFO_APPEND("\ngbb.rootkey: %s", sha1sum); } } @@ -700,7 +702,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx) struct vb2_workbuf wblocal = wb; rv = vb2_gbb_read_recovery_key(ctx, &key, NULL, &wblocal); if (rv == VB2_SUCCESS) { - snprint_sha1_sum(key, sha1sum, sizeof(sha1sum)); + snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum)); DEBUG_INFO_APPEND("\ngbb.recovery_key: %s", sha1sum); } } @@ -710,7 +712,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx) sd->kernel_key_offset) { struct vb2_packed_key *key = vb2_member_of(sd, sd->kernel_key_offset); - snprint_sha1_sum(key, sha1sum, sizeof(sha1sum)); + snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum)); DEBUG_INFO_APPEND("\nkernel_subkey: %s", sha1sum); } @@ -749,3 +751,14 @@ void vb2_set_boot_mode(struct vb2_context *ctx) *boot_mode = VB2_BOOT_MODE_DEVELOPER; } } + +bool vb2api_hwcrypto_allowed(struct vb2_context *ctx) +{ + /* disable hwcrypto in recovery mode */ + if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) + return 0; + + /* enable hwcrypto only if RW firmware set the flag */ + return vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) & + VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED; +} diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c index 3a6c230e..4bc3f6a7 100644 --- a/firmware/2lib/2sha_utility.c +++ b/firmware/2lib/2sha_utility.c @@ -56,13 +56,32 @@ size_t vb2_hash_block_size(enum vb2_hash_algorithm alg) } test_mockable -vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, - enum vb2_hash_algorithm hash_alg) +vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto, + enum vb2_hash_algorithm algo, uint32_t data_size) { - dc->hash_alg = hash_alg; + const char msg[] = "%u bytes, hash algo %d, HW acceleration %s"; + + dc->hash_alg = algo; dc->using_hwcrypto = 0; - switch (dc->hash_alg) { + if (allow_hwcrypto) { + vb2_error_t rv = vb2ex_hwcrypto_digest_init(algo, data_size); + if (rv == VB2_SUCCESS) { + VB2_DEBUG(msg, data_size, algo, "enabled\n"); + dc->using_hwcrypto = 1; + return VB2_SUCCESS; + } + if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) { + VB2_DEBUG(msg, data_size, algo, "initialization error"); + VB2_DEBUG_RAW(": %#x\n", rv); + return rv; + } + VB2_DEBUG(msg, data_size, algo, "unsupported\n"); + } else { + VB2_DEBUG(msg, data_size, algo, "forbidden\n"); + } + + switch (algo) { #if VB2_SUPPORT_SHA1 case VB2_HASH_SHA1: vb2_sha1_init(&dc->sha1); @@ -71,13 +90,13 @@ vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, #if VB2_SUPPORT_SHA256 case VB2_HASH_SHA224: case VB2_HASH_SHA256: - vb2_sha256_init(&dc->sha256, hash_alg); + vb2_sha256_init(&dc->sha256, algo); return VB2_SUCCESS; #endif #if VB2_SUPPORT_SHA512 case VB2_HASH_SHA384: case VB2_HASH_SHA512: - vb2_sha512_init(&dc->sha512, hash_alg); + vb2_sha512_init(&dc->sha512, algo); return VB2_SUCCESS; #endif default: @@ -89,6 +108,9 @@ test_mockable vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf, uint32_t size) { + if (dc->using_hwcrypto) + return vb2ex_hwcrypto_digest_extend(buf, size); + switch (dc->hash_alg) { #if VB2_SUPPORT_SHA1 case VB2_HASH_SHA1: @@ -116,6 +138,9 @@ test_mockable vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, uint32_t digest_size) { + if (dc->using_hwcrypto) + return vb2ex_hwcrypto_digest_finalize(digest, digest_size); + if (digest_size < vb2_digest_size(dc->hash_alg)) return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE; @@ -142,27 +167,26 @@ vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, } } -test_mockable -vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, - enum vb2_hash_algorithm hash_alg, uint8_t *digest, - uint32_t digest_size) +vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf, + uint32_t size, enum vb2_hash_algorithm algo, + struct vb2_hash *hash) { struct vb2_digest_context dc; + hash->algo = algo; - VB2_TRY(vb2_digest_init(&dc, hash_alg)); + VB2_TRY(vb2_digest_init(&dc, allow_hwcrypto, algo, size)); VB2_TRY(vb2_digest_extend(&dc, buf, size)); - return vb2_digest_finalize(&dc, digest, digest_size); + return vb2_digest_finalize(&dc, hash->raw, vb2_digest_size(algo)); } -vb2_error_t vb2_hash_verify(const void *buf, uint32_t size, +vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size, const struct vb2_hash *hash) { - uint8_t hash_buf[VB2_MAX_DIGEST_SIZE]; - size_t hash_size = vb2_digest_size(hash->algo); + struct vb2_hash tmp; - VB2_TRY(vb2_digest_buffer(buf, size, hash->algo, hash_buf, hash_size)); - if (memcmp(hash_buf, hash->raw, hash_size)) + VB2_TRY(vb2_hash_calculate(allow_hwcrypto, buf, size, hash->algo, &tmp)); + if (memcmp(tmp.raw, hash->raw, vb2_digest_size(hash->algo))) return VB2_ERROR_SHA_MISMATCH; else return VB2_SUCCESS; diff --git a/firmware/2lib/2struct.c b/firmware/2lib/2struct.c index a16f8690..0223570f 100644 --- a/firmware/2lib/2struct.c +++ b/firmware/2lib/2struct.c @@ -170,35 +170,19 @@ vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block, const struct vb2_workbuf *wb) { const struct vb2_signature *sig = &block->keyblock_hash; - struct vb2_workbuf wblocal = *wb; - struct vb2_digest_context *dc; - uint8_t *digest; - uint32_t digest_size; + struct vb2_hash hash; /* Validity check keyblock before attempting hash check of data */ VB2_TRY(vb2_check_keyblock(block, size, sig)); VB2_DEBUG("Checking keyblock hash...\n"); - /* Digest goes at start of work buffer */ - digest_size = vb2_digest_size(VB2_HASH_SHA512); - digest = vb2_workbuf_alloc(&wblocal, digest_size); - if (!digest) - return VB2_ERROR_VDATA_WORKBUF_DIGEST; + /* This is only used in developer mode, so hwcrypto not important. */ + VB2_TRY(vb2_hash_calculate(false, block, sig->data_size, + VB2_HASH_SHA512, &hash)); - /* Hashing requires temp space for the context */ - dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); - if (!dc) - return VB2_ERROR_VDATA_WORKBUF_HASHING; - - VB2_TRY(vb2_digest_init(dc, VB2_HASH_SHA512)); - - VB2_TRY(vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size)); - - VB2_TRY(vb2_digest_finalize(dc, digest, digest_size)); - - if (vb2_safe_memcmp(vb2_signature_data(sig), digest, - digest_size) != 0) { + if (vb2_safe_memcmp(vb2_signature_data(sig), hash.sha512, + sizeof(hash.sha512)) != 0) { VB2_DEBUG("Invalid keyblock hash.\n"); return VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE; } diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index fdb6a72f..f185ec4d 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -895,7 +895,11 @@ void vb2ex_printf(const char *func, const char *fmt, ...); * Initialize the hardware crypto engine to calculate a block-style digest. * * @param hash_alg Hash algorithm to use - * @param data_size Expected total size of data to hash + * @param data_size Expected total size of data to hash, or 0. If 0, the + * total size is not known in advance. Implementations that + * cannot handle unknown sizes should return UNSUPPORTED + * in that case. If the value is non-zero, implementations + * can trust it to be accurate. * @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal). */ vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, @@ -948,6 +952,15 @@ vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key, uint32_t *workbuf32, int exp); /* + * Report if hardware crypto is allowed in the current context. It may be + * disabled by TPM flag and is categorically disallowed in recovery mode. + * + * @param ctx Vboot context + * @returns 1 if hardware crypto is allowed, 0 if it is forbidden. + */ +bool vb2api_hwcrypto_allowed(struct vb2_context *ctx); + +/* * Abort vboot flow due to a failed assertion or broken assumption. * * Likely due to caller misusing vboot (e.g. calling API functions diff --git a/firmware/2lib/include/2rsa.h b/firmware/2lib/include/2rsa.h index 6d5ffcbe..7597dd5e 100644 --- a/firmware/2lib/include/2rsa.h +++ b/firmware/2lib/include/2rsa.h @@ -22,7 +22,7 @@ struct vb2_public_key { const char *desc; /* Description */ uint32_t version; /* Key version */ const struct vb2_id *id; /* Key ID */ - int allow_hwcrypto; /* Is hwcrypto allowed for key */ + bool allow_hwcrypto; /* Is hwcrypto allowed for key */ }; /** diff --git a/firmware/2lib/include/2secdata.h b/firmware/2lib/include/2secdata.h index f9a0e308..ae9888af 100644 --- a/firmware/2lib/include/2secdata.h +++ b/firmware/2lib/include/2secdata.h @@ -220,24 +220,4 @@ int vb2_secdata_fwmp_get_flag(struct vb2_context *ctx, */ uint8_t *vb2_secdata_fwmp_get_dev_key_hash(struct vb2_context *ctx); -/* - * Helper function to check if hwcrypto is allowed. - */ -static inline int vb2_hwcrypto_allowed(struct vb2_context *ctx) -{ - - /* disable hwcrypto in recovery mode */ - if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) - return 0; - - /* enable hwcrypto only if RW firmware set the flag */ - if (vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) - & VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED) - return 1; - - return 0; - -} - - #endif /* VBOOT_REFERENCE_2SECDATA_H_ */ diff --git a/firmware/2lib/include/2sha.h b/firmware/2lib/include/2sha.h index e586a77d..503eb7c2 100644 --- a/firmware/2lib/include/2sha.h +++ b/firmware/2lib/include/2sha.h @@ -102,8 +102,8 @@ struct vb2_digest_context { /* Current hash algorithm */ enum vb2_hash_algorithm hash_alg; - /* 1 if digest is computed with vb2ex_hwcrypto routines, else 0 */ - int using_hwcrypto; + /* `true` if digest is computed with vb2ex_hwcrypto routines */ + bool using_hwcrypto; }; /* @@ -206,14 +206,18 @@ size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg); size_t vb2_hash_block_size(enum vb2_hash_algorithm alg); /** - * Initialize a digest context for doing block-style digesting. + * Initialize a digest context for doing block-style digesting, potentially + * making use of the vb2ex_hwcrypto APIs. Whether HW crypto is allowed by policy + * in the current context depends on the caller and can be passed in. If HW + * crypto is not allowed or not supported, will automatically fall back to SW. * * @param dc Digest context - * @param hash_alg Hash algorithm + * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow. + * @param algo Hash algorithm * @return VB2_SUCCESS, or non-zero on error. */ -vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, - enum vb2_hash_algorithm hash_alg); +vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto, + enum vb2_hash_algorithm algo, uint32_t data_size); /** * Extend a digest's hash with another block of data. @@ -240,47 +244,30 @@ vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, uint32_t digest_size); /** - * Calculate the digest of a buffer and store the result. - * - * @param buf Data to hash - * @param size Length of data in bytes - * @param hash_alg Hash algorithm - * @param digest Destination for digest - * @param digest_size Length of digest buffer in bytes. - * @return VB2_SUCCESS, or non-zero on error. - */ -vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, - enum vb2_hash_algorithm hash_alg, uint8_t *digest, - uint32_t digest_size); - -/** * Fill a vb2_hash structure with the hash of a buffer. * + * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow. * @param buf Buffer to hash * @param size Size of |buf| in bytes * @param algo The hash algorithm to use (and store in |hash|) * @param hash vb2_hash structure to fill with the hash of |buf| * @return VB2_SUCCESS, or non-zero on error. */ -static inline vb2_error_t vb2_hash_calculate(const void *buf, uint32_t size, - enum vb2_hash_algorithm algo, - struct vb2_hash *hash) -{ - hash->algo = algo; - return vb2_digest_buffer(buf, size, algo, hash->raw, - vb2_digest_size(algo)); -} +vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf, + uint32_t size, enum vb2_hash_algorithm algo, + struct vb2_hash *hash); /** * Verify that a vb2_hash matches a buffer. * + * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow. * @param buf Buffer to hash and match to |hash| * @param size Size of |buf| in bytes * @param hash Hash to compare to the buffer * @return VB2_SUCCESS if hash matches, VB2_ERROR_SHA_MISMATCH if hash doesn't * match, or non-zero on other error. */ -vb2_error_t vb2_hash_verify(const void *buf, uint32_t size, +vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size, const struct vb2_hash *hash); #endif /* VBOOT_REFERENCE_2SHA_H_ */ diff --git a/firmware/2lib/include/2sysincludes.h b/firmware/2lib/include/2sysincludes.h index 1e671e9a..00e92e95 100644 --- a/firmware/2lib/include/2sysincludes.h +++ b/firmware/2lib/include/2sysincludes.h @@ -15,6 +15,7 @@ #include <ctype.h> #include <inttypes.h> /* For PRIu64 */ +#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c index 403e932e..c021db33 100644 --- a/firmware/lib20/api_kernel.c +++ b/firmware/lib20/api_kernel.c @@ -99,7 +99,8 @@ vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf, vb2_member_of(sd, sd->data_key_offset), sd->data_key_size)); - VB2_TRY(vb2_digest_init(dc, key.hash_alg)); + VB2_TRY(vb2_digest_init(dc, vb2api_hwcrypto_allowed(ctx), + key.hash_alg, size)); VB2_TRY(vb2_digest_extend(dc, buf, size)); diff --git a/futility/cmd_create.c b/futility/cmd_create.c index 16a37332..cf02f097 100644 --- a/futility/cmd_create.c +++ b/futility/cmd_create.c @@ -262,8 +262,10 @@ static int vb2_make_keypair(void) /* Update the IDs */ if (!force_id) { - vb2_digest_buffer(keyb_data, keyb_size, VB2_HASH_SHA1, - opt_id.raw, sizeof(opt_id.raw)); + struct vb2_hash hash; + vb2_hash_calculate(false, keyb_data, keyb_size, VB2_HASH_SHA1, + &hash); + memcpy(opt_id.raw, hash.raw, sizeof(opt_id.raw)); } memcpy((struct vb2_id *)pubkey->id, &opt_id, sizeof(opt_id)); diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c index 458c7549..6101173f 100644 --- a/futility/cmd_gscvd.c +++ b/futility/cmd_gscvd.c @@ -437,7 +437,7 @@ static int calculate_ranges_digest(const struct file_buf *ap_firmware_file, size_t i; /* Calculate the ranges digest. */ - if (vb2_digest_init(&dc, hash_alg) != VB2_SUCCESS) { + if (vb2_digest_init(&dc, false, hash_alg, 0) != VB2_SUCCESS) { ERROR("Failed to init digest!\n"); return 1; } @@ -904,10 +904,10 @@ static int validate_gscvd(int argc, char *argv[]) /* Find the keyblock. */ kblock = (struct vb2_keyblock *)((uintptr_t)gvd + gvd->size); - if ((argc > 1) && (vb2_hash_verify - (vb2_packed_key_data(&gvd->root_key_header), - gvd->root_key_header.key_size, - &root_key_digest) != VB2_SUCCESS)) { + if ((argc > 1) && (vb2_hash_verify(false, + vb2_packed_key_data(&gvd->root_key_header), + gvd->root_key_header.key_size, + &root_key_digest) != VB2_SUCCESS)) { ERROR("Sha256 mismatch\n"); break; } @@ -946,7 +946,7 @@ static void dump_pubk_hash(const struct vb2_packed_key *pubk) struct vb2_hash hash; size_t i; - vb2_hash_calculate(vb2_packed_key_data(pubk), pubk->key_size, + vb2_hash_calculate(false, vb2_packed_key_data(pubk), pubk->key_size, VB2_HASH_SHA256, &hash); printf("Root key body sha256 hash:\n"); diff --git a/futility/cmd_pcr.c b/futility/cmd_pcr.c index e267b24a..bc6de62c 100644 --- a/futility/cmd_pcr.c +++ b/futility/cmd_pcr.c @@ -129,12 +129,14 @@ static int do_pcr(int argc, char *argv[]) print_digest(accum + digest_size, digest_size); printf("\n"); - if (VB2_SUCCESS != vb2_digest_buffer(accum, digest_size * 2, - digest_alg, - pcr, digest_size)) { + struct vb2_hash hash; + if (VB2_SUCCESS != vb2_hash_calculate(false, accum, + digest_size * 2, + digest_alg, &hash)) { fprintf(stderr, "Error computing digest!\n"); return 1; } + memcpy(pcr, hash.raw, digest_size); printf("PCR: "); print_digest(pcr, digest_size); diff --git a/futility/file_type_usbpd1.c b/futility/file_type_usbpd1.c index a128a996..024303d8 100644 --- a/futility/file_type_usbpd1.c +++ b/futility/file_type_usbpd1.c @@ -345,7 +345,7 @@ static void show_usbpd1_stuff(const char *name, { struct vb2_public_key key; struct vb21_packed_key *pkey; - uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; int i; vb2_pubkey_from_usbpd1(&key, sig_alg, hash_alg, @@ -354,16 +354,16 @@ static void show_usbpd1_stuff(const char *name, if (vb21_public_key_pack(&pkey, &key)) return; - vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size, - VB2_HASH_SHA1, sha1sum, sizeof(sha1sum)); + vb2_hash_calculate(false, (uint8_t *)pkey + pkey->key_offset, + pkey->key_size, VB2_HASH_SHA1, &hash); printf("USB-PD v1 image: %s\n", name); printf(" Algorithm: %s %s\n", vb2_get_sig_algorithm_name(sig_alg), vb2_get_hash_algorithm_name(hash_alg)); printf(" Key sha1sum: "); - for (i = 0; i < VB2_SHA1_DIGEST_SIZE; i++) - printf("%02x", sha1sum[i]); + for (i = 0; i < sizeof(hash.sha1); i++) + printf("%02x", hash.sha1[i]); printf("\n"); free(pkey); diff --git a/futility/misc.c b/futility/misc.c index 4aec13a3..874039f0 100644 --- a/futility/misc.c +++ b/futility/misc.c @@ -146,17 +146,17 @@ int print_hwid_digest(struct vb2_gbb_header *gbb, uint8_t *buf = (uint8_t *)gbb; char *hwid_str = (char *)(buf + gbb->hwid_offset); int is_valid = 0; - uint8_t digest[VB2_SHA256_DIGEST_SIZE]; + struct vb2_hash hash; - if (VB2_SUCCESS == vb2_digest_buffer(buf + gbb->hwid_offset, - strlen(hwid_str), VB2_HASH_SHA256, - digest, sizeof(digest))) { + if (VB2_SUCCESS == vb2_hash_calculate(false, buf + gbb->hwid_offset, + strlen(hwid_str), VB2_HASH_SHA256, + &hash)) { int i; is_valid = 1; /* print it, comparing as we go */ - for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) { + for (i = 0; i < sizeof(hash.sha256); i++) { printf("%02x", gbb->hwid_digest[i]); - if (gbb->hwid_digest[i] != digest[i]) + if (gbb->hwid_digest[i] != hash.sha256[i]) is_valid = 0; } } @@ -176,16 +176,18 @@ void update_hwid_digest(struct vb2_gbb_header *gbb) uint8_t *buf = (uint8_t *)gbb; char *hwid_str = (char *)(buf + gbb->hwid_offset); + struct vb2_hash hash; - vb2_digest_buffer(buf + gbb->hwid_offset, strlen(hwid_str), - VB2_HASH_SHA256, - gbb->hwid_digest, sizeof(gbb->hwid_digest)); + vb2_hash_calculate(false, buf + gbb->hwid_offset, strlen(hwid_str), + VB2_HASH_SHA256, &hash); + memcpy(gbb->hwid_digest, hash.raw, sizeof(gbb->hwid_digest)); } /* Sets the HWID string field inside a GBB header. */ int futil_set_gbb_hwid(struct vb2_gbb_header *gbb, const char *hwid) { uint8_t *to = (uint8_t *)gbb + gbb->hwid_offset; + struct vb2_hash hash; size_t len; assert(hwid); @@ -201,8 +203,9 @@ int futil_set_gbb_hwid(struct vb2_gbb_header *gbb, const char *hwid) if (gbb->major_version == 1 && gbb->minor_version < 2) return 0; - return vb2_digest_buffer(to, len, VB2_HASH_SHA256, gbb->hwid_digest, - sizeof(gbb->hwid_digest)); + VB2_TRY(vb2_hash_calculate(false, to, len, VB2_HASH_SHA256, &hash)); + memcpy(gbb->hwid_digest, hash.raw, sizeof(gbb->hwid_digest)); + return VB2_SUCCESS; } /* diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c index a8452db6..2105fe53 100644 --- a/futility/vb2_helper.c +++ b/futility/vb2_helper.c @@ -46,15 +46,16 @@ static inline void vb2_print_bytes(const void *ptr, uint32_t len) printf("%02x", *buf++); } -static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest) +static int vb2_public_key_sha1sum(struct vb2_public_key *key, + struct vb2_hash *hash) { struct vb21_packed_key *pkey; if (vb21_public_key_pack(&pkey, key)) return 0; - vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size, - VB2_HASH_SHA1, digest, VB2_SHA1_DIGEST_SIZE); + vb2_hash_calculate(false, (uint8_t *)pkey + pkey->key_offset, + pkey->key_size, VB2_HASH_SHA1, hash); free(pkey); return 1; @@ -64,7 +65,7 @@ int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len, void *data) { struct vb2_public_key key; - uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; /* The key's members will point into the state buffer after this. Don't * free anything. */ @@ -82,10 +83,10 @@ int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len, printf(" ID: "); vb2_print_bytes(key.id, sizeof(*key.id)); printf("\n"); - if (vb2_public_key_sha1sum(&key, sha1sum) && - memcmp(key.id, sha1sum, sizeof(*key.id))) { + if (vb2_public_key_sha1sum(&key, &hash) && + memcmp(key.id, hash.sha1, sizeof(*key.id))) { printf(" Key sha1sum: "); - vb2_print_bytes(sha1sum, sizeof(sha1sum)); + vb2_print_bytes(hash.sha1, sizeof(hash.sha1)); printf("\n"); } return 0; @@ -107,7 +108,8 @@ int ft_show_vb21_pubkey(const char *name, void *data) return rv; } -static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest) +static int vb2_private_key_sha1sum(struct vb2_private_key *key, + struct vb2_hash *hash) { uint8_t *buf; uint32_t buflen; @@ -115,8 +117,7 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest) if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) return 0; - vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, - VB2_SHA1_DIGEST_SIZE); + vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, hash); free(buf); return 1; @@ -125,7 +126,7 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest) int ft_show_vb21_privkey(const char *name, void *data) { struct vb2_private_key *key = 0; - uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; int fd = -1; uint8_t *buf; uint32_t len; @@ -149,10 +150,10 @@ int ft_show_vb21_privkey(const char *name, void *data) printf(" ID: "); vb2_print_bytes(&key->id, sizeof(key->id)); printf("\n"); - if (vb2_private_key_sha1sum(key, sha1sum) && - memcmp(&key->id, sha1sum, sizeof(key->id))) { + if (vb2_private_key_sha1sum(key, &hash) && + memcmp(&key->id, hash.sha1, sizeof(key->id))) { printf(" Key sha1sum: "); - vb2_print_bytes(sha1sum, sizeof(sha1sum)); + vb2_print_bytes(hash.sha1, sizeof(hash.sha1)); printf("\n"); } vb2_private_key_free(key); @@ -202,8 +203,8 @@ int ft_show_pem(const char *name, void *data) { RSA *rsa_key; uint8_t *keyb; - uint8_t digest[VB2_SHA1_DIGEST_SIZE]; uint32_t keyb_len; + struct vb2_hash hash; int i, bits; const BIGNUM *rsa_key_n, *rsa_key_d; int fd = -1; @@ -235,10 +236,9 @@ int ft_show_pem(const char *name, void *data) } printf(" Key sha1sum: "); - vb2_digest_buffer(keyb, keyb_len, VB2_HASH_SHA1, - digest, sizeof(digest)); - for (i = 0; i < sizeof(digest); i++) - printf("%02x", digest[i]); + vb2_hash_calculate(false, keyb, keyb_len, VB2_HASH_SHA1, &hash); + for (i = 0; i < sizeof(hash.sha1); i++) + printf("%02x", hash.sha1[i]); printf("\n"); free(keyb); diff --git a/host/lib/file_keys.c b/host/lib/file_keys.c index 7ae71802..4349dc9b 100644 --- a/host/lib/file_keys.c +++ b/host/lib/file_keys.c @@ -31,7 +31,7 @@ vb2_error_t DigestFile(char *input_file, enum vb2_hash_algorithm alg, fprintf(stderr, "Couldn't open %s\n", input_file); return VB2_ERROR_UNKNOWN; } - vb2_digest_init(&ctx, alg); + vb2_digest_init(&ctx, false, alg, 0); while ((len = read(input_fd, data, sizeof(data))) == sizeof(data)) vb2_digest_extend(&ctx, data, len); if (len != -1) diff --git a/host/lib/host_signature.c b/host/lib/host_signature.c index 5b71d29a..68e6991d 100644 --- a/host/lib/host_signature.c +++ b/host/lib/host_signature.c @@ -113,34 +113,33 @@ struct vb2_signature *vb2_external_signature(const uint8_t *data, uint32_t size, uint32_t key_algorithm, const char *external_signer) { - int vb2_alg = vb2_crypto_to_hash(key_algorithm); - uint8_t digest[VB2_MAX_DIGEST_SIZE]; - int digest_size = vb2_digest_size(vb2_alg); + struct vb2_hash hash; + + /* Calculate the digest */ + if (VB2_SUCCESS != vb2_hash_calculate(false, data, size, + vb2_crypto_to_hash(key_algorithm), + &hash)) + return NULL; uint32_t digest_info_size = 0; const uint8_t *digest_info = NULL; - if (VB2_SUCCESS != vb2_digest_info(vb2_alg, + if (VB2_SUCCESS != vb2_digest_info(hash.algo, &digest_info, &digest_info_size)) return NULL; - + int digest_size = vb2_digest_size(hash.algo); uint8_t *signature_digest; uint64_t signature_digest_len = digest_size + digest_info_size; int rv; - /* Calculate the digest */ - if (VB2_SUCCESS != vb2_digest_buffer(data, size, vb2_alg, - digest, sizeof(digest))) - return NULL; - /* Prepend the digest info to the digest */ signature_digest = calloc(signature_digest_len, 1); if (!signature_digest) return NULL; memcpy(signature_digest, digest_info, digest_info_size); - memcpy(signature_digest + digest_info_size, digest, digest_size); + memcpy(signature_digest + digest_info_size, hash.raw, digest_size); /* Allocate output signature */ uint32_t sig_size = diff --git a/host/lib/host_signature2.c b/host/lib/host_signature2.c index b6cd6520..83b97984 100644 --- a/host/lib/host_signature2.c +++ b/host/lib/host_signature2.c @@ -65,17 +65,18 @@ vb2_error_t vb2_copy_signature(struct vb2_signature *dest, struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size) { - uint8_t digest[VB2_SHA512_DIGEST_SIZE]; - if (VB2_SUCCESS != vb2_digest_buffer(data, size, VB2_HASH_SHA512, - digest, sizeof(digest))) + struct vb2_hash hash; + if (VB2_SUCCESS != vb2_hash_calculate(false, data, size, + VB2_HASH_SHA512, &hash)) return NULL; struct vb2_signature *sig = - vb2_alloc_signature(VB2_SHA512_DIGEST_SIZE, size); + vb2_alloc_signature(sizeof(hash.sha512), size); if (!sig) return NULL; - memcpy(vb2_signature_data_mutable(sig), digest, VB2_SHA512_DIGEST_SIZE); + memcpy(vb2_signature_data_mutable(sig), hash.sha512, + sizeof(hash.sha512)); return sig; } @@ -83,7 +84,7 @@ struct vb2_signature *vb2_calculate_signature( const uint8_t *data, uint32_t size, const struct vb2_private_key *key) { - uint8_t digest[VB2_MAX_DIGEST_SIZE]; + struct vb2_hash hash; uint32_t digest_size = vb2_digest_size(key->hash_alg); uint32_t digest_info_size = 0; @@ -93,8 +94,8 @@ struct vb2_signature *vb2_calculate_signature( return NULL; /* Calculate the digest */ - if (VB2_SUCCESS != vb2_digest_buffer(data, size, key->hash_alg, - digest, digest_size)) + if (VB2_SUCCESS != vb2_hash_calculate(false, data, size, key->hash_alg, + &hash)) return NULL; /* Prepend the digest info to the digest */ @@ -104,7 +105,7 @@ struct vb2_signature *vb2_calculate_signature( return NULL; memcpy(signature_digest, digest_info, digest_info_size); - memcpy(signature_digest + digest_info_size, digest, digest_size); + memcpy(signature_digest + digest_info_size, hash.raw, digest_size); /* Allocate output signature */ struct vb2_signature *sig = (struct vb2_signature *) diff --git a/host/lib/signature_digest.c b/host/lib/signature_digest.c index f6be00a3..a0364702 100644 --- a/host/lib/signature_digest.c +++ b/host/lib/signature_digest.c @@ -38,8 +38,7 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len, { uint8_t* info_digest = NULL; - uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */ - enum vb2_hash_algorithm hash_alg; + struct vb2_hash hash; if (algorithm >= VB2_ALG_COUNT) { fprintf(stderr, @@ -47,11 +46,10 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len, return NULL; } - hash_alg = vb2_crypto_to_hash(algorithm); - - if (VB2_SUCCESS == vb2_digest_buffer(buf, len, hash_alg, - digest, sizeof(digest))) { - info_digest = PrependDigestInfo(hash_alg, digest); + if (VB2_SUCCESS == vb2_hash_calculate(false, buf, len, + vb2_crypto_to_hash(algorithm), + &hash)) { + info_digest = PrependDigestInfo(hash.algo, hash.raw); } return info_digest; } diff --git a/host/lib/util_misc.c b/host/lib/util_misc.c index 26f7dac8..c92a2b0a 100644 --- a/host/lib/util_misc.c +++ b/host/lib/util_misc.c @@ -25,15 +25,15 @@ const char *packed_key_sha1_string(const struct vb2_packed_key *key) { uint8_t *buf = ((uint8_t *)key) + key->key_offset; uint32_t buflen = key->key_size; - uint8_t digest[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; - vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest)); + vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash); char *dnext = dest; int i; - for (i = 0; i < sizeof(digest); i++) - dnext += sprintf(dnext, "%02x", digest[i]); + for (i = 0; i < sizeof(hash.sha1); i++) + dnext += sprintf(dnext, "%02x", hash.sha1[i]); return dest; } @@ -42,7 +42,7 @@ const char *private_key_sha1_string(const struct vb2_private_key *key) { uint8_t *buf; uint32_t buflen; - uint8_t digest[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; if (!key->rsa_private_key || @@ -50,12 +50,12 @@ const char *private_key_sha1_string(const struct vb2_private_key *key) return "<error>"; } - vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest)); + vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash); char *dnext = dest; int i; - for (i = 0; i < sizeof(digest); i++) - dnext += sprintf(dnext, "%02x", digest[i]); + for (i = 0; i < sizeof(hash.sha1); i++) + dnext += sprintf(dnext, "%02x", hash.sha1[i]); free(buf); return dest; diff --git a/host/lib21/host_common.c b/host/lib21/host_common.c index 245b1885..d0268c23 100644 --- a/host/lib21/host_common.c +++ b/host/lib21/host_common.c @@ -285,7 +285,7 @@ vb2_error_t vb21_verify_data(const void *data, uint32_t size, if (!dc) return VB2_ERROR_VDATA_WORKBUF_HASHING; - rv = vb2_digest_init(dc, key->hash_alg); + rv = vb2_digest_init(dc, false, key->hash_alg, 0); if (rv) return rv; diff --git a/host/lib21/host_signature.c b/host/lib21/host_signature.c index 77ee448a..cd49b3b2 100644 --- a/host/lib21/host_signature.c +++ b/host/lib21/host_signature.c @@ -125,7 +125,7 @@ vb2_error_t vb21_sign_data(struct vb21_signature **sig_ptr, const uint8_t *data, memcpy(sig_digest, info, info_size); /* Calculate hash digest */ - if (vb2_digest_init(&dc, s.hash_alg)) { + if (vb2_digest_init(&dc, false, s.hash_alg, 0)) { free(sig_digest); return VB2_SIGN_DATA_DIGEST_INIT; } diff --git a/tests/sha_benchmark.c b/tests/sha_benchmark.c index d7ba31ab..4626a429 100644 --- a/tests/sha_benchmark.c +++ b/tests/sha_benchmark.c @@ -20,14 +20,13 @@ int main(int argc, char *argv[]) { double speed; uint32_t msecs; uint8_t *buffer = malloc(TEST_BUFFER_SIZE); - uint8_t digest[VB2_MAX_DIGEST_SIZE]; + struct vb2_hash hash; ClockTimerState ct; /* Iterate through all the hash functions. */ for(i = VB2_HASH_SHA1; i < VB2_HASH_ALG_COUNT; i++) { StartTimer(&ct); - vb2_digest_buffer(buffer, TEST_BUFFER_SIZE, i, - digest, sizeof(digest)); + vb2_hash_calculate(false, buffer, TEST_BUFFER_SIZE, i, &hash); StopTimer(&ct); msecs = GetDurationMsecs(&ct); diff --git a/tests/vb20_api_kernel_tests.c b/tests/vb20_api_kernel_tests.c index bc585b48..74aa4f4f 100644 --- a/tests/vb20_api_kernel_tests.c +++ b/tests/vb20_api_kernel_tests.c @@ -133,7 +133,7 @@ static void reset_common_data(enum reset_type t) sig->sig_offset = vb2_offset_of(sig, sdata); sig->sig_size = VB2_SHA512_DIGEST_SIZE; - vb2_digest_init(&dc, VB2_HASH_SHA256); + vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0); vb2_digest_extend(&dc, (const uint8_t *)kernel_data, sizeof(kernel_data)); vb2_digest_finalize(&dc, sdata, sig->sig_size); diff --git a/tests/vb20_kernel_tests.c b/tests/vb20_kernel_tests.c index 05f21ab6..6d685f64 100644 --- a/tests/vb20_kernel_tests.c +++ b/tests/vb20_kernel_tests.c @@ -67,7 +67,7 @@ static void rehash_keyblock(void) hashsig->sig_offset = vb2_offset_of(hashsig, mock_vblock.k.hash); hashsig->sig_size = sizeof(mock_vblock.k.hash); hashsig->data_size = hashsig->sig_offset; - vb2_digest_init(&dc, VB2_HASH_SHA512); + vb2_digest_init(&dc, false, VB2_HASH_SHA512, 0); vb2_digest_extend(&dc, (const uint8_t *)kb, hashsig->data_size); vb2_digest_finalize(&dc, mock_vblock.k.hash, hashsig->sig_size); } @@ -212,19 +212,6 @@ static void verify_keyblock_hash_tests(void) "Keyblock check hash sig"); reset_common_data(FOR_KEYBLOCK); - wb.size = VB2_SHA512_DIGEST_SIZE - 1; - TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb), - VB2_ERROR_VDATA_WORKBUF_DIGEST, - "Keyblock check hash workbuf digest"); - - reset_common_data(FOR_KEYBLOCK); - wb.size = VB2_SHA512_DIGEST_SIZE + - sizeof(struct vb2_digest_context) - 1; - TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb), - VB2_ERROR_VDATA_WORKBUF_HASHING, - "Keyblock check hash workbuf hashing"); - - reset_common_data(FOR_KEYBLOCK); mock_vblock.k.data_key_data[0] ^= 0xa0; TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb), VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE, diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c index ca2f7e93..2d0ffbf1 100644 --- a/tests/vb2_api_tests.c +++ b/tests/vb2_api_tests.c @@ -40,12 +40,6 @@ static const uint32_t digest_result_size = sizeof(digest_result); /* Mocked function data */ -static enum { - HWCRYPTO_DISABLED, - HWCRYPTO_ENABLED, - HWCRYPTO_FORBIDDEN, -} hwcrypto_state; - static int force_dev_mode; static vb2_error_t retval_vb2_fw_init_gbb; static vb2_error_t retval_vb2_check_dev_switch; @@ -81,9 +75,6 @@ static void reset_common_data(enum reset_type t) vb2api_secdata_kernel_create(ctx); vb2_secdata_kernel_init(ctx); - if (hwcrypto_state != HWCRYPTO_FORBIDDEN) - vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS, - VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED); force_dev_mode = 0; retval_vb2_fw_init_gbb = VB2_SUCCESS; @@ -176,59 +167,19 @@ vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key, return VB2_SUCCESS; } -vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, - uint32_t data_size) -{ - switch (hwcrypto_state) { - case HWCRYPTO_DISABLED: - return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; - case HWCRYPTO_ENABLED: - if (hash_alg != mock_hash_alg) - return VB2_ERROR_SHA_INIT_ALGORITHM; - else - return VB2_SUCCESS; - case HWCRYPTO_FORBIDDEN: - default: - return VB2_ERROR_UNKNOWN; - } -} - -vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, - uint32_t size) -{ - if (hwcrypto_state != HWCRYPTO_ENABLED) - return VB2_ERROR_UNKNOWN; - - 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); } -vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, - uint32_t digest_size) +vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto, + enum vb2_hash_algorithm algo, uint32_t data_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; -} - -vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, - enum vb2_hash_algorithm hash_alg) -{ - if (hwcrypto_state == HWCRYPTO_ENABLED) - return VB2_ERROR_UNKNOWN; - if (hash_alg != mock_hash_alg) + if (algo != mock_hash_alg) return VB2_ERROR_SHA_INIT_ALGORITHM; - dc->hash_alg = hash_alg; + dc->hash_alg = algo; dc->using_hwcrypto = 0; return VB2_SUCCESS; @@ -237,8 +188,6 @@ vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf, uint32_t size) { - if (hwcrypto_state == HWCRYPTO_ENABLED) - return VB2_ERROR_UNKNOWN; if (dc->hash_alg != mock_hash_alg) return VB2_ERROR_SHA_EXTEND_ALGORITHM; @@ -248,9 +197,6 @@ vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf, vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, 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); @@ -740,14 +686,11 @@ static void extend_hash_tests(void) TEST_EQ(vb2api_extend_hash(ctx, mock_body, 0), VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty"); - if (hwcrypto_state != HWCRYPTO_ENABLED) { - reset_common_data(FOR_EXTEND_HASH); - dc = (struct vb2_digest_context *) - vb2_member_of(sd, sd->hash_offset); - dc->hash_alg = mock_hash_alg + 1; - TEST_EQ(vb2api_extend_hash(ctx, mock_body, mock_body_size), - VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail"); - } + reset_common_data(FOR_EXTEND_HASH); + dc = (struct vb2_digest_context *)vb2_member_of(sd, sd->hash_offset); + dc->hash_alg = mock_hash_alg + 1; + TEST_EQ(vb2api_extend_hash(ctx, mock_body, mock_body_size), + VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail"); } static void check_hash_tests(void) @@ -766,28 +709,30 @@ static void check_hash_tests(void) "check digest value"); /* Test hwcrypto conditions */ - if (hwcrypto_state == HWCRYPTO_FORBIDDEN) { - reset_common_data(FOR_CHECK_HASH); - TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); - TEST_EQ(last_used_key.allow_hwcrypto, 0, - "hwcrypto is forbidden by TPM flag"); - - reset_common_data(FOR_CHECK_HASH); - ctx->flags |= VB2_CONTEXT_RECOVERY_MODE; - TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); - TEST_EQ(last_used_key.allow_hwcrypto, 0, - "hwcrypto is forbidden by TPM flag on recovery mode"); - } else { - reset_common_data(FOR_CHECK_HASH); - TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); - TEST_EQ(last_used_key.allow_hwcrypto, 1, "hwcrypto is allowed"); - - reset_common_data(FOR_CHECK_HASH); - ctx->flags |= VB2_CONTEXT_RECOVERY_MODE; - TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); - TEST_EQ(last_used_key.allow_hwcrypto, 0, - "hwcrypto is forbidden on recovery mode"); - } + reset_common_data(FOR_CHECK_HASH); + TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); + TEST_EQ(last_used_key.allow_hwcrypto, 0, + "hwcrypto is forbidden by TPM flag"); + + reset_common_data(FOR_CHECK_HASH); + ctx->flags |= VB2_CONTEXT_RECOVERY_MODE; + TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); + TEST_EQ(last_used_key.allow_hwcrypto, 0, + "hwcrypto is forbidden by TPM flag on recovery mode"); + + reset_common_data(FOR_CHECK_HASH); + vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS, + VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED); + TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); + TEST_EQ(last_used_key.allow_hwcrypto, 1, "hwcrypto is allowed"); + + reset_common_data(FOR_CHECK_HASH); + ctx->flags |= VB2_CONTEXT_RECOVERY_MODE; + vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS, + VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED); + TEST_SUCC(vb2api_check_hash(ctx), "check hash good"); + TEST_EQ(last_used_key.allow_hwcrypto, 0, + "hwcrypto is forbidden on recovery mode"); reset_common_data(FOR_CHECK_HASH); TEST_EQ(vb2api_check_hash_get_digest(ctx, digest_result, @@ -854,20 +799,6 @@ int main(int argc, char* argv[]) phase2_tests(); phase3_tests(); - fprintf(stderr, "Running hash API tests without hwcrypto support...\n"); - hwcrypto_state = HWCRYPTO_DISABLED; - init_hash_tests(); - extend_hash_tests(); - check_hash_tests(); - - fprintf(stderr, "Running hash API tests with hwcrypto support...\n"); - hwcrypto_state = HWCRYPTO_ENABLED; - init_hash_tests(); - extend_hash_tests(); - check_hash_tests(); - - fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n"); - hwcrypto_state = HWCRYPTO_FORBIDDEN; init_hash_tests(); extend_hash_tests(); check_hash_tests(); diff --git a/tests/vb2_common2_tests.c b/tests/vb2_common2_tests.c index e793e57a..18398c11 100644 --- a/tests/vb2_common2_tests.c +++ b/tests/vb2_common2_tests.c @@ -19,6 +19,28 @@ static const uint8_t test_data[] = "This is some test data to sign."; static const uint32_t test_size = sizeof(test_data); +static const uint8_t test_data_sha1[VB2_SHA1_DIGEST_SIZE] = { + 0x6f, 0xde, 0xe7, 0x73, 0x93, 0xbe, 0x23, 0x34, + 0xb3, 0x54, 0xc2, 0xe9, 0x18, 0xb8, 0x1b, 0xf8, + 0x99, 0x36, 0x63, 0x09, +}; +static const uint8_t test_data_sha256[VB2_SHA256_DIGEST_SIZE] = { + 0xc0, 0x2c, 0xdb, 0x18, 0xe4, 0xd9, 0xfc, 0x65, + 0xcb, 0xea, 0x11, 0x8e, 0x9e, 0x1c, 0x51, 0x2d, + 0xeb, 0x69, 0x5f, 0x56, 0x1f, 0xd8, 0x77, 0x7b, + 0x7d, 0x9d, 0x4f, 0x21, 0x81, 0xac, 0x9e, 0xd5, +}; +static const uint8_t test_data_sha512[VB2_SHA512_DIGEST_SIZE] = { + 0x0e, 0x0c, 0x9c, 0xf7, 0x08, 0x28, 0xee, 0xd7, + 0x0d, 0x62, 0xf5, 0x46, 0xa1, 0x2d, 0xf3, 0x79, + 0x41, 0x0c, 0x80, 0xbf, 0xaf, 0x1f, 0xfa, 0x41, + 0xdb, 0x8e, 0x30, 0x02, 0x16, 0xf1, 0x4b, 0x2c, + 0x67, 0x1f, 0x5b, 0xfb, 0x06, 0x49, 0xc9, 0xf4, + 0x6b, 0x62, 0xb9, 0x27, 0x94, 0xc3, 0xf4, 0xb8, + 0xc7, 0x23, 0x40, 0xc5, 0xfb, 0x74, 0xab, 0xa4, + 0x63, 0xfd, 0x3f, 0xf3, 0x2b, 0xa3, 0xc5, 0x3b, +}; +static const uint8_t *hwcrypto_next_hash; static enum hwcrypto_state { HWCRYPTO_OK, @@ -44,9 +66,23 @@ static vb2_error_t hwcrypto_mock(enum hwcrypto_state *state) return VB2_ERROR_MOCK; } -vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, +vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm algo, uint32_t data_size) { + switch (algo) { + case VB2_HASH_SHA1: + hwcrypto_next_hash = test_data_sha1; + break; + case VB2_HASH_SHA256: + hwcrypto_next_hash = test_data_sha256; + break; + case VB2_HASH_SHA512: + hwcrypto_next_hash = test_data_sha512; + break; + default: + TEST_TRUE(false, " no mock hash for algorithm"); + break; + } return hwcrypto_mock(&hwcrypto_state_digest); } @@ -58,6 +94,7 @@ vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size) { + memcpy(digest, hwcrypto_next_hash, digest_size); return hwcrypto_mock(&hwcrypto_state_digest); } diff --git a/tests/vb2_load_kernel2_tests.c b/tests/vb2_load_kernel2_tests.c index dfb06fbf..3ec392fa 100644 --- a/tests/vb2_load_kernel2_tests.c +++ b/tests/vb2_load_kernel2_tests.c @@ -235,9 +235,8 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size, return cur_kernel->rv; } -vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, - enum vb2_hash_algorithm hash_alg, uint8_t *digest, - uint32_t digest_size) +vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, + uint32_t digest_size) { return cur_kernel->rv; } diff --git a/tests/vb2_load_kernel_tests.c b/tests/vb2_load_kernel_tests.c index bb6f3487..932bc128 100644 --- a/tests/vb2_load_kernel_tests.c +++ b/tests/vb2_load_kernel_tests.c @@ -262,11 +262,13 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size, return VB2_SUCCESS; } -vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, - enum vb2_hash_algorithm hash_alg, uint8_t *digest, - uint32_t digest_size) +vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, + uint32_t digest_size) { - memcpy(digest, mock_digest, sizeof(mock_digest)); + if (digest_size == sizeof(mock_digest)) + memcpy(digest, mock_digest, digest_size); + else + TEST_TRUE(false, " unexpected digest size"); return VB2_SUCCESS; } diff --git a/tests/vb2_sha256_x86_tests.c b/tests/vb2_sha256_x86_tests.c index e17d3951..3269cc54 100644 --- a/tests/vb2_sha256_x86_tests.c +++ b/tests/vb2_sha256_x86_tests.c @@ -13,9 +13,9 @@ #include "common/tests.h" #include "sha_test_vectors.h" -vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, - enum vb2_hash_algorithm hash_alg, uint8_t *digest, - uint32_t digest_size) +static vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size, + enum vb2_hash_algorithm hash_alg, + uint8_t *digest, uint32_t digest_size) { VB2_TRY(vb2ex_hwcrypto_digest_init(hash_alg, size)); VB2_TRY(vb2ex_hwcrypto_digest_extend(buf, size)); diff --git a/tests/vb2_sha_api_tests.c b/tests/vb2_sha_api_tests.c index 6ed0b74b..be277b38 100644 --- a/tests/vb2_sha_api_tests.c +++ b/tests/vb2_sha_api_tests.c @@ -2,9 +2,11 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * Tests for vb2_hash_(calculate|verify) functions. + * Tests for vb2_hash_(calculate|verify) functions, and hwcrypto handling + * of vb2_digest_*. */ +#include "2api.h" #include "2return_codes.h" #include "2sha.h" #include "2sysincludes.h" @@ -17,41 +19,83 @@ _Static_assert(sizeof(mock_sha1) == VB2_SHA1_DIGEST_SIZE, ""); struct vb2_hash mock_hash; uint8_t mock_buffer[] = "Mock Buffer"; -vb2_error_t mock_init_rv; -vb2_error_t mock_extend_rv; -vb2_error_t mock_finalize_rv; +static enum hwcrypto_state { + HWCRYPTO_OK, + HWCRYPTO_NOTSUPPORTED, + HWCRYPTO_ERROR, + HWCRYPTO_ABORT, +} hwcrypto_state; -static void reset_common_data(void) +static vb2_error_t hwcrypto_mock(enum hwcrypto_state *state) { + switch (*state) { + case HWCRYPTO_OK: + return VB2_SUCCESS; + case HWCRYPTO_NOTSUPPORTED: + return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; + case HWCRYPTO_ERROR: + return VB2_ERROR_MOCK; + case HWCRYPTO_ABORT: + vb2ex_abort(); + /* shouldn't reach here but added for compiler */ + return VB2_ERROR_MOCK; + } + return VB2_ERROR_MOCK; +} + +static void reset_common_data(enum hwcrypto_state state) +{ + hwcrypto_state = state; memset(&mock_hash, 0xaa, sizeof(mock_hash)); +} - mock_init_rv = VB2_SUCCESS; - mock_extend_rv = VB2_SUCCESS; - mock_finalize_rv = VB2_SUCCESS; +void vb2_sha1_init(struct vb2_sha1_context *ctx) +{ + TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED || + hwcrypto_state == HWCRYPTO_ABORT, + " hwcrypto_state in SW init"); } -vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, - enum vb2_hash_algorithm hash_alg) +void vb2_sha1_update(struct vb2_sha1_context *ctx, + const uint8_t *data, + uint32_t size) { - if (hash_alg != VB2_HASH_SHA1) - return VB2_ERROR_MOCK; - return mock_init_rv; + TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED || + hwcrypto_state == HWCRYPTO_ABORT, + " hwcrypto_state in SW extend"); + TEST_PTR_EQ(data, mock_buffer, " digest_extend buf"); + TEST_EQ(size, sizeof(mock_buffer), " digest_extend size"); +} + +void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest) +{ + TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED || + hwcrypto_state == HWCRYPTO_ABORT, + " hwcrypto_state in SW finalize"); + memcpy(digest, mock_sha1, sizeof(mock_sha1)); } -vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf, - uint32_t size) +vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, + uint32_t data_size) { - TEST_PTR_EQ(buf, mock_buffer, "digest_extend unexpected buf"); - TEST_EQ(size, sizeof(mock_buffer), "digest_extend unexpected size"); - return mock_extend_rv; + if (data_size) + TEST_EQ(data_size, sizeof(mock_buffer), + " hwcrypto_digest_init size"); + return hwcrypto_mock(&hwcrypto_state); } -vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, - uint32_t size) +vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) { - TEST_EQ(size, VB2_SHA1_DIGEST_SIZE, "digest_finalize unexpected size"); - memcpy(digest, mock_sha1, size); - return mock_finalize_rv; + TEST_PTR_EQ(buf, mock_buffer, " hwcrypto_digest_extend buf"); + TEST_EQ(size, sizeof(mock_buffer), " hwcrypto_digest_extend size"); + return hwcrypto_mock(&hwcrypto_state); +} + +vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, + uint32_t digest_size) +{ + memcpy(digest, mock_sha1, sizeof(mock_sha1)); + return hwcrypto_mock(&hwcrypto_state); } static void vb2_hash_cbfs_compatibility_test(void) @@ -73,56 +117,93 @@ static void vb2_hash_cbfs_compatibility_test(void) static void vb2_hash_calculate_tests(void) { - reset_common_data(); - TEST_SUCC(vb2_hash_calculate(&mock_buffer, sizeof(mock_buffer), + reset_common_data(HWCRYPTO_ABORT); + TEST_SUCC(vb2_hash_calculate(false, &mock_buffer, sizeof(mock_buffer), VB2_HASH_SHA1, &mock_hash), "hash_calculate success"); TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)), " got the right hash"); TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, " set algo correctly"); - reset_common_data(); - mock_init_rv = VB2_ERROR_MOCK; - TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer), - VB2_HASH_SHA1, &mock_hash), - VB2_ERROR_MOCK, "hash_calculate init error"); - - reset_common_data(); - mock_extend_rv = VB2_ERROR_MOCK; - TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer), - VB2_HASH_SHA1, &mock_hash), - VB2_ERROR_MOCK, "hash_calculate extend error"); - - reset_common_data(); - mock_finalize_rv = VB2_ERROR_MOCK; - TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer), - VB2_HASH_SHA1, &mock_hash), - VB2_ERROR_MOCK, "hash_calculate finalize error"); + reset_common_data(HWCRYPTO_ABORT); + TEST_EQ(vb2_hash_calculate(false, mock_buffer, sizeof(mock_buffer), + -1, &mock_hash), + VB2_ERROR_SHA_INIT_ALGORITHM, "hash_calculate wrong algo"); } static void vb2_hash_verify_tests(void) { - reset_common_data(); + reset_common_data(HWCRYPTO_ABORT); memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)); mock_hash.algo = VB2_HASH_SHA1; - TEST_SUCC(vb2_hash_verify(mock_buffer, sizeof(mock_buffer), + TEST_SUCC(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer), &mock_hash), "hash_verify success"); memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)); - mock_hash.algo = VB2_HASH_SHA256; - TEST_EQ(vb2_hash_verify(mock_buffer, sizeof(mock_buffer), - &mock_hash), VB2_ERROR_MOCK, + mock_hash.algo = -1; + TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer), + &mock_hash), VB2_ERROR_SHA_INIT_ALGORITHM, "hash_verify wrong algo"); memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)); mock_hash.sha1[5] = 0xfe; mock_hash.algo = VB2_HASH_SHA1; - TEST_EQ(vb2_hash_verify(mock_buffer, sizeof(mock_buffer), + TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer), &mock_hash), VB2_ERROR_SHA_MISMATCH, "hash_verify mismatch"); } +static void vb2_hash_hwcrypto_tests(void) +{ + struct vb2_digest_context dc; + + reset_common_data(HWCRYPTO_OK); + TEST_SUCC(vb2_digest_init(&dc, true, VB2_HASH_SHA1, + sizeof(mock_buffer)), + "digest_init, HW enabled"); + TEST_EQ(dc.using_hwcrypto, 1, " using_hwcrypto set"); + TEST_SUCC(vb2_digest_extend(&dc, mock_buffer, sizeof(mock_buffer)), + "digest_extend, HW enabled"); + TEST_SUCC(vb2_digest_finalize(&dc, mock_hash.raw, VB2_SHA1_DIGEST_SIZE), + "digest_finalize, HW enabled "); + TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)), + " got the right hash"); + + reset_common_data(HWCRYPTO_OK); + TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer), + VB2_HASH_SHA1, &mock_hash), + "hash_calculate, HW enabled"); + TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)), + " got the right hash"); + TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, " algo set"); + + reset_common_data(HWCRYPTO_ERROR); + TEST_EQ(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer), + VB2_HASH_SHA1, &mock_hash), + VB2_ERROR_MOCK, "hash_calculate, HW error"); + + reset_common_data(HWCRYPTO_NOTSUPPORTED); + TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer), + VB2_HASH_SHA1, &mock_hash), + "hash_calculate, HW unsupported"); + TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)), + " got the right hash"); + + reset_common_data(HWCRYPTO_OK); + memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)); + mock_hash.algo = VB2_HASH_SHA1; + TEST_SUCC(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer), + &mock_hash), "hash_verify, HW enabled"); + + memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)); + mock_hash.sha1[5] = 0xfe; + mock_hash.algo = VB2_HASH_SHA1; + TEST_EQ(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer), + &mock_hash), VB2_ERROR_SHA_MISMATCH, + "hash_verify HW mismatch"); +} + int main(int argc, char *argv[]) { TEST_EQ(sizeof(mock_hash), @@ -132,6 +213,7 @@ int main(int argc, char *argv[]) vb2_hash_cbfs_compatibility_test(); vb2_hash_calculate_tests(); vb2_hash_verify_tests(); + vb2_hash_hwcrypto_tests(); return gTestSuccess ? 0 : 255; } diff --git a/tests/vb2_sha_tests.c b/tests/vb2_sha_tests.c index 40cf42f5..92213830 100644 --- a/tests/vb2_sha_tests.c +++ b/tests/vb2_sha_tests.c @@ -16,7 +16,7 @@ static void sha1_tests(void) { - uint8_t digest[VB2_SHA1_DIGEST_SIZE]; + struct vb2_hash hash; uint8_t *test_inputs[3]; int i; @@ -25,20 +25,21 @@ static void sha1_tests(void) test_inputs[2] = (uint8_t *) long_msg; for (i = 0; i < 3; i++) { - TEST_SUCC(vb2_digest_buffer(test_inputs[i], - strlen((char *)test_inputs[i]), - VB2_HASH_SHA1, - digest, sizeof(digest)), - "vb2_digest_buffer() SHA1"); - TEST_EQ(memcmp(digest, sha1_results[i], sizeof(digest)), - 0, "SHA1 digest"); + TEST_SUCC(vb2_hash_calculate(false, test_inputs[i], + strlen((const char *)test_inputs[i]), + VB2_HASH_SHA1, &hash), + "vb2_hash_calculate() SHA-1"); + TEST_EQ(memcmp(hash.sha1, sha1_results[i], + sizeof(sha1_results[i])), 0, " SHA-1 digest"); } - TEST_EQ(vb2_digest_buffer(test_inputs[0], - strlen((char *)test_inputs[0]), - VB2_HASH_SHA1, digest, sizeof(digest) - 1), + struct vb2_digest_context dc; + vb2_digest_init(&dc, false, VB2_HASH_SHA1, 0); + vb2_digest_extend(&dc, test_inputs[0], + strlen((const char *)test_inputs[0])); + TEST_EQ(vb2_digest_finalize(&dc, hash.sha1, sizeof(hash.sha1) - 1), VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, - "vb2_digest_buffer() too small"); + "vb2_digest_finalize() SHA-1 too small"); TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA1), VB2_SHA1_BLOCK_SIZE, "vb2_hash_block_size(VB2_HASH_SHA1)"); @@ -46,7 +47,7 @@ static void sha1_tests(void) static void sha256_tests(void) { - uint8_t digest[VB2_SHA256_DIGEST_SIZE]; + struct vb2_hash hash; uint8_t *test_inputs[3]; struct vb2_sha256_context ctx; const uint8_t expect_multiple[VB2_SHA256_DIGEST_SIZE] = { @@ -68,41 +69,41 @@ static void sha256_tests(void) test_inputs[2] = (uint8_t *) long_msg; for (i = 0; i < 3; i++) { - TEST_SUCC(vb2_digest_buffer(test_inputs[i], - strlen((char *)test_inputs[i]), - VB2_HASH_SHA256, - digest, sizeof(digest)), - "vb2_digest_buffer() SHA256"); - TEST_EQ(memcmp(digest, sha256_results[i], sizeof(digest)), - 0, "SHA-256 digest"); + TEST_SUCC(vb2_hash_calculate(false, test_inputs[i], + strlen((const char *)test_inputs[i]), + VB2_HASH_SHA256, &hash), + "vb2_hash_calculate() SHA-256"); + TEST_EQ(memcmp(hash.sha256, sha256_results[i], + sizeof(sha256_results[i])), 0, " SHA-256 digest"); } - TEST_EQ(vb2_digest_buffer(test_inputs[0], - strlen((char *)test_inputs[0]), - VB2_HASH_SHA256, digest, sizeof(digest) - 1), + struct vb2_digest_context dc; + vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0); + vb2_digest_extend(&dc, test_inputs[0], strlen((const char *)test_inputs[0])); + TEST_EQ(vb2_digest_finalize(&dc, hash.sha256, sizeof(hash.sha256) - 1), VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, - "vb2_digest_buffer() too small"); + "vb2_digest_finalize() SHA-256 too small"); /* Test multiple small extends */ vb2_sha256_init(&ctx, VB2_HASH_SHA256); vb2_sha256_update(&ctx, (uint8_t *)"test1", 5); vb2_sha256_update(&ctx, (uint8_t *)"test2", 5); vb2_sha256_update(&ctx, (uint8_t *)"test3", 5); - vb2_sha256_finalize(&ctx, digest, VB2_HASH_SHA256); - TEST_EQ(memcmp(digest, expect_multiple, sizeof(digest)), 0, + vb2_sha256_finalize(&ctx, hash.sha256, VB2_HASH_SHA256); + TEST_EQ(memcmp(hash.sha256, expect_multiple, sizeof(hash.sha256)), 0, "SHA-256 multiple extends"); TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA256), VB2_SHA256_BLOCK_SIZE, "vb2_hash_block_size(VB2_HASH_SHA256)"); /* Test SHA256 hash extend */ - vb2_sha256_extend(extend_from, extend_by, digest); - TEST_SUCC(memcmp(digest, expected_extend, sizeof(digest)), NULL); + vb2_sha256_extend(extend_from, extend_by, hash.sha256); + TEST_SUCC(memcmp(hash.sha256, expected_extend, sizeof(hash.sha256)), NULL); } static void sha512_tests(void) { - uint8_t digest[VB2_SHA512_DIGEST_SIZE]; + struct vb2_hash hash; uint8_t *test_inputs[3]; int i; @@ -111,20 +112,20 @@ static void sha512_tests(void) test_inputs[2] = (uint8_t *) long_msg; for (i = 0; i < 3; i++) { - TEST_SUCC(vb2_digest_buffer(test_inputs[i], - strlen((char *)test_inputs[i]), - VB2_HASH_SHA512, - digest, sizeof(digest)), - "vb2_digest_buffer() SHA512"); - TEST_EQ(memcmp(digest, sha512_results[i], sizeof(digest)), - 0, "SHA-512 digest"); + TEST_SUCC(vb2_hash_calculate(false, test_inputs[i], + strlen((const char *)test_inputs[i]), + VB2_HASH_SHA512, &hash), + "vb2_hash_calculate() SHA512"); + TEST_EQ(memcmp(hash.sha512, sha512_results[i], + sizeof(sha512_results[i])), 0, " SHA-512 digest"); } - TEST_EQ(vb2_digest_buffer(test_inputs[0], - strlen((char *)test_inputs[0]), - VB2_HASH_SHA512, digest, sizeof(digest) - 1), + struct vb2_digest_context dc; + vb2_digest_init(&dc, false, VB2_HASH_SHA512, 0); + vb2_digest_extend(&dc, test_inputs[0], strlen((const char *)test_inputs[0])); + TEST_EQ(vb2_digest_finalize(&dc, hash.sha512, sizeof(hash.sha512) - 1), VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE, - "vb2_digest_buffer() too small"); + "vb2_digest_finalize() SHA-512 too small"); TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA512), VB2_SHA512_BLOCK_SIZE, "vb2_hash_block_size(VB2_HASH_SHA512)"); @@ -153,13 +154,8 @@ static void misc_tests(void) TEST_EQ(vb2_hash_block_size(VB2_HASH_INVALID), 0, "vb2_hash_block_size(VB2_HASH_INVALID)"); - TEST_EQ(vb2_digest_buffer((uint8_t *)oneblock_msg, strlen(oneblock_msg), - VB2_HASH_INVALID, digest, sizeof(digest)), - VB2_ERROR_SHA_INIT_ALGORITHM, - "vb2_digest_buffer() invalid alg"); - /* Test bad algorithm inside extend and finalize */ - vb2_digest_init(&dc, VB2_HASH_SHA256); + vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0); dc.hash_alg = VB2_HASH_INVALID; TEST_EQ(vb2_digest_extend(&dc, digest, sizeof(digest)), VB2_ERROR_SHA_EXTEND_ALGORITHM, @@ -185,7 +181,7 @@ static void known_value_tests(void) char *sent_base = test.overflow + \ offsetof(struct vb2_hash, raw) + sizeof(value) - 1; \ strcpy(sent_base, sentinel); \ - TEST_SUCC(vb2_hash_calculate(str, sizeof(str) - 1, \ + TEST_SUCC(vb2_hash_calculate(false, str, sizeof(str) - 1, \ algo, &test.hash), \ "Calculate known hash " #algo ": " #str); \ TEST_EQ(memcmp(test.hash.raw, value, sizeof(value) - 1), 0, \ |