void misc_tests(void) { uint8_t digest[VB2_SHA512_DIGEST_SIZE]; struct vb2_digest_context dc; /* Crypto algorithm to hash algorithm mapping */ TEST_EQ(vb2_crypto_to_hash(VB2_ALG_RSA1024_SHA1), VB2_HASH_SHA1, "Crypto map to SHA1"); TEST_EQ(vb2_crypto_to_hash(VB2_ALG_RSA2048_SHA256), VB2_HASH_SHA256, "Crypto map to SHA256"); TEST_EQ(vb2_crypto_to_hash(VB2_ALG_RSA4096_SHA256), VB2_HASH_SHA256, "Crypto map to SHA256 2"); TEST_EQ(vb2_crypto_to_hash(VB2_ALG_RSA8192_SHA512), VB2_HASH_SHA512, "Crypto map to SHA512"); TEST_EQ(vb2_crypto_to_hash(VB2_ALG_COUNT), VB2_HASH_INVALID, "Crypto map to invalid"); TEST_EQ(vb2_digest_size(VB2_HASH_INVALID), 0, "digest size invalid alg"); TEST_EQ(vb2_digest((uint8_t *)oneblock_msg, strlen(oneblock_msg), VB2_HASH_INVALID, digest, sizeof(digest)), VB2_ERROR_SHA_INIT_ALGORITHM, "vb2_digest() invalid alg"); /* Test bad algorithm inside extend and finalize */ vb2_digest_init(&dc, VB2_HASH_SHA256); dc.hash_alg = VB2_HASH_INVALID; TEST_EQ(vb2_digest_extend(&dc, digest, sizeof(digest)), VB2_ERROR_SHA_EXTEND_ALGORITHM, "vb2_digest_extend() invalid alg"); TEST_EQ(vb2_digest_finalize(&dc, digest, sizeof(digest)), VB2_ERROR_SHA_FINALIZE_ALGORITHM, "vb2_digest_finalize() invalid alg"); }
int vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest, uint32_t digest_size) { if (digest_size < vb2_digest_size(dc->hash_alg)) return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE; switch (dc->hash_alg) { #if VB2_SUPPORT_SHA1 case VB2_HASH_SHA1: vb2_sha1_finalize(&dc->sha1, digest); return VB2_SUCCESS; #endif #if VB2_SUPPORT_SHA256 case VB2_HASH_SHA256: vb2_sha256_finalize(&dc->sha256, digest); return VB2_SUCCESS; #endif #if VB2_SUPPORT_SHA512 case VB2_HASH_SHA512: vb2_sha512_finalize(&dc->sha512, digest); return VB2_SUCCESS; #endif default: return VB2_ERROR_SHA_FINALIZE_ALGORITHM; } }
int vb2api_check_hash(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_digest_context *dc = (struct vb2_digest_context *) (ctx->workbuf + sd->workbuf_hash_offset); struct vb2_workbuf wb; uint8_t *digest; uint32_t digest_size = vb2_digest_size(dc->hash_alg); const struct vb2_signature *sig; int rv; vb2_workbuf_from_ctx(ctx, &wb); /* Get signature pointer */ if (!sd->hash_tag) return VB2_ERROR_API_CHECK_HASH_TAG; sig = (const struct vb2_signature *)(ctx->workbuf + sd->hash_tag); /* Must have initialized hash digest work area */ if (!sd->workbuf_hash_size) return VB2_ERROR_API_CHECK_HASH_WORKBUF; /* Should have hashed the right amount of data */ if (sd->hash_remaining_size) return VB2_ERROR_API_CHECK_HASH_SIZE; /* Allocate the digest */ digest = vb2_workbuf_alloc(&wb, digest_size); if (!digest) return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; /* Finalize the digest */ if (dc->using_hwcrypto) rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size); else rv = vb2_digest_finalize(dc, digest, digest_size); if (rv) return rv; /* Compare with the signature */ if (vb2_safe_memcmp(digest, (const uint8_t *)sig + sig->sig_offset, digest_size)) return VB2_ERROR_API_CHECK_HASH_SIG; // TODO: the old check-hash function called vb2_fail() on any mismatch. // I don't think it should do that; the caller should. return VB2_SUCCESS; }
int vb2_verify_data(const uint8_t *data, uint32_t size, struct vb2_signature *sig, const struct vb2_public_key *key, const struct vb2_workbuf *wb) { struct vb2_workbuf wblocal = *wb; struct vb2_digest_context *dc; uint8_t *digest; uint32_t digest_size; int rv; 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; digest = vb2_workbuf_alloc(&wblocal, digest_size); if (!digest) return VB2_ERROR_VDATA_WORKBUF_DIGEST; /* Hashing requires temp space for the context */ dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); if (!dc) return VB2_ERROR_VDATA_WORKBUF_HASHING; rv = vb2_digest_init(dc, key->hash_alg); if (rv) return rv; rv = vb2_digest_extend(dc, data, sig->data_size); if (rv) return rv; rv = vb2_digest_finalize(dc, digest, digest_size); if (rv) return rv; vb2_workbuf_free(&wblocal, sizeof(*dc)); return vb2_verify_digest(key, sig, digest, &wblocal); }