summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.c2
-rw-r--r--board/cr50/build.mk11
-rw-r--r--board/cr50/dcrypto/app_key.c37
-rw-r--r--board/cr50/dcrypto/dcrypto.h168
-rw-r--r--board/cr50/dcrypto/dcrypto_runtime.c8
-rw-r--r--board/cr50/dcrypto/hkdf.c22
-rw-r--r--board/cr50/dcrypto/hmac.c62
-rw-r--r--board/cr50/dcrypto/hmac_drbg.c40
-rw-r--r--board/cr50/dcrypto/hmac_sw.c72
-rw-r--r--board/cr50/dcrypto/hmacsha2.h490
-rw-r--r--board/cr50/dcrypto/internal.h56
-rw-r--r--board/cr50/dcrypto/p256_ecies.c8
-rw-r--r--board/cr50/dcrypto/rsa.c59
-rw-r--r--board/cr50/dcrypto/sha1.c158
-rw-r--r--board/cr50/dcrypto/sha256.c337
-rw-r--r--board/cr50/dcrypto/sha384.c20
-rw-r--r--board/cr50/dcrypto/sha512.c249
-rw-r--r--board/cr50/dcrypto/sha_hw.c265
-rw-r--r--board/cr50/dcrypto/x509.c14
-rw-r--r--board/cr50/fips.c35
-rw-r--r--board/cr50/tpm2/ecc.c9
-rw-r--r--board/cr50/tpm2/endorsement.c14
-rw-r--r--board/cr50/tpm2/hash.c42
-rw-r--r--board/cr50/tpm2/rsa.c8
-rw-r--r--board/cr50/tpm2/virtual_nvmem.c12
-rw-r--r--board/cr50/u2f.c8
-rw-r--r--board/cr50/usb_spi.c17
-rw-r--r--board/cr50/usb_spi_board.h11
-rw-r--r--board/host/dcrypto.h27
-rw-r--r--builtin/endian.h4
-rw-r--r--chip/g/usb_spi.h6
-rw-r--r--chip/host/build.mk20
-rw-r--r--chip/host/dcrypto/app_cipher.c6
-rw-r--r--chip/host/dcrypto/sha256.c22
-rw-r--r--common/ap_ro_integrity_check.c4
-rw-r--r--common/ccd_config.c13
-rw-r--r--common/pinweaver.c46
-rw-r--r--common/rma_auth.c16
-rw-r--r--common/u2f.c54
-rw-r--r--fuzz/mem_hash_tree.cc18
-rw-r--r--test/pinweaver.c23
-rw-r--r--test/test_config.h2
-rw-r--r--test/u2f.c34
43 files changed, 1799 insertions, 730 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 71453e888e..80ec7b623e 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -48,8 +48,6 @@
/* Define interrupt and gpio structs */
#include "gpio_list.h"
-#include "cryptoc/sha.h"
-
/*
* Need to include Implementation.h here to make sure that NVRAM size
* definitions match across different git repos.
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index d1bbc4a517..6d5996ddc5 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -70,16 +70,16 @@ ifneq ($(CRYPTO_TEST),)
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/gcm.o
endif
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hkdf.o
-fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/hmac.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
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/p256.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/p256_ec.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/rsa.o
+fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha_hw.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha1.o
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha256.o
ifeq ($(CONFIG_UPTO_SHA512),y)
-fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/sha384.o
ifeq ($(CONFIG_DCRYPTO_SHA512),y)
fips-${CONFIG_DCRYPTO_BOARD} += dcrypto/dcrypto_sha512.o
else
@@ -145,16 +145,13 @@ CPPFLAGS += -I$(abspath .)
CPPFLAGS += -I$(abspath $(BDIR))
CPPFLAGS += -I$(abspath ./fuzz)
CPPFLAGS += -I$(abspath ./test)
-ifeq ($(CONFIG_UPTO_SHA512),y)
-CPPFLAGS += -DSHA512_SUPPORT
-endif
# Make sure the context of the software sha512 implementation fits. If it ever
# increases, a compile time assert will fire in tpm2/hash.c.
ifeq ($(CONFIG_UPTO_SHA512),y)
-CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=208
+CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=200
else
-CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=112
+CFLAGS += -DUSER_MIN_HASH_STATE_SIZE=104
endif
# Configure TPM2 headers accordingly.
CFLAGS += -DEMBEDDED_MODE=1
diff --git a/board/cr50/dcrypto/app_key.c b/board/cr50/dcrypto/app_key.c
index f655471f69..0bc7620ed7 100644
--- a/board/cr50/dcrypto/app_key.c
+++ b/board/cr50/dcrypto/app_key.c
@@ -21,9 +21,8 @@ const char *const dcrypto_app_names[] = {
};
static void name_hash(enum dcrypto_appid appid,
- uint32_t digest[SHA256_DIGEST_WORDS])
+ struct sha256_digest *digest)
{
- LITE_SHA256_CTX ctx;
const char *name = dcrypto_app_names[appid];
size_t x;
@@ -31,20 +30,18 @@ static void name_hash(enum dcrypto_appid appid,
* exists to prevent data loss.
*/
if (appid == PERSO_AUTH) {
- digest[0] = 0x2019da34;
- digest[1] = 0xf1a01a13;
- digest[2] = 0x0fb9f73f;
- digest[3] = 0xf2e85f76;
- digest[4] = 0x5ecb7690;
- digest[5] = 0x09f732c9;
- digest[6] = 0xe540bf14;
- digest[7] = 0xcc46799a;
+ digest->b32[0] = 0x2019da34;
+ digest->b32[1] = 0xf1a01a13;
+ digest->b32[2] = 0x0fb9f73f;
+ digest->b32[3] = 0xf2e85f76;
+ digest->b32[4] = 0x5ecb7690;
+ digest->b32[5] = 0x09f732c9;
+ digest->b32[6] = 0xe540bf14;
+ digest->b32[7] = 0xcc46799a;
return;
}
- DCRYPTO_SHA256_init(&ctx, 0);
- HASH_update(&ctx, name, strlen(name));
- memcpy(digest, HASH_final(&ctx), SHA256_DIGEST_SIZE);
+ SHA256_hw_hash(name, strlen(name), digest);
/* The digests were originally endian swapped because xxd was used to
* print them so this operation is needed to keep the derived keys the
@@ -53,17 +50,17 @@ static void name_hash(enum dcrypto_appid appid,
* effectively be reset and user data will be lost by the key change.
*/
for (x = 0; x < SHA256_DIGEST_WORDS; ++x)
- digest[x] = __builtin_bswap32(digest[x]);
+ digest->b32[x] = __builtin_bswap32(digest->b32[x]);
}
int DCRYPTO_appkey_init(enum dcrypto_appid appid, struct APPKEY_CTX *ctx)
{
- uint32_t digest[SHA256_DIGEST_WORDS];
+ struct sha256_digest digest;
memset(ctx, 0, sizeof(*ctx));
- name_hash(appid, digest);
+ name_hash(appid, &digest);
- if (!dcrypto_ladder_compute_usr(appid, digest))
+ if (!dcrypto_ladder_compute_usr(appid, digest.b32))
return 0;
return 1;
@@ -78,8 +75,8 @@ void DCRYPTO_appkey_finish(struct APPKEY_CTX *ctx)
int DCRYPTO_appkey_derive(enum dcrypto_appid appid, const uint32_t input[8],
uint32_t output[8])
{
- uint32_t digest[SHA256_DIGEST_WORDS];
+ struct sha256_digest digest;
- name_hash(appid, digest);
- return !!dcrypto_ladder_derive(appid, digest, input, output);
+ name_hash(appid, &digest);
+ return !!dcrypto_ladder_derive(appid, digest.b32, input, output);
}
diff --git a/board/cr50/dcrypto/dcrypto.h b/board/cr50/dcrypto/dcrypto.h
index 8cf1071090..ef3c778398 100644
--- a/board/cr50/dcrypto/dcrypto.h
+++ b/board/cr50/dcrypto/dcrypto.h
@@ -6,51 +6,44 @@
/*
* Crypto wrapper library for the g chip.
*/
-#ifndef __EC_CHIP_G_DCRYPTO_DCRYPTO_H
-#define __EC_CHIP_G_DCRYPTO_DCRYPTO_H
+#ifndef __EC_BOARD_CR50_DCRYPTO_DCRYPTO_H
+#define __EC_BOARD_CR50_DCRYPTO_DCRYPTO_H
#ifdef __cplusplus
extern "C" {
#endif
-#if defined(TEST_FUZZ) || !defined(TEST_BUILD)
-
#include "internal.h"
#include "crypto_api.h"
#include <stddef.h>
-#include "cryptoc/hmac.h"
-
enum cipher_mode {
CIPHER_MODE_ECB = 0, /* NIST SP 800-38A */
CIPHER_MODE_CTR = 1, /* NIST SP 800-38A */
CIPHER_MODE_CBC = 2, /* NIST SP 800-38A */
- CIPHER_MODE_GCM = 3 /* NIST SP 800-38D */
+ CIPHER_MODE_GCM = 3 /* NIST SP 800-38D */
};
-enum encrypt_mode {
- DECRYPT_MODE = 0,
- ENCRYPT_MODE = 1
-};
+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_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 */
};
/*
* AES implementation, based on a hardware AES block.
* FIPS Publication 197, The Advanced Encryption Standard (AES)
*/
-#define AES256_BLOCK_CIPHER_KEY_SIZE 32
+#define AES256_BLOCK_CIPHER_KEY_SIZE 32
int DCRYPTO_aes_init(const uint8_t *key, uint32_t key_len, const uint8_t *iv,
- enum cipher_mode c_mode, enum encrypt_mode e_mode);
+ enum cipher_mode c_mode, enum encrypt_mode e_mode);
int DCRYPTO_aes_block(const uint8_t *in, uint8_t *out);
void DCRYPTO_aes_write_iv(const uint8_t *iv);
@@ -60,7 +53,7 @@ void DCRYPTO_aes_read_iv(uint8_t *iv);
* NIST Special Publication 800-38A
*/
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);
+ const uint8_t *iv, const uint8_t *in, size_t in_len);
/* AES-GCM-128/192/256
* NIST Special Publication 800-38D, IV is provided externally
@@ -81,7 +74,7 @@ struct GCM_CTX {
/* Initialize the GCM context structure. */
void DCRYPTO_gcm_init(struct GCM_CTX *ctx, uint32_t key_bits,
- const uint8_t *key, const uint8_t *iv, size_t iv_len);
+ const uint8_t *key, const uint8_t *iv, size_t iv_len);
/* Additional authentication data to include in the tag calculation. */
void DCRYPTO_gcm_aad(struct GCM_CTX *ctx, const uint8_t *aad_data, size_t len);
/* Encrypt & decrypt return the number of bytes written to out
@@ -98,10 +91,10 @@ int DCRYPTO_gcm_decrypt(struct GCM_CTX *ctx, uint8_t *out, size_t out_len,
/* Encrypt & decrypt a partial final block, if any. These functions
* return the number of bytes written to out (<= 15), or -1 on error.
*/
-int DCRYPTO_gcm_encrypt_final(struct GCM_CTX *ctx,
- uint8_t *out, size_t out_len);
-int DCRYPTO_gcm_decrypt_final(struct GCM_CTX *ctx,
- uint8_t *out, size_t out_len);
+int DCRYPTO_gcm_encrypt_final(struct GCM_CTX *ctx, uint8_t *out,
+ size_t out_len);
+int DCRYPTO_gcm_decrypt_final(struct GCM_CTX *ctx, uint8_t *out,
+ size_t out_len);
/* Compute the tag over AAD + encrypt or decrypt data, and return the
* number of bytes written to tag. Returns -1 on error.
*/
@@ -116,13 +109,13 @@ void DCRYPTO_gcm_finish(struct GCM_CTX *ctx);
* otherwise.
*/
int DCRYPTO_aes_cmac(const uint8_t *K, const uint8_t *M, const uint32_t len,
- uint32_t T[4]);
+ uint32_t T[4]);
/* key: 128-bit key, M: message, len: number of bytes in M,
* T: tag to be verified
* Returns 1 if the tag is correct and 0 otherwise.
*/
int DCRYPTO_aes_cmac_verify(const uint8_t *key, const uint8_t *M, const int len,
- const uint32_t T[4]);
+ const uint32_t T[4]);
/*
* SHA implementation. This abstraction is backed by either a
@@ -133,27 +126,35 @@ int DCRYPTO_aes_cmac_verify(const uint8_t *key, const uint8_t *M, const int len,
* is TRUE, in which case there will be no attempt to use the hardware for
* this particular hashing session.
*/
-void DCRYPTO_SHA1_init(SHA_CTX *ctx, uint32_t sw_required);
-/* SHA256/384/512 FIPS 180-4
- */
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required);
-void DCRYPTO_SHA384_init(LITE_SHA384_CTX *ctx);
-void DCRYPTO_SHA512_init(LITE_SHA512_CTX *ctx);
-const uint8_t *DCRYPTO_SHA1_hash(const void *data, uint32_t n,
- uint8_t *digest);
-const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
- uint8_t *digest);
-const uint8_t *DCRYPTO_SHA384_hash(const void *data, uint32_t n,
- uint8_t *digest);
-const uint8_t *DCRYPTO_SHA512_hash(const void *data, uint32_t n,
- uint8_t *digest);
+
+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 DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len);
+void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
+ size_t len);
/* DCRYPTO HMAC-SHA256 final */
-const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx);
+const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx);
/*
* BIGNUM utility methods.
@@ -170,15 +171,15 @@ void DCRYPTO_bn_wrap(struct LITE_BIGNUM *b, void *buf, size_t len);
* is not required, and enabling support would result in increased
* stack usage for all key sizes.)
*/
-#define RSA_BYTES_2K 256
-#define RSA_BYTES_4K 512
-#define RSA_WORDS_2K (RSA_BYTES_2K / sizeof(uint32_t))
-#define RSA_WORDS_4K (RSA_BYTES_4K / sizeof(uint32_t))
+#define RSA_BYTES_2K 256
+#define RSA_BYTES_4K 512
+#define RSA_WORDS_2K (RSA_BYTES_2K / sizeof(uint32_t))
+#define RSA_WORDS_4K (RSA_BYTES_4K / sizeof(uint32_t))
#ifndef RSA_MAX_BYTES
-#define RSA_MAX_BYTES RSA_BYTES_2K
+#define RSA_MAX_BYTES RSA_BYTES_2K
#endif
-#define RSA_MAX_WORDS (RSA_MAX_BYTES / sizeof(uint32_t))
-#define RSA_F4 65537
+#define RSA_MAX_WORDS (RSA_MAX_BYTES / sizeof(uint32_t))
+#define RSA_F4 65537
struct RSA {
uint32_t e;
@@ -188,11 +189,11 @@ struct RSA {
enum padding_mode {
PADDING_MODE_PKCS1 = 0,
- PADDING_MODE_OAEP = 1,
+ PADDING_MODE_OAEP = 1,
PADDING_MODE_PSS = 2,
/* USE OF NULL PADDING IS NOT RECOMMENDED.
* SUPPORT EXISTS AS A REQUIREMENT FOR TPM2 OPERATION. */
- PADDING_MODE_NULL = 3
+ PADDING_MODE_NULL = 3
};
/* RSA support, FIPS PUB 186-4 *
@@ -215,21 +216,21 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
* return 0 if error
*/
int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
- const uint8_t *in, const uint32_t in_len,
- enum padding_mode padding, enum hashing_mode hashing);
+ const uint8_t *in, const uint32_t in_len,
+ enum padding_mode padding, enum hashing_mode hashing);
/* Calculate r = m ^ e mod N
* return 0 if error
*/
int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
- uint32_t digest_len, const uint8_t *sig,
- const uint32_t sig_len, enum padding_mode padding,
- enum hashing_mode hashing);
+ uint32_t digest_len, const uint8_t *sig,
+ const uint32_t sig_len, enum padding_mode padding,
+ enum hashing_mode hashing);
/* Calculate n = p * q, d = e ^ -1 mod phi. */
int DCRYPTO_rsa_key_compute(struct LITE_BIGNUM *N, struct LITE_BIGNUM *d,
- struct LITE_BIGNUM *p, struct LITE_BIGNUM *q,
- uint32_t e);
+ struct LITE_BIGNUM *p, struct LITE_BIGNUM *q,
+ uint32_t e);
/*
* EC.
@@ -244,9 +245,8 @@ int DCRYPTO_p256_base_point_mul(p256_int *out_x, p256_int *out_y,
/* DCRYPTO_p256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
* the order of the group.
*/
-int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
- const p256_int *n, const p256_int *in_x,
- const p256_int *in_y);
+int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y, const p256_int *n,
+ const p256_int *in_x, const p256_int *in_y);
/*
* Key selection based on FIPS-186-4, section B.4.2 (Key Pair
* Generation by Testing Candidates).
@@ -257,7 +257,6 @@ int DCRYPTO_p256_point_mul(p256_int *out_x, p256_int *out_y,
int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
const uint8_t bytes[P256_NBYTES]);
-
/* P256 based integration encryption (DH+AES128+SHA256).
* Not FIPS 140-2 compliant, not used other than for tests
* Authenticated data may be provided, where the first auth_data_len
@@ -267,18 +266,17 @@ int DCRYPTO_p256_key_from_bytes(p256_int *x, p256_int *y, p256_int *d,
* 0x04 || PUBKEY || AUTH_DATA || AES128_CTR(PLAINTEXT) ||
* HMAC_SHA256(AUTH_DATA || CIPHERTEXT)
*/
-size_t DCRYPTO_ecies_encrypt(
- void *out, size_t out_len, const void *in, size_t in_len,
- size_t auth_data_len, const uint8_t *iv,
- const p256_int *pub_x, const p256_int *pub_y,
- const uint8_t *salt, size_t salt_len,
- const uint8_t *info, size_t info_len);
-size_t DCRYPTO_ecies_decrypt(
- void *out, size_t out_len, const void *in, size_t in_len,
- size_t auth_data_len, const uint8_t *iv,
- const p256_int *d,
- const uint8_t *salt, size_t salt_len,
- const uint8_t *info, size_t info_len);
+size_t DCRYPTO_ecies_encrypt(void *out, size_t out_len, const void *in,
+ size_t in_len, size_t auth_data_len,
+ const uint8_t *iv, const p256_int *pub_x,
+ const p256_int *pub_y, const uint8_t *salt,
+ size_t salt_len, const uint8_t *info,
+ size_t info_len);
+size_t DCRYPTO_ecies_decrypt(void *out, size_t out_len, const void *in,
+ size_t in_len, size_t auth_data_len,
+ const uint8_t *iv, const p256_int *d,
+ const uint8_t *salt, size_t salt_len,
+ const uint8_t *info, size_t info_len);
/*
* HKDF as per RFC 5869. Mentioned as conforming NIST SP 800-56C Rev.1
@@ -286,10 +284,9 @@ size_t DCRYPTO_ecies_decrypt(
* key-derivation procedure using HMAC for both the extraction and expansion
* steps.
*/
-int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len,
- const uint8_t *salt, size_t salt_len,
- const uint8_t *IKM, size_t IKM_len,
- const uint8_t *info, size_t info_len);
+int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len, const uint8_t *salt,
+ size_t salt_len, const uint8_t *IKM, size_t IKM_len,
+ const uint8_t *info, size_t info_len);
/*
* BN.
@@ -301,10 +298,10 @@ int DCRYPTO_hkdf(uint8_t *OKM, size_t OKM_len,
int DCRYPTO_bn_generate_prime(struct LITE_BIGNUM *p);
void DCRYPTO_bn_wrap(struct LITE_BIGNUM *b, void *buf, size_t len);
void DCRYPTO_bn_mul(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a,
- const struct LITE_BIGNUM *b);
+ const struct LITE_BIGNUM *b);
int DCRYPTO_bn_div(struct LITE_BIGNUM *quotient, struct LITE_BIGNUM *remainder,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *divisor);
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *divisor);
/*
* ASN.1 DER
@@ -362,8 +359,8 @@ int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
* @param n: max size of cert
*/
int DCRYPTO_x509_gen_u2f_cert(const p256_int *d, const p256_int *pk_x,
- const p256_int *pk_y, const p256_int *serial,
- uint8_t *cert, const int n);
+ const p256_int *pk_y, const p256_int *serial,
+ uint8_t *cert, const int n);
/*
* Memory related functions.
@@ -427,10 +424,9 @@ BUILD_ASSERT(DCRYPTO_CIPHER_SALT_SIZE == CIPHER_SALT_SIZE);
* @param len Number of bytes to read from in / write to out.
* @return non-zero on success, and zero otherwise.
*/
-int DCRYPTO_app_cipher(enum dcrypto_appid appid, const void *salt,
- void *out, const void *in, size_t len);
+int DCRYPTO_app_cipher(enum dcrypto_appid appid, const void *salt, void *out,
+ const void *in, size_t len);
-#endif /* ^^^^^^^^^^^^^^^^^^^^^ !TEST_BUILD */
/*
* Query whether Key Ladder is enabled.
*
@@ -442,4 +438,4 @@ int DCRYPTO_ladder_is_enabled(void);
}
#endif
-#endif /* ! __EC_CHIP_G_DCRYPTO_DCRYPTO_H */
+#endif /* ! __EC_BOARD_CR50_DCRYPTO_DCRYPTO_H */
diff --git a/board/cr50/dcrypto/dcrypto_runtime.c b/board/cr50/dcrypto/dcrypto_runtime.c
index 394293ab83..60a0365c92 100644
--- a/board/cr50/dcrypto/dcrypto_runtime.c
+++ b/board/cr50/dcrypto/dcrypto_runtime.c
@@ -413,7 +413,7 @@ exit:
static int command_dcrypto_ecdsa_test(int argc, char *argv[])
{
p256_int entropy, message, r, s;
- LITE_SHA256_CTX hsh;
+ struct sha256_ctx hsh;
int result = 0;
char *new_stack;
const uint32_t new_stack_size = 2 * 1024;
@@ -424,9 +424,9 @@ static int command_dcrypto_ecdsa_test(int argc, char *argv[])
for (uint8_t i = 0; i < 8; i++)
entropy.a[i] = i;
- DCRYPTO_SHA256_init(&hsh, 0);
- HASH_update(&hsh, &ten, sizeof(ten));
- p256_from_bin(HASH_final(&hsh), &message);
+ SHA256_hw_init(&hsh);
+ SHA256_update(&hsh, &ten, sizeof(ten));
+ p256_from_bin(SHA256_final(&hsh)->b8, &message);
r = entropy;
s = message;
diff --git a/board/cr50/dcrypto/hkdf.c b/board/cr50/dcrypto/hkdf.c
index c6692ef554..8e06455337 100644
--- a/board/cr50/dcrypto/hkdf.c
+++ b/board/cr50/dcrypto/hkdf.c
@@ -7,12 +7,10 @@
#include "dcrypto.h"
#include "internal.h"
-#include "cryptoc/sha256.h"
-
static int hkdf_extract(uint8_t *PRK, const uint8_t *salt, size_t salt_len,
const uint8_t *IKM, size_t IKM_len)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
if (PRK == NULL)
return 0;
@@ -21,9 +19,9 @@ static int hkdf_extract(uint8_t *PRK, const uint8_t *salt, size_t salt_len,
if (IKM == NULL && IKM_len > 0)
return 0;
- DCRYPTO_HMAC_SHA256_init(&ctx, salt, salt_len);
- HASH_update(&ctx.hash, IKM, IKM_len);
- memcpy(PRK, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
+ HMAC_SHA256_hw_init(&ctx, salt, salt_len);
+ HMAC_SHA256_update(&ctx, IKM, IKM_len);
+ memcpy(PRK, HMAC_SHA256_hw_final(&ctx), SHA256_DIGEST_SIZE);
return 1;
}
@@ -46,15 +44,15 @@ static int hkdf_expand(uint8_t *OKM, size_t OKM_len, const uint8_t *PRK,
return 0;
while (OKM_len > 0) {
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
const size_t block_size = OKM_len < SHA256_DIGEST_SIZE ?
OKM_len : SHA256_DIGEST_SIZE;
- DCRYPTO_HMAC_SHA256_init(&ctx, PRK, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, T, T_len);
- HASH_update(&ctx.hash, info, info_len);
- HASH_update(&ctx.hash, &count, sizeof(count));
- memcpy(OKM, DCRYPTO_HMAC_final(&ctx), block_size);
+ HMAC_SHA256_hw_init(&ctx, PRK, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, T, T_len);
+ HMAC_SHA256_update(&ctx, info, info_len);
+ HMAC_SHA256_update(&ctx, &count, sizeof(count));
+ memcpy(OKM, HMAC_SHA256_hw_final(&ctx), block_size);
T += T_len;
T_len = SHA256_DIGEST_SIZE;
diff --git a/board/cr50/dcrypto/hmac.c b/board/cr50/dcrypto/hmac.c
deleted file mode 100644
index 72d4296422..0000000000
--- a/board/cr50/dcrypto/hmac.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright 2015 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"
-#include "dcrypto.h"
-
-#include <stdint.h>
-
-#include "cryptoc/sha256.h"
-
-/* TODO(sukhomlinov): add support for hardware hmac. */
-static void hmac_sha256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len)
-{
- unsigned int i;
-
- BUILD_ASSERT(sizeof(ctx->opad) >= SHA256_BLOCK_SIZE);
-
- memset(&ctx->opad[0], 0, SHA256_BLOCK_SIZE);
-
- if (len > SHA256_BLOCK_SIZE) {
- DCRYPTO_SHA256_init(&ctx->hash, 0);
- HASH_update(&ctx->hash, key, len);
- memcpy(&ctx->opad[0], HASH_final(&ctx->hash),
- HASH_size(&ctx->hash));
- } else {
- memcpy(&ctx->opad[0], key, len);
- }
-
- for (i = 0; i < SHA256_BLOCK_SIZE; ++i)
- ctx->opad[i] ^= 0x36;
-
- DCRYPTO_SHA256_init(&ctx->hash, 0);
- /* hash ipad */
- HASH_update(&ctx->hash, ctx->opad, SHA256_BLOCK_SIZE);
-
- for (i = 0; i < SHA256_BLOCK_SIZE; ++i)
- ctx->opad[i] ^= (0x36 ^ 0x5c);
-}
-
-void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len)
-{
- hmac_sha256_init(ctx, key, len);
-}
-
-const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
-{
- uint8_t digest[SHA256_DIGEST_SIZE]; /* up to SHA256 */
-
- memcpy(digest, HASH_final(&ctx->hash),
- (HASH_size(&ctx->hash) <= sizeof(digest) ?
- HASH_size(&ctx->hash) :
- sizeof(digest)));
- DCRYPTO_SHA256_init(&ctx->hash, 0);
- HASH_update(&ctx->hash, ctx->opad, SHA256_BLOCK_SIZE);
- HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
- always_memset(&ctx->opad[0], 0, SHA256_BLOCK_SIZE); /* wipe key */
- return HASH_final(&ctx->hash);
-}
diff --git a/board/cr50/dcrypto/hmac_drbg.c b/board/cr50/dcrypto/hmac_drbg.c
index d601e721de..85c0fe863a 100644
--- a/board/cr50/dcrypto/hmac_drbg.c
+++ b/board/cr50/dcrypto/hmac_drbg.c
@@ -14,30 +14,28 @@
/* V = HMAC(K, V) */
static void update_v(const uint32_t *k, uint32_t *v)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
- DCRYPTO_HMAC_SHA256_init(&ctx, k, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, v, SHA256_DIGEST_SIZE);
- memcpy(v, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
+ HMAC_SHA256_hw_init(&ctx, k, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, v, SHA256_DIGEST_SIZE);
+ memcpy(v, HMAC_SHA256_final(&ctx), SHA256_DIGEST_SIZE);
}
/* K = HMAC(K, V || tag || p0 || p1 || p2) */
/* V = HMAC(K, V) */
-static void update_kv(uint32_t *k, uint32_t *v, uint8_t tag,
- const void *p0, size_t p0_len,
- const void *p1, size_t p1_len,
+static void update_kv(uint32_t *k, uint32_t *v, uint8_t tag, const void *p0,
+ size_t p0_len, const void *p1, size_t p1_len,
const void *p2, size_t p2_len)
{
- LITE_HMAC_CTX ctx;
-
- DCRYPTO_HMAC_SHA256_init(&ctx, k, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, v, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, &tag, 1);
- HASH_update(&ctx.hash, p0, p0_len);
- HASH_update(&ctx.hash, p1, p1_len);
- HASH_update(&ctx.hash, p2, p2_len);
- memcpy(k, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
-
+ struct hmac_sha256_ctx ctx;
+
+ HMAC_SHA256_hw_init(&ctx, k, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, v, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, &tag, 1);
+ HMAC_SHA256_update(&ctx, p0, p0_len);
+ HMAC_SHA256_update(&ctx, p1, p1_len);
+ HMAC_SHA256_update(&ctx, p2, p2_len);
+ memcpy(k, HMAC_SHA256_final(&ctx), SHA256_DIGEST_SIZE);
update_v(k, v);
}
@@ -179,7 +177,7 @@ static int cmd_rfc6979(int argc, char **argv)
static const char message[] = "sample";
static struct drbg_ctx drbg;
- static HASH_CTX ctx;
+ static struct sha256_ctx ctx;
int result;
static const uint8_t priv_from_rfc[] = {
0xC9, 0xAF, 0xA9, 0xD8, 0x45, 0xBA, 0x75, 0x16,
@@ -197,9 +195,9 @@ static int cmd_rfc6979(int argc, char **argv)
p256_int *reference_k = (p256_int *)k_from_rfc;
/* h1 = H(m) */
- DCRYPTO_SHA256_init(&ctx, 1);
- HASH_update(&ctx, message, sizeof(message) - 1);
- memcpy(&h1, HASH_final(&ctx), SHA256_DIGEST_SIZE);
+ SHA256_hw_init(&ctx);
+ SHA256_update(&ctx, message, sizeof(message) - 1);
+ memcpy(&h1, SHA256_final(&ctx)->b8, SHA256_DIGEST_SIZE);
hmac_drbg_init_rfc6979(&drbg, x, &h1);
do {
diff --git a/board/cr50/dcrypto/hmac_sw.c b/board/cr50/dcrypto/hmac_sw.c
new file mode 100644
index 0000000000..91e056546d
--- /dev/null
+++ b/board/cr50/dcrypto/hmac_sw.c
@@ -0,0 +1,72 @@
+/* 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 "dcrypto.h"
+#include "internal.h"
+
+#include <stdint.h>
+
+#include "cryptoc/util.h"
+
+/**
+ * Generic software HMAC support for any type of hash.
+ */
+
+/* Calculate location of storage for ipad/opad in generic way */
+static inline uint32_t *HMAC_opad(union hmac_ctx *const ctx)
+{
+ return (uint32_t *)((uint8_t *)ctx + ctx->f->context_size);
+}
+/**
+ * Initialize HMAC for pre-configured hash function.
+ * 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)
+{
+ uint32_t *const opad = HMAC_opad(ctx);
+ const size_t block_size = HASH_block_size(&ctx->hash);
+ size_t i;
+ /* inner padding with zeros */
+ memset(opad, 0, block_size);
+ /**
+ * HMAC (K, m) = H( (K' ⊕ opad) || H ((K' ⊕ ipad) || m) )
+ * K' = H(K) if K is longer than block size for H, or
+ * = K padded with zeroes otherwise
+ */
+ if (len > block_size) {
+ /* ctx already contains proper vtable for hash functions */
+ /* But we need to reinit it after use. */
+ HASH_update(&ctx->hash, key, len);
+ memcpy(opad, HASH_final(&ctx->hash), HASH_size(&ctx->hash));
+ HASH_reinit(&ctx->hash);
+ } else {
+ memcpy(opad, key, len);
+ }
+ /* inner pad is K ⊕ 0x36, computed at word level */
+ for (i = 0; i < block_size / sizeof(opad[0]); ++i)
+ opad[i] ^= 0x36363636;
+
+ HASH_update(&ctx->hash, opad, block_size); /* hash ipad */
+ /* compute outer padding from the inner. */
+ for (i = 0; i < block_size / sizeof(opad[0]); ++i)
+ opad[i] ^= (0x36363636 ^ 0x5c5c5c5c);
+}
+
+const union sha_digests *HMAC_sw_final(union hmac_ctx *const ctx)
+{
+ uint32_t *const opad = HMAC_opad(ctx);
+ uint32_t *digest; /* storage for intermediate digest */
+ const size_t block_size = HASH_block_size(&ctx->hash);
+ const size_t hash_size = HASH_size(&ctx->hash);
+ /* allocate storage dynamically, just enough for particular hash. */
+ digest = alloca(hash_size);
+ memcpy(digest, HASH_final(&ctx->hash), hash_size);
+ HASH_reinit(&ctx->hash);
+ HASH_update(&ctx->hash, opad, block_size);
+ HASH_update(&ctx->hash, digest, hash_size);
+ memset(opad, 0, block_size); /* wipe key */
+ return HASH_final(&ctx->hash);
+}
diff --git a/board/cr50/dcrypto/hmacsha2.h b/board/cr50/dcrypto/hmacsha2.h
new file mode 100644
index 0000000000..6d9c842c1e
--- /dev/null
+++ b/board/cr50/dcrypto/hmacsha2.h
@@ -0,0 +1,490 @@
+/* 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))
+
+/**
+ * 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);
+
+/**
+ * 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 2e6f62e2e8..17430036cb 100644
--- a/board/cr50/dcrypto/internal.h
+++ b/board/cr50/dcrypto/internal.h
@@ -2,7 +2,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
#ifndef __EC_CHIP_G_DCRYPTO_INTERNAL_H
#define __EC_CHIP_G_DCRYPTO_INTERNAL_H
@@ -13,10 +12,7 @@
#include "util.h"
#include "cryptoc/p256.h"
-#include "cryptoc/sha.h"
-#include "cryptoc/sha256.h"
-#include "cryptoc/sha384.h"
-#include "cryptoc/sha512.h"
+#include "hmacsha2.h"
#ifdef __cplusplus
extern "C" {
@@ -33,12 +29,16 @@ extern "C" {
#define SHA_DIGEST_WORDS (SHA_DIGEST_SIZE / sizeof(uint32_t))
#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / sizeof(uint32_t))
-#ifdef SHA512_SUPPORT
+#ifdef CONFIG_UPTO_SHA512
#define SHA_DIGEST_MAX_BYTES SHA512_DIGEST_SIZE
#else
#define SHA_DIGEST_MAX_BYTES SHA256_DIGEST_SIZE
#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
enum sha_mode {
SHA1_MODE = 0,
SHA256_MODE = 1
@@ -56,12 +56,6 @@ struct access_helper {
int dcrypto_grab_sha_hw(void);
void dcrypto_release_sha_hw(void);
#endif
-void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data,
- uint32_t n, uint8_t *digest);
-void dcrypto_sha_init(enum sha_mode mode);
-void dcrypto_sha_update(struct HASH_CTX *unused,
- const void *data, uint32_t n);
-void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest);
/*
* BIGNUM.
@@ -206,6 +200,44 @@ uint32_t dcrypto_dmem_load(size_t offset, const void *words, size_t n_words);
*/
void *always_memset(void *s, int c, size_t n);
+#ifndef __alias
+#define __alias(func) __attribute__((alias(#func)))
+#endif
+
+/* rotate 32-bit value right */
+static inline uint32_t ror(uint32_t value, int bits)
+{
+ /* return __builtin_rotateright32(value, bits); */
+ return (value >> bits) | (value << (32 - bits));
+}
+
+/* rotate 64-bit value right */
+static inline uint64_t ror64(uint64_t value, int bits)
+{
+ /* return __builtin_rotateright64(value, bits); */
+ return (value >> bits) | (value << (64 - bits));
+}
+
+/* rotate 32-bit value left */
+static inline uint32_t rol(uint32_t value, int bits)
+{
+ /* return __builtin_rotateleft32(value, bits); */
+ return (value << bits) | (value >> (32 - bits));
+}
+
+/* rotate 64-bit value left */
+static inline uint64_t rol64(uint64_t value, int bits)
+{
+ /* return __builtin_rotateleft64(value, bits); */
+ return (value << bits) | (value >> (64 - bits));
+}
+
+/* stack based allocation */
+#ifndef alloca
+#define alloca __builtin_alloca
+#endif
+
+
/*
* Key ladder.
*/
diff --git a/board/cr50/dcrypto/p256_ecies.c b/board/cr50/dcrypto/p256_ecies.c
index 30a410d828..7b77efd507 100644
--- a/board/cr50/dcrypto/p256_ecies.c
+++ b/board/cr50/dcrypto/p256_ecies.c
@@ -98,10 +98,10 @@ size_t DCRYPTO_ecies_encrypt(
outp += P256_NBYTES;
/* Calculate HMAC(auth_data || ciphertext). */
- DCRYPTO_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
+ HMAC_SHA256_hw_init(&ctx, hmac_key, HMAC_KEY_BYTES);
HASH_update(&ctx.hash, outp, in_len);
outp += in_len;
- memcpy(outp, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
+ memcpy(outp, HMAC_SHA256_hw_final(&ctx), SHA256_DIGEST_SIZE);
outp += SHA256_DIGEST_SIZE;
return outp - (uint8_t *) out;
@@ -159,9 +159,9 @@ size_t DCRYPTO_ecies_decrypt(
aes_key = &key[0];
hmac_key = &key[AES_KEY_BYTES];
- DCRYPTO_HMAC_SHA256_init(&ctx, hmac_key, HMAC_KEY_BYTES);
+ HMAC_SHA256_hw_init(&ctx, hmac_key, HMAC_KEY_BYTES);
HASH_update(&ctx.hash, inp, in_len);
- if (!DCRYPTO_equals(inp + in_len, DCRYPTO_HMAC_final(&ctx),
+ if (!DCRYPTO_equals(inp + in_len, HMAC_SHA256_hw_final(&ctx),
SHA256_DIGEST_SIZE))
return 0;
diff --git a/board/cr50/dcrypto/rsa.c b/board/cr50/dcrypto/rsa.c
index 053c75f16e..6b7146068d 100644
--- a/board/cr50/dcrypto/rsa.c
+++ b/board/cr50/dcrypto/rsa.c
@@ -11,11 +11,6 @@
#include <assert.h>
-#include "cryptoc/sha.h"
-#include "cryptoc/sha256.h"
-#include "cryptoc/sha384.h"
-#include "cryptoc/sha512.h"
-
/* Extend the MSB throughout the word. */
static uint32_t msb_extend(uint32_t a)
{
@@ -34,11 +29,15 @@ static uint32_t select(uint32_t mask, uint32_t a, uint32_t b)
return (mask & a) | (~mask & 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)
{
- HASH_CTX ctx;
+ union hash_ctx ctx;
+
struct {
uint8_t b3;
uint8_t b2;
@@ -46,21 +45,21 @@ 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) ? SHA_DIGEST_SIZE
- : SHA256_DIGEST_SIZE;
+ const size_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE :
+ SHA256_DIGEST_SIZE;
cnt.b0 = cnt.b1 = cnt.b2 = cnt.b3 = 0;
while (dst_len) {
int i;
if (hashing == HASH_SHA1)
- DCRYPTO_SHA1_init(&ctx, 0);
+ SHA1_hw_init(&ctx.sha1);
else
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx.sha256);
HASH_update(&ctx, seed, seed_len);
- HASH_update(&ctx, (uint8_t *) &cnt, sizeof(cnt));
- digest = HASH_final(&ctx);
+ HASH_update(&ctx, (uint8_t *)&cnt, sizeof(cnt));
+ digest = HASH_final(&ctx)->b8;
for (i = 0; i < dst_len && i < hash_size; ++i)
*dst++ ^= *digest++;
dst_len -= i;
@@ -93,7 +92,7 @@ static int oaep_pad(uint8_t *output, uint32_t output_len,
const uint32_t max_msg_len = output_len - 2 - 2 * hash_size;
const uint32_t ps_len = max_msg_len - msg_len;
uint8_t *const one = PS + ps_len;
- struct HASH_CTX ctx;
+ union hash_ctx ctx;
if (output_len < 2 + 2 * hash_size)
return 0; /* Key size too small for chosen hash. */
@@ -111,12 +110,12 @@ static int oaep_pad(uint8_t *output, uint32_t output_len,
}
if (hashing == HASH_SHA1)
- DCRYPTO_SHA1_init(&ctx, 0);
+ SHA1_hw_init(&ctx.sha1);
else
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx.sha256);
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
- memcpy(phash, HASH_final(&ctx), hash_size);
+ 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,
@@ -137,7 +136,7 @@ static int check_oaep_pad(uint8_t *out, uint32_t *out_len,
uint8_t *phash = seed + hash_size;
uint8_t *PS = phash + hash_size;
const uint32_t max_msg_len = padded_len - 2 - 2 * hash_size;
- struct HASH_CTX ctx;
+ union hash_ctx ctx;
size_t one_index = 0;
uint32_t looking_for_one_byte = ~0;
int bad;
@@ -152,12 +151,12 @@ static int check_oaep_pad(uint8_t *out, uint32_t *out_len,
MGF1_xor(phash, hash_size + 1 + max_msg_len, seed, hash_size, hashing);
if (hashing == HASH_SHA1)
- DCRYPTO_SHA1_init(&ctx, 0);
+ SHA1_hw_init(&ctx.sha1);
else
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx.sha256);
HASH_update(&ctx, label, label ? strlen(label) + 1 : 0);
- bad = !DCRYPTO_equals(phash, HASH_final(&ctx), hash_size);
+ bad = !DCRYPTO_equals(phash, HASH_final(&ctx)->b8, hash_size);
bad |= padded[0];
for (i = PS - padded; i < padded_len; i++) {
@@ -283,7 +282,7 @@ static int pkcs1_get_der(enum hashing_mode hashing, const uint8_t **der,
case HASH_SHA1:
*der = &SHA1_DER[0];
*der_size = sizeof(SHA1_DER);
- *hash_size = SHA_DIGEST_SIZE;
+ *hash_size = SHA1_DIGEST_SIZE;
break;
case HASH_SHA256:
*der = &SHA256_DER[0];
@@ -382,12 +381,12 @@ static int pkcs1_pss_pad(uint8_t *padded, uint32_t padded_len,
const uint8_t *in, uint32_t in_len,
enum hashing_mode hashing)
{
- const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
+ const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE
: SHA256_DIGEST_SIZE;
const uint32_t salt_len = MIN(padded_len - hash_size - 2, hash_size);
uint32_t db_len;
uint32_t ps_len;
- struct HASH_CTX ctx;
+ union hash_ctx ctx;
if (in_len != hash_size)
return 0;
@@ -396,9 +395,9 @@ static int pkcs1_pss_pad(uint8_t *padded, uint32_t padded_len,
db_len = padded_len - hash_size - 1;
if (hashing == HASH_SHA1)
- DCRYPTO_SHA1_init(&ctx, 0);
+ SHA1_hw_init(&ctx.sha1);
else
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx.sha256);
/* Pilfer bits of output for temporary use. */
memset(padded, 0, 8);
@@ -409,7 +408,7 @@ static int pkcs1_pss_pad(uint8_t *padded, uint32_t padded_len,
HASH_update(&ctx, padded, salt_len);
/* Output hash. */
- memcpy(padded + db_len, HASH_final(&ctx), hash_size);
+ memcpy(padded + db_len, HASH_final(&ctx)->b8, hash_size);
/* Prepare DB. */
ps_len = db_len - salt_len - 1;
@@ -430,13 +429,13 @@ static int check_pkcs1_pss_pad(const uint8_t *in, uint32_t in_len,
uint8_t *padded, uint32_t padded_len,
enum hashing_mode hashing)
{
- const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA_DIGEST_SIZE
+ const uint32_t hash_size = (hashing == HASH_SHA1) ? SHA1_DIGEST_SIZE
: SHA256_DIGEST_SIZE;
const uint8_t zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t db_len;
uint32_t max_ps_len;
uint32_t salt_len;
- HASH_CTX ctx;
+ union hash_ctx ctx;
int bad = 0;
int i;
@@ -468,9 +467,9 @@ static int check_pkcs1_pss_pad(const uint8_t *in, uint32_t in_len,
salt_len = max_ps_len - i;
if (hashing == HASH_SHA1)
- DCRYPTO_SHA1_init(&ctx, 0);
+ SHA1_hw_init(&ctx.sha1);
else
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx.sha256);
HASH_update(&ctx, zeros, sizeof(zeros));
HASH_update(&ctx, in, in_len);
HASH_update(&ctx, padded + db_len - salt_len, salt_len);
diff --git a/board/cr50/dcrypto/sha1.c b/board/cr50/dcrypto/sha1.c
index 07ef3a34ef..e0f576d758 100644
--- a/board/cr50/dcrypto/sha1.c
+++ b/board/cr50/dcrypto/sha1.c
@@ -1,65 +1,137 @@
-/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+/* 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 "dcrypto.h"
+#include "endian.h"
#include "internal.h"
-#include "registers.h"
-#include "cryptoc/sha.h"
+static void SHA1_transform(struct sha1_ctx *const ctx)
+{
+ uint32_t W[80];
+ uint32_t A, B, C, D, E;
+ size_t t;
+ static const uint32_t K[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC,
+ 0xCA62C1D6 };
+
+ for (t = 0; t < 16; ++t)
+ W[t] = be32toh(ctx->b32[t]);
+ for (; t < 80; t++)
+ W[t] = rol(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
-static void dcrypto_sha1_init(SHA_CTX *ctx);
-static const uint8_t *dcrypto_sha1_final(SHA_CTX *unused);
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+ for (t = 0; t < 80; t++) {
+ uint32_t tmp = rol(A, 5) + E + W[t];
-/*
- * Hardware SHA implementation.
+ if (t < 20)
+ tmp += (D ^ (B & (C ^ D))) + K[0];
+ else if (t < 40)
+ tmp += (B ^ C ^ D) + K[1];
+ else if (t < 60)
+ tmp += ((B & C) | (D & (B | C))) + K[2];
+ else
+ tmp += (B ^ C ^ D) + K[3];
+ E = D;
+ D = C;
+ C = rol(B, 30);
+ B = A;
+ A = tmp;
+ }
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+/**
+ * Define aliases taking union type as parameter. This is safe
+ * as union type has header in same place and is not less than original type.
+ * Equal to:
+ * void SHA1_init_as_hash(hash_ctx_t *const ctx) {SHA1_init(&ctx.sha1);}
+ * but save some space for embedded uses.
*/
-static const HASH_VTAB HW_SHA1_VTAB = {
- dcrypto_sha1_init,
- dcrypto_sha_update,
- dcrypto_sha1_final,
- DCRYPTO_SHA1_hash,
- SHA_DIGEST_SIZE
-};
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha1_ctx));
+static void SHA1_init_as_hash(union hash_ctx *const ctx) __alias(SHA1_sw_init);
+static void SHA1_update_as_hash(union hash_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA1_sw_update);
+static const union sha_digests *SHA1_final_as_hash(union hash_ctx *const ctx)
+ __alias(SHA1_sw_final);
-/* Requires dcrypto_grab_sha_hw() to be called first. */
-static void dcrypto_sha1_init(SHA_CTX *ctx)
+void SHA1_sw_init(struct sha1_ctx *const ctx)
{
- ctx->f = &HW_SHA1_VTAB;
- dcrypto_sha_init(SHA1_MODE);
+ static const struct hash_vtable sha1_vtab = {
+ SHA1_init_as_hash, SHA1_update_as_hash, SHA1_final_as_hash,
+ HMAC_sw_final, SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE,
+ sizeof(struct sha1_ctx)
+ };
+ static const uint32_t sha1_init[SHA1_DIGEST_WORDS] = {
+ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
+ };
+
+ ctx->f = &sha1_vtab;
+ memcpy(ctx->state, sha1_init, sizeof(ctx->state));
+ ctx->count = 0;
}
-/* Select and initialize either the software or hardware
- * implementation. If "multi-threaded" behaviour is required, then
- * callers must set sw_required to 1. This is because SHA1 state
- * internal to the hardware cannot be extracted, so it is not possible
- * to suspend and resume a hardware based SHA operation.
- *
- * If the caller has no preference as to implementation, then hardware
- * is preferred based on availability. Hardware is considered to be
- * in use between init() and finished() calls. */
-void DCRYPTO_SHA1_init(SHA_CTX *ctx, uint32_t sw_required)
+void SHA1_sw_update(struct sha1_ctx *const ctx, const void *data, size_t len)
{
- if (!sw_required && dcrypto_grab_sha_hw())
- dcrypto_sha1_init(ctx);
- else
- SHA_init(ctx);
+ size_t i = ctx->count & (SHA1_BLOCK_SIZE - 1);
+ const uint8_t *p = (const uint8_t *)data;
+
+ ctx->count += len;
+ while (len--) {
+ ctx->b8[i++] = *p++;
+ if (i == SHA1_BLOCK_SIZE) {
+ SHA1_transform(ctx);
+ i = 0;
+ }
+ }
}
-static const uint8_t *dcrypto_sha1_final(SHA_CTX *ctx)
+const struct sha1_digest *SHA1_sw_final(struct sha1_ctx *const ctx)
{
- dcrypto_sha_wait(SHA1_MODE, (uint32_t *) ctx->buf);
- return ctx->buf;
+ uint64_t cnt = (uint64_t)ctx->count * CHAR_BIT;
+ size_t i = ctx->count & (SHA1_BLOCK_SIZE - 1);
+
+ /**
+ * append the bit '1' to the message which would be 0x80 if message
+ * length is a multiple of 8 bits.
+ */
+ ctx->b8[i++] = 0x80;
+ /**
+ * append 0 ≤ k < 512 bits '0', such that the resulting message length
+ * in bits is congruent to −64 ≡ 448 (mod 512)
+ */
+ if (i > (SHA1_BLOCK_SIZE - sizeof(cnt))) {
+ /* current block won't fit length, so move to next */
+ while (i < SHA1_BLOCK_SIZE)
+ ctx->b8[i++] = 0;
+ SHA1_transform(ctx);
+ i = 0;
+ }
+ /* pad rest of zeros */
+ while (i < (SHA1_BLOCK_SIZE - sizeof(cnt)))
+ ctx->b8[i++] = 0;
+ /* place big-endian 64-bit bit counter at the end of block */
+ ctx->b64[SHA1_BLOCK_DWORDS - 1] = htobe64(cnt);
+ SHA1_transform(ctx);
+ for (i = 0; i < 5; i++)
+ ctx->b32[i] = htobe32(ctx->state[i]);
+ return &ctx->digest;
}
-const uint8_t *DCRYPTO_SHA1_hash(const void *data, uint32_t n,
- uint8_t *digest)
+/* One shot SHA1 calculation */
+const struct sha1_digest *SHA1_sw_hash(const void *data, size_t len,
+ struct sha1_digest *digest)
{
- if (dcrypto_grab_sha_hw())
- /* dcrypto_sha_wait() will release the hw. */
- dcrypto_sha_hash(SHA1_MODE, data, n, digest);
- else
- SHA_hash(data, n, digest);
+ struct sha1_ctx ctx;
+
+ SHA1_sw_init(&ctx);
+ SHA1_sw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA1_sw_final(&ctx)->b8, SHA1_DIGEST_SIZE);
return digest;
}
diff --git a/board/cr50/dcrypto/sha256.c b/board/cr50/dcrypto/sha256.c
index f127ab445a..2df4514081 100644
--- a/board/cr50/dcrypto/sha256.c
+++ b/board/cr50/dcrypto/sha256.c
@@ -4,192 +4,205 @@
*/
#include "dcrypto.h"
+#include "endian.h"
#include "internal.h"
#include "registers.h"
#include "util.h"
-#include "cryptoc/sha256.h"
-
-static void dcrypto_sha256_init(LITE_SHA256_CTX *ctx);
-static const uint8_t *dcrypto_sha256_final(LITE_SHA256_CTX *ctx);
-
-#ifdef SECTION_IS_RO
-/* RO is single threaded. */
-#define mutex_lock(x)
-#define mutex_unlock(x)
-static inline int dcrypto_grab_sha_hw(void)
-{
- return 1;
-}
-static inline void dcrypto_release_sha_hw(void)
-{
-}
-#else
-#include "task.h"
-static struct mutex hw_busy_mutex;
-
-static int hw_busy;
-
-int dcrypto_grab_sha_hw(void)
+static void SHA256_transform(struct sha256_ctx *const ctx)
{
- int rv = 0;
-
- mutex_lock(&hw_busy_mutex);
- if (!hw_busy) {
- rv = 1;
- hw_busy = 1;
+ static const uint32_t K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
+ 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
+ 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
+ 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
+ 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
+ 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
+ 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
+ 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
+ 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+ uint32_t W[64];
+ uint32_t A, B, C, D, E, F, G, H;
+ size_t t;
+
+ for (t = 0; t < 16; ++t)
+ W[t] = be32toh(ctx->b32[t]);
+ for (; t < 64; t++) {
+ uint32_t s0 = ror(W[t - 15], 7) ^ ror(W[t - 15], 18) ^
+ (W[t - 15] >> 3);
+ uint32_t s1 = ror(W[t - 2], 17) ^ ror(W[t - 2], 19) ^
+ (W[t - 2] >> 10);
+
+ W[t] = W[t - 16] + s0 + W[t - 7] + s1;
}
- mutex_unlock(&hw_busy_mutex);
-
- return rv;
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+ F = ctx->state[5];
+ G = ctx->state[6];
+ H = ctx->state[7];
+ for (t = 0; t < 64; t++) {
+ uint32_t s0 = ror(A, 2) ^ ror(A, 13) ^ ror(A, 22);
+ uint32_t maj = (A & B) ^ (A & C) ^ (B & C);
+ uint32_t t2 = s0 + maj;
+ uint32_t s1 = ror(E, 6) ^ ror(E, 11) ^ ror(E, 25);
+ uint32_t ch = (E & F) ^ ((~E) & G);
+ uint32_t t1 = H + s1 + ch + K[t] + W[t];
+
+ H = G;
+ G = F;
+ F = E;
+ E = D + t1;
+ D = C;
+ C = B;
+ B = A;
+ A = t1 + t2;
+ }
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+ ctx->state[5] += F;
+ ctx->state[6] += G;
+ ctx->state[7] += H;
}
-
-void dcrypto_release_sha_hw(void)
+/**
+ * Define aliases taking union type as parameter. This is safe
+ * as union type has header in same place and is not less than original type.
+ * Equal to:
+ * void SHA256_init_as_hash(HASH_CTX *const ctx) {SHA256_init(&ctx.sha256);}
+ * but save some space for embedded uses.
+ */
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha256_ctx));
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha224_ctx));
+
+static void SHA256_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA256_sw_init);
+static void SHA256_update_as_hash(union hash_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA256_sw_update);
+static const union sha_digests *SHA256_final_as_hash(union hash_ctx *const ctx)
+ __alias(SHA256_sw_final);
+static void SHA224_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA224_sw_init);
+
+void SHA256_sw_init(struct sha256_ctx *const ctx)
{
- mutex_lock(&hw_busy_mutex);
- hw_busy = 0;
- mutex_unlock(&hw_busy_mutex);
+ static const struct hash_vtable sha256_vtable = {
+ SHA256_init_as_hash, SHA256_update_as_hash,
+ SHA256_final_as_hash, HMAC_sw_final,
+ SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE,
+ sizeof(struct sha256_ctx)
+ };
+ static const uint32_t sha256_init[SHA256_DIGEST_WORDS] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ };
+
+ ctx->f = &sha256_vtable;
+ memcpy(ctx->state, sha256_init, sizeof(ctx->state));
+ ctx->count = 0;
}
-#endif /* ! SECTION_IS_RO */
-
-void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest)
-{
- int i;
- const int digest_len = (mode == SHA1_MODE) ?
- SHA_DIGEST_SIZE :
- SHA256_DIGEST_SIZE;
-
- /* Stop LIVESTREAM mode. */
- GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;
-
- /* Wait for SHA DONE interrupt. */
- while (!GREG32(KEYMGR, SHA_ITOP))
- ;
-
- /* Read out final digest. */
- for (i = 0; i < digest_len / 4; ++i)
- *digest++ = GR_KEYMGR_SHA_HASH(i);
- dcrypto_release_sha_hw();
-}
+/* SHA2-224 and SHA2-256 use same internal context. */
+BUILD_ASSERT(sizeof(struct sha224_ctx) == sizeof(struct sha256_ctx));
+void SHA224_sw_update(struct sha224_ctx *ctx, const void *data, size_t len)
+ __alias(SHA256_sw_update);
-/* Hardware SHA implementation. */
-static const HASH_VTAB HW_SHA256_VTAB = {
- dcrypto_sha256_init,
- dcrypto_sha_update,
- dcrypto_sha256_final,
- DCRYPTO_SHA256_hash,
- SHA256_DIGEST_SIZE
-};
-
-void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data, uint32_t n,
- uint8_t *digest)
+void SHA256_sw_update(struct sha256_ctx *ctx, const void *data, size_t len)
{
- dcrypto_sha_init(mode);
- dcrypto_sha_update(NULL, data, n);
- dcrypto_sha_wait(mode, (uint32_t *) digest);
+ size_t i = ctx->count & (SHA256_BLOCK_SIZE - 1);
+ const uint8_t *p = (const uint8_t *)data;
+
+ ctx->count += len;
+ while (len--) {
+ ctx->b8[i++] = *p++;
+ if (i == SHA256_BLOCK_SIZE) {
+ SHA256_transform(ctx);
+ i = 0;
+ }
+ }
}
-
-void dcrypto_sha_update(struct HASH_CTX *unused,
- const void *data, uint32_t n)
+const struct sha224_digest *SHA224_sw_final(struct sha224_ctx *const ctx)
+ __alias(SHA256_sw_final);
+const struct sha256_digest *SHA256_sw_final(struct sha256_ctx *const ctx)
{
- const uint8_t *bp = (const uint8_t *) data;
- const uint32_t *wp;
-
- /* Feed unaligned start bytes. */
- while (n != 0 && ((uint32_t)bp & 3)) {
- GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
- n -= 1;
- }
-
- /* Feed groups of aligned words. */
- wp = (uint32_t *)bp;
- while (n >= 8*4) {
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- n -= 8*4;
- }
- /* Feed individual aligned words. */
- while (n >= 4) {
- GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
- n -= 4;
- }
-
- /* Feed remaing bytes. */
- bp = (uint8_t *) wp;
- while (n != 0) {
- GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
- n -= 1;
+ uint64_t cnt = (uint64_t)ctx->count * CHAR_BIT;
+ size_t i = ctx->count & (SHA256_BLOCK_SIZE - 1);
+
+ /**
+ * append the bit '1' to the message which would be 0x80 if message
+ * length is a multiple of 8 bits.
+ */
+ ctx->b8[i++] = 0x80;
+ /**
+ * Append 0 ≤ k < 512 bits '0', such that the resulting message length
+ * in bits is congruent to −64 ≡ 448 (mod 512).
+ */
+ if (i > (SHA256_BLOCK_SIZE - sizeof(cnt))) {
+ /* Current block won't fit length, so move to next. */
+ while (i < SHA256_BLOCK_SIZE)
+ ctx->b8[i++] = 0;
+ SHA256_transform(ctx);
+ i = 0;
}
+ /* Pad rest of zeros. */
+ while (i < (SHA256_BLOCK_SIZE - sizeof(cnt)))
+ ctx->b8[i++] = 0;
+
+ /* Place big-endian 64-bit bit counter at the end of block. */
+ ctx->b64[SHA256_BLOCK_DWORDS - 1] = htobe64(cnt);
+ SHA256_transform(ctx);
+ for (i = 0; i < 8; i++)
+ ctx->b32[i] = htobe32(ctx->state[i]);
+ return &ctx->digest;
}
-void dcrypto_sha_init(enum sha_mode mode)
+void SHA224_sw_init(struct sha224_ctx *const ctx)
{
- int val;
-
- /* Stop LIVESTREAM mode, in case final() was not called. */
- GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;
- /* Clear interrupt status. */
- GREG32(KEYMGR, SHA_ITOP) = 0;
-
- /* Enable streaming mode. */
- val = GC_KEYMGR_SHA_CFG_EN_LIVESTREAM_MASK;
- /* Enable SHA DONE interrupt. */
- val |= GC_KEYMGR_SHA_CFG_EN_INT_EN_DONE_MASK;
- /* Select SHA mode. */
- if (mode == SHA1_MODE)
- val |= GC_KEYMGR_SHA_CFG_EN_SHA1_MASK;
- GREG32(KEYMGR, SHA_CFG_EN) = val;
-
- /* Turn off random nops (which are enabled by default). */
- GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, STALL_EN, 0);
- /* Configure random nop percentage at 12%. */
- GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, FREQ, 2);
- /* Now turn on random nops. */
- GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, STALL_EN, 1);
-
- /* Start SHA engine. */
- GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_GO_MASK;
+ /* SHA2-224 differs from SHA2-256 only in initialization. */
+ static const struct hash_vtable sha224_vtable = {
+ SHA224_init_as_hash, SHA256_update_as_hash,
+ SHA256_final_as_hash, HMAC_sw_final,
+ SHA224_DIGEST_SIZE, SHA224_BLOCK_SIZE,
+ sizeof(struct sha224_ctx)
+ };
+ static const uint32_t sha224_init[SHA256_DIGEST_WORDS] = {
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+ };
+
+ ctx->f = &sha224_vtable;
+ memcpy(ctx->state, sha224_init, sizeof(ctx->state));
+ ctx->count = 0;
}
-static void dcrypto_sha256_init(LITE_SHA256_CTX *ctx)
+/* One shot hash computation. */
+const struct sha224_digest *SHA224_sw_hash(const void *data, size_t len,
+ struct sha224_digest *digest)
{
- ctx->f = &HW_SHA256_VTAB;
- dcrypto_sha_init(SHA256_MODE);
-}
+ struct sha224_ctx ctx;
-/* Requires dcrypto_grab_sha_hw() to be called first. */
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
-{
- if (!sw_required && dcrypto_grab_sha_hw())
- dcrypto_sha256_init(ctx);
-#ifndef SECTION_IS_RO
- else
- SHA256_init(ctx);
-#endif
+ SHA224_sw_init(&ctx);
+ SHA224_sw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA224_sw_final(&ctx), SHA224_DIGEST_SIZE);
+ return digest;
}
-
-static const uint8_t *dcrypto_sha256_final(LITE_SHA256_CTX *ctx)
+/* One shot hash computation */
+const struct sha256_digest *SHA256_sw_hash(const void *data, size_t len,
+ struct sha256_digest *digest)
{
- dcrypto_sha_wait(SHA256_MODE, (uint32_t *) ctx->buf);
- return ctx->buf;
-}
+ struct sha256_ctx ctx;
-const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
- uint8_t *digest)
-{
- if (dcrypto_grab_sha_hw())
- /* dcrypto_sha_wait() will release the hw. */
- dcrypto_sha_hash(SHA256_MODE, data, n, digest);
-#ifndef SECTION_IS_RO
- else
- SHA256_hash(data, n, digest);
-#endif
+ SHA256_sw_init(&ctx);
+ SHA256_sw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA256_sw_final(&ctx)->b8, SHA256_DIGEST_SIZE);
return digest;
}
diff --git a/board/cr50/dcrypto/sha384.c b/board/cr50/dcrypto/sha384.c
deleted file mode 100644
index 6f3c6ca096..0000000000
--- a/board/cr50/dcrypto/sha384.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright 2016 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 "dcrypto.h"
-#include "internal.h"
-
-#include "cryptoc/sha384.h"
-
-void DCRYPTO_SHA384_init(LITE_SHA512_CTX *ctx)
-{
- SHA384_init(ctx);
-}
-
-const uint8_t *DCRYPTO_SHA384_hash(const void *data, uint32_t n,
- uint8_t *digest)
-{
- return SHA384_hash(data, n, digest);
-}
diff --git a/board/cr50/dcrypto/sha512.c b/board/cr50/dcrypto/sha512.c
index 1446970174..31b0d47c1a 100644
--- a/board/cr50/dcrypto/sha512.c
+++ b/board/cr50/dcrypto/sha512.c
@@ -4,17 +4,254 @@
*/
#include "dcrypto.h"
+#include "endian.h"
#include "internal.h"
-#include "cryptoc/sha512.h"
+static void SHA512_transform(struct sha512_ctx *ctx)
+{
+ static const uint64_t K[80] = {
+ 0x428A2F98D728AE22ll, 0x7137449123EF65CDll,
+ 0xB5C0FBCFEC4D3B2Fll, 0xE9B5DBA58189DBBCll,
+ 0x3956C25BF348B538ll, 0x59F111F1B605D019ll,
+ 0x923F82A4AF194F9Bll, 0xAB1C5ED5DA6D8118ll,
+ 0xD807AA98A3030242ll, 0x12835B0145706FBEll,
+ 0x243185BE4EE4B28Cll, 0x550C7DC3D5FFB4E2ll,
+ 0x72BE5D74F27B896Fll, 0x80DEB1FE3B1696B1ll,
+ 0x9BDC06A725C71235ll, 0xC19BF174CF692694ll,
+ 0xE49B69C19EF14AD2ll, 0xEFBE4786384F25E3ll,
+ 0x0FC19DC68B8CD5B5ll, 0x240CA1CC77AC9C65ll,
+ 0x2DE92C6F592B0275ll, 0x4A7484AA6EA6E483ll,
+ 0x5CB0A9DCBD41FBD4ll, 0x76F988DA831153B5ll,
+ 0x983E5152EE66DFABll, 0xA831C66D2DB43210ll,
+ 0xB00327C898FB213Fll, 0xBF597FC7BEEF0EE4ll,
+ 0xC6E00BF33DA88FC2ll, 0xD5A79147930AA725ll,
+ 0x06CA6351E003826Fll, 0x142929670A0E6E70ll,
+ 0x27B70A8546D22FFCll, 0x2E1B21385C26C926ll,
+ 0x4D2C6DFC5AC42AEDll, 0x53380D139D95B3DFll,
+ 0x650A73548BAF63DEll, 0x766A0ABB3C77B2A8ll,
+ 0x81C2C92E47EDAEE6ll, 0x92722C851482353Bll,
+ 0xA2BFE8A14CF10364ll, 0xA81A664BBC423001ll,
+ 0xC24B8B70D0F89791ll, 0xC76C51A30654BE30ll,
+ 0xD192E819D6EF5218ll, 0xD69906245565A910ll,
+ 0xF40E35855771202All, 0x106AA07032BBD1B8ll,
+ 0x19A4C116B8D2D0C8ll, 0x1E376C085141AB53ll,
+ 0x2748774CDF8EEB99ll, 0x34B0BCB5E19B48A8ll,
+ 0x391C0CB3C5C95A63ll, 0x4ED8AA4AE3418ACBll,
+ 0x5B9CCA4F7763E373ll, 0x682E6FF3D6B2B8A3ll,
+ 0x748F82EE5DEFB2FCll, 0x78A5636F43172F60ll,
+ 0x84C87814A1F0AB72ll, 0x8CC702081A6439ECll,
+ 0x90BEFFFA23631E28ll, 0xA4506CEBDE82BDE9ll,
+ 0xBEF9A3F7B2C67915ll, 0xC67178F2E372532Bll,
+ 0xCA273ECEEA26619Cll, 0xD186B8C721C0C207ll,
+ 0xEADA7DD6CDE0EB1Ell, 0xF57D4F7FEE6ED178ll,
+ 0x06F067AA72176FBAll, 0x0A637DC5A2C898A6ll,
+ 0x113F9804BEF90DAEll, 0x1B710B35131C471Bll,
+ 0x28DB77F523047D84ll, 0x32CAAB7B40C72493ll,
+ 0x3C9EBE0A15C9BEBCll, 0x431D67C49C100D4Cll,
+ 0x4CC5D4BECB3E42B6ll, 0x597F299CFC657E2All,
+ 0x5FCB6FAB3AD6FAECll, 0x6C44198C4A475817ll
+ };
+ uint64_t W[80];
+ uint64_t A, B, C, D, E, F, G, H;
+ size_t t;
+
+ for (t = 0; t < 16; t++)
+ W[t] = be64toh(ctx->b64[t]);
+
+ for (; t < 80; t++) {
+ uint64_t Wt2 = W[t - 2];
+ uint64_t Wt7 = W[t - 7];
+ uint64_t Wt15 = W[t - 15];
+ uint64_t Wt16 = W[t - 16];
+ uint64_t s0 = ror64(Wt15, 1) ^ ror64(Wt15, 8) ^ (Wt15 >> 7);
+ uint64_t s1 = ror64(Wt2, 19) ^ ror64(Wt2, 61) ^ (Wt2 >> 6);
+
+ W[t] = s1 + Wt7 + s0 + Wt16;
+ }
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+ F = ctx->state[5];
+ G = ctx->state[6];
+ H = ctx->state[7];
+ for (t = 0; t < 80; t++) {
+ uint64_t s0 = ror64(A, 28) ^ ror64(A, 34) ^ ror64(A, 39);
+ uint64_t maj = (A & B) ^ (A & C) ^ (B & C);
+ uint64_t t2 = s0 + maj;
+ uint64_t s1 = ror64(E, 14) ^ ror64(E, 18) ^ ror64(E, 41);
+ uint64_t ch = (E & F) ^ ((~E) & G);
+ uint64_t t1 = H + s1 + ch + W[t] + K[t];
+
+ H = G;
+ G = F;
+ F = E;
+ E = D + t1;
+ D = C;
+ C = B;
+ B = A;
+ A = t1 + t2;
+ }
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+ ctx->state[5] += F;
+ ctx->state[6] += G;
+ ctx->state[7] += H;
+}
+
+/**
+ * Define aliases taking union type as parameter. This is safe
+ * as union type has header in same place and is not less than original type.
+ * Equal to:
+ * void SHA512_init_as_hash(HASH_CTX *const ctx) {SHA512_init(&ctx.sha512);}
+ * but save some space for embedded uses.
+ */
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha512_ctx));
+BUILD_ASSERT(sizeof(union hash_ctx) >= sizeof(struct sha384_ctx));
+
+static void SHA512_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA512_sw_init);
+static void SHA512_update_as_hash(union hash_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA512_sw_update);
+static const union sha_digests *SHA512_final_as_hash(union hash_ctx *const ctx)
+ __alias(SHA512_sw_final);
+static void SHA384_init_as_hash(union hash_ctx *const ctx)
+ __alias(SHA384_sw_init);
+
+void SHA512_sw_init(struct sha512_ctx *const ctx)
+{
+ static const struct hash_vtable sha512_vtable = {
+ SHA512_init_as_hash, SHA512_update_as_hash,
+ SHA512_final_as_hash, HMAC_sw_final,
+ SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE,
+ sizeof(struct sha512_ctx)
+ };
+ static const uint64_t sha512_init[SHA512_DIGEST_DWORDS] = {
+ 0x6a09e667f3bcc908ll, 0xbb67ae8584caa73bll,
+ 0x3c6ef372fe94f82bll, 0xa54ff53a5f1d36f1ll,
+ 0x510e527fade682d1ll, 0x9b05688c2b3e6c1fll,
+ 0x1f83d9abfb41bd6bll, 0x5be0cd19137e2179ll
+ };
+
+ memcpy(ctx->state, sha512_init, sizeof(ctx->state));
+ ctx->f = &sha512_vtable;
+ ctx->count = 0;
+}
+
+/* SHA2-384 and SHA2-512 use same internal context. */
+BUILD_ASSERT(sizeof(struct sha384_ctx) == sizeof(struct sha512_ctx));
+
+void SHA384_sw_update(struct sha384_ctx *const ctx, const void *data,
+ size_t len) __alias(SHA512_sw_update);
+
+void SHA512_sw_update(struct sha512_ctx *const ctx, const void *data,
+ size_t len)
+{
+ size_t i = ctx->count & (SHA512_BLOCK_SIZE - 1);
+ const uint8_t *p = (const uint8_t *)data;
-void DCRYPTO_SHA512_init(LITE_SHA512_CTX *ctx)
+ ctx->count += len;
+ while (len--) {
+ ctx->b8[i++] = *p++;
+ if (i == SHA512_BLOCK_SIZE) {
+ SHA512_transform(ctx);
+ i = 0;
+ }
+ }
+}
+
+const struct sha384_digest *SHA384_sw_final(struct sha384_ctx *const ctx)
+ __alias(SHA512_sw_final);
+
+const struct sha512_digest *SHA512_sw_final(struct sha512_ctx *const ctx)
{
- SHA512_init(ctx);
+ uint64_t cnt = (uint64_t)ctx->count * CHAR_BIT;
+ size_t i = ctx->count & (SHA512_BLOCK_SIZE - 1);
+
+ /**
+ * Append the bit '1' to the message which would be 0x80 if message
+ * length is a multiple of 8 bits.
+ */
+ ctx->b8[i++] = 0x80;
+ /**
+ * Append 0 ≤ k < 1024 bits '0', such that the resulting message
+ * length in bits is congruent to −64 ≡ 896 (mod 1024).
+ */
+ if (i > (SHA512_BLOCK_SIZE - 2 * sizeof(cnt))) {
+ /* Current block won't fit length, so move to next. */
+ while (i < SHA512_BLOCK_SIZE)
+ ctx->b8[i++] = 0;
+ SHA512_transform(ctx);
+ i = 0;
+ }
+ /* pad rest of zeros, including 8 bytes of 128-bit counter */
+ while (i < (SHA512_BLOCK_SIZE - sizeof(cnt)))
+ ctx->b8[i++] = 0;
+ /* place big-endian 64-bit bit counter at the end of block */
+ ctx->b64[SHA512_BLOCK_DWORDS - 1] = htobe64(cnt);
+ SHA512_transform(ctx);
+ for (i = 0; i < 8; i++)
+ ctx->b64[i] = htobe64(ctx->state[i]);
+ return &ctx->digest;
}
-const uint8_t *DCRYPTO_SHA512_hash(const void *data, uint32_t n,
- uint8_t *digest)
+const struct sha512_digest *SHA512_sw_hash(const void *data, size_t len,
+ struct sha512_digest *digest)
{
- return SHA512_hash(data, n, digest);
+ struct sha512_ctx ctx;
+
+ SHA512_sw_init(&ctx);
+ SHA512_sw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA512_sw_final(&ctx)->b8, SHA512_DIGEST_SIZE);
+ return digest;
+}
+
+void SHA384_sw_init(struct sha384_ctx *ctx)
+{
+ /* SHA2-384 differs from SHA2-512 only in initialization. */
+ static const struct hash_vtable sha384_vtable = {
+ SHA384_init_as_hash, SHA512_update_as_hash,
+ SHA512_final_as_hash, HMAC_sw_final,
+ SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE,
+ sizeof(struct sha384_ctx)
+ };
+ static const uint64_t sha384_init[SHA512_DIGEST_DWORDS] = {
+ 0xcbbb9d5dc1059ed8ll, 0x629a292a367cd507ll,
+ 0x9159015a3070dd17ll, 0x152fecd8f70e5939ll,
+ 0x67332667ffc00b31ll, 0x8eb44a8768581511ll,
+ 0xdb0c2e0d64f98fa7ll, 0x47b5481dbefa4fa4ll
+ };
+
+ memcpy(ctx->state, sha384_init, sizeof(ctx->state));
+ ctx->count = 0;
+ ctx->f = &sha384_vtable;
}
+
+const struct sha384_digest *SHA384_sw_hash(const void *data, size_t len,
+ struct sha384_digest *digest)
+{
+ struct sha384_ctx ctx;
+
+ SHA384_sw_init(&ctx);
+ SHA384_sw_update(&ctx, data, len);
+ memcpy(digest->b8, SHA384_sw_final(&ctx)->b8, SHA384_DIGEST_SIZE);
+ return digest;
+}
+
+/**
+ * We don't support HW-accelerated SHA384/SHA512 yet, so alias it to software.
+ */
+const struct sha512_digest *SHA512_hw_hash(const void *data, size_t len,
+ struct sha512_digest *digest)
+ __alias(SHA512_sw_hash);
+
+const struct sha384_digest *SHA384_hw_hash(const void *data, size_t len,
+ struct sha384_digest *digest)
+ __alias(SHA384_sw_hash);
+
+void SHA512_hw_init(struct sha512_ctx *const ctx) __alias(SHA512_sw_init);
+void SHA384_hw_init(struct sha384_ctx *const ctx) __alias(SHA384_sw_init);
diff --git a/board/cr50/dcrypto/sha_hw.c b/board/cr50/dcrypto/sha_hw.c
new file mode 100644
index 0000000000..acad1ba29d
--- /dev/null
+++ b/board/cr50/dcrypto/sha_hw.c
@@ -0,0 +1,265 @@
+/* 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 "dcrypto.h"
+#include "internal.h"
+#include "registers.h"
+
+#ifdef SECTION_IS_RO
+/* RO is single threaded. */
+#define mutex_lock(x)
+#define mutex_unlock(x)
+static inline int dcrypto_grab_sha_hw(void)
+{
+ return 1;
+}
+static inline void dcrypto_release_sha_hw(void)
+{
+}
+#else
+#include "task.h"
+static struct mutex hw_busy_mutex;
+
+static bool hw_busy;
+
+int dcrypto_grab_sha_hw(void)
+{
+ int rv = 0;
+
+ mutex_lock(&hw_busy_mutex);
+ if (!hw_busy) {
+ rv = 1;
+ hw_busy = true;
+ }
+ mutex_unlock(&hw_busy_mutex);
+
+ return rv;
+}
+
+void dcrypto_release_sha_hw(void)
+{
+ mutex_lock(&hw_busy_mutex);
+ hw_busy = false;
+ mutex_unlock(&hw_busy_mutex);
+}
+
+#endif /* ! SECTION_IS_RO */
+
+static void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest)
+{
+ int i;
+ const int digest_len = (mode == SHA1_MODE) ? SHA1_DIGEST_SIZE :
+ SHA256_DIGEST_SIZE;
+
+ /* Stop LIVESTREAM mode. */
+ GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;
+
+ /* Wait for SHA DONE interrupt. */
+ while (!GREG32(KEYMGR, SHA_ITOP))
+ ;
+
+ /* Read out final digest. */
+ for (i = 0; i < digest_len / 4; ++i)
+ *digest++ = GR_KEYMGR_SHA_HASH(i);
+ dcrypto_release_sha_hw();
+}
+
+static void dcrypto_sha_update(union hash_ctx *unused, const void *data,
+ size_t n)
+{
+ const uint8_t *bp = (const uint8_t *)data;
+ const uint32_t *wp;
+
+ /* Feed unaligned start bytes. */
+ while (n != 0 && ((uint32_t)bp & 3)) {
+ GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
+ n -= 1;
+ }
+
+ /* Feed groups of aligned words. */
+ wp = (uint32_t *)bp;
+ while (n >= 8 * 4) {
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ n -= 8 * 4;
+ }
+ /* Feed individual aligned words. */
+ while (n >= 4) {
+ GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
+ n -= 4;
+ }
+
+ /* Feed remaining bytes. */
+ bp = (uint8_t *)wp;
+ while (n != 0) {
+ GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
+ n -= 1;
+ }
+}
+
+static void dcrypto_sha_init(enum sha_mode mode)
+{
+ int val;
+
+ /* Stop LIVESTREAM mode, in case final() was not called. */
+ GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;
+ /* Clear interrupt status. */
+ GREG32(KEYMGR, SHA_ITOP) = 0;
+
+ /* Enable streaming mode. */
+ val = GC_KEYMGR_SHA_CFG_EN_LIVESTREAM_MASK;
+ /* Enable SHA DONE interrupt. */
+ val |= GC_KEYMGR_SHA_CFG_EN_INT_EN_DONE_MASK;
+ /* Select SHA mode. */
+ if (mode == SHA1_MODE)
+ val |= GC_KEYMGR_SHA_CFG_EN_SHA1_MASK;
+ GREG32(KEYMGR, SHA_CFG_EN) = val;
+
+ /* Turn off random nops (which are enabled by default). */
+ GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, STALL_EN, 0);
+ /* Configure random nop percentage at 12%. */
+ GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, FREQ, 2);
+ /* Now turn on random nops. */
+ GWRITE_FIELD(KEYMGR, SHA_RAND_STALL_CTL, STALL_EN, 1);
+
+ /* Start SHA engine. */
+ GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_GO_MASK;
+}
+
+static const struct sha1_digest *dcrypto_sha1_final(union hash_ctx *ctx)
+{
+ dcrypto_sha_wait(SHA1_MODE, ctx->sha1.digest.b32);
+ return &ctx->sha1.digest;
+}
+
+static const struct sha256_digest *dcrypto_sha256_final(union hash_ctx *ctx)
+{
+ dcrypto_sha_wait(SHA256_MODE, ctx->sha256.digest.b32);
+ return &ctx->sha256.digest;
+}
+
+static const union sha_digests *dcrypto_sha256_final_as_hash(
+ union hash_ctx *const ctx) __alias(dcrypto_sha256_final);
+static const union sha_digests *dcrypto_sha1_final_as_hash(
+ union hash_ctx *const ctx) __alias(dcrypto_sha1_final);
+
+static void dcrypto_sha_hash(enum sha_mode mode, const uint8_t *data, size_t n,
+ uint32_t *digest)
+{
+ dcrypto_sha_init(mode);
+ dcrypto_sha_update(NULL, data, n);
+ dcrypto_sha_wait(mode, digest);
+}
+
+/* Requires dcrypto_grab_sha_hw() to be called first. */
+static void dcrypto_sha1_init(union hash_ctx *ctx)
+{
+ static const struct hash_vtable hw_sha1_vtab = {
+ dcrypto_sha1_init, dcrypto_sha_update,
+ dcrypto_sha1_final_as_hash, HMAC_sw_final,
+ SHA1_DIGEST_SIZE, SHA1_BLOCK_SIZE,
+ sizeof(struct sha1_ctx)
+ };
+
+ ctx->f = &hw_sha1_vtab;
+ dcrypto_sha_init(SHA1_MODE);
+}
+
+static void dcrypto_sha256_init(union hash_ctx *ctx)
+{
+ /* Hardware SHA implementation. */
+ static const struct hash_vtable HW_SHA256_VTAB = {
+ dcrypto_sha256_init, dcrypto_sha_update,
+ dcrypto_sha256_final_as_hash, HMAC_sw_final,
+ SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE,
+ sizeof(struct sha256_ctx)
+ };
+
+ ctx->f = &HW_SHA256_VTAB;
+ dcrypto_sha_init(SHA256_MODE);
+}
+
+/**
+ * Select and initialize either the software or hardware
+ * implementation. If "multi-threaded" behaviour is required, then
+ * callers must specifically use software version SHA1_sw_init(). This
+ * is because SHA1 state internal to the hardware cannot be extracted, so
+ * it is not possible to suspend and resume a hardware based SHA operation.
+ *
+ * Hardware implementation is selected based on availability. Hardware is
+ * considered to be in use between init() and finished() calls. If hardware
+ * is not available, fall back to software implementation.
+ */
+void SHA1_hw_init(struct sha1_ctx *ctx)
+{
+ if (dcrypto_grab_sha_hw())
+ dcrypto_sha1_init((union hash_ctx *)ctx);
+ else
+ SHA1_sw_init(ctx);
+}
+
+/**
+ * Select and initialize either the software or hardware
+ * implementation. If "multi-threaded" behaviour is required, then
+ * callers must specifically use software version SHA256_sw_init(). This
+ * is because SHA256 state internal to the hardware cannot be extracted, so
+ * it is not possible to suspend and resume a hardware based SHA operation.
+ *
+ * Hardware implementation is selected based on availability. Hardware is
+ * considered to be in use between init() and finished() calls. If hardware
+ * is not available, fall back to software implementation.
+ */
+void SHA256_hw_init(struct sha256_ctx *ctx)
+{
+ if (dcrypto_grab_sha_hw())
+ dcrypto_sha256_init((union hash_ctx *)ctx);
+ else
+ SHA256_sw_init(ctx);
+}
+
+const struct sha1_digest *SHA1_hw_hash(const void *data, size_t n,
+ struct sha1_digest *digest)
+{
+ if (dcrypto_grab_sha_hw())
+ /* dcrypto_sha_wait() will release the hw. */
+ dcrypto_sha_hash(SHA1_MODE, data, n, digest->b32);
+ else
+ SHA1_sw_hash(data, n, digest);
+ return digest;
+}
+
+const struct sha256_digest *SHA256_hw_hash(const void *data, size_t n,
+ struct sha256_digest *digest)
+{
+ if (dcrypto_grab_sha_hw())
+ /* dcrypto_sha_wait() will release the hw. */
+ dcrypto_sha_hash(SHA256_MODE, data, n, digest->b32);
+ else
+ SHA256_sw_hash(data, n, digest);
+ 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);
+
+/* TODO(b/195092622): initialize HW HMAC instead. */
+void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
+ size_t len)
+{
+ SHA256_hw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+
+const struct sha256_digest *
+HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx)
+{
+ return HMAC_SHA256_final(ctx);
+}
diff --git a/board/cr50/dcrypto/x509.c b/board/cr50/dcrypto/x509.c
index 81f1674db1..3850100443 100644
--- a/board/cr50/dcrypto/x509.c
+++ b/board/cr50/dcrypto/x509.c
@@ -366,7 +366,7 @@ int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
const uint8_t *sig;
size_t sig_len;
- uint8_t digest[SHA256_DIGEST_SIZE];
+ struct sha256_digest digest;
/* Read Certificate SEQUENCE. */
if (!asn1_parse_certificate(&p, &len))
@@ -398,8 +398,8 @@ int DCRYPTO_x509_verify(const uint8_t *cert, size_t len,
sig_len--;
}
- DCRYPTO_SHA256_hash(tbs, tbs_len, digest);
- return DCRYPTO_rsa_verify(ca_pub_key, digest, sizeof(digest),
+ SHA256_hw_hash(tbs, tbs_len, &digest);
+ return DCRYPTO_rsa_verify(ca_pub_key, digest.b8, sizeof(digest),
sig, sig_len, PADDING_MODE_PKCS1, HASH_SHA256);
}
@@ -425,7 +425,7 @@ int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
const char *name, uint8_t *cert, const int n)
{
struct asn1 ctx = {cert, 0};
- HASH_CTX sha;
+ struct sha256_ctx sha;
p256_int h, r, s;
struct drbg_ctx drbg;
@@ -513,9 +513,9 @@ int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
SEQ_END(ctx); /* Cert body */
/* Sign all of cert body */
- DCRYPTO_SHA256_init(&sha, 0);
- HASH_update(&sha, body, (ctx.p + ctx.n) - body);
- p256_from_bin(HASH_final(&sha), &h);
+ SHA256_hw_init(&sha);
+ SHA256_update(&sha, body, (ctx.p + ctx.n) - body);
+ p256_from_bin(SHA256_final(&sha)->b8, &h);
hmac_drbg_init_rfc6979(&drbg, d, &h);
if (!dcrypto_p256_ecdsa_sign(&drbg, d, &h, &r, &s))
return 0;
diff --git a/board/cr50/fips.c b/board/cr50/fips.c
index 51a392e2ac..948bd2fba4 100644
--- a/board/cr50/fips.c
+++ b/board/cr50/fips.c
@@ -153,7 +153,7 @@ void fips_throw_err(enum fips_status err)
/* KAT for SHA256, test values from OpenSSL. */
static bool fips_sha256_kat(void)
{
- struct HASH_CTX ctx;
+ struct sha256_ctx ctx;
static const uint8_t in[] = /* "etaonrishd" */ { 0x65, 0x74, 0x61, 0x6f,
0x6e, 0x72, 0x69, 0x73,
@@ -164,16 +164,16 @@ static bool fips_sha256_kat(void)
0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6,
0x50, 0x4f, 0x47, 0x57 };
- DCRYPTO_SHA256_init(&ctx, 0);
- HASH_update(&ctx, in, sizeof(in));
+ SHA256_hw_init(&ctx);
+ SHA256_update(&ctx, in, sizeof(in));
return !(fips_break_cmd == FIPS_BREAK_SHA256) &&
- (memcmp(HASH_final(&ctx), ans, SHA256_DIGEST_SIZE) == 0);
+ (memcmp(SHA256_final(&ctx), ans, SHA256_DIGEST_SIZE) == 0);
}
/* KAT for HMAC-SHA256, test values from OpenSSL. */
static bool fips_hmac_sha256_kat(void)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
static const uint8_t k[SHA256_DIGEST_SIZE] =
/* "etaonrishd" */ { 0x65, 0x74, 0x61, 0x6f, 0x6e, 0x72, 0x69,
@@ -190,10 +190,11 @@ static bool fips_hmac_sha256_kat(void)
0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51,
0xff, 0xda, 0x24, 0xf4 };
- DCRYPTO_HMAC_SHA256_init(&ctx, k, sizeof(k));
- HASH_update(&ctx.hash, in, sizeof(in));
+ HMAC_SHA256_hw_init(&ctx, k, sizeof(k));
+ HMAC_SHA256_update(&ctx, in, sizeof(in));
return !(fips_break_cmd == FIPS_BREAK_HMAC_SHA256) &&
- (memcmp(DCRYPTO_HMAC_final(&ctx), ans, SHA256_DIGEST_SIZE) == 0);
+ (memcmp(HMAC_SHA256_hw_final(&ctx), ans, SHA256_DIGEST_SIZE) ==
+ 0);
}
/**
@@ -397,12 +398,12 @@ static bool fips_ecdsa_verify_kat(void)
};
p256_int p256_digest;
- uint8_t digest[SHA256_DIGEST_SIZE];
+ struct sha256_digest digest;
uint8_t bad_msg[128];
int passed;
- DCRYPTO_SHA256_hash(msg, sizeof(msg), digest);
- p256_from_bin(digest, &p256_digest);
+ SHA256_hw_hash(msg, sizeof(msg), &digest);
+ p256_from_bin(digest.b8, &p256_digest);
passed = dcrypto_p256_ecdsa_verify(&qx, &qy, &p256_digest, &r, &s);
if (!passed)
return false;
@@ -413,8 +414,8 @@ static bool fips_ecdsa_verify_kat(void)
*/
memcpy(bad_msg, msg, sizeof(msg));
bad_msg[92] ^= 0x10;
- DCRYPTO_SHA256_hash(bad_msg, sizeof(bad_msg), digest);
- p256_from_bin(digest, &p256_digest);
+ SHA256_hw_hash(bad_msg, sizeof(bad_msg), &digest);
+ p256_from_bin(digest.b8, &p256_digest);
passed = dcrypto_p256_ecdsa_verify(&qx, &qy, &p256_digest, &r, &s);
return !(fips_break_cmd == FIPS_BREAK_ECDSA) && (passed == 0);
}
@@ -580,19 +581,19 @@ static bool call_on_stack(void *new_stack, bool (*func)(void))
}
/* Placeholder for SHA256 digest of module computed during build time. */
-const uint8_t fips_integrity[SHA256_DIGEST_SIZE]
+const struct sha256_digest fips_integrity
__attribute__((section(".rodata.fips.checksum")));
static bool fips_self_integrity(void)
{
- uint8_t digest[SHA256_DIGEST_SIZE];
+ struct sha256_digest digest;
size_t module_length = &__fips_module_end - &__fips_module_start;
#ifdef CR50_DEV
CPRINTS("FIPS self-integrity start %x, length %u",
(uintptr_t)&__fips_module_start, module_length);
#endif
- DCRYPTO_SHA256_hash(&__fips_module_start, module_length, digest);
+ SHA256_hw_hash(&__fips_module_start, module_length, &digest);
#ifdef CR50_DEV
CPRINTS("Stored, %ph, computed %ph",
@@ -600,7 +601,7 @@ static bool fips_self_integrity(void)
HEX_BUF(digest, sizeof(digest)));
#endif
- return DCRYPTO_equals(fips_integrity, digest, sizeof(digest));
+ return DCRYPTO_equals(fips_integrity.b8, digest.b8, sizeof(digest));
}
/**
diff --git a/board/cr50/tpm2/ecc.c b/board/cr50/tpm2/ecc.c
index 1bcf2d5c5a..5607aaff87 100644
--- a/board/cr50/tpm2/ecc.c
+++ b/board/cr50/tpm2/ecc.c
@@ -192,7 +192,7 @@ CRYPT_RESULT _cpri__GenerateKeyEcc(
TPM2B *local_extra;
uint32_t count = 0;
uint8_t key_bytes[P256_NBYTES];
- LITE_HMAC_CTX hmac;
+ struct hmac_sha256_ctx hmac;
if (curve_id != TPM_ECC_NIST_P256)
return CRYPT_PARAMETER;
@@ -208,9 +208,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. */
- DCRYPTO_HMAC_SHA256_init(&hmac, seed->buffer, seed->size);
- HASH_update(&hmac.hash, "ECC", 4);
- memcpy(local_seed.t.buffer, DCRYPTO_HMAC_final(&hmac),
+ HMAC_SHA256_hw_init(&hmac, seed->buffer,
+ seed->size);
+ HMAC_SHA256_update(&hmac, "ECC", 4);
+ memcpy(local_seed.t.buffer, HMAC_SHA256_final(&hmac),
local_seed.t.size);
always_memset(&hmac, 0, sizeof(hmac));
/* b/35576109: the personalize code uses only the first 4 bytes
diff --git a/board/cr50/tpm2/endorsement.c b/board/cr50/tpm2/endorsement.c
index 844d07e2a6..49f542f782 100644
--- a/board/cr50/tpm2/endorsement.c
+++ b/board/cr50/tpm2/endorsement.c
@@ -30,8 +30,6 @@
#include "dcrypto.h"
-#include <cryptoc/sha256.h>
-
#include <endian.h>
#include <string.h>
@@ -548,7 +546,7 @@ enum manufacturing_status tpm_endorse(void)
enum manufacturing_status result;
uint8_t eps[PRIMARY_SEED_SIZE];
- LITE_HMAC_CTX hmac;
+ struct hmac_sha256_ctx hmac;
flash_cert_region_enable();
@@ -592,12 +590,12 @@ enum manufacturing_status tpm_endorse(void)
*
* This will fail if we are not running w/ expected keyladder.
*/
- DCRYPTO_HMAC_SHA256_init(&hmac, eps, sizeof(eps));
- HASH_update(&hmac.hash, "RSA", 4);
- DCRYPTO_HMAC_SHA256_init(&hmac, DCRYPTO_HMAC_final(&hmac), 32);
- HASH_update(&hmac.hash, p, RO_CERTS_REGION_SIZE - 32);
+ HMAC_SHA256_hw_init(&hmac, eps, sizeof(eps));
+ HMAC_SHA256_update(&hmac, "RSA", 4);
+ HMAC_SHA256_hw_init(&hmac, HMAC_SHA256_hw_final(&hmac), 32);
+ HMAC_SHA256_update(&hmac, p, RO_CERTS_REGION_SIZE - 32);
if (!DCRYPTO_equals(p + RO_CERTS_REGION_SIZE - 32,
- DCRYPTO_HMAC_final(&hmac), 32)) {
+ HMAC_SHA256_hw_final(&hmac), 32)) {
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 7774a6f819..4494451844 100644
--- a/board/cr50/tpm2/hash.c
+++ b/board/cr50/tpm2/hash.c
@@ -42,7 +42,7 @@ uint16_t _cpri__GetHashBlockSize(TPM_ALG_ID alg)
return lookup_hash_info(alg)->blockSize;
}
-BUILD_ASSERT(sizeof(LITE_SHA256_CTX) == USER_MIN_HASH_STATE_SIZE);
+BUILD_ASSERT(sizeof(struct sha256_ctx) <= USER_MIN_HASH_STATE_SIZE);
BUILD_ASSERT(sizeof(CPRI_HASH_STATE) == sizeof(EXPORT_HASH_STATE));
void _cpri__ImportExportHashState(CPRI_HASH_STATE *osslFmt,
EXPORT_HASH_STATE *externalFmt,
@@ -57,7 +57,7 @@ void _cpri__ImportExportHashState(CPRI_HASH_STATE *osslFmt,
uint16_t _cpri__HashBlock(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
uint32_t out_len, uint8_t *out)
{
- uint8_t digest[SHA_DIGEST_MAX_BYTES];
+ union sha_digests digest;
const uint16_t digest_len = _cpri__GetDigestSize(alg);
if (digest_len == 0)
@@ -65,17 +65,17 @@ uint16_t _cpri__HashBlock(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
switch (alg) {
case TPM_ALG_SHA1:
- DCRYPTO_SHA1_hash(in, in_len, digest);
+ SHA1_hw_hash(in, in_len, &digest.sha1);
break;
case TPM_ALG_SHA256:
- DCRYPTO_SHA256_hash(in, in_len, digest);
+ SHA256_hw_hash(in, in_len, &digest.sha256);
break;
case TPM_ALG_SHA384:
- DCRYPTO_SHA384_hash(in, in_len, digest);
+ SHA384_hw_hash(in, in_len, &digest.sha384);
break;
case TPM_ALG_SHA512:
- DCRYPTO_SHA512_hash(in, in_len, digest);
+ SHA512_hw_hash(in, in_len, &digest.sha512);
break;
default:
FAIL(FATAL_ERROR_INTERNAL);
@@ -83,16 +83,16 @@ uint16_t _cpri__HashBlock(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
}
out_len = MIN(out_len, digest_len);
- memcpy(out, digest, out_len);
+ memcpy(out, digest.b8, out_len);
return out_len;
}
-BUILD_ASSERT(sizeof(struct HASH_CTX) <=
+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)
{
- struct HASH_CTX *ctx = (struct 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
@@ -103,20 +103,20 @@ uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence,
*/
switch (alg) {
case TPM_ALG_SHA1:
- DCRYPTO_SHA1_init(ctx, 1);
+ SHA1_sw_init(&ctx->sha1);
result = HASH_size(ctx);
break;
case TPM_ALG_SHA256:
- DCRYPTO_SHA256_init(ctx, 1);
+ SHA256_sw_init(&ctx->sha256);
result = HASH_size(ctx);
break;
case TPM_ALG_SHA384:
- DCRYPTO_SHA384_init(ctx);
+ SHA384_sw_init(&ctx->sha384);
result = HASH_size(ctx);
break;
case TPM_ALG_SHA512:
- DCRYPTO_SHA512_init(ctx);
+ SHA512_sw_init(&ctx->sha512);
result = HASH_size(ctx);
break;
default:
@@ -133,7 +133,7 @@ uint16_t _cpri__StartHash(TPM_ALG_ID alg, BOOL sequence,
void _cpri__UpdateHash(CPRI_HASH_STATE *state, uint32_t in_len,
BYTE *in)
{
- struct HASH_CTX *ctx = (struct HASH_CTX *) state->state;
+ union hash_ctx *ctx = (union hash_ctx *) state->state;
HASH_update(ctx, in, in_len);
}
@@ -141,10 +141,10 @@ void _cpri__UpdateHash(CPRI_HASH_STATE *state, uint32_t in_len,
uint16_t _cpri__CompleteHash(CPRI_HASH_STATE *state,
uint32_t out_len, uint8_t *out)
{
- struct HASH_CTX *ctx = (struct HASH_CTX *) state->state;
+ union hash_ctx *ctx = (union hash_ctx *) state->state;
out_len = MIN(HASH_size(ctx), out_len);
- memcpy(out, HASH_final(ctx), out_len);
+ memcpy(out, HASH_final(ctx)->b8, out_len);
return out_len;
}
@@ -294,7 +294,7 @@ static uint16_t do_software_hmac(TPM_ALG_ID alg, uint32_t in_len, uint8_t *in,
static uint16_t do_dcrypto_hmac(TPM_ALG_ID alg, uint32_t in_len,
uint8_t *in, int32_t out_len, uint8_t *out)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
uint8_t *key;
uint32_t key_len;
@@ -304,10 +304,10 @@ static uint16_t do_dcrypto_hmac(TPM_ALG_ID alg, uint32_t in_len,
key = in + in_len;
key_len = *key++;
key_len = key_len * 256 + *key++;
- DCRYPTO_HMAC_SHA256_init(&ctx, key, key_len);
- HASH_update(&ctx.hash, in, in_len);
+ 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, DCRYPTO_HMAC_final(&ctx), out_len);
+ memcpy(out, HMAC_SHA256_hw_final(&ctx), out_len);
return out_len;
}
@@ -382,7 +382,7 @@ static void hash_command_handler(void *cmd_body,
case HASH_ALG_SHA256:
alg = TPM_ALG_SHA256;
break;
-#ifdef SHA512_SUPPORT
+#ifdef CONFIG_UPTO_SHA512
case HASH_ALG_SHA384:
alg = TPM_ALG_SHA384;
break;
diff --git a/board/cr50/tpm2/rsa.c b/board/cr50/tpm2/rsa.c
index 70e14fba97..9d15d66823 100644
--- a/board/cr50/tpm2/rsa.c
+++ b/board/cr50/tpm2/rsa.c
@@ -396,11 +396,11 @@ CRYPT_RESULT _cpri__GenerateKeyRSA(
} else
#endif
{
- LITE_HMAC_CTX hmac;
+ struct hmac_sha256_ctx hmac;
- DCRYPTO_HMAC_SHA256_init(&hmac, seed->buffer, seed->size);
- HASH_update(&hmac.hash, "RSA", 4);
- memcpy(local_seed.t.buffer, DCRYPTO_HMAC_final(&hmac),
+ HMAC_SHA256_hw_init(&hmac, seed->buffer, seed->size);
+ HMAC_SHA256_update(&hmac, "RSA", 4);
+ memcpy(local_seed.t.buffer, HMAC_SHA256_hw_final(&hmac),
local_seed.t.size);
}
diff --git a/board/cr50/tpm2/virtual_nvmem.c b/board/cr50/tpm2/virtual_nvmem.c
index ef2bf62300..dc65d75f46 100644
--- a/board/cr50/tpm2/virtual_nvmem.c
+++ b/board/cr50/tpm2/virtual_nvmem.c
@@ -9,7 +9,7 @@
#include "board_id.h"
#include "console.h"
-#include "cryptoc/sha256.h"
+#include "dcrypto.h"
#include "link_defs.h"
#include "rma_auth.h"
#include "sn_bits.h"
@@ -300,16 +300,16 @@ BUILD_ASSERT(VIRTUAL_NV_INDEX_G2F_CERT_SIZE == G2F_ATTESTATION_CERT_MAX_LEN);
static void GetRSUDevID(BYTE *to, size_t offset, size_t size)
{
- LITE_SHA256_CTX ctx;
+ struct sha256_ctx ctx;
uint8_t rma_device_id[RMA_DEVICE_ID_SIZE];
const uint8_t *rsu_device_id;
get_rma_device_id(rma_device_id);
- SHA256_init(&ctx);
- HASH_update(&ctx, rma_device_id, sizeof(rma_device_id));
- HASH_update(&ctx, kRsuSalt, RSU_SALT_SIZE);
- rsu_device_id = HASH_final(&ctx);
+ SHA256_hw_init(&ctx);
+ SHA256_update(&ctx, rma_device_id, sizeof(rma_device_id));
+ SHA256_update(&ctx, kRsuSalt, RSU_SALT_SIZE);
+ rsu_device_id = SHA256_final(&ctx)->b8;
memcpy(to, rsu_device_id + offset, size);
}
diff --git a/board/cr50/u2f.c b/board/cr50/u2f.c
index d1d44a2ffa..43082d5008 100644
--- a/board/cr50/u2f.c
+++ b/board/cr50/u2f.c
@@ -222,11 +222,11 @@ int g2f_individual_keypair(p256_int *d, p256_int *pk_x, p256_int *pk_y)
/* Generate unbiased private key */
while (!DCRYPTO_p256_key_from_bytes(pk_x, pk_y, d, buf)) {
- HASH_CTX sha;
+ struct sha256_ctx sha;
- DCRYPTO_SHA256_init(&sha, 0);
- HASH_update(&sha, buf, sizeof(buf));
- memcpy(buf, HASH_final(&sha), sizeof(buf));
+ SHA256_hw_init(&sha);
+ SHA256_update(&sha, buf, sizeof(buf));
+ memcpy(buf, SHA256_final(&sha), sizeof(buf));
}
return EC_SUCCESS;
diff --git a/board/cr50/usb_spi.c b/board/cr50/usb_spi.c
index 8988ed30e1..6876272297 100644
--- a/board/cr50/usb_spi.c
+++ b/board/cr50/usb_spi.c
@@ -20,6 +20,7 @@
#include "tpm_registers.h"
#include "tpm_vendor_cmds.h"
#include "usb_spi.h"
+#include "usb_spi_board.h"
#include "watchdog.h"
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
@@ -670,19 +671,20 @@ static enum vendor_cmd_rc spi_hash_dump(uint8_t *dest, uint32_t offset,
return VENDOR_RC_SUCCESS;
}
-int usb_spi_sha256_start(HASH_CTX *ctx)
+int usb_spi_sha256_start(struct sha256_ctx *ctx)
{
if (get_spi_bus_user() != SPI_BUS_USER_HASH) {
CPRINTS("%s: not enabled", __func__);
return EC_ERROR_BUSY;
}
- DCRYPTO_SHA256_init(ctx, 0);
+ SHA256_hw_init(ctx);
return EC_SUCCESS;
}
-int usb_spi_sha256_update(HASH_CTX *ctx, uint32_t offset, uint32_t size)
+int usb_spi_sha256_update(struct sha256_ctx *ctx, uint32_t offset,
+ uint32_t size)
{
uint8_t data[SPI_HASH_CHUNK_SIZE];
@@ -695,7 +697,7 @@ int usb_spi_sha256_update(HASH_CTX *ctx, uint32_t offset, uint32_t size)
return VENDOR_RC_READ_FLASH_FAIL;
}
/* Update hash */
- HASH_update(ctx, data, this_chunk);
+ SHA256_update(ctx, data, this_chunk);
/* Kick the watchdog every 128 chunks. */
if (((size / SPI_HASH_CHUNK_SIZE) % 128) == 127) {
@@ -709,12 +711,13 @@ int usb_spi_sha256_update(HASH_CTX *ctx, uint32_t offset, uint32_t size)
return EC_SUCCESS;
}
-void usb_spi_sha256_final(HASH_CTX *ctx, void *digest, size_t digest_size)
+void usb_spi_sha256_final(struct sha256_ctx *ctx, void *digest,
+ size_t digest_size)
{
size_t copy_size;
copy_size = MIN(digest_size, SHA256_DIGEST_SIZE);
- memcpy(digest, HASH_final(ctx), copy_size);
+ memcpy(digest, SHA256_final(ctx), copy_size);
if (copy_size < digest_size)
memset((uint8_t *)digest + copy_size, 0,
@@ -724,7 +727,7 @@ void usb_spi_sha256_final(HASH_CTX *ctx, void *digest, size_t digest_size)
static enum vendor_cmd_rc spi_hash_sha256(uint8_t *dest, uint32_t offset,
uint32_t size)
{
- HASH_CTX sha;
+ struct sha256_ctx sha;
CPRINTS("%s: 0x%x 0x%x", __func__, offset, size);
if (size > MAX_SPI_HASH_SIZE)
diff --git a/board/cr50/usb_spi_board.h b/board/cr50/usb_spi_board.h
new file mode 100644
index 0000000000..1c40f0814d
--- /dev/null
+++ b/board/cr50/usb_spi_board.h
@@ -0,0 +1,11 @@
+/* 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 "dcrypto.h"
+
+int usb_spi_sha256_start(struct sha256_ctx *ctx);
+int usb_spi_sha256_update(struct sha256_ctx *ctx, uint32_t offset,
+ uint32_t size);
+void usb_spi_sha256_final(struct sha256_ctx *ctx, void *digest,
+ size_t digest_size);
diff --git a/board/host/dcrypto.h b/board/host/dcrypto.h
index ce924e64fa..9c56674413 100644
--- a/board/host/dcrypto.h
+++ b/board/host/dcrypto.h
@@ -21,28 +21,13 @@
#ifndef CONFIG_DCRYPTO_MOCK
/* If not using the mock struct definitions, use the ones from Cr50. */
-#include "chip/g/dcrypto/dcrypto.h"
+#include "board/cr50/dcrypto/dcrypto.h"
#else /* defined(CONFIG_DCRYPTO_MOCK) */
-#include <sha256.h>
-
-#define HASH_CTX sha256_ctx
-
-/* Used as a replacement for declarations in cryptoc that are used by Cr50, but
- * add unnecessary complexity to the test code.
- */
-struct dcrypto_mock_ctx_t {
- struct HASH_CTX hash;
-};
-#define LITE_HMAC_CTX struct dcrypto_mock_ctx_t
-#define LITE_SHA256_CTX struct HASH_CTX
-
-void HASH_update(struct HASH_CTX *ctx, const void *data, size_t len);
-uint8_t *HASH_final(struct HASH_CTX *ctx);
+#include "board/cr50/dcrypto/hmacsha2.h"
#define AES256_BLOCK_CIPHER_KEY_SIZE 32
-#define SHA256_DIGEST_SIZE 32
enum dcrypto_appid {
RESERVED = 0,
@@ -55,11 +40,11 @@ enum dcrypto_appid {
/* This enum value should not exceed 7. */
};
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required);
+void SHA256_hw_init(struct sha256_ctx *ctx);
-void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len);
-const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_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);
diff --git a/builtin/endian.h b/builtin/endian.h
index 8a50cb4815..8ea6cb2da9 100644
--- a/builtin/endian.h
+++ b/builtin/endian.h
@@ -32,12 +32,12 @@ static inline uint64_t be64toh(uint64_t in)
return __builtin_bswap64(in);
}
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+
#define htobe16 be16toh
#define htobe32 be32toh
#define htobe64 be64toh
-#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
-
#ifdef __cplusplus
}
#endif
diff --git a/chip/g/usb_spi.h b/chip/g/usb_spi.h
index 2432dc2cd9..4cf38742af 100644
--- a/chip/g/usb_spi.h
+++ b/chip/g/usb_spi.h
@@ -8,7 +8,7 @@
/* USB SPI driver for Chrome EC */
#include "compile_time_macros.h"
-#include "cryptoc/sha256.h"
+#include "dcrypto.h"
#include "hooks.h"
#include "queue.h"
#include "queue_policies.h"
@@ -280,8 +280,4 @@ static inline bool usb_spi_shortcut_active(void) { return false; }
void enable_ap_spi_hash_shortcut(void);
void disable_ap_spi_hash_shortcut(void);
-int usb_spi_sha256_start(HASH_CTX *ctx);
-int usb_spi_sha256_update(HASH_CTX *ctx, uint32_t offset, uint32_t size);
-void usb_spi_sha256_final(HASH_CTX *ctx, void *digest, size_t digest_size);
-
#endif /* __CROS_EC_USB_SPI_H */
diff --git a/chip/host/build.mk b/chip/host/build.mk
index 8b7ab0efc2..0ea6027533 100644
--- a/chip/host/build.mk
+++ b/chip/host/build.mk
@@ -15,9 +15,16 @@ chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
endif
ifeq ($(CONFIG_DCRYPTO),y)
-CPPFLAGS += -I$(abspath ./chip/g)
-dirs-y += chip/g/dcrypto
+CPPFLAGS += -I$(abspath ./board/cr50)
+dirs-y += board/cr50/dcrypto
+LDFLAGS_EXTRA += -lcrypto
endif
+
+ifeq ($(CONFIG_DCRYPTO_MOCK),y)
+CPPFLAGS += -I$(abspath ./board/cr50)
+dirs-y += board/cr50/dcrypto
+endif
+
dirs-y += chip/host/dcrypto
chip-$(CONFIG_DCRYPTO)+= dcrypto/aes.o
@@ -26,4 +33,11 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/app_key.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/sha256.o
# Object files that can be shared with the Cr50 dcrypto implementation
-chip-$(CONFIG_DCRYPTO)+= ../g/dcrypto/hmac.o
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/hmac_sw.o
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/sha1.o
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/sha256.o
+chip-$(CONFIG_DCRYPTO)+= ../../board/cr50/dcrypto/hmac_drbg.o
+
+# We still want raw SHA & HMAC implementations for mocked dcrypto
+chip-$(CONFIG_DCRYPTO_MOCK)+= ../../board/cr50/dcrypto/sha256.o
+chip-$(CONFIG_DCRYPTO_MOCK)+= ../../board/cr50/dcrypto/hmac_sw.o \ No newline at end of file
diff --git a/chip/host/dcrypto/app_cipher.c b/chip/host/dcrypto/app_cipher.c
index 4c4809005c..a3ce4e3184 100644
--- a/chip/host/dcrypto/app_cipher.c
+++ b/chip/host/dcrypto/app_cipher.c
@@ -9,15 +9,15 @@
void app_compute_hash(const void *p_buf, size_t num_bytes, void *p_hash,
size_t hash_len)
{
- uint8_t digest[SHA256_DIGEST_SIZE];
+ struct sha256_digest digest;
/*
* Use the built in dcrypto engine to generate the sha1 hash of the
* buffer.
*/
- DCRYPTO_SHA256_hash(p_buf, num_bytes, digest);
+ SHA256_hw_hash(p_buf, num_bytes, &digest);
- memcpy(p_hash, digest, MIN(hash_len, sizeof(digest)));
+ memcpy(p_hash, digest.b8, MIN(hash_len, sizeof(digest)));
if (hash_len > sizeof(digest))
memset((uint8_t *)p_hash + sizeof(digest), 0,
diff --git a/chip/host/dcrypto/sha256.c b/chip/host/dcrypto/sha256.c
index 429588c8ac..1c9fda27c2 100644
--- a/chip/host/dcrypto/sha256.c
+++ b/chip/host/dcrypto/sha256.c
@@ -5,14 +5,26 @@
#include "dcrypto.h"
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
+void SHA256_hw_init(struct sha256_ctx *ctx)
{
- SHA256_init(ctx);
+ SHA256_sw_init(ctx);
}
-const uint8_t *DCRYPTO_SHA256_hash(const void *data, uint32_t n,
- uint8_t *digest)
+const struct sha256_digest *SHA256_hw_hash(const void *data, size_t n,
+ struct sha256_digest *digest)
{
- SHA256_hash(data, n, digest);
+ SHA256_sw_hash(data, n, digest);
return digest;
}
+
+void HMAC_SHA256_hw_init(struct hmac_sha256_ctx *ctx, const void *key,
+ size_t len)
+{
+ SHA256_hw_init(&ctx->hash);
+ HMAC_sw_init((union hmac_ctx *)ctx, key, len);
+}
+
+const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx)
+{
+ return HMAC_SHA256_final(ctx);
+}
diff --git a/common/ap_ro_integrity_check.c b/common/ap_ro_integrity_check.c
index f6592d1ca9..ea0456ad5a 100644
--- a/common/ap_ro_integrity_check.c
+++ b/common/ap_ro_integrity_check.c
@@ -12,11 +12,11 @@
#include "extension.h"
#include "flash.h"
#include "flash_info.h"
-#include "cryptoc/sha256.h"
#include "stddef.h"
#include "stdint.h"
#include "timer.h"
#include "usb_spi.h"
+#include "usb_spi_board.h"
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ##args)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ##args)
@@ -269,7 +269,7 @@ static enum ap_ro_check_vc_errors ap_ro_check_unsupported(int add_flash_event)
int validate_ap_ro(void)
{
uint32_t i;
- HASH_CTX ctx;
+ struct sha256_ctx ctx;
uint8_t digest[SHA256_DIGEST_SIZE];
int rv;
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 3433766b7c..b3b12e12a7 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -9,7 +9,6 @@
#include "byteorder.h"
#include "ccd_config.h"
#include "console.h"
-#include "cryptoc/sha256.h"
#include "dcrypto.h"
#include "extension.h"
#include "hooks.h"
@@ -239,17 +238,17 @@ static int raw_has_password(void)
*/
static void ccd_password_digest(uint8_t *digest, const char *password)
{
- HASH_CTX sha;
+ struct sha256_ctx sha;
uint8_t *unique_id;
int unique_id_len;
unique_id_len = system_get_chip_unique_id(&unique_id);
- DCRYPTO_SHA256_init(&sha, 0);
- HASH_update(&sha, config.password_salt, sizeof(config.password_salt));
- HASH_update(&sha, unique_id, unique_id_len);
- HASH_update(&sha, password, strlen(password));
- memcpy(digest, HASH_final(&sha), CCD_PASSWORD_DIGEST_SIZE);
+ SHA256_hw_init(&sha);
+ 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);
}
/**
diff --git a/common/pinweaver.c b/common/pinweaver.c
index 2cc4118c7d..7cea0ca1b0 100644
--- a/common/pinweaver.c
+++ b/common/pinweaver.c
@@ -159,17 +159,19 @@ static int create_merkle_tree(struct bits_per_level_t bits_per_level,
uint8_t temp_hash[PW_HASH_SIZE] = {};
uint8_t hx;
uint16_t kx;
- LITE_SHA256_CTX ctx;
+ struct sha256_ctx ctx;
merkle_tree->bits_per_level = bits_per_level;
merkle_tree->height = height;
/* Initialize the root hash. */
for (hx = 0; hx < height.v; ++hx) {
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx);
for (kx = 0; kx < fan_out; ++kx)
- HASH_update(&ctx, temp_hash, PW_HASH_SIZE);
- memcpy(temp_hash, HASH_final(&ctx), PW_HASH_SIZE);
+ HASH_update((union hash_ctx *)&ctx, temp_hash,
+ PW_HASH_SIZE);
+ memcpy(temp_hash, HASH_final((union hash_ctx *)&ctx),
+ PW_HASH_SIZE);
}
memcpy(merkle_tree->root, temp_hash, PW_HASH_SIZE);
@@ -179,24 +181,25 @@ 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,
- const struct imported_leaf_data_t *imported_leaf_data,
- uint8_t result[PW_HASH_SIZE])
+static void compute_hmac(const struct merkle_tree_t *merkle_tree,
+ const struct imported_leaf_data_t *imported_leaf_data,
+ uint8_t result[PW_HASH_SIZE])
{
- LITE_HMAC_CTX hmac;
+ struct hmac_sha256_ctx hmac;
- DCRYPTO_HMAC_SHA256_init(&hmac, merkle_tree->hmac_key,
+ HMAC_SHA256_hw_init(&hmac, merkle_tree->hmac_key,
sizeof(merkle_tree->hmac_key));
- HASH_update(&hmac.hash, imported_leaf_data->head,
+ /* 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(&hmac.hash, imported_leaf_data->iv,
+ HASH_update((union hash_ctx *)&hmac.hash, imported_leaf_data->iv,
sizeof(PW_WRAP_BLOCK_SIZE));
- HASH_update(&hmac.hash, imported_leaf_data->pub,
+ HASH_update((union hash_ctx *)&hmac.hash, imported_leaf_data->pub,
imported_leaf_data->head->pub_len);
- HASH_update(&hmac.hash, imported_leaf_data->cipher_text,
+ HASH_update((union hash_ctx *)&hmac.hash,
+ imported_leaf_data->cipher_text,
imported_leaf_data->head->sec_len);
- memcpy(result, DCRYPTO_HMAC_final(&hmac), PW_HASH_SIZE);
+ memcpy(result, HMAC_SHA256_hw_final(&hmac), PW_HASH_SIZE);
}
/* Computes the root hash for the specified path and child hash. */
@@ -1386,16 +1389,17 @@ void compute_hash(const uint8_t hashes[][PW_HASH_SIZE], uint16_t num_hashes,
const uint8_t child_hash[PW_HASH_SIZE],
uint8_t result[PW_HASH_SIZE])
{
- LITE_SHA256_CTX ctx;
+ struct sha256_ctx ctx;
- DCRYPTO_SHA256_init(&ctx, 0);
+ SHA256_hw_init(&ctx);
if (location.v > 0)
- HASH_update(&ctx, hashes[0], PW_HASH_SIZE * location.v);
- HASH_update(&ctx, child_hash, PW_HASH_SIZE);
+ HASH_update((union hash_ctx *)&ctx, hashes[0],
+ PW_HASH_SIZE * location.v);
+ HASH_update((union hash_ctx *)&ctx, child_hash, PW_HASH_SIZE);
if (location.v < num_hashes)
- HASH_update(&ctx, hashes[location.v],
+ HASH_update((union hash_ctx *)&ctx, hashes[location.v],
PW_HASH_SIZE * (num_hashes - location.v));
- memcpy(result, HASH_final(&ctx), PW_HASH_SIZE);
+ memcpy(result, HASH_final((union hash_ctx *)&ctx), PW_HASH_SIZE);
}
/* 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 7a34396acd..09539c537b 100644
--- a/common/rma_auth.c
+++ b/common/rma_auth.c
@@ -80,11 +80,11 @@ static void get_hmac_sha256(void *hmac_out, const uint8_t *secret,
size_t ch_size)
{
#ifdef USE_DCRYPTO
- LITE_HMAC_CTX hmac;
+ struct hmac_sha256_ctx hmac;
- DCRYPTO_HMAC_SHA256_init(&hmac, secret, secret_size);
- HASH_update(&hmac.hash, ch_ptr, ch_size);
- memcpy(hmac_out, DCRYPTO_HMAC_final(&hmac), 32);
+ HMAC_SHA256_hw_init(&hmac, secret, secret_size);
+ HMAC_SHA256_update(&hmac, ch_ptr, ch_size);
+ memcpy(hmac_out, HMAC_SHA256_hw_final(&hmac), 32);
#else
hmac_SHA256(hmac_out, secret, secret_size, ch_ptr, ch_size);
#endif
@@ -131,7 +131,7 @@ static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
* until the genreated bublic key has the compliant Y coordinate.
*/
while (1) {
- HASH_CTX sha;
+ struct sha256_ctx sha;
if (DCRYPTO_p256_key_from_bytes(&pk_x, &pk_y, &d, buf)) {
@@ -141,9 +141,9 @@ static void p256_get_pub_key_and_secret(uint8_t pub_key[P256_NBYTES],
}
/* Did not succeed, rehash the private key and try again. */
- DCRYPTO_SHA256_init(&sha, 0);
- HASH_update(&sha, buf, sizeof(buf));
- memcpy(buf, HASH_final(&sha), sizeof(buf));
+ SHA256_hw_init(&sha);
+ SHA256_update(&sha, buf, sizeof(buf));
+ memcpy(buf, SHA256_final(&sha), sizeof(buf));
}
/* X coordinate is passed to the server as the public key. */
diff --git a/common/u2f.c b/common/u2f.c
index 7a5b3e5945..c209be466e 100644
--- a/common/u2f.c
+++ b/common/u2f.c
@@ -8,10 +8,6 @@
#include "console.h"
#include "cryptoc/p256.h"
-#ifndef TEST_BUILD
-#include "cryptoc/sha256.h"
-#endif
-
#include "dcrypto.h"
#include "extension.h"
#include "system.h"
@@ -444,7 +440,7 @@ static enum vendor_cmd_rc u2f_attest(enum vendor_cmd_cc code, void *buf,
int verify_ret;
- struct HASH_CTX h_ctx;
+ struct sha256_ctx h_ctx;
struct drbg_ctx dr_ctx;
/* Data hash, and corresponding signature. */
@@ -471,9 +467,9 @@ static enum vendor_cmd_rc u2f_attest(enum vendor_cmd_cc code, void *buf,
return verify_ret;
/* Message signature */
- DCRYPTO_SHA256_init(&h_ctx, 0);
- HASH_update(&h_ctx, req->data, u2f_attest_format_size(req->format));
- p256_from_bin(HASH_final(&h_ctx), &h);
+ SHA256_hw_init(&h_ctx);
+ SHA256_update(&h_ctx, req->data, u2f_attest_format_size(req->format));
+ p256_from_bin(SHA256_final(&h_ctx)->b8, &h);
/* Derive G2F Attestation Key */
if (g2f_individual_keypair(&d, &pk_x, &pk_y)) {
@@ -509,7 +505,7 @@ int u2f_origin_user_keyhandle(const uint8_t *origin, const uint8_t *user,
const uint8_t *origin_seed,
struct u2f_key_handle *key_handle)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
struct u2f_state *state = get_state();
if (!state)
@@ -517,12 +513,13 @@ int u2f_origin_user_keyhandle(const uint8_t *origin, const uint8_t *user,
memcpy(key_handle->origin_seed, origin_seed, P256_NBYTES);
- DCRYPTO_HMAC_SHA256_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, origin, P256_NBYTES);
- HASH_update(&ctx.hash, user, P256_NBYTES);
- HASH_update(&ctx.hash, origin_seed, P256_NBYTES);
+ HMAC_SHA256_hw_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, origin, P256_NBYTES);
+ HMAC_SHA256_update(&ctx, user, P256_NBYTES);
+ HMAC_SHA256_update(&ctx, origin_seed, P256_NBYTES);
- memcpy(key_handle->hmac, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
+ memcpy(key_handle->hmac, HMAC_SHA256_hw_final(&ctx),
+ SHA256_DIGEST_SIZE);
return EC_SUCCESS;
}
@@ -532,7 +529,7 @@ int u2f_origin_user_versioned_keyhandle(
uint8_t version,
struct u2f_versioned_key_handle_header *key_handle_header)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
struct u2f_state *state = get_state();
if (!state)
@@ -541,13 +538,13 @@ int u2f_origin_user_versioned_keyhandle(
key_handle_header->version = version;
memcpy(key_handle_header->origin_seed, origin_seed, P256_NBYTES);
- DCRYPTO_HMAC_SHA256_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, origin, P256_NBYTES);
- HASH_update(&ctx.hash, user, P256_NBYTES);
- HASH_update(&ctx.hash, origin_seed, P256_NBYTES);
- HASH_update(&ctx.hash, &version, sizeof(key_handle_header->version));
+ HMAC_SHA256_hw_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, origin, P256_NBYTES);
+ HMAC_SHA256_update(&ctx, user, P256_NBYTES);
+ HMAC_SHA256_update(&ctx, origin_seed, P256_NBYTES);
+ HMAC_SHA256_update(&ctx, &version, sizeof(key_handle_header->version));
- memcpy(key_handle_header->kh_hmac, DCRYPTO_HMAC_final(&ctx),
+ memcpy(key_handle_header->kh_hmac, HMAC_SHA256_hw_final(&ctx),
SHA256_DIGEST_SIZE);
return EC_SUCCESS;
@@ -557,19 +554,20 @@ int u2f_authorization_hmac(const uint8_t *authorization_salt,
const struct u2f_versioned_key_handle_header *header,
const uint8_t *auth_time_secret_hash, uint8_t *hmac)
{
- LITE_HMAC_CTX ctx;
+ struct hmac_sha256_ctx ctx;
struct u2f_state *state = get_state();
if (!state)
return EC_ERROR_UNKNOWN;
- DCRYPTO_HMAC_SHA256_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
- HASH_update(&ctx.hash, authorization_salt, U2F_AUTHORIZATION_SALT_SIZE);
- HASH_update(&ctx.hash, (uint8_t *)header,
- sizeof(struct u2f_versioned_key_handle_header));
- HASH_update(&ctx.hash, auth_time_secret_hash, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_hw_init(&ctx, state->salt_kek, SHA256_DIGEST_SIZE);
+ HMAC_SHA256_update(&ctx, authorization_salt,
+ U2F_AUTHORIZATION_SALT_SIZE);
+ HMAC_SHA256_update(&ctx, (uint8_t *)header,
+ sizeof(struct u2f_versioned_key_handle_header));
+ HMAC_SHA256_update(&ctx, auth_time_secret_hash, SHA256_DIGEST_SIZE);
- memcpy(hmac, DCRYPTO_HMAC_final(&ctx), SHA256_DIGEST_SIZE);
+ memcpy(hmac, HMAC_SHA256_hw_final(&ctx), SHA256_DIGEST_SIZE);
return EC_SUCCESS;
}
diff --git a/fuzz/mem_hash_tree.cc b/fuzz/mem_hash_tree.cc
index 15c9de4142..88e85b87cf 100644
--- a/fuzz/mem_hash_tree.cc
+++ b/fuzz/mem_hash_tree.cc
@@ -72,23 +72,23 @@ void MemHashTree::UpdatePath(uint64_t label,
for (int level = 0; level < height_; ++level) {
shifted_parent_label &= ~child_index_mask;
- LITE_SHA256_CTX ctx;
- DCRYPTO_SHA256_init(&ctx, 1);
+ struct sha256_ctx ctx;
+ SHA256_hw_init(&ctx);
int empty_nodes = 0;
for (int index = 0; index < fan_out; ++index) {
auto itr =
hash_tree_.find(MaskedLabel(shifted_parent_label | index, level));
if (itr == hash_tree_.end()) {
- HASH_update(&ctx, empty_node_hashes_[level].data(),
+ SHA256_update(&ctx, empty_node_hashes_[level].data(),
empty_node_hashes_[level].size());
++empty_nodes;
} else {
- HASH_update(&ctx, itr->second.data(), itr->second.size());
+ SHA256_update(&ctx, itr->second.data(), itr->second.size());
}
}
shifted_parent_label = shifted_parent_label >> bits_per_level_;
- const uint8_t* temp = HASH_final(&ctx);
+ const uint8_t* temp = SHA256_final(&ctx)->b8;
std::copy(temp, temp + SHA256_DIGEST_SIZE, hash.begin());
MaskedLabel node_key(shifted_parent_label, level + 1);
if (empty_nodes == fan_out) {
@@ -118,12 +118,12 @@ 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) {
- LITE_SHA256_CTX ctx;
- DCRYPTO_SHA256_init(&ctx, 1);
+ struct sha256_ctx ctx;
+ SHA256_hw_init(&ctx);
for (int index = 0; index < fan_out; ++index) {
- HASH_update(&ctx, hash.data(), hash.size());
+ SHA256_update(&ctx, hash.data(), hash.size());
}
- const uint8_t* temp = HASH_final(&ctx);
+ const uint8_t* temp = SHA256_final(&ctx)->b8;
std::copy(temp, temp + SHA256_DIGEST_SIZE, hash.begin());
empty_node_hashes_[level] = hash;
}
diff --git a/test/pinweaver.c b/test/pinweaver.c
index 63a7e2e067..d6df149135 100644
--- a/test/pinweaver.c
+++ b/test/pinweaver.c
@@ -7,7 +7,6 @@
#include <dcrypto.h>
#include <nvmem_vars.h>
-#include <sha256.h>
#include <stdint.h>
#include <string.h>
#include <timer.h>
@@ -885,40 +884,40 @@ void rand_bytes(void *buffer, size_t len)
/* Mock implementations of Dcrypto functionality.
*/
-void HASH_update(struct HASH_CTX *ctx, const void *data, size_t len)
+void HASH_update(union hash_ctx *ctx, const void *data, size_t len)
{
if (MOCK_hash_update_cb)
MOCK_hash_update_cb(data, len);
if (ctx)
- SHA256_update(ctx, data, len);
+ SHA256_sw_update(&ctx->sha256, data, len);
}
-uint8_t *HASH_final(struct HASH_CTX *ctx)
+const union sha_digests *HASH_final(union hash_ctx *ctx)
{
++MOCK_DECRYPTO_release_counter;
- return SHA256_final(ctx);
+ return (union sha_digests *)SHA256_sw_final(&ctx->sha256);
}
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
+void SHA256_hw_init(struct sha256_ctx *ctx)
{
- SHA256_init(ctx);
+ SHA256_sw_init(ctx);
++MOCK_DECRYPTO_init_counter;
}
-void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len)
+void HMAC_SHA256_hw_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_init(&ctx->hash);
+ SHA256_sw_init(&ctx->hash);
++MOCK_DECRYPTO_init_counter;
}
-const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
+const struct sha256_digest *HMAC_SHA256_hw_final(struct hmac_sha256_ctx *ctx)
{
++MOCK_DECRYPTO_release_counter;
- return MOCK_hmac;
+ return (struct sha256_digest *)MOCK_hmac;
}
/* Perform a symmetric transformation of the data to simulate AES without
diff --git a/test/test_config.h b/test/test_config.h
index 33c65322c6..f7b222302f 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -190,7 +190,7 @@ enum nvmem_users { NVMEM_TPM = 0, NVMEM_CR50, NVMEM_NUM_USERS };
#endif
#ifdef TEST_U2F
-#define CONFIG_DCRYPTO_MOCK
+#define CONFIG_DCRYPTO
#define CONFIG_U2F
#define CC_EXTENSION CC_COMMAND
#endif
diff --git a/test/u2f.c b/test/u2f.c
index 56ae0cf65e..c74bc847a3 100644
--- a/test/u2f.c
+++ b/test/u2f.c
@@ -42,40 +42,6 @@ int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
return 1;
}
-void hmac_drbg_init_rfc6979(struct drbg_ctx *ctx,
- const p256_int *key,
- const p256_int *message)
-{
- memset(ctx, 0, sizeof(struct drbg_ctx));
-}
-
-void HASH_update(struct HASH_CTX *ctx, const void *data, size_t len)
-{
- if (ctx)
- SHA256_update(ctx, data, len);
-}
-
-uint8_t *HASH_final(struct HASH_CTX *ctx)
-{
- return SHA256_final(ctx);
-}
-
-void DCRYPTO_SHA256_init(LITE_SHA256_CTX *ctx, uint32_t sw_required)
-{
- SHA256_init(ctx);
-}
-
-void DCRYPTO_HMAC_SHA256_init(LITE_HMAC_CTX *ctx, const void *key,
- unsigned int len)
-{
- SHA256_init(&ctx->hash);
-}
-
-const uint8_t *DCRYPTO_HMAC_final(LITE_HMAC_CTX *ctx)
-{
- return SHA256_final(&ctx->hash);
-}
-
/******************************************************************************/
/* Mock implementations of U2F functionality.
*/