diff options
-rw-r--r-- | hal.h | 4 | ||||
-rw-r--r-- | hash.c | 55 | ||||
-rw-r--r-- | tests/test-hash.c | 15 | ||||
-rw-r--r-- | verilog_constants.h | 14 |
4 files changed, 65 insertions, 23 deletions
@@ -79,7 +79,7 @@ #define SHA1_VERSION "0.50" #define SHA256_NAME "sha2-256" -#define SHA256_VERSION "0.81" +#define SHA256_VERSION "1.80" #define SHA512_NAME "sha2-512" #define SHA512_VERSION "0.80" @@ -233,6 +233,7 @@ typedef struct hal_hash_driver hal_hash_driver_t; typedef enum { hal_digest_algorithm_none, hal_digest_algorithm_sha1, + hal_digest_algorithm_sha224, hal_digest_algorithm_sha256, hal_digest_algorithm_sha512_224, hal_digest_algorithm_sha512_256, @@ -266,6 +267,7 @@ typedef struct hal_hmac_state hal_hmac_state_t; */ extern const hal_hash_descriptor_t hal_hash_sha1[1]; +extern const hal_hash_descriptor_t hal_hash_sha224[1]; extern const hal_hash_descriptor_t hal_hash_sha256[1]; extern const hal_hash_descriptor_t hal_hash_sha512_224[1]; extern const hal_hash_descriptor_t hal_hash_sha512_256[1]; @@ -136,24 +136,28 @@ static const hal_hash_driver_t sha1_driver = { SHA1_LENGTH_LEN, SHA1_ADDR_BLOCK, SHA1_ADDR_DIGEST, 0, sw_hash_core_sha1, sizeof(uint32_t) }; +static const hal_hash_driver_t sha224_driver = { + SHA256_LENGTH_LEN, SHA256_ADDR_BLOCK, SHA256_ADDR_DIGEST, SHA256_MODE_SHA_224, sw_hash_core_sha256, sizeof(uint32_t) +}; + static const hal_hash_driver_t sha256_driver = { - SHA256_LENGTH_LEN, SHA256_ADDR_BLOCK, SHA256_ADDR_DIGEST, 0, sw_hash_core_sha256, sizeof(uint32_t) + SHA256_LENGTH_LEN, SHA256_ADDR_BLOCK, SHA256_ADDR_DIGEST, SHA256_MODE_SHA_256, sw_hash_core_sha256, sizeof(uint32_t) }; static const hal_hash_driver_t sha512_224_driver = { - SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, MODE_SHA_512_224, sw_hash_core_sha512, sizeof(uint64_t) + SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, SHA512_MODE_SHA_512_224, sw_hash_core_sha512, sizeof(uint64_t) }; static const hal_hash_driver_t sha512_256_driver = { - SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, MODE_SHA_512_256, sw_hash_core_sha512, sizeof(uint64_t) + SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, SHA512_MODE_SHA_512_256, sw_hash_core_sha512, sizeof(uint64_t) }; static const hal_hash_driver_t sha384_driver = { - SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, MODE_SHA_384, sw_hash_core_sha512, sizeof(uint64_t) + SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, SHA512_MODE_SHA_384, sw_hash_core_sha512, sizeof(uint64_t) }; static const hal_hash_driver_t sha512_driver = { - SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, MODE_SHA_512, sw_hash_core_sha512, sizeof(uint64_t) + SHA512_LENGTH_LEN, SHA512_ADDR_BLOCK, SHA512_ADDR_DIGEST, SHA512_MODE_SHA_512, sw_hash_core_sha512, sizeof(uint64_t) }; /* @@ -175,6 +179,7 @@ static const uint8_t dalgid_sha256[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00 }, dalgid_sha384[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00 }, dalgid_sha512[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00 }, + dalgid_sha224[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00 }, dalgid_sha512_224[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00 }, dalgid_sha512_256[] = { 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00 }; @@ -193,6 +198,14 @@ const hal_hash_descriptor_t hal_hash_sha1[1] = {{ &sha1_driver, SHA1_NAME, 0 }}; +const hal_hash_descriptor_t hal_hash_sha224[1] = {{ + hal_digest_algorithm_sha256, + SHA256_BLOCK_LEN, SHA224_DIGEST_LEN, + sizeof(hal_hash_state_t), sizeof(hal_hmac_state_t), + dalgid_sha224, sizeof(dalgid_sha224), + &sha224_driver, SHA256_NAME, 1 +}}; + const hal_hash_descriptor_t hal_hash_sha256[1] = {{ hal_digest_algorithm_sha256, SHA256_BLOCK_LEN, SHA256_DIGEST_LEN, @@ -1000,22 +1013,30 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state) } /* - * Software implementation of SHA-256 block algorithm; doesn't support truncated variants because - * the Cryptech Verilog implementation doesn't. + * Software implementation of SHA-256 block algorithm, including support for same truncated variants + * that the Cryptech Verilog SHA-256 core supports. */ static hal_error_t sw_hash_core_sha256(hal_hash_state_t *state) { - static const uint32_t iv[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL}; + static const uint32_t sha224_iv[8] = {0xC1059ED8UL, 0x367CD507UL, 0x3070DD17UL, 0xF70E5939UL, + 0xFFC00B31UL, 0x68581511UL, 0x64F98FA7UL, 0xBEFA4FA4UL}; + + static const uint32_t sha256_iv[8] = {0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL}; if (state == NULL) return HAL_ERROR_BAD_ARGUMENTS; uint32_t *H = (uint32_t *) state->core_state, S[8], W[64]; - if (state->block_count == 0) - memcpy(H, iv, sizeof(iv)); + if (state->block_count == 0) { + switch (state->driver_ctrl_mode & SHA256_MODE_MASK) { + case SHA256_MODE_SHA_224: memcpy(H, sha224_iv, sizeof(sha224_iv)); break; + case SHA256_MODE_SHA_256: memcpy(H, sha256_iv, sizeof(sha256_iv)); break; + default: return HAL_ERROR_IMPOSSIBLE; + } + } memcpy(S, H, sizeof(S)); @@ -1067,12 +1088,12 @@ static hal_error_t sw_hash_core_sha512(hal_hash_state_t *state) uint64_t *H = (uint64_t *) state->core_state, S[8], W[80]; if (state->block_count == 0) { - switch (state->driver->ctrl_mode & MODE_SHA_MASK) { - case MODE_SHA_512_224: memcpy(H, sha512_224_iv, sizeof(sha512_224_iv)); break; - case MODE_SHA_512_256: memcpy(H, sha512_256_iv, sizeof(sha512_256_iv)); break; - case MODE_SHA_384: memcpy(H, sha384_iv, sizeof(sha384_iv)); break; - case MODE_SHA_512: memcpy(H, sha512_iv, sizeof(sha512_iv)); break; - default: return HAL_ERROR_IMPOSSIBLE; + switch (state->driver->ctrl_mode & SHA512_MODE_MASK) { + case SHA512_MODE_SHA_512_224: memcpy(H, sha512_224_iv, sizeof(sha512_224_iv)); break; + case SHA512_MODE_SHA_512_256: memcpy(H, sha512_256_iv, sizeof(sha512_256_iv)); break; + case SHA512_MODE_SHA_384: memcpy(H, sha384_iv, sizeof(sha384_iv)); break; + case SHA512_MODE_SHA_512: memcpy(H, sha512_iv, sizeof(sha512_iv)); break; + default: return HAL_ERROR_IMPOSSIBLE; } } diff --git a/tests/test-hash.c b/tests/test-hash.c index e8c6a01..65ddf15 100644 --- a/tests/test-hash.c +++ b/tests/test-hash.c @@ -53,6 +53,12 @@ static const uint8_t sha1_single_digest[] = { /* 20 bytes */ 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d }; +static const uint8_t sha224_single_digest[] = { /* 28 bytes */ + 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, 0x86, 0x42, 0xa4, 0x77, + 0xbd, 0xa2, 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, + 0xe3, 0x6c, 0x9d, 0xa7 +}; + static const uint8_t sha256_single_digest[] = { /* 32 bytes */ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, @@ -73,6 +79,12 @@ static const uint8_t sha1_double_digest[] = { /* 20 bytes */ 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 }; +static const uint8_t sha224_double_digest[] = { /* 28 bytes */ + 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, 0x5d, 0xba, 0x5d, 0xa1, + 0xfd, 0x89, 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, + 0x52, 0x52, 0x25, 0x25 +}; + static const uint8_t sha256_double_digest[] = { /* 32 bytes */ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, @@ -655,6 +667,9 @@ int main (int argc, char *argv[]) ok &= test_hash(sha1_core, hal_hash_sha1, nist_512_single, sha1_single_digest, "SHA-1 single block"); ok &= test_hash(sha1_core, hal_hash_sha1, nist_512_double, sha1_double_digest, "SHA-1 double block"); + ok &= test_hash(sha256_core, hal_hash_sha224, nist_512_single, sha224_single_digest, "SHA-224 single block"); + ok &= test_hash(sha256_core, hal_hash_sha224, nist_512_double, sha224_double_digest, "SHA-224 double block"); + ok &= test_hash(sha256_core, hal_hash_sha256, nist_512_single, sha256_single_digest, "SHA-256 single block"); ok &= test_hash(sha256_core, hal_hash_sha256, nist_512_double, sha256_double_digest, "SHA-256 double block"); diff --git a/verilog_constants.h b/verilog_constants.h index 43b7a0c..085b973 100644 --- a/verilog_constants.h +++ b/verilog_constants.h @@ -67,7 +67,11 @@ #define SHA256_ADDR_DIGEST (0x20) #define SHA256_BLOCK_LEN bitsToBytes(512) #define SHA256_LENGTH_LEN bitsToBytes(64) +#define SHA224_DIGEST_LEN bitsToBytes(224) #define SHA256_DIGEST_LEN bitsToBytes(256) +#define SHA256_MODE_SHA_224 (0 << 2) +#define SHA256_MODE_SHA_256 (1 << 2) +#define SHA256_MODE_MASK (1 << 2) #define SHA512_ADDR_BLOCK (0x10) #define SHA512_ADDR_DIGEST (0x40) @@ -77,11 +81,11 @@ #define SHA512_256_DIGEST_LEN bitsToBytes(256) #define SHA384_DIGEST_LEN bitsToBytes(384) #define SHA512_DIGEST_LEN bitsToBytes(512) -#define MODE_SHA_512_224 (0 << 2) -#define MODE_SHA_512_256 (1 << 2) -#define MODE_SHA_384 (2 << 2) -#define MODE_SHA_512 (3 << 2) -#define MODE_SHA_MASK (3 << 2) +#define SHA512_MODE_SHA_512_224 (0 << 2) +#define SHA512_MODE_SHA_512_256 (1 << 2) +#define SHA512_MODE_SHA_384 (2 << 2) +#define SHA512_MODE_SHA_512 (3 << 2) +#define SHA512_MODE_MASK (3 << 2) /* * RNG cores. |