aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-05-31 23:40:17 -0400
committerRob Austein <sra@hactrn.net>2016-05-31 23:40:17 -0400
commit00f3181d2411068353efd6a5aadb3e70f064db2a (patch)
treed718597a46fc3484eb41f7222b48a48243edcf84
parentc51fa2770ba45837cf3af8576c813b7934cb709f (diff)
SHA-224 driver and soft core.
-rw-r--r--hal.h4
-rw-r--r--hash.c55
-rw-r--r--tests/test-hash.c15
-rw-r--r--verilog_constants.h14
4 files changed, 65 insertions, 23 deletions
diff --git a/hal.h b/hal.h
index f62c89e..12ed579 100644
--- a/hal.h
+++ b/hal.h
@@ -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];
diff --git a/hash.c b/hash.c
index 1c82af5..225a99d 100644
--- a/hash.c
+++ b/hash.c
@@ -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.