summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-09-27 17:47:29 -0700
committerCommit Bot <commit-bot@chromium.org>2021-10-02 04:01:49 +0000
commit0ad46f2259b79b07a1d4b114fd58472a88c19282 (patch)
tree8313e9894a779c602cca27fd79b81bcc9a7ca3b6
parent7b25ee08172491864900e3a2ba59d761355f4069 (diff)
downloadchrome-ec-0ad46f2259b79b07a1d4b114fd58472a88c19282.tar.gz
cr50: provide public crypto API for HMAC/HASH with error reporting.
To implement FIPS mode for Cr50 we should be able to block access to crypto functions if errors are detected. Historically all HASH/HMAC functions were declared as void with no return type. 1) Split existing functions into public part (data structs, update and final parts) and internal part - unchecked init functions. 2) Introduced new functions to start SHA / HMAC operation which returns status code and block access to crypto in case of FIPS errors. 3) Dcrypto hash algorithms codes updated to match TPM_ALG_ID to simplify adaptation layer and move checks inside Dcrypto module. 4) Updated all uses of API outside FIPS module to check return code and act accordingly. 5) As a side effect RSA can now support SHA384 & SHA512 for signing, board/host mock ups simplified. BUG=b:197893750 TEST=make buildall -j; make BOARD=cr50 CRYPTO_TEST=1; test/tpm_test/tpm_test.py TCG tests ------------------------------ Test Result Summary --------------------- Test executed on: Tue Sep 28 15:23:35 2021 Performed Tests: 248 Passed Tests: 248 Failed Tests: 0 Errors: 0 Warnings: 0 ======================================================================== Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: Ibbc38703496f417cba693c37d39a82a662c3f7ee Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3192137 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/build.mk2
-rw-r--r--board/cr50/dcrypto/dcrypto.h605
-rw-r--r--board/cr50/dcrypto/hash_api.c170
-rw-r--r--board/cr50/dcrypto/hmacsha2.h523
-rw-r--r--board/cr50/dcrypto/internal.h149
-rw-r--r--board/cr50/dcrypto/rsa.c302
-rw-r--r--board/cr50/dcrypto/sha_hw.c4
-rw-r--r--board/cr50/tpm2/ecc.c6
-rw-r--r--board/cr50/tpm2/endorsement.c10
-rw-r--r--board/cr50/tpm2/hash.c83
-rw-r--r--board/cr50/tpm2/rsa.c8
-rw-r--r--board/cr50/tpm2/virtual_nvmem.c8
-rw-r--r--board/cr50/usb_spi.c3
-rw-r--r--board/host/dcrypto.h70
-rw-r--r--chip/host/build.mk4
-rw-r--r--chip/host/dcrypto/app_cipher.c7
-rw-r--r--chip/host/dcrypto/sha256.c13
-rw-r--r--common/ccd_config.c24
-rw-r--r--common/pinweaver.c90
-rw-r--r--common/rma_auth.c45
-rw-r--r--fuzz/mem_hash_tree.cc6
-rw-r--r--include/pinweaver.h7
-rw-r--r--include/rma_auth.h3
-rw-r--r--test/pinweaver.c19
-rw-r--r--test/u2f.c5
25 files changed, 1259 insertions, 907 deletions
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index c3ab7a6f53..1fa86307a5 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -116,7 +116,7 @@ ifneq ($(CRYPTO_TEST),)
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/gcm.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hkdf.o
endif
-
+fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hash_api.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hmac_sw.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hmac_drbg.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/key_ladder.o
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index 035ce9b18c..bbb8e0b2ef 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -16,7 +16,7 @@ extern "C" {
#include <stdbool.h>
#include <stddef.h>
-#include "hmacsha2.h"
+#include "common.h"
/**
* Result codes for crypto operations, targeting
@@ -39,17 +39,571 @@ enum cipher_mode {
enum encrypt_mode { DECRYPT_MODE = 0, ENCRYPT_MODE = 1 };
enum hashing_mode {
- HASH_SHA1 = 0,
- HASH_SHA256 = 1,
- HASH_SHA384 = 2, /* Only supported for PKCS#1 signing */
- HASH_SHA512 = 3, /* Only supported for PKCS#1 signing */
- HASH_NULL = 4 /* Only supported for PKCS#1 signing */
+ HASH_SHA1 = 0x0004, /* = TPM_ALG_SHA1 */
+ HASH_SHA256 = 0x000B, /* = TPM_ALG_SHA256 */
+ HASH_SHA384 = 0x000C, /* = TPM_ALG_SHA384 */
+ HASH_SHA512 = 0x000D, /* = TPM_ALG_SHA512 */
+ HASH_NULL = 0x0010 /* = TPM_ALG_NULL, Only supported for PKCS#1 */
};
#ifndef __warn_unused_result
#define __warn_unused_result __attribute__((warn_unused_result))
#endif
+/**
+ * SHA1/SHA2, HMAC API
+ */
+#define SHA1_DIGEST_SIZE 20
+#define SHA_DIGEST_SIZE SHA1_DIGEST_SIZE
+
+#define SHA224_DIGEST_SIZE 28
+#define SHA256_DIGEST_SIZE 32
+#define SHA1_BLOCK_SIZE 64
+#define SHA1_BLOCK_WORDS (SHA1_BLOCK_SIZE / sizeof(uint32_t))
+#define SHA1_BLOCK_DWORDS (SHA1_BLOCK_SIZE / sizeof(uint64_t))
+#define SHA1_DIGEST_WORDS (SHA1_DIGEST_SIZE / sizeof(uint32_t))
+#define SHA224_BLOCK_SIZE 64
+#define SHA224_BLOCK_WORDS (SHA224_BLOCK_SIZE / sizeof(uint32_t))
+#define SHA224_BLOCK_DWORDS (SHA224_BLOCK_SIZE / sizeof(uint64_t))
+#define SHA224_DIGEST_WORDS (SHA224_DIGEST_SIZE / sizeof(uint32_t))
+#define SHA256_BLOCK_SIZE 64
+#define SHA256_BLOCK_WORDS (SHA256_BLOCK_SIZE / sizeof(uint32_t))
+#define SHA256_BLOCK_DWORDS (SHA256_BLOCK_SIZE / sizeof(uint64_t))
+#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
+
+#define SHA_DIGEST_WORDS (SHA_DIGEST_SIZE / sizeof(uint32_t))
+#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
+
+#ifdef CONFIG_UPTO_SHA512
+#define SHA_DIGEST_MAX_BYTES SHA512_DIGEST_SIZE
+#else
+#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_SIZE
+#endif
+
+/**
+ * Hash contexts. Each context starts with pointer to vtable containing
+ * functions to perform implementation specific operations.
+ * It is designed to support both software and hardware implementations.
+ * Contexts for different digest types can overlap, but vtable stores
+ * actual size of context which enables stack-efficient implementation of
+ * HMAC - say HMAC SHA2-256 shouldn't reserve space as for HMAC SHA2-512.
+ */
+union hash_ctx; /* forward declaration of generic hash context type */
+union hmac_ctx; /* forward declaration of generic HMAC context type */
+
+union sha_digests; /* forward declaration of generic digest type */
+
+/* Combined HASH & HMAC vtable to support SW & HW implementations. */
+struct hash_vtable {
+ /* SHA init function, used primarily by SW HMAC implementation. */
+ void (*const init)(union hash_ctx *const);
+ /* Update function for SHA & HMAC, assuming it's the same. */
+ void (*const update)(union hash_ctx *const, const void *, size_t);
+ /* SHA final function, digest specific. */
+ const union sha_digests *(*const final)(union hash_ctx *const);
+
+ /* HW HMAC support may require special ending. */
+ const union sha_digests *(*const hmac_final)(union hmac_ctx *const);
+
+ /* Digest size of in bytes. */
+ size_t digest_size;
+
+ /* Digest block size in bytes. */
+ size_t block_size;
+
+ /* Offset of first byte after context, used for HMAC */
+ size_t context_size;
+};
+
+struct sha256_digest {
+ union {
+ uint8_t b8[SHA256_DIGEST_SIZE];
+ uint32_t b32[SHA256_DIGEST_WORDS];
+ };
+};
+BUILD_ASSERT(sizeof(struct sha256_digest) == SHA256_DIGEST_SIZE);
+
+struct sha224_digest {
+ union {
+ uint8_t b8[SHA224_DIGEST_SIZE];
+ uint32_t b32[SHA224_DIGEST_WORDS];
+ };
+};
+BUILD_ASSERT(sizeof(struct sha224_digest) == SHA224_DIGEST_SIZE);
+
+struct sha1_digest {
+ union {
+ uint8_t b8[SHA1_DIGEST_SIZE];
+ uint32_t b32[SHA1_DIGEST_WORDS];
+ };
+};
+BUILD_ASSERT(sizeof(struct sha1_digest) == SHA1_DIGEST_SIZE);
+
+
+/* SHA256 specific type to allocate just enough memory. */
+struct sha256_ctx {
+ const struct hash_vtable *f; /* metadata & vtable */
+ size_t count; /* number of bytes processed */
+ uint32_t state[SHA256_DIGEST_WORDS]; /* up to SHA2-256 */
+ union {
+ uint8_t b8[SHA256_BLOCK_SIZE];
+ uint32_t b32[SHA256_BLOCK_WORDS];
+ uint64_t b64[SHA256_BLOCK_DWORDS];
+ struct sha256_digest digest;
+ };
+};
+
+#define sha224_ctx sha256_ctx
+
+struct sha1_ctx {
+ const struct hash_vtable *f; /* metadata & vtable. */
+ size_t count; /* number of bytes processed. */
+ uint32_t state[SHA1_DIGEST_WORDS];
+ union {
+ uint8_t b8[SHA1_BLOCK_SIZE];
+ uint32_t b32[SHA1_BLOCK_WORDS];
+ uint64_t b64[SHA1_BLOCK_DWORDS];
+ struct sha1_digest digest;
+ };
+};
+
+#ifdef CONFIG_UPTO_SHA512
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
+
+#define SHA384_BLOCK_SIZE 128
+#define SHA512_BLOCK_SIZE 128
+
+#define SHA384_BLOCK_WORDS (SHA384_BLOCK_SIZE / sizeof(uint32_t))
+#define SHA384_BLOCK_DWORDS (SHA384_BLOCK_SIZE / sizeof(uint64_t))
+#define SHA384_DIGEST_WORDS (SHA384_DIGEST_SIZE / sizeof(uint32_t))
+#define SHA384_DIGEST_DWORDS (SHA384_DIGEST_SIZE / sizeof(uint64_t))
+
+#define SHA512_BLOCK_WORDS (SHA512_BLOCK_SIZE / sizeof(uint32_t))
+#define SHA512_BLOCK_DWORDS (SHA512_BLOCK_SIZE / sizeof(uint64_t))
+#define SHA512_DIGEST_WORDS (SHA512_DIGEST_SIZE / sizeof(uint32_t))
+#define SHA512_DIGEST_DWORDS (SHA512_DIGEST_SIZE / sizeof(uint64_t))
+
+struct sha384_digest {
+ union {
+ uint8_t b8[SHA384_DIGEST_SIZE];
+ uint32_t b32[SHA384_DIGEST_WORDS];
+ };
+};
+BUILD_ASSERT(sizeof(struct sha384_digest) == SHA384_DIGEST_SIZE);
+
+struct sha512_digest {
+ union {
+ uint8_t b8[SHA512_DIGEST_SIZE];
+ uint32_t b32[SHA512_DIGEST_WORDS];
+ };
+};
+BUILD_ASSERT(sizeof(struct sha512_digest) == SHA512_DIGEST_SIZE);
+
+struct sha512_ctx {
+ const struct hash_vtable *f; /* metadata & vtable. */
+ size_t count; /* number of bytes processed. */
+ uint64_t state[SHA512_DIGEST_DWORDS]; /* up to SHA2-512. */
+ union {
+ uint8_t b8[SHA512_BLOCK_SIZE];
+ uint32_t b32[SHA512_BLOCK_WORDS];
+ uint64_t b64[SHA512_BLOCK_DWORDS];
+ struct sha512_digest digest;
+ };
+};
+
+#define sha384_ctx sha512_ctx
+#endif
+
+/**
+ * Generic hash type, allocating memory for any supported hash context
+ * Each context should have header at known location.
+ */
+union hash_ctx {
+ const struct hash_vtable *f; /* common metadata & vtable */
+ struct sha1_ctx sha1;
+ struct sha256_ctx sha256;
+ struct sha224_ctx sha224;
+#ifdef CONFIG_UPTO_SHA512
+ struct sha384_ctx sha384;
+ struct sha512_ctx sha512;
+#endif
+};
+
+union sha_digests {
+ struct sha1_digest sha1;
+ struct sha224_digest sha224;
+ struct sha256_digest sha256;
+#ifdef CONFIG_UPTO_SHA512
+ struct sha384_digest sha384;
+ struct sha512_digest sha512;
+#endif
+ /* Convenience accessor to bytes. */
+ uint8_t b8[SHA256_DIGEST_SIZE];
+};
+
+/* Header should be at constant offset to safely cast types to smaller size */
+BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha1_ctx, f));
+BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha256_ctx, f));
+BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha224_ctx, f));
+
+#ifdef CONFIG_UPTO_SHA512
+BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha384_ctx, f));
+BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha512_ctx, f));
+#endif
+
+struct hmac_sha1_ctx {
+ struct sha1_ctx hash;
+ uint32_t opad[SHA1_BLOCK_WORDS];
+};
+
+struct hmac_sha224_ctx {
+ struct sha224_ctx hash;
+ uint32_t opad[SHA224_BLOCK_WORDS];
+};
+
+struct hmac_sha256_ctx {
+ struct sha256_ctx hash;
+ uint32_t opad[SHA256_BLOCK_WORDS];
+};
+
+#ifdef CONFIG_UPTO_SHA512
+struct hmac_sha384_ctx {
+ struct sha384_ctx hash;
+ uint32_t opad[SHA384_BLOCK_WORDS];
+};
+
+struct hmac_sha512_ctx {
+ struct sha512_ctx hash;
+ uint32_t opad[SHA512_BLOCK_WORDS];
+};
+#endif
+
+/**
+ * HMAC context reserving memory for any supported hash type.
+ * It's SHA context following storage for ipad/opad
+ */
+union hmac_ctx {
+ const struct hash_vtable *f; /* common metadata & vtable */
+ union hash_ctx hash; /* access as hash */
+ /* hmac contexts */
+ struct hmac_sha1_ctx hmac_sha1;
+ struct hmac_sha256_ctx hmac_sha256;
+ struct hmac_sha224_ctx hmac_sha224;
+#ifdef CONFIG_UPTO_SHA512
+ struct hmac_sha384_ctx hmac_sha384;
+ struct hmac_sha512_ctx hmac_sha512;
+#endif
+};
+
+/* Header should be at constant offset to safely cast types to smaller size */
+BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha1_ctx, f));
+BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha256_ctx, f));
+BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha224_ctx, f));
+
+#ifdef CONFIG_UPTO_SHA512
+BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha384_ctx, f));
+BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha512_ctx, f));
+#endif
+
+/**
+ * Initialize software version of hash computation which explicitly allows
+ * context switching / serialization.
+ *
+ * @param ctx storage for context
+ * @param mode hashing algorithm
+ *
+ * @return DCRYPTO_OK if successful, DCRYPTO_FAIL otherwise.
+ */
+enum dcrypto_result DCRYPTO_sw_hash_init(
+ union hash_ctx *ctx, enum hashing_mode mode) __warn_unused_result;
+
+/**
+ * Initialize hardware-acceleated or software version of hash computation,
+ * preferring hardware version when available.
+ *
+ * @param ctx storage for context
+ * @param mode hashing algorithm
+ *
+ * @return DCRYPTO_OK if successful, DCRYPTO_FAIL otherwise.
+ */
+enum dcrypto_result DCRYPTO_hw_hash_init(
+ union hash_ctx *ctx, enum hashing_mode mode) __warn_unused_result;
+
+/**
+ * Return hash size for specified hash algorithm
+ * @param mode hash algorithm
+ * @return non-zero if algorithm is supported, 0 otherwise
+ */
+size_t DCRYPTO_hash_size(enum hashing_mode mode);
+
+/**
+ * Initialize software version of hash computation which explicitly allows
+ * context switching / serialization.
+ *
+ * @param ctx storage for context
+ * @param key HMAC key
+ * @param len length of HMAC key
+ * @param mode hashing algorithm
+ *
+ * @return DCRYPTO_OK if successful, DCRYPTO_FAIL otherwise.
+ */
+enum dcrypto_result DCRYPTO_sw_hmac_init(union hmac_ctx *ctx, const void *key,
+ size_t len, enum hashing_mode mode)
+ __warn_unused_result;
+
+/**
+ * Initialize hardware-acceleated or software version of HMAC computation,
+ * preferring hardware version when available.
+ *
+ * @param ctx storage for context
+ * @param key HMAC key
+ * @param len length of HMAC key
+ * @param mode hashing algorithm
+ *
+ * @return DCRYPTO_OK if successful, DCRYPTO_FAIL otherwise.
+ */
+enum dcrypto_result DCRYPTO_hw_hmac_init(union hmac_ctx *ctx, const void *key,
+ size_t len, enum hashing_mode mode)
+ __warn_unused_result;
+
+/**
+ * Compute SHA256 using preferably hardware implementation.
+ * API maintained compatible with RO code.
+ *
+ * @param data input data
+ * @param n length of data
+ * @param digest destination
+ * @return NULL if failure, digest if successful
+ */
+const uint8_t *DCRYPTO_SHA256_hash(const void *data, size_t n, uint8_t *digest);
+
+/**
+ * Compute SHA256 using preferably hardware implementation.
+ * API maintained compatible with RO code.
+ *
+ * @param data input data
+ * @param n length of data
+ * @param digest destination
+ * @return NULL if failure, digest if successful
+ */
+const uint8_t *DCRYPTO_SHA1_hash(const void *data, size_t n, uint8_t *digest);
+
+/**
+ * Convenience wrappers with type checks.
+ */
+#ifndef CONFIG_DCRYPTO_MOCK
+
+/**
+ * Add data to message, call configured transform function when block
+ * is full.
+ * @param ctx digest context (can be one of union subtypes).
+ * @param data input data
+ * @param len length of data
+ */
+static inline void HASH_update(union hash_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update(ctx, data, len);
+}
+/**
+ * Finalize hash computation by adding padding, message length.
+ * Returns pointer to computed digest stored inside provided context.
+ *
+ * @param ctx digest context (can be one of union subtypes).
+ *
+ * @return pointer to computed digest inside ctx.
+ */
+static inline const union sha_digests *HASH_final(union hash_ctx *const ctx)
+{
+ return ctx->f->final(ctx);
+}
+
+/**
+ * Add data to message, call configured transform function when block
+ * is full.
+ * @param ctx SHA256 digest context
+ * @param data input data
+ * @param len length of data
+ */
+static inline void SHA256_update(struct sha256_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+
+/**
+ * Finalize hash computation by adding padding, message length.
+ * Returns pointer to computed digest stored inside provided context.
+ *
+ * @param ctx SHA256 digest context.
+ *
+ * @return pointer to computed digest inside ctx.
+ */
+static inline const struct sha256_digest *SHA256_final(
+ struct sha256_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha256;
+}
+static inline void HMAC_SHA256_update(struct hmac_sha256_ctx *const ctx,
+ const void *data, size_t len)
+{
+ ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
+}
+
+static inline const struct sha256_digest *HMAC_SHA256_final(
+ struct hmac_sha256_ctx *ctx)
+{
+ return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha256;
+}
+static inline void SHA1_update(struct sha1_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+static inline const struct sha1_digest *SHA1_final(struct sha1_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha1;
+}
+
+/**
+ * Initialize SHA2-256 computation
+ *
+ * @param ctx SHA256 context
+
+ * @return DCRYPTO_OK if successful
+ */
+static inline __warn_unused_result enum dcrypto_result DCRYPTO_hw_sha256_init(
+ struct sha256_ctx *ctx)
+{
+ return DCRYPTO_hw_hash_init((union hash_ctx *)ctx, HASH_SHA256);
+}
+
+/**
+ * Initialize HMAC SHA2-256 computation
+ *
+ * @param ctx HMAC SHA256 context
+ * @param key HMAC key
+ * @param len length of key
+ * @return DCRYPTO_OK if successful
+ */
+static inline __warn_unused_result enum dcrypto_result
+DCRYPTO_hw_hmac_sha256_init(struct hmac_sha256_ctx *ctx, const void *key,
+ size_t len)
+{
+ return DCRYPTO_hw_hmac_init((union hmac_ctx *)ctx, key, len,
+ HASH_SHA256);
+}
+
+#else
+/* To enable DCRYPTO mocks just provide prototypes. */
+void HASH_update(union hash_ctx *const ctx, const void *data, size_t len);
+const union sha_digests *HASH_final(union hash_ctx *const ctx);
+void SHA256_update(struct sha256_ctx *const ctx, const void *data, size_t len);
+const struct sha256_digest *SHA256_final(struct sha256_ctx *const ctx);
+void HMAC_SHA256_update(struct hmac_sha256_ctx *const ctx, const void *data,
+ size_t len);
+const struct sha256_digest *HMAC_SHA256_final(struct hmac_sha256_ctx *ctx);
+void SHA1_update(struct sha1_ctx *const ctx, const void *data, size_t len);
+const struct sha1_digest *SHA1_final(struct sha1_ctx *const ctx);
+enum dcrypto_result DCRYPTO_hw_sha256_init(struct sha256_ctx *ctx);
+enum dcrypto_result DCRYPTO_hw_hmac_sha256_init(struct hmac_sha256_ctx *ctx,
+ const void *key, size_t len);
+#endif
+
+/**
+ * Returns digest size for configured hash.
+ */
+static inline size_t HASH_size(union hash_ctx *const ctx)
+{
+ return ctx->f->digest_size;
+}
+
+/**
+ * Return block size for configured hash.
+ */
+static inline size_t HASH_block_size(union hash_ctx *const ctx)
+{
+ return ctx->f->block_size;
+}
+
+/* HMAC_update() is same as HASH_update(). */
+static inline void HMAC_update(union hmac_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update(&ctx->hash, data, len);
+}
+
+static inline size_t HMAC_size(union hmac_ctx *const ctx)
+{
+ return ctx->f->digest_size;
+}
+
+static inline const union sha_digests *HMAC_final(union hmac_ctx *const ctx)
+{
+ return ctx->f->hmac_final(ctx);
+}
+
+static inline void HMAC_SHA1_update(struct hmac_sha1_ctx *const ctx,
+ const void *data, size_t len)
+{
+ ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
+}
+
+static inline const struct sha1_digest *HMAC_SHA1_final(
+ struct hmac_sha1_ctx *const ctx)
+{
+ return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha1;
+}
+
+#ifdef CONFIG_UPTO_SHA512
+static inline void SHA384_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+
+static inline const struct sha384_digest *SHA384_final(
+ struct sha384_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha384;
+}
+
+static inline void SHA512_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len)
+{
+ ctx->f->update((union hash_ctx *)ctx, data, len);
+}
+
+static inline const struct sha512_digest *SHA512_final(
+ struct sha512_ctx *const ctx)
+{
+ return &ctx->f->final((union hash_ctx *)ctx)->sha512;
+}
+
+static inline void HMAC_SHA384_update(struct hmac_sha384_ctx *ctx,
+ const void *data, size_t len)
+{
+ ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
+}
+static inline const struct sha384_digest *HMAC_SHA384_final(
+ struct hmac_sha384_ctx *ctx)
+{
+ return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha384;
+}
+
+static inline void HMAC_SHA512_update(struct hmac_sha512_ctx *ctx,
+ const void *data, size_t len)
+{
+ ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
+}
+static inline const struct sha512_digest *HMAC_SHA512_final(
+ struct hmac_sha512_ctx *ctx)
+{
+ return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha512;
+}
+#endif
+
/*
* AES implementation, based on a hardware AES block.
* FIPS Publication 197, The Advanced Encryption Standard (AES)
@@ -132,45 +686,6 @@ int DCRYPTO_aes_cmac_verify(const uint8_t *key, const uint8_t *M, const int len,
const uint32_t T[4]);
/*
- * SHA implementation. This abstraction is backed by either a
- * software or hardware implementation.
- *
- * There could be only a single hardware SHA context in progress. The init
- * functions will try using the HW context, if available, unless 'sw_required'
- * is TRUE, in which case there will be no attempt to use the hardware for
- * this particular hashing session.
- */
-
-void SHA1_hw_init(struct sha1_ctx *ctx);
-void SHA256_hw_init(struct sha256_ctx *ctx);
-const struct sha1_digest *SHA1_hw_hash(const void *data, size_t len,
- struct sha1_digest *digest);
-const struct sha256_digest *SHA256_hw_hash(const void *data, size_t len,
- struct sha256_digest *digest);
-#ifdef CONFIG_UPTO_SHA512
-void SHA384_hw_init(struct sha384_ctx *ctx);
-void SHA512_hw_init(struct sha512_ctx *ctx);
-const struct sha384_digest *SHA384_hw_hash(const void *data, size_t len,
- struct sha384_digest *digest);
-
-const struct sha512_digest *SHA512_hw_hash(const void *data, size_t len,
- struct sha512_digest *digest);
-#endif
-
-const uint8_t *DCRYPTO_SHA1_hash(const void *data, size_t n, uint8_t *digest);
-
-/* TODO: remove dependency on board/cr50/dcrypto/dcrypto.h for RO. */
-const uint8_t *DCRYPTO_SHA256_hash(const void *data, size_t n, uint8_t *digest);
-
-/*
- * HMAC. FIPS 198-1
- */
-void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
- size_t len);
-/* DCRYPTO HMAC-SHA256 final */
-const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx);
-
-/*
* BIGNUM utility methods.
*/
diff --git a/board/cr50/dcrypto/hash_api.c b/board/cr50/dcrypto/hash_api.c
new file mode 100644
index 0000000000..34b5d88d55
--- /dev/null
+++ b/board/cr50/dcrypto/hash_api.c
@@ -0,0 +1,170 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "internal.h"
+
+size_t DCRYPTO_hash_size(enum hashing_mode mode)
+{
+ if (!fips_crypto_allowed())
+ return 0;
+
+ switch (mode) {
+ case HASH_SHA1:
+ return SHA1_DIGEST_SIZE;
+ case HASH_SHA256:
+ return SHA256_DIGEST_SIZE;
+#ifdef CONFIG_UPTO_SHA512
+ case HASH_SHA384:
+ return SHA384_DIGEST_SIZE;
+ case HASH_SHA512:
+ return SHA512_DIGEST_SIZE;
+#endif
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+enum dcrypto_result DCRYPTO_sw_hash_init(union hash_ctx *ctx,
+ enum hashing_mode mode)
+{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ switch (mode) {
+ case HASH_SHA1:
+ SHA1_sw_init(&ctx->sha1);
+ break;
+ case HASH_SHA256:
+ SHA256_sw_init(&ctx->sha256);
+ break;
+#ifdef CONFIG_UPTO_SHA512
+ case HASH_SHA384:
+ SHA384_sw_init(&ctx->sha384);
+ break;
+ case HASH_SHA512:
+ SHA512_sw_init(&ctx->sha512);
+ break;
+#endif
+ default:
+ return DCRYPTO_FAIL;
+ }
+ return DCRYPTO_OK;
+}
+
+enum dcrypto_result DCRYPTO_hw_hash_init(union hash_ctx *ctx,
+ enum hashing_mode mode)
+{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ switch (mode) {
+ case HASH_SHA1:
+ SHA1_hw_init(&ctx->sha1);
+ break;
+ case HASH_SHA256:
+ SHA256_hw_init(&ctx->sha256);
+ break;
+#ifdef CONFIG_UPTO_SHA512
+ case HASH_SHA384:
+ SHA384_hw_init(&ctx->sha384);
+ break;
+ case HASH_SHA512:
+ SHA512_hw_init(&ctx->sha512);
+ break;
+#endif
+ default:
+ return DCRYPTO_FAIL;
+ }
+ return DCRYPTO_OK;
+}
+
+enum dcrypto_result DCRYPTO_sw_hmac_init(union hmac_ctx *ctx, const void *key,
+ size_t len, enum hashing_mode mode)
+{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ switch (mode) {
+ case HASH_SHA1:
+ SHA1_sw_init(&ctx->hmac_sha1.hash);
+ break;
+ case HASH_SHA256:
+ SHA256_sw_init(&ctx->hmac_sha256.hash);
+ break;
+#ifdef CONFIG_UPTO_SHA512
+ case HASH_SHA384:
+ SHA384_sw_init(&ctx->hmac_sha384.hash);
+ break;
+ case HASH_SHA512:
+ SHA512_sw_init(&ctx->hmac_sha512.hash);
+ break;
+#endif
+ default:
+ return DCRYPTO_FAIL;
+ }
+ HMAC_sw_init(ctx, key, len);
+ return DCRYPTO_OK;
+}
+
+enum dcrypto_result DCRYPTO_hw_hmac_init(union hmac_ctx *ctx, const void *key,
+ size_t len, enum hashing_mode mode)
+{
+ if (!fips_crypto_allowed())
+ return DCRYPTO_FAIL;
+
+ switch (mode) {
+ case HASH_SHA1:
+ SHA1_hw_init(&ctx->hmac_sha1.hash);
+ HMAC_sw_init(ctx, key, len);
+ break;
+ case HASH_SHA256:
+ HMAC_SHA256_hw_init(&ctx->hmac_sha256, key, len);
+ break;
+#ifdef CONFIG_UPTO_SHA512
+ case HASH_SHA384:
+ SHA384_hw_init(&ctx->hmac_sha384.hash);
+ HMAC_sw_init(ctx, key, len);
+ break;
+ case HASH_SHA512:
+ SHA512_hw_init(&ctx->hmac_sha512.hash);
+ HMAC_sw_init(ctx, key, len);
+ break;
+#endif
+ default:
+ return DCRYPTO_FAIL;
+ }
+ return DCRYPTO_OK;
+}
+
+const uint8_t *DCRYPTO_SHA1_hash(const void *data, size_t n, uint8_t *digest)
+{
+ if (!fips_crypto_allowed())
+ return NULL;
+
+ if (is_not_aligned(digest)) {
+ struct sha1_digest d;
+
+ SHA1_hw_hash(data, n, &d);
+ memcpy(digest, d.b8, sizeof(d));
+ } else
+ SHA1_hw_hash(data, n, (struct sha1_digest *)digest);
+ return digest;
+}
+
+const uint8_t *DCRYPTO_SHA256_hash(const void *data, size_t n, uint8_t *digest)
+{
+ if (!fips_crypto_allowed())
+ return NULL;
+
+ if (is_not_aligned(digest)) {
+ struct sha256_digest d;
+
+ SHA256_hw_hash(data, n, &d);
+ memcpy(digest, d.b8, sizeof(d));
+ } else
+ SHA256_hw_hash(data, n, (struct sha256_digest *)digest);
+ return digest;
+}
diff --git a/board/cr50/dcrypto/hmacsha2.h b/board/cr50/dcrypto/hmacsha2.h
deleted file mode 100644
index 5e34b99189..0000000000
--- a/board/cr50/dcrypto/hmacsha2.h
+++ /dev/null
@@ -1,523 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#pragma once
-#include "common.h"
-
-#define SHA1_DIGEST_SIZE 20
-#define SHA_DIGEST_SIZE SHA1_DIGEST_SIZE
-
-#define SHA224_DIGEST_SIZE 28
-#define SHA256_DIGEST_SIZE 32
-#define SHA1_BLOCK_SIZE 64
-#define SHA1_BLOCK_WORDS (SHA1_BLOCK_SIZE / sizeof(uint32_t))
-#define SHA1_BLOCK_DWORDS (SHA1_BLOCK_SIZE / sizeof(uint64_t))
-#define SHA1_DIGEST_WORDS (SHA1_DIGEST_SIZE / sizeof(uint32_t))
-#define SHA224_BLOCK_SIZE 64
-#define SHA224_BLOCK_WORDS (SHA224_BLOCK_SIZE / sizeof(uint32_t))
-#define SHA224_BLOCK_DWORDS (SHA224_BLOCK_SIZE / sizeof(uint64_t))
-#define SHA224_DIGEST_WORDS (SHA224_DIGEST_SIZE / sizeof(uint32_t))
-#define SHA256_BLOCK_SIZE 64
-#define SHA256_BLOCK_WORDS (SHA256_BLOCK_SIZE / sizeof(uint32_t))
-#define SHA256_BLOCK_DWORDS (SHA256_BLOCK_SIZE / sizeof(uint64_t))
-#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
-
-#define SHA_DIGEST_WORDS (SHA_DIGEST_SIZE / sizeof(uint32_t))
-#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
-
-#ifdef CONFIG_UPTO_SHA512
-#define SHA_DIGEST_MAX_BYTES SHA512_DIGEST_SIZE
-#else
-#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_SIZE
-#endif
-
-/**
- * Hash contexts. Each context starts with pointer to vtable containing
- * functions to perform implementation specific operations.
- * It is designed to support both software and hardware implementations.
- * Contexts for different digest types can overlap, but vtable stores
- * actual size of context which enables stack-efficient implementation of
- * HMAC - say HMAC SHA2-256 shouldn't reserve space as for HMAC SHA2-512.
- */
-union hash_ctx; /* forward declaration of generic hash context type */
-union hmac_ctx; /* forward declaration of generic HMAC context type */
-
-union sha_digests; /* forward declaration of generic digest type */
-
-/* Combined HASH & HMAC vtable to support SW & HW implementations. */
-struct hash_vtable {
- /* SHA init function, used primarily by SW HMAC implementation. */
- void (*const init)(union hash_ctx *const);
- /* Update function for SHA & HMAC, assuming it's the same. */
- void (*const update)(union hash_ctx *const, const void *, size_t);
- /* SHA final function, digest specific. */
- const union sha_digests *(*const final)(union hash_ctx *const);
-
- /* HW HMAC support may require special ending. */
- const union sha_digests *(*const hmac_final)(union hmac_ctx *const);
-
- /* Digest size of in bytes. */
- size_t digest_size;
-
- /* Digest block size in bytes. */
- size_t block_size;
-
- /* Offset of first byte after context, used for HMAC */
- size_t context_size;
-};
-
-struct sha256_digest {
- union {
- uint8_t b8[SHA256_DIGEST_SIZE];
- uint32_t b32[SHA256_DIGEST_WORDS];
- };
-};
-BUILD_ASSERT(sizeof(struct sha256_digest) == SHA256_DIGEST_SIZE);
-
-struct sha224_digest {
- union {
- uint8_t b8[SHA224_DIGEST_SIZE];
- uint32_t b32[SHA224_DIGEST_WORDS];
- };
-};
-BUILD_ASSERT(sizeof(struct sha224_digest) == SHA224_DIGEST_SIZE);
-
-struct sha1_digest {
- union {
- uint8_t b8[SHA1_DIGEST_SIZE];
- uint32_t b32[SHA1_DIGEST_WORDS];
- };
-};
-BUILD_ASSERT(sizeof(struct sha1_digest) == SHA1_DIGEST_SIZE);
-
-
-/* SHA256 specific type to allocate just enough memory. */
-struct sha256_ctx {
- const struct hash_vtable *f; /* metadata & vtable */
- size_t count; /* number of bytes processed */
- uint32_t state[SHA256_DIGEST_WORDS]; /* up to SHA2-256 */
- union {
- uint8_t b8[SHA256_BLOCK_SIZE];
- uint32_t b32[SHA256_BLOCK_WORDS];
- uint64_t b64[SHA256_BLOCK_DWORDS];
- struct sha256_digest digest;
- };
-};
-
-#define sha224_ctx sha256_ctx
-
-struct sha1_ctx {
- const struct hash_vtable *f; /* metadata & vtable. */
- size_t count; /* number of bytes processed. */
- uint32_t state[SHA1_DIGEST_WORDS];
- union {
- uint8_t b8[SHA1_BLOCK_SIZE];
- uint32_t b32[SHA1_BLOCK_WORDS];
- uint64_t b64[SHA1_BLOCK_DWORDS];
- struct sha1_digest digest;
- };
-};
-
-#ifdef CONFIG_UPTO_SHA512
-#define SHA384_DIGEST_SIZE 48
-#define SHA512_DIGEST_SIZE 64
-
-#define SHA384_BLOCK_SIZE 128
-#define SHA512_BLOCK_SIZE 128
-
-#define SHA384_BLOCK_WORDS (SHA384_BLOCK_SIZE / sizeof(uint32_t))
-#define SHA384_BLOCK_DWORDS (SHA384_BLOCK_SIZE / sizeof(uint64_t))
-#define SHA384_DIGEST_WORDS (SHA384_DIGEST_SIZE / sizeof(uint32_t))
-#define SHA384_DIGEST_DWORDS (SHA384_DIGEST_SIZE / sizeof(uint64_t))
-
-#define SHA512_BLOCK_WORDS (SHA512_BLOCK_SIZE / sizeof(uint32_t))
-#define SHA512_BLOCK_DWORDS (SHA512_BLOCK_SIZE / sizeof(uint64_t))
-#define SHA512_DIGEST_WORDS (SHA512_DIGEST_SIZE / sizeof(uint32_t))
-#define SHA512_DIGEST_DWORDS (SHA512_DIGEST_SIZE / sizeof(uint64_t))
-
-struct sha384_digest {
- union {
- uint8_t b8[SHA384_DIGEST_SIZE];
- uint32_t b32[SHA384_DIGEST_WORDS];
- };
-};
-BUILD_ASSERT(sizeof(struct sha384_digest) == SHA384_DIGEST_SIZE);
-
-struct sha512_digest {
- union {
- uint8_t b8[SHA512_DIGEST_SIZE];
- uint32_t b32[SHA512_DIGEST_WORDS];
- };
-};
-BUILD_ASSERT(sizeof(struct sha512_digest) == SHA512_DIGEST_SIZE);
-
-struct sha512_ctx {
- const struct hash_vtable *f; /* metadata & vtable. */
- size_t count; /* number of bytes processed. */
- uint64_t state[SHA512_DIGEST_DWORDS]; /* up to SHA2-512. */
- union {
- uint8_t b8[SHA512_BLOCK_SIZE];
- uint32_t b32[SHA512_BLOCK_WORDS];
- uint64_t b64[SHA512_BLOCK_DWORDS];
- struct sha512_digest digest;
- };
-};
-
-#define sha384_ctx sha512_ctx
-#endif
-
-/**
- * Generic hash type, allocating memory for any supported hash context
- * Each context should have header at known location.
- */
-union hash_ctx {
- const struct hash_vtable *f; /* common metadata & vtable */
- struct sha1_ctx sha1;
- struct sha256_ctx sha256;
- struct sha224_ctx sha224;
-#ifdef CONFIG_UPTO_SHA512
- struct sha384_ctx sha384;
- struct sha512_ctx sha512;
-#endif
-};
-
-union sha_digests {
- struct sha1_digest sha1;
- struct sha224_digest sha224;
- struct sha256_digest sha256;
-#ifdef CONFIG_UPTO_SHA512
- struct sha384_digest sha384;
- struct sha512_digest sha512;
-#endif
- /* Convenience accessor to bytes. */
- uint8_t b8[SHA256_DIGEST_SIZE];
-};
-
-/* Header should be at constant offset to safely cast types to smaller size */
-BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha1_ctx, f));
-BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha256_ctx, f));
-BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha224_ctx, f));
-
-#ifdef CONFIG_UPTO_SHA512
-BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha384_ctx, f));
-BUILD_ASSERT(offsetof(union hash_ctx, f) == offsetof(struct sha512_ctx, f));
-#endif
-
-struct hmac_sha1_ctx {
- struct sha1_ctx hash;
- uint32_t opad[SHA1_BLOCK_WORDS];
-};
-
-struct hmac_sha224_ctx {
- struct sha224_ctx hash;
- uint32_t opad[SHA224_BLOCK_WORDS];
-};
-
-struct hmac_sha256_ctx {
- struct sha256_ctx hash;
- uint32_t opad[SHA256_BLOCK_WORDS];
-};
-
-#ifdef CONFIG_UPTO_SHA512
-struct hmac_sha384_ctx {
- struct sha384_ctx hash;
- uint32_t opad[SHA384_BLOCK_WORDS];
-};
-
-struct hmac_sha512_ctx {
- struct sha512_ctx hash;
- uint32_t opad[SHA512_BLOCK_WORDS];
-};
-#endif
-
-/**
- * HMAC context reserving memory for any supported hash type.
- * It's SHA context following storage for ipad/opad
- */
-union hmac_ctx {
- const struct hash_vtable *f; /* common metadata & vtable */
- union hash_ctx hash; /* access as hash */
- /* hmac contexts */
- struct hmac_sha1_ctx hmac_sha1;
- struct hmac_sha256_ctx hmac_sha256;
- struct hmac_sha224_ctx hmac_sha224;
-#ifdef CONFIG_UPTO_SHA512
- struct hmac_sha384_ctx hmac_sha384;
- struct hmac_sha512_ctx hmac_sha512;
-#endif
-};
-
-/* Header should be at constant offset to safely cast types to smaller size */
-BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha1_ctx, f));
-BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha256_ctx, f));
-BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha224_ctx, f));
-
-#ifdef CONFIG_UPTO_SHA512
-BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha384_ctx, f));
-BUILD_ASSERT(offsetof(union hmac_ctx, f) == offsetof(struct sha512_ctx, f));
-#endif
-
-/**
- * Reset hash context with the same hash function as configured.
- * Will crash if previously not configured! Used for HMAC.
- */
-static inline void HASH_reinit(union hash_ctx *const ctx)
-{
- ctx->f->init(ctx);
-}
-
-#ifndef CONFIG_DCRYPTO_MOCK
-/**
- * Add data to message, call configured transform function when block
- * is full.
- */
-static inline void HASH_update(union hash_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update(ctx, data, len);
-}
-#else
-void HASH_update(union hash_ctx *const ctx, const void *data, size_t len);
-#endif
-
-static inline void SHA1_update(struct sha1_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update((union hash_ctx *)ctx, data, len);
-}
-
-static inline void SHA256_update(struct sha256_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update((union hash_ctx *)ctx, data, len);
-}
-
-/**
- * Finalize hash computation by adding padding, message length.
- * Returns pointer to computed digest stored inside provided context.
- */
-#ifndef CONFIG_DCRYPTO_MOCK
-static inline const union sha_digests *HASH_final(union hash_ctx *const ctx)
-{
- return ctx->f->final(ctx);
-}
-#else
-const union sha_digests *HASH_final(union hash_ctx *const ctx);
-#endif
-
-static inline const struct sha1_digest *SHA1_final(struct sha1_ctx *const ctx)
-{
- return &ctx->f->final((union hash_ctx *)ctx)->sha1;
-}
-
-static inline const struct sha256_digest *SHA256_final(
- struct sha256_ctx *const ctx)
-{
- return &ctx->f->final((union hash_ctx *)ctx)->sha256;
-}
-
-/**
- * Returns digest size for configured hash.
- */
-static inline size_t HASH_size(union hash_ctx *const ctx)
-{
- return ctx->f->digest_size;
-}
-
-/**
- * Return block size for configured hash.
- */
-static inline size_t HASH_block_size(union hash_ctx *const ctx)
-{
- return ctx->f->block_size;
-}
-
-/* Software implementations of hash functions. */
-void SHA1_sw_init(struct sha1_ctx *const ctx);
-void SHA1_sw_update(struct sha1_ctx *const ctx, const void *data, size_t len);
-const struct sha1_digest *SHA1_sw_final(struct sha1_ctx *const ctx);
-const struct sha1_digest *SHA1_sw_hash(const void *data, size_t len,
- struct sha1_digest *digest);
-void SHA256_sw_init(struct sha256_ctx *const ctx);
-void SHA256_sw_update(struct sha256_ctx *const ctx, const void *data,
- size_t len);
-const struct sha256_digest *SHA256_sw_final(struct sha256_ctx *const ctx);
-const struct sha256_digest *SHA256_sw_hash(const void *data, size_t len,
- struct sha256_digest *digest);
-void SHA224_sw_init(struct sha224_ctx *const ctx);
-void SHA224_sw_update(struct sha224_ctx *const ctx, const void *data,
- size_t len);
-const struct sha224_digest *SHA224_sw_final(struct sha224_ctx *const ctx);
-const struct sha224_digest *SHA224_sw_hash(const void *data, size_t len,
- struct sha224_digest *digest);
-
-/**
- * Initialize HMAC for pre-configured hash.
- * This is generic function which can initialize HMAC with any supported
- * hash function.
- */
-void HMAC_sw_init(union hmac_ctx *const ctx, const void *key, size_t len);
-const union sha_digests *HMAC_sw_final(union hmac_ctx *const ctx);
-
-/* HMAC update is same as SHA update. */
-static inline void HMAC_update(union hmac_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update(&ctx->hash, data, len);
-}
-
-static inline size_t HMAC_size(union hmac_ctx *const ctx)
-{
- return ctx->f->digest_size;
-}
-
-static inline const union sha_digests *HMAC_final(union hmac_ctx *const ctx)
-{
- return ctx->f->hmac_final(ctx);
-}
-
-/**
- * HMAC SHA1 initialization.
- */
-static inline void HMAC_SHA1_sw_init(struct hmac_sha1_ctx *const ctx,
- const void *key, size_t len)
-{
- SHA1_sw_init(&ctx->hash);
- HMAC_sw_init((union hmac_ctx *)ctx, key, len);
-}
-
-static inline void HMAC_SHA1_update(struct hmac_sha1_ctx *const ctx,
- const void *data, size_t len)
-{
- ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
-}
-
-static inline const struct sha1_digest *
-HMAC_SHA1_final(struct hmac_sha1_ctx *const ctx)
-{
- return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha1;
-}
-
-/**
- * HMAC SHA2-224 initialization.
- */
-static inline void HMAC_SHA224_sw_init(struct hmac_sha224_ctx *const ctx,
- const void *key, size_t len)
-{
- SHA224_sw_init(&ctx->hash);
- HMAC_sw_init((union hmac_ctx *)ctx, key, len);
-}
-
-static inline void HMAC_SHA224_update(struct hmac_sha224_ctx *const ctx,
- const void *data, size_t len)
-{
- ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
-}
-
-static inline const struct sha224_digest *
-HMAC_SHA224_final(struct hmac_sha224_ctx *const ctx)
-{
- return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha224;
-}
-
-/**
- * HMAC SHA2-256 initialization.
- */
-static inline void HMAC_SHA256_sw_init(struct hmac_sha256_ctx *const ctx,
- const void *key, size_t len)
-{
- SHA256_sw_init(&ctx->hash);
- HMAC_sw_init((union hmac_ctx *)ctx, key, len);
-}
-
-static inline void HMAC_SHA256_update(struct hmac_sha256_ctx *const ctx,
- const void *data, size_t len)
-{
- ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
-}
-
-static inline const struct sha256_digest *
-HMAC_SHA256_final(struct hmac_sha256_ctx *ctx)
-{
- return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha256;
-}
-
-#ifdef CONFIG_UPTO_SHA512
-void SHA384_sw_init(struct sha384_ctx *const ctx);
-void SHA384_sw_update(struct sha384_ctx *const ctx, const void *data,
- size_t len);
-const struct sha384_digest *SHA384_sw_final(struct sha384_ctx *const ctx);
-const struct sha384_digest *SHA384_sw_hash(const void *data, size_t len,
- struct sha384_digest *digest);
-void SHA512_sw_init(struct sha512_ctx *const ctx);
-void SHA512_sw_update(struct sha512_ctx *const ctx, const void *data,
- size_t len);
-const struct sha512_digest *SHA512_sw_final(struct sha512_ctx *ctx);
-const struct sha512_digest *SHA512_sw_hash(const void *data, size_t len,
- struct sha512_digest *digest);
-
-static inline void SHA384_update(struct sha384_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update((union hash_ctx *)ctx, data, len);
-}
-
-static inline const struct sha384_digest *SHA384_final(
- struct sha384_ctx *const ctx)
-{
- return &ctx->f->final((union hash_ctx *)ctx)->sha384;
-}
-
-static inline void SHA512_update(struct sha512_ctx *const ctx, const void *data,
- size_t len)
-{
- ctx->f->update((union hash_ctx *)ctx, data, len);
-}
-
-static inline const struct sha512_digest *SHA512_final(
- struct sha512_ctx *const ctx)
-{
- return &ctx->f->final((union hash_ctx *)ctx)->sha512;
-}
-
-/**
- * HMAC SHA2-384 initialization.
- */
-static inline void HMAC_SHA384_sw_init(struct hmac_sha384_ctx *ctx,
- const void *key, size_t len)
-{
- SHA384_sw_init(&ctx->hash);
- HMAC_sw_init((union hmac_ctx *)ctx, key, len);
-}
-
-static inline void HMAC_SHA384_update(struct hmac_sha384_ctx *ctx,
- const void *data, size_t len)
-{
- ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
-}
-static inline const struct sha384_digest *
-HMAC_SHA384_final(struct hmac_sha384_ctx *ctx)
-{
- return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha384;
-}
-/**
- * HMAC SHA2-512 initialization.
- */
-static inline void HMAC_SHA512_sw_init(struct hmac_sha512_ctx *ctx,
- const void *key, size_t len)
-{
- SHA512_sw_init(&ctx->hash);
- HMAC_sw_init((union hmac_ctx *)ctx, key, len);
-}
-static inline void HMAC_SHA512_update(struct hmac_sha512_ctx *ctx,
- const void *data, size_t len)
-{
- ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
-}
-static inline const struct sha512_digest *
-HMAC_SHA512_final(struct hmac_sha512_ctx *ctx)
-{
- return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha512;
-}
-#endif
diff --git a/board/cr50/dcrypto/internal.h b/board/cr50/dcrypto/internal.h
index ed1f324079..638c6357f8 100644
--- a/board/cr50/dcrypto/internal.h
+++ b/board/cr50/dcrypto/internal.h
@@ -12,7 +12,6 @@
#include "dcrypto.h"
#include "fips.h"
#include "fips_rand.h"
-#include "hmacsha2.h"
#include "util.h"
#ifdef __cplusplus
@@ -41,6 +40,154 @@ void dcrypto_release_sha_hw(void);
void dcrypto_sha_fifo_load(const void *data, size_t n);
/*
+ * SHA implementation. This abstraction is backed by either a
+ * software or hardware implementation.
+ *
+ * There could be only a single hardware SHA context in progress. The init
+ * functions will try using the HW context, if available, unless 'sw_required'
+ * is TRUE, in which case there will be no attempt to use the hardware for
+ * this particular hashing session.
+ */
+
+/**
+ * Reset hash context with the same hash function as configured.
+ * Will crash if previously not configured! Used for HMAC.
+ */
+static inline void HASH_reinit(union hash_ctx *const ctx)
+{
+ ctx->f->init(ctx);
+}
+
+/* Software implementations of hash functions. */
+void SHA1_sw_init(struct sha1_ctx *const ctx);
+void SHA1_sw_update(struct sha1_ctx *const ctx, const void *data, size_t len);
+const struct sha1_digest *SHA1_sw_final(struct sha1_ctx *const ctx);
+const struct sha1_digest *SHA1_sw_hash(const void *data, size_t len,
+ struct sha1_digest *digest);
+void SHA256_sw_init(struct sha256_ctx *const ctx);
+void SHA256_sw_update(struct sha256_ctx *const ctx, const void *data,
+ size_t len);
+const struct sha256_digest *SHA256_sw_final(struct sha256_ctx *const ctx);
+const struct sha256_digest *SHA256_sw_hash(const void *data, size_t len,
+ struct sha256_digest *digest);
+void SHA224_sw_init(struct sha224_ctx *const ctx);
+void SHA224_sw_update(struct sha224_ctx *const ctx, const void *data,
+ size_t len);
+const struct sha224_digest *SHA224_sw_final(struct sha224_ctx *const ctx);
+const struct sha224_digest *SHA224_sw_hash(const void *data, size_t len,
+ struct sha224_digest *digest);
+
+
+/**
+ * Initialize HMAC for pre-configured hash.
+ * This is generic function which can initialize HMAC with any supported
+ * hash function.
+ */
+void HMAC_sw_init(union hmac_ctx *const ctx, const void *key, size_t len);
+const union sha_digests *HMAC_sw_final(union hmac_ctx *const ctx);
+
+/**
+ * HMAC SHA2-224 initialization.
+ */
+static inline void HMAC_SHA224_sw_init(struct hmac_sha224_ctx *const ctx,
+ const void *key, size_t len)
+{
+ SHA224_sw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+
+static inline void HMAC_SHA224_update(struct hmac_sha224_ctx *const ctx,
+ const void *data, size_t len)
+{
+ ctx->hash.f->update((union hash_ctx *)&ctx->hash, data, len);
+}
+
+static inline const struct sha224_digest *
+HMAC_SHA224_final(struct hmac_sha224_ctx *const ctx)
+{
+ return &ctx->hash.f->hmac_final((union hmac_ctx *)ctx)->sha224;
+}
+
+/**
+ * HMAC SHA2-256 initialization.
+ */
+static inline void HMAC_SHA256_sw_init(struct hmac_sha256_ctx *const ctx,
+ const void *key, size_t len)
+{
+ SHA256_sw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+
+
+/**
+ * HMAC SHA1 initialization.
+ */
+static inline void HMAC_SHA1_sw_init(struct hmac_sha1_ctx *const ctx,
+ const void *key, size_t len)
+{
+ SHA1_sw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+
+void SHA1_hw_init(struct sha1_ctx *ctx);
+void SHA256_hw_init(struct sha256_ctx *ctx);
+const struct sha1_digest *SHA1_hw_hash(const void *data, size_t len,
+ struct sha1_digest *digest);
+const struct sha256_digest *SHA256_hw_hash(const void *data, size_t len,
+ struct sha256_digest *digest);
+
+#ifdef CONFIG_UPTO_SHA512
+void SHA384_sw_init(struct sha384_ctx *const ctx);
+void SHA384_sw_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len);
+const struct sha384_digest *SHA384_sw_final(struct sha384_ctx *const ctx);
+const struct sha384_digest *SHA384_sw_hash(const void *data, size_t len,
+ struct sha384_digest *digest);
+void SHA512_sw_init(struct sha512_ctx *const ctx);
+void SHA512_sw_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len);
+const struct sha512_digest *SHA512_sw_final(struct sha512_ctx *ctx);
+const struct sha512_digest *SHA512_sw_hash(const void *data, size_t len,
+ struct sha512_digest *digest);
+
+void SHA384_hw_init(struct sha384_ctx *ctx);
+void SHA512_hw_init(struct sha512_ctx *ctx);
+const struct sha384_digest *SHA384_hw_hash(const void *data, size_t len,
+ struct sha384_digest *digest);
+
+const struct sha512_digest *SHA512_hw_hash(const void *data, size_t len,
+ struct sha512_digest *digest);
+
+
+/**
+ * HMAC SHA2-384 initialization.
+ */
+static inline void HMAC_SHA384_sw_init(struct hmac_sha384_ctx *ctx,
+ const void *key, size_t len)
+{
+ SHA384_sw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+/**
+ * HMAC SHA2-512 initialization.
+ */
+static inline void HMAC_SHA512_sw_init(struct hmac_sha512_ctx *ctx,
+ const void *key, size_t len)
+{
+ SHA512_sw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+#endif
+
+/*
+ * HMAC. FIPS 198-1
+ */
+void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
+ size_t len);
+/* DCRYPTO HMAC-SHA256 final */
+const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx);
+
+/*
* BIGNUM.
*/
#define LITE_BN_BITS2 32
diff --git a/board/cr50/dcrypto/rsa.c b/board/cr50/dcrypto/rsa.c
index 9c721abc5e..524d3d14f4 100644
--- a/board/cr50/dcrypto/rsa.c
+++ b/board/cr50/dcrypto/rsa.c
@@ -31,9 +31,9 @@ static uint32_t select(uint32_t mask, uint32_t a, uint32_t b)
/* We use SHA256 context to store SHA1 context, so make sure it's ok. */
BUILD_ASSERT(sizeof(struct sha256_ctx) >= sizeof(struct sha1_ctx));
-static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
- const uint8_t *seed, uint32_t seed_len,
- enum hashing_mode hashing)
+static enum dcrypto_result MGF1_xor(uint8_t *dst, uint32_t dst_len,
+ const uint8_t *seed, uint32_t seed_len,
+ enum hashing_mode hashing)
{
union hash_ctx ctx;
@@ -44,17 +44,19 @@ static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
uint8_t b0;
} cnt;
const uint8_t *digest;
- const size_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE :
- SHA256_DIGEST_SIZE;
+ const size_t hash_size = DCRYPTO_hash_size(hashing);
+
+ if (!hash_size)
+ return DCRYPTO_FAIL;
cnt.b0 = cnt.b1 = cnt.b2 = cnt.b3 = 0;
while (dst_len) {
size_t i;
+ enum dcrypto_result result;
- if (hashing == HASH_SHA1)
- SHA1_hw_init(&ctx.sha1);
- else
- SHA256_hw_init(&ctx.sha256);
+ result = DCRYPTO_hw_hash_init(&ctx, hashing);
+ if (result != DCRYPTO_OK)
+ return result;
HASH_update(&ctx, seed, seed_len);
HASH_update(&ctx, (uint8_t *)&cnt, sizeof(cnt));
@@ -65,6 +67,7 @@ static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
if (!++cnt.b0)
++cnt.b1;
}
+ return DCRYPTO_OK;
}
/*
@@ -78,12 +81,12 @@ static void MGF1_xor(uint8_t *dst, uint32_t dst_len,
* };
*/
/* encrypt */
-static int oaep_pad(uint8_t *output, uint32_t output_len,
- const uint8_t *msg, uint32_t msg_len,
- enum hashing_mode hashing, const char *label)
+static enum dcrypto_result oaep_pad(uint8_t *output, uint32_t output_len,
+ const uint8_t *msg, uint32_t msg_len,
+ enum hashing_mode hashing,
+ const char *label)
{
- const size_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
- : SHA256_DIGEST_SIZE;
+ const size_t hash_size = DCRYPTO_hash_size(hashing);
uint8_t *const seed = output + 1;
uint8_t *const phash = seed + hash_size;
uint8_t *const PS = phash + hash_size;
@@ -91,39 +94,44 @@ static int oaep_pad(uint8_t *output, uint32_t output_len,
const uint32_t ps_len = max_msg_len - msg_len;
uint8_t *const one = PS + ps_len;
union hash_ctx ctx;
+ enum dcrypto_result result;
+ if (!hash_size)
+ return DCRYPTO_FAIL;
if (output_len < 2 + 2 * hash_size)
- return 0; /* Key size too small for chosen hash. */
+ return DCRYPTO_FAIL; /* Key size too small for chosen hash. */
if (msg_len > output_len - 2 - 2 * hash_size)
- return 0; /* Input message too large for key size. */
+ return DCRYPTO_FAIL; /* Input message too large for key size. */
always_memset(output, 0, output_len);
if (!fips_rand_bytes(seed, hash_size))
- return 0;
+ return DCRYPTO_FAIL;
- if (hashing == HASH_SHA1)
- SHA1_hw_init(&ctx.sha1);
- else
- SHA256_hw_init(&ctx.sha256);
+ result = DCRYPTO_hw_hash_init(&ctx, hashing);
+ if (result != DCRYPTO_OK)
+ return result;
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
memcpy(phash, HASH_final(&ctx)->b8, hash_size);
*one = 1;
memcpy(one + 1, msg, msg_len);
- MGF1_xor(phash, hash_size + 1 + max_msg_len,
- seed, hash_size, hashing);
- MGF1_xor(seed, hash_size, phash, hash_size + 1 + max_msg_len,
- hashing);
- return 1;
+ result = MGF1_xor(phash, hash_size + 1 + max_msg_len, seed, hash_size,
+ hashing);
+ result |= MGF1_xor(seed, hash_size, phash, hash_size + 1 + max_msg_len,
+ hashing);
+
+ if (result != DCRYPTO_OK)
+ return DCRYPTO_FAIL;
+
+ return result;
}
/* decrypt */
-static int check_oaep_pad(uint8_t *out, size_t *out_len,
+static enum dcrypto_result check_oaep_pad(uint8_t *out, size_t *out_len,
uint8_t *padded, size_t padded_len,
enum hashing_mode hashing, const char *label)
{
- const size_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
- : SHA256_DIGEST_SIZE;
+ const size_t hash_size = DCRYPTO_hash_size(hashing);
uint8_t *seed = padded + 1;
uint8_t *phash = seed + hash_size;
uint8_t *PS = phash + hash_size;
@@ -133,27 +141,35 @@ static int check_oaep_pad(uint8_t *out, size_t *out_len,
uint32_t looking_for_one_byte = ~0;
int bad;
size_t i;
+ enum dcrypto_result result;
+
+ if (!hash_size)
+ return DCRYPTO_FAIL;
if (padded_len < 2 + 2 * hash_size)
- return 0; /* Invalid input size. */
+ return DCRYPTO_FAIL; /* Invalid input size. */
/* Recover seed. */
- MGF1_xor(seed, hash_size, phash, hash_size + 1 + max_msg_len, hashing);
+ result = MGF1_xor(seed, hash_size, phash, hash_size + 1 + max_msg_len,
+ hashing);
/* Recover db. */
- MGF1_xor(phash, hash_size + 1 + max_msg_len, seed, hash_size, hashing);
+ result |= MGF1_xor(phash, hash_size + 1 + max_msg_len, seed, hash_size,
+ hashing);
+
+ if (result != DCRYPTO_OK)
+ return DCRYPTO_FAIL;
- if (hashing == HASH_SHA1)
- SHA1_hw_init(&ctx.sha1);
- else
- SHA256_hw_init(&ctx.sha256);
+ result = DCRYPTO_hw_hash_init(&ctx, hashing);
+ if (result != DCRYPTO_OK)
+ return result;
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
- /* bad should be zero if CRYPTO_OK is returned. */
- bad = DCRYPTO_equals(phash, HASH_final(&ctx)->b8, hash_size) -
- DCRYPTO_OK;
+ /* bad should be zero if DCRYPTO_OK is returned. */
+ result = DCRYPTO_equals(phash, HASH_final(&ctx)->b8, hash_size);
+ bad = result - DCRYPTO_OK; /* bad = 0 if result == DCRYPTO_OK */
bad |= padded[0];
- for (i = PS - padded; i < padded_len; i++) {
+ for (i = PS - padded; i < padded_len; i++) {
uint32_t equals0 = is_zero(padded[i]);
uint32_t equals1 = is_zero(padded[i] ^ 1);
@@ -168,29 +184,30 @@ static int check_oaep_pad(uint8_t *out, size_t *out_len,
bad |= looking_for_one_byte;
if (bad)
- return 0;
+ return DCRYPTO_FAIL;
one_index++;
if (*out_len < padded_len - one_index)
- return 0;
+ return DCRYPTO_FAIL;
memcpy(out, padded + one_index, padded_len - one_index);
*out_len = padded_len - one_index;
- return 1;
+ /* Result should be DCRYPTO_OK after DCRYPTO_equals() */
+ return result;
}
/* Constants from RFC 3447. */
#define RSA_PKCS1_PADDING_SIZE 11
/* encrypt */
-static int pkcs1_type2_pad(uint8_t *padded, size_t padded_len,
- const uint8_t *in, size_t in_len)
+static enum dcrypto_result pkcs1_type2_pad(uint8_t *padded, size_t padded_len,
+ const uint8_t *in, size_t in_len)
{
size_t PS_len;
if (padded_len < RSA_PKCS1_PADDING_SIZE)
- return 0;
+ return DCRYPTO_FAIL;
if (in_len > padded_len - RSA_PKCS1_PADDING_SIZE)
- return 0;
+ return DCRYPTO_FAIL;
PS_len = padded_len - 3 - in_len;
*(padded++) = 0;
@@ -200,7 +217,7 @@ static int pkcs1_type2_pad(uint8_t *padded, size_t padded_len,
uint8_t r[SHA256_DIGEST_SIZE];
if (!fips_rand_bytes(r, sizeof(r)))
- return 0;
+ return DCRYPTO_FAIL;
/**
* zero byte has special meaning in PKCS1, so copy
@@ -215,11 +232,11 @@ static int pkcs1_type2_pad(uint8_t *padded, size_t padded_len,
}
*(padded++) = 0;
memcpy(padded, in, in_len);
- return 1;
+ return DCRYPTO_OK;
}
/* decrypt */
-static int check_pkcs1_type2_pad(uint8_t *out, size_t *out_len,
+static enum dcrypto_result check_pkcs1_type2_pad(uint8_t *out, size_t *out_len,
const uint8_t *padded, size_t padded_len)
{
size_t i;
@@ -228,7 +245,7 @@ static int check_pkcs1_type2_pad(uint8_t *out, size_t *out_len,
uint32_t looking_for_index = ~0;
if (padded_len < RSA_PKCS1_PADDING_SIZE)
- return 0;
+ return DCRYPTO_FAIL;
valid = (padded[0] == 0);
valid &= (padded[1] == 2);
@@ -245,13 +262,14 @@ static int check_pkcs1_type2_pad(uint8_t *out, size_t *out_len,
valid &= ~looking_for_index;
valid &= (zero_index >= RSA_PKCS1_PADDING_SIZE);
if (!valid)
- return 0;
+ return DCRYPTO_FAIL;
if (*out_len < padded_len - zero_index)
- return 0;
+ return DCRYPTO_FAIL;
+
memcpy(out, &padded[zero_index], padded_len - zero_index);
*out_len = padded_len - zero_index;
- return 1;
+ return DCRYPTO_OK;
}
static const uint8_t SHA1_DER[] = {
@@ -274,8 +292,9 @@ static const uint8_t SHA512_DER[] = {
0x00, 0x04, 0x40
};
-static int pkcs1_get_der(enum hashing_mode hashing, const uint8_t **der,
- size_t *der_size, size_t *hash_size)
+static enum dcrypto_result pkcs1_get_der(enum hashing_mode hashing,
+ const uint8_t **der, size_t *der_size,
+ size_t *hash_size)
{
switch (hashing) {
case HASH_SHA1:
@@ -301,33 +320,35 @@ static int pkcs1_get_der(enum hashing_mode hashing, const uint8_t **der,
case HASH_NULL:
*der = NULL;
*der_size = 0;
- *hash_size = 0; /* any size allowed */
+ *hash_size = 0; /* any size allowed */
break;
default:
- return 0;
+ return DCRYPTO_FAIL;
}
- return 1;
+ return DCRYPTO_OK;
}
/* sign */
-static int pkcs1_type1_pad(uint8_t *padded, size_t padded_len,
- const uint8_t *in, size_t in_len,
- enum hashing_mode hashing)
+static enum dcrypto_result pkcs1_type1_pad(uint8_t *padded, size_t padded_len,
+ const uint8_t *in, size_t in_len,
+ enum hashing_mode hashing)
{
const uint8_t *der;
size_t der_size;
size_t hash_size;
size_t ps_len;
+ enum dcrypto_result result;
- if (!pkcs1_get_der(hashing, &der, &der_size, &hash_size))
- return 0;
+ result = pkcs1_get_der(hashing, &der, &der_size, &hash_size);
+ if (result != DCRYPTO_OK)
+ return result;
if (padded_len < RSA_PKCS1_PADDING_SIZE + der_size)
- return 0;
+ return DCRYPTO_FAIL;
if (!in_len || (hash_size && in_len != hash_size))
- return 0;
+ return DCRYPTO_FAIL;
if (in_len > padded_len - RSA_PKCS1_PADDING_SIZE - der_size)
- return 0;
+ return DCRYPTO_FAIL;
ps_len = padded_len - 3 - der_size - in_len;
*(padded++) = 0;
@@ -338,73 +359,83 @@ static int pkcs1_type1_pad(uint8_t *padded, size_t padded_len,
memcpy(padded, der, der_size);
padded += der_size;
memcpy(padded, in, in_len);
- return 1;
+ return DCRYPTO_OK;
}
/* verify */
-static int check_pkcs1_type1_pad(const uint8_t *msg, size_t msg_len,
- const uint8_t *padded, size_t padded_len,
- enum hashing_mode hashing)
+static enum dcrypto_result check_pkcs1_type1_pad(const uint8_t *msg,
+ size_t msg_len,
+ const uint8_t *padded,
+ size_t padded_len,
+ enum hashing_mode hashing)
{
size_t i;
const uint8_t *der;
size_t der_size;
size_t hash_size;
size_t ps_len;
+ enum dcrypto_result result;
- if (!pkcs1_get_der(hashing, &der, &der_size, &hash_size))
- return 0;
+ result = pkcs1_get_der(hashing, &der, &der_size, &hash_size);
+ if (result != DCRYPTO_OK)
+ return result;
if (msg_len != hash_size)
- return 0;
+ return DCRYPTO_FAIL;
if (padded_len < RSA_PKCS1_PADDING_SIZE + der_size + hash_size)
- return 0;
+ return DCRYPTO_FAIL;
ps_len = padded_len - 3 - der_size - hash_size;
if (padded[0] != 0 || padded[1] != 1)
- return 0;
+ return DCRYPTO_FAIL;
for (i = 2; i < ps_len + 2; i++) {
if (padded[i] != 0xFF)
- return 0;
+ return DCRYPTO_FAIL;
}
if (padded[i++] != 0)
- return 0;
- if (DCRYPTO_equals(&padded[i], der, der_size) != DCRYPTO_OK)
- return 0;
+ return DCRYPTO_FAIL;
+
+ result = DCRYPTO_equals(&padded[i], der, der_size);
i += der_size;
- return DCRYPTO_equals(msg, &padded[i], hash_size) == DCRYPTO_OK;
+ result |= DCRYPTO_equals(msg, &padded[i], hash_size);
+ if (result != DCRYPTO_OK)
+ return DCRYPTO_FAIL;
+ return result;
}
/* sign */
-static int pkcs1_pss_pad(uint8_t *padded, size_t padded_len,
- const uint8_t *in, size_t in_len,
- enum hashing_mode hashing)
+static enum dcrypto_result pkcs1_pss_pad(uint8_t *padded, size_t padded_len,
+ const uint8_t *in, size_t in_len,
+ enum hashing_mode hashing)
{
- const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE
- : SHA256_DIGEST_SIZE;
+ const uint32_t hash_size = DCRYPTO_hash_size(hashing);
const uint32_t salt_len = MIN(padded_len - hash_size - 2, hash_size);
size_t db_len;
size_t ps_len;
union hash_ctx ctx;
+ enum dcrypto_result result;
+ if (!hash_size)
+ return DCRYPTO_FAIL;
if (in_len != hash_size)
- return 0;
+ return DCRYPTO_FAIL;
if (padded_len < hash_size + 2)
- return 0;
+ return DCRYPTO_FAIL;
db_len = padded_len - hash_size - 1;
- if (hashing == HASH_SHA1)
- SHA1_hw_init(&ctx.sha1);
- else
- SHA256_hw_init(&ctx.sha256);
+ result = DCRYPTO_hw_hash_init(&ctx, hashing);
+ if (result != DCRYPTO_OK)
+ return result;
/* Pilfer bits of output for temporary use. */
memset(padded, 0, 8);
HASH_update(&ctx, padded, 8);
HASH_update(&ctx, in, in_len);
/* Pilfer bits of output for temporary use. */
- if (!fips_rand_bytes(padded, salt_len))
- return 0;
+ if (!fips_rand_bytes(padded, salt_len)) {
+ HASH_final(&ctx); /* free up SHA engine */
+ return DCRYPTO_FAIL;
+ }
HASH_update(&ctx, padded, salt_len);
/* Output hash. */
@@ -415,22 +446,22 @@ static int pkcs1_pss_pad(uint8_t *padded, size_t padded_len,
memmove(padded + ps_len + 1, padded, salt_len);
memset(padded, 0, ps_len);
padded[ps_len] = 0x01;
- MGF1_xor(padded, db_len, padded + db_len, hash_size, hashing);
+ result = MGF1_xor(padded, db_len, padded + db_len, hash_size, hashing);
/* Clear most significant bit. */
padded[0] &= 0x7F;
/* Set trailing byte. */
padded[padded_len - 1] = 0xBC;
- return 1;
+ return result;
}
/* verify */
-static int check_pkcs1_pss_pad(const uint8_t *in, size_t in_len,
- uint8_t *padded, size_t padded_len,
- enum hashing_mode hashing)
+static enum dcrypto_result check_pkcs1_pss_pad(const uint8_t *in, size_t in_len,
+ uint8_t *padded,
+ size_t padded_len,
+ enum hashing_mode hashing)
{
- const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE
- : SHA256_DIGEST_SIZE;
+ const uint32_t hash_size = DCRYPTO_hash_size(hashing);
const uint8_t zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t db_len;
uint32_t max_ps_len;
@@ -438,11 +469,14 @@ static int check_pkcs1_pss_pad(const uint8_t *in, size_t in_len,
union hash_ctx ctx;
int bad = 0;
size_t i;
+ enum dcrypto_result result;
+ if (!hash_size)
+ return DCRYPTO_FAIL;
if (in_len != hash_size)
- return 0;
+ return DCRYPTO_FAIL;
if (padded_len < hash_size + 2)
- return 0;
+ return DCRYPTO_FAIL;
db_len = padded_len - hash_size - 1;
/* Top bit should be zero. */
@@ -451,7 +485,9 @@ static int check_pkcs1_pss_pad(const uint8_t *in, size_t in_len,
bad |= padded[padded_len - 1] ^ 0xBC;
/* Recover DB. */
- MGF1_xor(padded, db_len, padded + db_len, hash_size, hashing);
+ result = MGF1_xor(padded, db_len, padded + db_len, hash_size, hashing);
+ bad |= result - DCRYPTO_OK;
+
/* Clear top bit. */
padded[0] &= 0x7F;
/* Verify padding2. */
@@ -466,16 +502,18 @@ static int check_pkcs1_pss_pad(const uint8_t *in, size_t in_len,
/* Continue with zero-length salt if 0x01 was not found. */
salt_len = max_ps_len - i;
- if (hashing == HASH_SHA1)
- SHA1_hw_init(&ctx.sha1);
- else
- SHA256_hw_init(&ctx.sha256);
+ result |= DCRYPTO_hw_hash_init(&ctx, hashing);
+ if (result != DCRYPTO_OK)
+ return DCRYPTO_FAIL;
+
HASH_update(&ctx, zeros, sizeof(zeros));
HASH_update(&ctx, in, in_len);
HASH_update(&ctx, padded + db_len - salt_len, salt_len);
- bad |= DCRYPTO_equals(padded + db_len, HASH_final(&ctx), hash_size) -
- DCRYPTO_OK;
- return !bad;
+ result |= DCRYPTO_equals(padded + db_len, HASH_final(&ctx), hash_size);
+ bad |= result - DCRYPTO_OK;
+ if (bad)
+ result = DCRYPTO_FAIL;
+ return result;
}
static int check_modulus_params(
@@ -511,13 +549,14 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_OAEP:
- if (!oaep_pad((uint8_t *) padded.d, bn_size(&padded),
- (const uint8_t *) in, in_len, hashing, label))
+ if (oaep_pad((uint8_t *)padded.d, bn_size(&padded),
+ (const uint8_t *)in, in_len, hashing,
+ label) != DCRYPTO_OK)
return 0;
break;
case PADDING_MODE_PKCS1:
- if (!pkcs1_type2_pad((uint8_t *) padded.d, bn_size(&padded),
- (const uint8_t *) in, in_len))
+ if (pkcs1_type2_pad((uint8_t *)padded.d, bn_size(&padded),
+ (const uint8_t *)in, in_len) != DCRYPTO_OK)
return 0;
break;
case PADDING_MODE_NULL:
@@ -579,14 +618,15 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_OAEP:
- if (!check_oaep_pad(out, out_len, (uint8_t *) padded.d,
- bn_size(&padded), hashing, label))
+ if (check_oaep_pad(out, out_len, (uint8_t *)padded.d,
+ bn_size(&padded), hashing,
+ label) != DCRYPTO_OK)
ret = 0;
break;
case PADDING_MODE_PKCS1:
- if (!check_pkcs1_type2_pad(
- out, out_len, (const uint8_t *) padded.d,
- bn_size(&padded)))
+ if (check_pkcs1_type2_pad(out, out_len,
+ (const uint8_t *)padded.d,
+ bn_size(&padded)) != DCRYPTO_OK)
ret = 0;
break;
case PADDING_MODE_NULL:
@@ -626,13 +666,15 @@ int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, size_t *out_len,
switch (padding) {
case PADDING_MODE_PKCS1:
- if (!pkcs1_type1_pad((uint8_t *) padded.d, bn_size(&padded),
- (const uint8_t *) in, in_len, hashing))
+ if (pkcs1_type1_pad((uint8_t *)padded.d, bn_size(&padded),
+ (const uint8_t *)in, in_len,
+ hashing) != DCRYPTO_OK)
return 0;
break;
case PADDING_MODE_PSS:
- if (!pkcs1_pss_pad((uint8_t *) padded.d, bn_size(&padded),
- (const uint8_t *) in, in_len, hashing))
+ if (pkcs1_pss_pad((uint8_t *)padded.d, bn_size(&padded),
+ (const uint8_t *)in, in_len,
+ hashing) != DCRYPTO_OK)
return 0;
break;
default:
@@ -679,15 +721,15 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
switch (padding) {
case PADDING_MODE_PKCS1:
- if (!check_pkcs1_type1_pad(
- digest, digest_len, (uint8_t *) padded.d,
- bn_size(&padded), hashing))
+ if (check_pkcs1_type1_pad(digest, digest_len,
+ (uint8_t *)padded.d, bn_size(&padded),
+ hashing) != DCRYPTO_OK)
ret = 0;
break;
case PADDING_MODE_PSS:
- if (!check_pkcs1_pss_pad(
- digest, digest_len, (uint8_t *) padded.d,
- bn_size(&padded), hashing))
+ if (check_pkcs1_pss_pad(digest, digest_len, (uint8_t *)padded.d,
+ bn_size(&padded),
+ hashing) != DCRYPTO_OK)
ret = 0;
break;
default:
diff --git a/board/cr50/dcrypto/sha_hw.c b/board/cr50/dcrypto/sha_hw.c
index 7d70d71c86..28ede02143 100644
--- a/board/cr50/dcrypto/sha_hw.c
+++ b/board/cr50/dcrypto/sha_hw.c
@@ -354,10 +354,6 @@ const struct sha256_digest *SHA256_hw_hash(const void *data, size_t n,
return digest;
}
-/* For compatibility with chip/g code. */
-const uint8_t *DCRYPTO_SHA1_hash(const void *data, size_t n, uint8_t *digest)
- __alias(SHA1_hw_hash);
-
const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx)
{
return HMAC_SHA256_final(ctx);
diff --git a/board/cr50/tpm2/ecc.c b/board/cr50/tpm2/ecc.c
index 6e8f5792ed..c7fe1c15b2 100644
--- a/board/cr50/tpm2/ecc.c
+++ b/board/cr50/tpm2/ecc.c
@@ -141,8 +141,10 @@ CRYPT_RESULT _cpri__GenerateKeyEcc(
/* Hash down the primary seed for ECC key generation, so that
* the derivation tree is distinct from RSA key derivation. */
- HMAC_SHA256_hw_init(&hmac, seed->buffer,
- seed->size);
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, seed->buffer, seed->size) !=
+ DCRYPTO_OK)
+ return CRYPT_FAIL;
+
HMAC_SHA256_update(&hmac, "ECC", 4);
memcpy(local_seed.t.buffer, HMAC_SHA256_final(&hmac),
local_seed.t.size);
diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c
index f929f1c405..b4d2b91775 100644
--- a/board/cr50/tpm2/endorsement.c
+++ b/board/cr50/tpm2/endorsement.c
@@ -590,12 +590,16 @@ enum manufacturing_status tpm_endorse(void)
*
* This will fail if we are not running w/ expected keyladder.
*/
- HMAC_SHA256_hw_init(&hmac, eps, sizeof(eps));
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, eps, sizeof(eps)) !=
+ DCRYPTO_OK)
+ return mnf_hmac_mismatch;
HMAC_SHA256_update(&hmac, "RSA", 4);
- HMAC_SHA256_hw_init(&hmac, HMAC_SHA256_hw_final(&hmac), 32);
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, HMAC_SHA256_final(&hmac),
+ 32) != DCRYPTO_OK)
+ return mnf_hmac_mismatch;
HMAC_SHA256_update(&hmac, p, RO_CERTS_REGION_SIZE - 32);
if (DCRYPTO_equals(p + RO_CERTS_REGION_SIZE - 32,
- HMAC_SHA256_hw_final(&hmac),
+ HMAC_SHA256_final(&hmac),
32) != DCRYPTO_OK) {
CPRINTF("%s: bad cert region hmac;", __func__);
#ifdef CR50_INCLUDE_FALLBACK_CERT
diff --git a/board/cr50/tpm2/hash.c b/board/cr50/tpm2/hash.c
index 4494451844..98b60e760b 100644
--- a/board/cr50/tpm2/hash.c
+++ b/board/cr50/tpm2/hash.c
@@ -54,45 +54,38 @@ void _cpri__ImportExportHashState(CPRI_HASH_STATE *osslFmt,
memcpy(externalFmt, osslFmt, sizeof(CPRI_HASH_STATE));
}
+/* We try to use same encoding for TPM & Dcrypto. */
+BUILD_ASSERT(TPM_ALG_SHA1 == HASH_SHA1);
+BUILD_ASSERT(TPM_ALG_SHA256 == HASH_SHA256);
+BUILD_ASSERT(TPM_ALG_SHA384 == HASH_SHA384);
+BUILD_ASSERT(TPM_ALG_SHA512 == HASH_SHA512);
+BUILD_ASSERT(TPM_ALG_NULL == HASH_NULL);
+
uint16_t _cpri__HashBlock(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
- uint32_t out_len, uint8_t *out)
+ uint32_t out_len, uint8_t *out)
{
- union sha_digests digest;
const uint16_t digest_len = _cpri__GetDigestSize(alg);
+ union hash_ctx ctx;
if (digest_len == 0)
return 0;
- switch (alg) {
- case TPM_ALG_SHA1:
- SHA1_hw_hash(in, in_len, &digest.sha1);
- break;
-
- case TPM_ALG_SHA256:
- SHA256_hw_hash(in, in_len, &digest.sha256);
- break;
- case TPM_ALG_SHA384:
- SHA384_hw_hash(in, in_len, &digest.sha384);
- break;
- case TPM_ALG_SHA512:
- SHA512_hw_hash(in, in_len, &digest.sha512);
- break;
- default:
+ if (DCRYPTO_hw_hash_init(&ctx, alg) != DCRYPTO_OK) {
FAIL(FATAL_ERROR_INTERNAL);
- break;
+ return 0;
}
-
+ HASH_update(&ctx, in, in_len);
out_len = MIN(out_len, digest_len);
- memcpy(out, digest.b8, out_len);
+ memcpy(out, HASH_final(&ctx), out_len);
return out_len;
}
BUILD_ASSERT(sizeof(union hash_ctx) <=
sizeof(((CPRI_HASH_STATE *)0)->state));
-uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence,
- CPRI_HASH_STATE *state)
+
+uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence, CPRI_HASH_STATE *state)
{
- union hash_ctx *ctx = (union hash_ctx *) state->state;
+ union hash_ctx *ctx = (union hash_ctx *)state->state;
uint16_t result;
/* NOTE: as per bug http://crosbug.com/p/55331#26 (NVMEM
@@ -101,28 +94,10 @@ uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence,
* that the key-ladder will not be used between SHA_init() and
* final().
*/
- switch (alg) {
- case TPM_ALG_SHA1:
- SHA1_sw_init(&ctx->sha1);
- result = HASH_size(ctx);
- break;
- case TPM_ALG_SHA256:
- SHA256_sw_init(&ctx->sha256);
- result = HASH_size(ctx);
- break;
+ if (DCRYPTO_sw_hash_init(ctx, (enum hashing_mode)alg) != DCRYPTO_OK)
+ return 0;
- case TPM_ALG_SHA384:
- SHA384_sw_init(&ctx->sha384);
- result = HASH_size(ctx);
- break;
- case TPM_ALG_SHA512:
- SHA512_sw_init(&ctx->sha512);
- result = HASH_size(ctx);
- break;
- default:
- result = 0;
- break;
- }
+ result = HASH_size(ctx);
if (result > 0)
state->hashAlg = alg;
@@ -291,23 +266,23 @@ static uint16_t do_software_hmac(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
return out_len;
}
-static uint16_t do_dcrypto_hmac(TPM_ALG_ID alg, uint32_t in_len,
- uint8_t *in, int32_t out_len, uint8_t *out)
+static uint16_t do_dcrypto_hmac(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
+ int32_t out_len, uint8_t *out)
{
- struct hmac_sha256_ctx ctx;
+ union hmac_ctx ctx;
uint8_t *key;
uint32_t key_len;
- /* Dcrypto only support SHA-256 */
- if (alg != TPM_ALG_SHA256)
- return 0;
key = in + in_len;
key_len = *key++;
key_len = key_len * 256 + *key++;
- HMAC_SHA256_hw_init(&ctx, key, key_len);
- HMAC_SHA256_update(&ctx, in, in_len);
- out_len = MIN(out_len, SHA256_DIGEST_SIZE);
- memcpy(out, HMAC_SHA256_hw_final(&ctx), out_len);
+ /* Check if requested algorithm is supported. */
+ if (DCRYPTO_hw_hmac_init(&ctx, key, key_len, (enum hashing_mode)alg) !=
+ DCRYPTO_OK)
+ return 0;
+ HMAC_update(&ctx, in, in_len);
+ out_len = MIN(out_len, DCRYPTO_hash_size((enum hashing_mode)alg));
+ memcpy(out, HMAC_final(&ctx), out_len);
return out_len;
}
diff --git a/board/cr50/tpm2/rsa.c b/board/cr50/tpm2/rsa.c
index 78cc3562de..97797d440a 100644
--- a/board/cr50/tpm2/rsa.c
+++ b/board/cr50/tpm2/rsa.c
@@ -397,10 +397,12 @@ CRYPT_RESULT _cpri__GenerateKeyRSA(
{
struct hmac_sha256_ctx hmac;
- HMAC_SHA256_hw_init(&hmac, seed->buffer, seed->size);
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, seed->buffer,
+ seed->size) != DCRYPTO_OK)
+ return CRYPT_FAIL;
HMAC_SHA256_update(&hmac, "RSA", 4);
- memcpy(local_seed.t.buffer, HMAC_SHA256_hw_final(&hmac),
- local_seed.t.size);
+ memcpy(local_seed.t.buffer, HMAC_SHA256_final(&hmac),
+ local_seed.t.size);
}
if (e_buf == 0)
diff --git a/board/cr50/tpm2/virtual_nvmem.c b/board/cr50/tpm2/virtual_nvmem.c
index 3ddaed067d..16a4028be9 100644
--- a/board/cr50/tpm2/virtual_nvmem.c
+++ b/board/cr50/tpm2/virtual_nvmem.c
@@ -304,9 +304,11 @@ static void GetRSUDevID(BYTE *to, size_t offset, size_t size)
uint8_t rma_device_id[RMA_DEVICE_ID_SIZE];
const uint8_t *rsu_device_id;
- get_rma_device_id(rma_device_id);
-
- SHA256_hw_init(&ctx);
+ if (get_rma_device_id(rma_device_id) != EC_SUCCESS ||
+ DCRYPTO_hw_sha256_init(&ctx) != DCRYPTO_OK) {
+ memset(to, 0, size);
+ return;
+ };
SHA256_update(&ctx, rma_device_id, sizeof(rma_device_id));
SHA256_update(&ctx, kRsuSalt, RSU_SALT_SIZE);
rsu_device_id = SHA256_final(&ctx)->b8;
diff --git a/board/cr50/usb_spi.c b/board/cr50/usb_spi.c
index 4aede92f19..32ef2b00c4 100644
--- a/board/cr50/usb_spi.c
+++ b/board/cr50/usb_spi.c
@@ -678,7 +678,8 @@ int usb_spi_sha256_start(struct sha256_ctx *ctx)
return EC_ERROR_BUSY;
}
- SHA256_hw_init(ctx);
+ if (DCRYPTO_hw_sha256_init(ctx) != DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
return EC_SUCCESS;
}
diff --git a/board/host/dcrypto.h b/board/host/dcrypto.h
index b9bd5b8be8..030e8bbb23 100644
--- a/board/host/dcrypto.h
+++ b/board/host/dcrypto.h
@@ -18,74 +18,12 @@
* this is not set, a combination of cryptoc and openssl are used for the
* dcrypto implementation.
*/
-#ifndef CONFIG_DCRYPTO_MOCK
-/* If not using the mock struct definitions, use the ones from Cr50. */
+#ifndef CONFIG_DCRYPTO_MOCK
#include "board/cr50/dcrypto/dcrypto.h"
+#else
+#include "board/cr50/dcrypto/internal.h"
+#endif
-#else /* defined(CONFIG_DCRYPTO_MOCK) */
-
-#include "board/cr50/dcrypto/hmacsha2.h"
-
-#define AES256_BLOCK_CIPHER_KEY_SIZE 32
-
-enum dcrypto_appid {
- RESERVED = 0,
- NVMEM = 1,
- U2F_ATTEST = 2,
- U2F_ORIGIN = 3,
- U2F_WRAP = 4,
- PERSO_AUTH = 5,
- PINWEAVER = 6,
- /* This enum value should not exceed 7. */
-};
-
-void SHA256_hw_init(struct sha256_ctx *ctx);
-
-void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
- size_t len);
-const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx);
-
-int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
- const uint8_t *iv, const uint8_t *in, size_t in_len);
-
-
-int DCRYPTO_appkey_init(enum dcrypto_appid appid);
-
-void DCRYPTO_appkey_finish(void);
-
-int DCRYPTO_appkey_derive(enum dcrypto_appid appid, const uint32_t input[8],
- uint32_t output[8]);
-
-#include "cryptoc/p256.h"
-
-int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
- const p256_int *pk_y, const p256_int *serial,
- const char *name, uint8_t *cert,
- const int n);
-
-int DCRYPTO_ladder_random(void *output);
-
-#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
-
-struct drbg_ctx {
- uint32_t k[SHA256_DIGEST_WORDS];
- uint32_t v[SHA256_DIGEST_WORDS];
- uint32_t reseed_counter;
-};
-
-enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg,
- const p256_int *key,
- const p256_int *message,
- p256_int *r, p256_int *s);
-
-void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx, const p256_int *key,
- const p256_int *message);
-
-bool fips_rand_bytes(void *buffer, size_t len);
-
-bool fips_crypto_allowed(void);
-
-#endif /* CONFIG_DCRYPTO_MOCK */
#endif /* __CROS_EC_HOST_DCRYPTO_H */
diff --git a/chip/host/build.mk b/chip/host/build.mk
index 6cdd9807d4..4355a47673 100644
--- a/chip/host/build.mk
+++ b/chip/host/build.mk
@@ -34,8 +34,12 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/sha256.o
# Object files that can be shared with the Cr50 dcrypto implementation
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/hmac_sw.o
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/hash_api.o
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/sha1.o
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/sha256.o
+ifeq ($(CONFIG_UPTO_SHA512),y)
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/sha512.o
+endif
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/hmac_drbg.o
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/p256.o
chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/compare.o
diff --git a/chip/host/dcrypto/app_cipher.c b/chip/host/dcrypto/app_cipher.c
index a3ce4e3184..6ce25b6199 100644
--- a/chip/host/dcrypto/app_cipher.c
+++ b/chip/host/dcrypto/app_cipher.c
@@ -15,7 +15,7 @@ void app_compute_hash(const void *p_buf, size_t num_bytes, void *p_hash,
* Use the built in dcrypto engine to generate the sha1 hash of the
* buffer.
*/
- SHA256_hw_hash(p_buf, num_bytes, &digest);
+ DCRYPTO_SHA256_hash(p_buf, num_bytes, digest.b8);
memcpy(p_hash, digest.b8, MIN(hash_len, sizeof(digest)));
@@ -46,3 +46,8 @@ int crypto_enabled(void)
{
return 1;
}
+
+bool fips_crypto_allowed(void)
+{
+ return true;
+}
diff --git a/chip/host/dcrypto/sha256.c b/chip/host/dcrypto/sha256.c
index 1c9fda27c2..ec2638ffc3 100644
--- a/chip/host/dcrypto/sha256.c
+++ b/chip/host/dcrypto/sha256.c
@@ -3,7 +3,18 @@
* found in the LICENSE file.
*/
-#include "dcrypto.h"
+#include "internal.h"
+
+void SHA1_hw_init(struct sha1_ctx *ctx)
+{
+ SHA1_sw_init(ctx);
+}
+
+const struct sha1_digest *SHA1_hw_hash(const void *data, size_t n,
+ struct sha1_digest *digest)
+{
+ return SHA1_sw_hash(data, n, digest);
+}
void SHA256_hw_init(struct sha256_ctx *ctx)
{
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 12e88689ad..d87842a055 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -236,7 +236,8 @@ static int raw_has_password(void)
* @param digest Pointer to a CCD_PASSWORD_DIGEST_SIZE buffer
* @param password The password to digest
*/
-static void ccd_password_digest(uint8_t *digest, const char *password)
+static enum ec_error_list ccd_password_digest(uint8_t *digest,
+ const char *password)
{
struct sha256_ctx sha;
uint8_t *unique_id;
@@ -244,11 +245,13 @@ static void ccd_password_digest(uint8_t *digest, const char *password)
unique_id_len = system_get_chip_unique_id(&unique_id);
- SHA256_hw_init(&sha);
+ if (DCRYPTO_hw_sha256_init(&sha) != DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
SHA256_update(&sha, config.password_salt, sizeof(config.password_salt));
SHA256_update(&sha, unique_id, unique_id_len);
SHA256_update(&sha, password, strlen(password));
memcpy(digest, SHA256_final(&sha)->b8, CCD_PASSWORD_DIGEST_SIZE);
+ return EC_SUCCESS;
}
/**
@@ -258,7 +261,7 @@ static void ccd_password_digest(uint8_t *digest, const char *password)
* @return EC_SUCCESS, EC_ERROR_BUSY if too soon since last attempt, or
* EC_ERROR_ACCESS_DENIED if mismatch.
*/
-static int raw_check_password(const char *password)
+static enum ec_error_list raw_check_password(const char *password)
{
/*
* Time of last password attempt; initialized to 0 at boot. Yes, we're
@@ -272,6 +275,7 @@ static int raw_check_password(const char *password)
uint8_t digest[CCD_PASSWORD_DIGEST_SIZE];
uint32_t t;
+ enum ec_error_list result;
/* If no password is set, match only an empty password */
if (!raw_has_password())
@@ -284,7 +288,9 @@ static int raw_check_password(const char *password)
last_password_time = t;
/* Calculate the digest of the password */
- ccd_password_digest(digest, password);
+ result = ccd_password_digest(digest, password);
+ if (result != EC_SUCCESS)
+ return result;
if (safe_memcmp(digest, config.password_digest,
sizeof(config.password_digest)))
@@ -312,19 +318,23 @@ static void raw_reset_password(void)
* @param password New password; must be non-empty
* @return EC_SUCCESS if successful
*/
-static int raw_set_password(const char *password)
+static enum ec_error_list raw_set_password(const char *password)
{
+ enum ec_error_list result;
+
/* Get a new salt */
if (!fips_rand_bytes(config.password_salt,
sizeof(config.password_salt)))
return EC_ERROR_HW_INTERNAL;
/* Update the password digest */
- ccd_password_digest(config.password_digest, password);
+ result = ccd_password_digest(config.password_digest, password);
+ if (result != EC_SUCCESS)
+ return result;
/* Track whether we were opened when we set the password */
raw_set_flag(CCD_FLAG_PASSWORD_SET_WHEN_UNLOCKED,
- ccd_state == CCD_STATE_UNLOCKED);
+ ccd_state == CCD_STATE_UNLOCKED);
return EC_SUCCESS;
}
diff --git a/common/pinweaver.c b/common/pinweaver.c
index 0bcd752ab6..9b7ad0b6d6 100644
--- a/common/pinweaver.c
+++ b/common/pinweaver.c
@@ -164,7 +164,8 @@ static int create_merkle_tree(struct bits_per_level_t bits_per_level,
/* Initialize the root hash. */
for (hx = 0; hx < height.v; ++hx) {
- SHA256_hw_init(&ctx);
+ if (DCRYPTO_hw_sha256_init(&ctx) != DCRYPTO_OK)
+ return PW_ERR_CRYPTO_FAILURE;
for (kx = 0; kx < fan_out; ++kx)
HASH_update((union hash_ctx *)&ctx, temp_hash,
PW_HASH_SIZE);
@@ -180,29 +181,31 @@ static int create_merkle_tree(struct bits_per_level_t bits_per_level,
}
/* Computes the HMAC for an encrypted leaf using the key in the merkle_tree. */
-static void compute_hmac(const struct merkle_tree_t *merkle_tree,
+static int compute_hmac(const struct merkle_tree_t *merkle_tree,
const struct imported_leaf_data_t *imported_leaf_data,
uint8_t result[PW_HASH_SIZE])
{
struct hmac_sha256_ctx hmac;
- HMAC_SHA256_hw_init(&hmac, merkle_tree->hmac_key,
- sizeof(merkle_tree->hmac_key));
- /* use HASH_update() vs. HMAC_update() due limits of dcrypto mock. */
- HASH_update((union hash_ctx *)&hmac.hash, imported_leaf_data->head,
- sizeof(*imported_leaf_data->head));
- HASH_update((union hash_ctx *)&hmac.hash, imported_leaf_data->iv,
- sizeof(PW_WRAP_BLOCK_SIZE));
- HASH_update((union hash_ctx *)&hmac.hash, imported_leaf_data->pub,
- imported_leaf_data->head->pub_len);
- HASH_update((union hash_ctx *)&hmac.hash,
- imported_leaf_data->cipher_text,
- imported_leaf_data->head->sec_len);
- memcpy(result, HMAC_SHA256_hw_final(&hmac), PW_HASH_SIZE);
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, merkle_tree->hmac_key,
+ sizeof(merkle_tree->hmac_key)) !=
+ DCRYPTO_OK)
+ return PW_ERR_CRYPTO_FAILURE;
+
+ HMAC_SHA256_update(&hmac, imported_leaf_data->head,
+ sizeof(*imported_leaf_data->head));
+ HMAC_SHA256_update(&hmac, imported_leaf_data->iv,
+ sizeof(PW_WRAP_BLOCK_SIZE));
+ HMAC_SHA256_update(&hmac, imported_leaf_data->pub,
+ imported_leaf_data->head->pub_len);
+ HMAC_SHA256_update(&hmac, imported_leaf_data->cipher_text,
+ imported_leaf_data->head->sec_len);
+ memcpy(result, HMAC_SHA256_final(&hmac), PW_HASH_SIZE);
+ return EC_SUCCESS;
}
/* Computes the root hash for the specified path and child hash. */
-static void compute_root_hash(const struct merkle_tree_t *merkle_tree,
+static int compute_root_hash(const struct merkle_tree_t *merkle_tree,
struct label_t path,
const uint8_t hashes[][PW_HASH_SIZE],
const uint8_t child_hash[PW_HASH_SIZE],
@@ -214,18 +217,25 @@ static void compute_root_hash(const struct merkle_tree_t *merkle_tree,
uint8_t temp_hash[PW_HASH_SIZE];
uint8_t hx = 0;
uint64_t index = path.v;
+ int ret;
+
+ ret = compute_hash(hashes, num_aux,
+ (struct index_t){ index & path_suffix_mask },
+ child_hash, temp_hash);
+ if (ret != EC_SUCCESS)
+ return ret;
- compute_hash(hashes, num_aux,
- (struct index_t){index & path_suffix_mask},
- child_hash, temp_hash);
for (hx = 1; hx < merkle_tree->height.v; ++hx) {
hashes += num_aux;
index = index >> merkle_tree->bits_per_level.v;
- compute_hash(hashes, num_aux,
- (struct index_t){index & path_suffix_mask},
- temp_hash, temp_hash);
+ ret = compute_hash(hashes, num_aux,
+ (struct index_t){ index & path_suffix_mask },
+ temp_hash, temp_hash);
+ if (ret != EC_SUCCESS)
+ return ret;
}
memcpy(new_root, temp_hash, sizeof(temp_hash));
+ return EC_SUCCESS;
}
/* Checks to see the specified path is valid. The length of the path should be
@@ -239,8 +249,11 @@ static int authenticate_path(const struct merkle_tree_t *merkle_tree,
const uint8_t child_hash[PW_HASH_SIZE])
{
uint8_t parent[PW_HASH_SIZE];
+ int ret;
- compute_root_hash(merkle_tree, path, hashes, child_hash, parent);
+ ret = compute_root_hash(merkle_tree, path, hashes, child_hash, parent);
+ if (ret != EC_SUCCESS)
+ return ret;
if (memcmp(parent, merkle_tree->root, sizeof(parent)) != 0)
return PW_ERR_PATH_AUTH_FAILED;
return EC_SUCCESS;
@@ -334,13 +347,13 @@ static int handle_leaf_update(
import_leaf((const struct unimported_leaf_data_t *)wrapped_leaf_data,
&ptrs);
- compute_hmac(merkle_tree, &ptrs, wrapped_leaf_data->hmac);
- compute_root_hash(merkle_tree, leaf_data->pub.label,
- hashes, wrapped_leaf_data->hmac,
- new_root);
+ ret = compute_hmac(merkle_tree, &ptrs, wrapped_leaf_data->hmac);
+ if (ret != EC_SUCCESS)
+ return ret;
- return EC_SUCCESS;
+ return compute_root_hash(merkle_tree, leaf_data->pub.label, hashes,
+ wrapped_leaf_data->hmac, new_root);
}
/******************************************************************************/
@@ -532,7 +545,9 @@ static int validate_request_with_wrapped_leaf(
if (ret != EC_SUCCESS)
return ret;
- compute_hmac(merkle_tree, imported_leaf_data, hmac);
+ ret = compute_hmac(merkle_tree, imported_leaf_data, hmac);
+ if (ret != EC_SUCCESS)
+ return ret;
/* Safe memcmp is used here to prevent an attacker from being able to
* brute force a valid HMAC for a crafted wrapped_leaf_data.
* memcmp provides an attacker a timing side-channel they can use to
@@ -994,8 +1009,10 @@ static int pw_handle_remove_leaf(struct merkle_tree_t *merkle_tree,
if (ret != EC_SUCCESS)
return ret;
- compute_root_hash(merkle_tree, request->leaf_location,
- request->path_hashes, empty_hash, new_root);
+ ret = compute_root_hash(merkle_tree, request->leaf_location,
+ request->path_hashes, empty_hash, new_root);
+ if (ret != EC_SUCCESS)
+ return ret;
ret = log_remove_leaf(request->leaf_location, new_root);
if (ret != EC_SUCCESS)
@@ -1283,7 +1300,10 @@ static int pw_handle_log_replay(const struct merkle_tree_t *merkle_tree,
if (log.entries[x].type.v != PW_TRY_AUTH)
return PW_ERR_TYPE_INVALID;
- compute_hmac(merkle_tree, &imported_leaf_data, hmac);
+ ret = compute_hmac(merkle_tree, &imported_leaf_data, hmac);
+ if (ret != EC_SUCCESS)
+ return ret;
+
if (safe_memcmp(hmac, request->unimported_leaf_data.hmac, sizeof(hmac)))
return PW_ERR_HMAC_AUTH_FAILED;
@@ -1385,14 +1405,15 @@ int get_path_auxiliary_hash_count(const struct merkle_tree_t *merkle_tree)
* ARRAY_SIZE(hashes) == num_hashes
* 0 <= location <= num_hashes
*/
-void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
+int compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
struct index_t location,
const uint8_t child_hash[PW_HASH_SIZE],
uint8_t result[PW_HASH_SIZE])
{
struct sha256_ctx ctx;
- SHA256_hw_init(&ctx);
+ if (DCRYPTO_hw_sha256_init(&ctx) != DCRYPTO_OK)
+ return PW_ERR_CRYPTO_FAILURE;
if (location.v > 0)
HASH_update((union hash_ctx *)&ctx, hashes[0],
PW_HASH_SIZE * location.v);
@@ -1401,6 +1422,7 @@ void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
HASH_update((union hash_ctx *)&ctx, hashes[location.v],
PW_HASH_SIZE * (num_hashes - location.v));
memcpy(result, HASH_final((union hash_ctx *)&ctx), PW_HASH_SIZE);
+ return EC_SUCCESS;
}
/* If a request from older protocol comes, this method should make it
diff --git a/common/rma_auth.c b/common/rma_auth.c
index 9de2d9984b..01c3ff827e 100644
--- a/common/rma_auth.c
+++ b/common/rma_auth.c
@@ -75,31 +75,38 @@ static char authcode[RMA_AUTHCODE_BUF_SIZE];
static int tries_left;
static uint64_t last_challenge_time;
-static void get_hmac_sha256(void *hmac_out, const uint8_t *secret,
+static enum ec_error_list get_hmac_sha256(void *hmac_out, const uint8_t *secret,
size_t secret_size, const void *ch_ptr,
size_t ch_size)
{
#ifdef USE_DCRYPTO
struct hmac_sha256_ctx hmac;
- HMAC_SHA256_hw_init(&hmac, secret, secret_size);
+ if (DCRYPTO_hw_hmac_sha256_init(&hmac, secret, secret_size) !=
+ DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
HMAC_SHA256_update(&hmac, ch_ptr, ch_size);
- memcpy(hmac_out, HMAC_SHA256_hw_final(&hmac), 32);
+ memcpy(hmac_out, HMAC_SHA256_final(&hmac), 32);
#else
hmac_SHA256(hmac_out, secret, secret_size, ch_ptr, ch_size);
#endif
+ return EC_SUCCESS;
}
-static void hash_buffer(void *dest, size_t dest_size,
- const void *buffer, size_t buf_size)
+static enum ec_error_list hash_buffer(void *dest, size_t dest_size,
+ const void *buffer, size_t buf_size)
{
/* We know that the destination is no larger than 32 bytes. */
uint8_t temp[32];
+ enum ec_error_list ret;
- get_hmac_sha256(temp, buffer, buf_size, buffer, buf_size);
+ ret = get_hmac_sha256(temp, buffer, buf_size, buffer, buf_size);
+ if (ret)
+ return ret;
/* Or should we do XOR of the temp modulo dest size? */
memcpy(dest, temp, dest_size);
+ return EC_SUCCESS;
}
#ifdef CONFIG_RMA_AUTH_USE_P256
@@ -148,7 +155,8 @@ static int p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
}
/* Did not succeed, rehash the private key and try again. */
- SHA256_hw_init(&sha);
+ if (DCRYPTO_hw_sha256_init(&sha) != DCRYPTO_OK)
+ return EC_ERROR_HW_INTERNAL;
SHA256_update(&sha, buf, sizeof(buf));
memcpy(buf, SHA256_final(&sha), sizeof(buf));
}
@@ -177,10 +185,11 @@ static int p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
}
#endif
-void get_rma_device_id(uint8_t rma_device_id[RMA_DEVICE_ID_SIZE])
+int get_rma_device_id(uint8_t rma_device_id[RMA_DEVICE_ID_SIZE])
{
uint8_t *chip_unique_id;
int chip_unique_id_size = system_get_chip_unique_id(&chip_unique_id);
+ enum ec_error_list ret;
if (chip_unique_id_size < 0)
chip_unique_id_size = 0;
@@ -198,9 +207,12 @@ void get_rma_device_id(uint8_t rma_device_id[RMA_DEVICE_ID_SIZE])
* rma_challenge:device_id, let's use first few bytes of
* its hash.
*/
- hash_buffer(rma_device_id, RMA_DEVICE_ID_SIZE,
- chip_unique_id, chip_unique_id_size);
+ ret = hash_buffer(rma_device_id, RMA_DEVICE_ID_SIZE,
+ chip_unique_id, chip_unique_id_size);
+ if (ret != EC_SUCCESS)
+ return ret;
}
+ return EC_SUCCESS;
}
/**
@@ -217,6 +229,7 @@ int rma_create_challenge(void)
struct board_id bid;
uint8_t *cptr = (uint8_t *)&c;
uint64_t t;
+ int ret;
/* Clear the current challenge and authcode, if any */
memset(challenge, 0, sizeof(challenge));
@@ -236,9 +249,11 @@ int rma_create_challenge(void)
return EC_ERROR_UNKNOWN;
memcpy(c.board_id, &bid.type, sizeof(c.board_id));
- get_rma_device_id(c.device_id);
+ ret = get_rma_device_id(c.device_id);
+ if (ret != EC_SUCCESS)
+ return ret;
- /* Calculate a new ephemeral key pair and the shared secret. */
+ /* Calculate a new ephemeral key pair and the shared secret. */
#ifdef CONFIG_RMA_AUTH_USE_P256
if (p256_get_pub_key_and_secret(c.device_pub_key, secret) != EC_SUCCESS)
return EC_ERROR_UNKNOWN;
@@ -251,13 +266,15 @@ int rma_create_challenge(void)
if (base32_encode(challenge, sizeof(challenge), cptr, 8 * sizeof(c), 9))
return EC_ERROR_UNKNOWN;
-
/*
* Auth code is a truncated HMAC of the ephemeral public key, BoardID,
* and DeviceID. Those are all in the right order in the challenge
* struct, after the version/key id byte.
*/
- get_hmac_sha256(temp, secret, sizeof(secret), cptr + 1, sizeof(c) - 1);
+ ret = get_hmac_sha256(temp, secret, sizeof(secret), cptr + 1,
+ sizeof(c) - 1);
+ if (ret != EC_SUCCESS)
+ return ret;
if (base32_encode(authcode, sizeof(authcode), temp,
RMA_AUTHCODE_CHARS * 5, 0))
return EC_ERROR_UNKNOWN;
diff --git a/fuzz/mem_hash_tree.cc b/fuzz/mem_hash_tree.cc
index 88e85b87cf..3aceb28518 100644
--- a/fuzz/mem_hash_tree.cc
+++ b/fuzz/mem_hash_tree.cc
@@ -73,7 +73,8 @@ void MemHashTree::UpdatePath(uint64_t label,
shifted_parent_label &= ~child_index_mask;
struct sha256_ctx ctx;
- SHA256_hw_init(&ctx);
+ if (DCRYPTO_hw_sha256_init(&ctx) != DCRYPTO_OK)
+ return;
int empty_nodes = 0;
for (int index = 0; index < fan_out; ++index) {
auto itr =
@@ -119,7 +120,8 @@ void MemHashTree::Reset(uint8_t bits_per_level, uint8_t height) {
uint8_t fan_out = 1 << bits_per_level;
for (int level = 1; level < height; ++level) {
struct sha256_ctx ctx;
- SHA256_hw_init(&ctx);
+ if (DCRYPTO_hw_sha256_init(&ctx) != DCRYPTO_OK)
+ return;
for (int index = 0; index < fan_out; ++index) {
SHA256_update(&ctx, hash.data(), hash.size());
}
diff --git a/include/pinweaver.h b/include/pinweaver.h
index 21571da7b0..6eb1f46092 100644
--- a/include/pinweaver.h
+++ b/include/pinweaver.h
@@ -163,8 +163,11 @@ void import_leaf(const struct unimported_leaf_data_t *unimported,
/* Computes the total number of the sibling hashes along a path. */
int get_path_auxiliary_hash_count(const struct merkle_tree_t *merkle_tree);
-/* Computes the parent hash for an array of child hashes. */
-void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
+/**
+ * Computes the parent hash for an array of child hashes.
+ * Return EC_SUCCESS if successful.
+ */
+int compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
struct index_t location,
const uint8_t child_hash[PW_HASH_SIZE],
uint8_t result[PW_HASH_SIZE]);
diff --git a/include/rma_auth.h b/include/rma_auth.h
index 0a4d7c7e71..caca9d07cc 100644
--- a/include/rma_auth.h
+++ b/include/rma_auth.h
@@ -75,7 +75,8 @@ int rma_try_authcode(const char *code);
*
* @param rma_device_id Pointer to the buffer that will be filled with
* the ID. The buffer must be of size RMA_DEVICE_ID_SIZE.
+ * @return EC_SUCCESS if successful
*/
-void get_rma_device_id(uint8_t rma_device_id[RMA_DEVICE_ID_SIZE]);
+int get_rma_device_id(uint8_t rma_device_id[RMA_DEVICE_ID_SIZE]);
#endif
diff --git a/test/pinweaver.c b/test/pinweaver.c
index 21bd30396d..df7327887f 100644
--- a/test/pinweaver.c
+++ b/test/pinweaver.c
@@ -894,29 +894,40 @@ void HASH_update(union hash_ctx *ctx, const void *data, size_t len)
SHA256_sw_update(&ctx->sha256, data, len);
}
+void HMAC_SHA256_update(struct hmac_sha256_ctx *ctx, const void *data,
+ size_t len)
+{
+ if (MOCK_hash_update_cb)
+ MOCK_hash_update_cb(data, len);
+ if (ctx)
+ SHA256_sw_update(&ctx->hash, data, len);
+}
+
const union sha_digests *HASH_final(union hash_ctx *ctx)
{
++MOCK_DECRYPTO_release_counter;
return (union sha_digests *)SHA256_sw_final(&ctx->sha256);
}
-void SHA256_hw_init(struct sha256_ctx *ctx)
+enum dcrypto_result DCRYPTO_hw_sha256_init(struct sha256_ctx *ctx)
{
SHA256_sw_init(ctx);
++MOCK_DECRYPTO_init_counter;
+ return DCRYPTO_OK;
}
-void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
- size_t len)
+enum dcrypto_result DCRYPTO_hw_hmac_sha256_init(struct hmac_sha256_ctx *ctx,
+ const void *key, size_t len)
{
TEST_ASRT_NORET(len == sizeof(EMPTY_TREE.hmac_key));
TEST_ASRT_NORET(memcmp(key, EMPTY_TREE.hmac_key,
sizeof(EMPTY_TREE.hmac_key)) == 0);
SHA256_sw_init(&ctx->hash);
++MOCK_DECRYPTO_init_counter;
+ return DCRYPTO_OK;
}
-const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx)
+const struct sha256_digest *HMAC_SHA256_final(struct hmac_sha256_ctx *ctx)
{
++MOCK_DECRYPTO_release_counter;
return (struct sha256_digest *)MOCK_hmac;
diff --git a/test/u2f.c b/test/u2f.c
index 21c5d6ea69..3ddf38616b 100644
--- a/test/u2f.c
+++ b/test/u2f.c
@@ -41,11 +41,6 @@ bool fips_trng_bytes(void *buffer, size_t len)
return true;
}
-bool fips_crypto_allowed(void)
-{
- return true;
-}
-
int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
const p256_int *pk_y, const p256_int *serial,
const char *name, uint8_t *cert, const int n)