diff options
-rw-r--r-- | sha2.c | 383 | ||||
-rw-r--r-- | sha2.h | 28 | ||||
-rw-r--r-- | tests.c | 71 |
3 files changed, 457 insertions, 25 deletions
@@ -1,9 +1,9 @@ #include "sha2.h" -#include <string.h> // memcpy +#include <string.h> // memcpy() // extract bytes from uint32_t // (used in sha256_fini() and sha224_fini()) -#define WB(ctx, i) \ +#define E4(ctx, i) \ ((ctx)->h[i] >> 24) & 0xff, \ ((ctx)->h[i] >> 16) & 0xff, \ ((ctx)->h[i] >> 8) & 0xff, \ @@ -17,10 +17,10 @@ static const uint32_t SHA256_INIT[8] = { 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, }; -// round constants +// sha256 round constants // (first 32 bits of the fractional parts of the cube roots of the first // 64 primes 2..311): -static const uint32_t K[64] = { +static const uint32_t K256[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, @@ -36,13 +36,28 @@ static const uint32_t K[64] = { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, }; -// rotate right +// rotate right (uint32_t) // (src: https://blog.regehr.org/archives/1063) static inline uint32_t -rr(const uint32_t v, const size_t n) { +rr32(const uint32_t v, const size_t n) { return (v << (32 - n)) | (v >> n); } +#if 0 +#define rr32(v, n) (((v) << (32 - (n))) | ((v) >> (n))) +#endif /* 0 */ + +// rotate right (uint64_t) +// (src: https://blog.regehr.org/archives/1063) +static inline uint64_t +rr64(const uint64_t v, const size_t n) { + return (v << (64 - n)) | (v >> n); +} + +#if 0 +#define rr64(v, n) (((v) << (64 - (n))) | ((v) >> (n))) +#endif /* 0 */ + void sha256_init(sha256_t * const ctx) { ctx->buf_len = 0; ctx->num_bytes = 0; @@ -63,17 +78,17 @@ void sha256_init(sha256_t * const ctx) { w7 = w[(i) - 7], \ w15 = w[(i) - 15], \ w16 = w[(i) - 16], \ - s0 = rr(w15, 7) ^ rr(w15, 18) ^ (w15 >> 3), \ - s1 = rr(w2, 17) ^ rr(w2, 19) ^ (w2 >> 10); \ + s0 = rr32(w15, 7) ^ rr32(w15, 18) ^ (w15 >> 3), \ + s1 = rr32(w2, 17) ^ rr32(w2, 19) ^ (w2 >> 10); \ w[i] = w16 + s0 + w7 + s1; \ } while (0) // WC: compress word #define WC(i) do { \ - const uint32_t s1 = rr(hs[4], 6) ^ rr(hs[4], 11) ^ rr(hs[4], 25), \ + const uint32_t s1 = rr32(hs[4], 6) ^ rr32(hs[4], 11) ^ rr32(hs[4], 25), \ ch = (hs[4] & hs[5]) ^ ((~(hs[4])) & hs[6]), \ - t0 = hs[7] + s1 + ch + K[i] + w[i], \ - s0 = rr(hs[0], 2) ^ rr(hs[0], 13) ^ rr(hs[0], 22), \ + t0 = hs[7] + s1 + ch + K256[i] + w[i], \ + s0 = rr32(hs[0], 2) ^ rr32(hs[0], 13) ^ rr32(hs[0], 22), \ mj = (hs[0] & hs[1]) ^ (hs[0] & hs[2]) ^ (hs[1] & hs[2]), \ t1 = s0 + mj; \ \ @@ -109,8 +124,8 @@ sha256_block(sha256_t * const ctx) { // w7 = w[i - 7], // w15 = w[i - 15], // w16 = w[i - 16], - // s0 = rr(w15, 7) ^ rr(w15, 18) ^ (w15 >> 3), - // s1 = rr(w2, 17) ^ rr(w2, 19) ^ (w2 >> 10); + // s0 = rr32(w15, 7) ^ rr32(w15, 18) ^ (w15 >> 3), + // s1 = rr32(w2, 17) ^ rr32(w2, 19) ^ (w2 >> 10); // w[i] = w16 + s0 + w7 + s1; // } // @@ -158,10 +173,10 @@ sha256_block(sha256_t * const ctx) { // a := temp1 + temp2 // // for (size_t i = 0; i < 64; i++) { - // const uint32_t s1 = rr(hs[4], 6) ^ rr(hs[4], 11) ^ rr(hs[4], 25), + // const uint32_t s1 = rr32(hs[4], 6) ^ rr32(hs[4], 11) ^ rr32(hs[4], 25), // ch = (hs[4] & hs[5]) ^ ((~(hs[4])) & hs[6]), - // t0 = hs[7] + s1 + ch + K[i] + w[i], - // s0 = rr(hs[0], 2) ^ rr(hs[0], 13) ^ rr(hs[0], 22), + // t0 = hs[7] + s1 + ch + K256[i] + w[i], + // s0 = rr32(hs[0], 2) ^ rr32(hs[0], 13) ^ rr32(hs[0], 22), // mj = (hs[0] & hs[1]) ^ (hs[0] & hs[2]) ^ (hs[1] & hs[2]), // t1 = s0 + mj; @@ -208,8 +223,6 @@ sha256_block(sha256_t * const ctx) { #undef WE #undef WC -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - void sha256_push( sha256_t * const ctx, const uint8_t * const src, @@ -264,8 +277,8 @@ sha256_push_u64( sha256_push(ctx, buf, sizeof(buf)); } -// end of stream padding -static const uint8_t PADDING[65] = { +// sha256 end of stream padding +static const uint8_t SHA256_PADDING[65] = { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -281,7 +294,7 @@ sha256_push_footer( const size_t pad_len = (65 - ((num_bytes + 1 + 8) % 64)); // push padding - sha256_push(ctx, PADDING, pad_len); + sha256_push(ctx, SHA256_PADDING, pad_len); // push length (in bits) sha256_push_u64(ctx, num_bytes * 8); @@ -296,8 +309,8 @@ void sha256_fini( // extract hash const uint8_t hash[32] = { - WB(ctx, 0), WB(ctx, 1), WB(ctx, 2), WB(ctx, 3), - WB(ctx, 4), WB(ctx, 5), WB(ctx, 6), WB(ctx, 7), + E4(ctx, 0), E4(ctx, 1), E4(ctx, 2), E4(ctx, 3), + E4(ctx, 4), E4(ctx, 5), E4(ctx, 6), E4(ctx, 7), }; memcpy(out, hash, sizeof(hash)); @@ -348,8 +361,8 @@ void sha224_fini( // extract hash const uint8_t hash[28] = { - WB(ctx, 0), WB(ctx, 1), WB(ctx, 2), WB(ctx, 3), - WB(ctx, 4), WB(ctx, 5), WB(ctx, 6), + E4(ctx, 0), E4(ctx, 1), E4(ctx, 2), E4(ctx, 3), + E4(ctx, 4), E4(ctx, 5), E4(ctx, 6), }; memcpy(out, hash, sizeof(hash)); @@ -365,3 +378,323 @@ void sha224( sha224_push(&ctx, src, src_len); sha224_fini(&ctx, dst); } + +// extract bytes from uint64_t +// (used in sha512_fini() and sha384_fini()) +#define E8(ctx, i) \ + ((ctx)->h[i] >> 56) & 0xff, \ + ((ctx)->h[i] >> 48) & 0xff, \ + ((ctx)->h[i] >> 40) & 0xff, \ + ((ctx)->h[i] >> 32) & 0xff, \ + ((ctx)->h[i] >> 24) & 0xff, \ + ((ctx)->h[i] >> 16) & 0xff, \ + ((ctx)->h[i] >> 8) & 0xff, \ + ((ctx)->h[i]) & 0xff + +// sha512 initial hash values +// (first 64 bits of the fractional parts of the square roots of the +// first 8 primes 2..19): +static const uint64_t SHA512_INIT[8] = { + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, +}; + +// sha512 round constants +// (first 64 bits of the fractional parts of the cube roots of the first +// 80 primes [2..409]): +static const uint64_t K512[80] = { + 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, + 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, + 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, + 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, + 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, + 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, + 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, + 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, + 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, + 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, + 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, + 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, + 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, + 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, + 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, + 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, + 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, + 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, + 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, + 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, + 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, + 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, + 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, + 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, +}; + +void sha512_init(sha512_t * const ctx) { + ctx->buf_len = 0; + ctx->num_bytes = 0; + memcpy(ctx->h, SHA512_INIT, sizeof(SHA512_INIT)); +} + +// WI64: decode buffer data as 64-bit words (used for the first 16 words) +#define WI64(i) ( \ + (((uint64_t) ctx->buf[8 * (i) + 0]) << 56) | \ + (((uint64_t) ctx->buf[8 * (i) + 1]) << 48) | \ + (((uint64_t) ctx->buf[8 * (i) + 2]) << 40) | \ + (((uint64_t) ctx->buf[8 * (i) + 3]) << 32) | \ + (((uint64_t) ctx->buf[8 * (i) + 4]) << 24) | \ + (((uint64_t) ctx->buf[8 * (i) + 5]) << 16) | \ + (((uint64_t) ctx->buf[8 * (i) + 6]) << 8) | \ + ((uint64_t) ctx->buf[8 * (i) + 7]) \ +) + +// WE64: expand first 16 buffer words into remaining 64 words +#define WE64(i) do { \ + const uint64_t w2 = w[(i) - 2], \ + w7 = w[(i) - 7], \ + w15 = w[(i) - 15], \ + w16 = w[(i) - 16], \ + s0 = rr64(w15, 1) ^ rr64(w15, 8) ^ (w15 >> 7), \ + s1 = rr64(w2, 19) ^ rr64(w2, 61) ^ (w2 >> 6); \ + w[i] = w16 + s0 + w7 + s1; \ +} while (0) + +// WC: compress word +#define WC64(i) do { \ + const uint64_t s1 = rr64(hs[4], 14) ^ rr64(hs[4], 18) ^ rr64(hs[4], 41), \ + ch = (hs[4] & hs[5]) ^ ((~(hs[4])) & hs[6]), \ + t0 = hs[7] + s1 + ch + K512[i] + w[i], \ + s0 = rr64(hs[0], 28) ^ rr64(hs[0], 34) ^ rr64(hs[0], 39), \ + mj = (hs[0] & hs[1]) ^ (hs[0] & hs[2]) ^ (hs[1] & hs[2]), \ + t1 = s0 + mj; \ +\ + hs[7] = hs[6]; \ + hs[6] = hs[5]; \ + hs[5] = hs[4]; \ + hs[4] = hs[3] + t0; \ + hs[3] = hs[2]; \ + hs[2] = hs[1]; \ + hs[1] = hs[0]; \ + hs[0] = t0 + t1; \ +} while (0) + +static void +sha512_block(sha512_t * const ctx) { + // init first 16 words from buffer + uint64_t w[80] = { + WI64(0), WI64(1), WI64(2), WI64(3), + WI64(4), WI64(5), WI64(6), WI64(7), + WI64(8), WI64(9), WI64(10), WI64(11), + WI64(12), WI64(13), WI64(14), WI64(15), + 0, + }; + + // Extend the first 16 words into the remaining 64 words w[16..80] of + // the message schedule array + for (size_t i = 16; i < 80; i++) { + WE64(i); + } + + // Initialize working variables to current hash value + uint64_t hs[8] = { + ctx->h[0], ctx->h[1], ctx->h[2], ctx->h[3], + ctx->h[4], ctx->h[5], ctx->h[6], ctx->h[7], + }; + + // Compression function main loop + // + // partially unrolled: + for (size_t i = 0; i < 80; i += 16) { + WC64(i + 0); WC64(i + 1); WC64(i + 2); WC64(i + 3); + WC64(i + 4); WC64(i + 5); WC64(i + 6); WC64(i + 7); + WC64(i + 8); WC64(i + 9); WC64(i + 10); WC64(i + 11); + WC64(i + 12); WC64(i + 13); WC64(i + 14); WC64(i + 15); + } + + // Add the compressed chunk to the current hash value + ctx->h[0] += hs[0]; + ctx->h[1] += hs[1]; + ctx->h[2] += hs[2]; + ctx->h[3] += hs[3]; + ctx->h[4] += hs[4]; + ctx->h[5] += hs[5]; + ctx->h[6] += hs[6]; + ctx->h[7] += hs[7]; +} + +#undef WI64 +#undef WE64 +#undef WC64 + +void sha512_push( + sha512_t * const ctx, + const uint8_t * const src, + const size_t src_len +) { + const size_t buf_left = 128 - ctx->buf_len; + + if (src_len >= buf_left) { + // fill remaining buffer + memcpy(ctx->buf + ctx->buf_len, src, buf_left); + sha512_block(ctx); + ctx->buf_len = 0; + + const size_t new_src_len = src_len - buf_left; + const size_t num_blocks = new_src_len / 128; + + // process chunks + for (size_t i = 0; i < num_blocks; i++) { + memcpy(ctx->buf, src + buf_left + (128 * i), 128); + sha512_block(ctx); + } + + // copy remaining bytes to buffer + const size_t new_buf_len = (new_src_len - 128 * num_blocks); + memcpy(ctx->buf, src + buf_left + (128 * num_blocks), new_buf_len); + ctx->buf_len = new_buf_len; + } else { + memcpy(ctx->buf + ctx->buf_len, src, src_len); + ctx->buf_len += src_len; + } + + // update byte count + ctx->num_bytes += src_len; +} + +static void +sha512_push_u128( + sha512_t * const ctx, + const uint64_t hi, + const uint64_t lo +) { + const uint8_t buf[16] = { + ((hi >> 56) & 0xff), + ((hi >> 48) & 0xff), + ((hi >> 40) & 0xff), + ((hi >> 32) & 0xff), + ((hi >> 24) & 0xff), + ((hi >> 16) & 0xff), + ((hi >> 8) & 0xff), + ((hi) & 0xff), + ((lo >> 56) & 0xff), + ((lo >> 48) & 0xff), + ((lo >> 40) & 0xff), + ((lo >> 32) & 0xff), + ((lo >> 24) & 0xff), + ((lo >> 16) & 0xff), + ((lo >> 8) & 0xff), + ((lo) & 0xff), + }; + + sha512_push(ctx, buf, sizeof(buf)); +} + +// sha512 end of stream padding +static const uint8_t SHA512_PADDING[129] = { + 128, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void +sha512_push_footer( + sha512_t * const ctx +) { + const uint64_t num_bytes = ctx->num_bytes; + const size_t pad_len = (129 - ((num_bytes + 1 + 16) % 128)); + + // push padding + sha512_push(ctx, SHA512_PADDING, pad_len); + + // push length (in bits) + sha512_push_u128(ctx, 0, num_bytes * 8); +} + +void sha512_fini( + sha512_t * const ctx, + uint8_t * const out +) { + // push footer + sha512_push_footer(ctx); + + // extract hash + const uint8_t hash[64] = { + E8(ctx, 0), E8(ctx, 1), E8(ctx, 2), E8(ctx, 3), + E8(ctx, 4), E8(ctx, 5), E8(ctx, 6), E8(ctx, 7), + }; + + memcpy(out, hash, sizeof(hash)); +} + +void sha512( + const uint8_t * const src, + const size_t src_len, + uint8_t * const dst +) { + sha512_t ctx; + sha512_init(&ctx); + sha512_push(&ctx, src, src_len); + sha512_fini(&ctx, dst); +} + +// sha384 initial hash values +// (the second 64 bits of the fractional parts of the square roots of +// the 9th through 16th primes 23..53) +static const uint64_t SHA384_INIT[8] = { + 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, + 0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511, + 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4 +}; + +void sha384_init(sha384_t * const ctx) { + ctx->ctx.buf_len = 0; + ctx->ctx.num_bytes = 0; + memcpy(ctx->ctx.h, SHA384_INIT, sizeof(SHA384_INIT)); +} + +void sha384_push( + sha384_t * const sha384_ctx, + const uint8_t * const src, + const size_t src_len +) { + sha512_t * const ctx = (sha512_t * const) sha384_ctx; + sha512_push(ctx, src, src_len); +} + +void sha384_fini( + sha384_t * const sha384_ctx, + uint8_t * const out +) { + sha512_t * const ctx = (sha512_t * const) sha384_ctx; + + // push footer + sha512_push_footer(ctx); + + // extract hash + const uint8_t hash[56] = { + E8(ctx, 0), E8(ctx, 1), E8(ctx, 2), E8(ctx, 3), + E8(ctx, 4), E8(ctx, 5), E8(ctx, 6), + }; + + memcpy(out, hash, sizeof(hash)); +} + +void sha384( + const uint8_t * const src, + const size_t src_len, + uint8_t * const dst +) { + sha384_t ctx; + sha384_init(&ctx); + sha384_push(&ctx, src, src_len); + sha384_fini(&ctx, dst); +} @@ -31,4 +31,32 @@ void sha224_push(sha224_t * const, const uint8_t *, size_t); void sha224_fini(sha224_t * const, uint8_t * const); void sha224(const uint8_t * const, const size_t, uint8_t * const); + +#define SHA512_HASH_SIZE 64 + +typedef struct { + uint8_t buf[128]; + size_t buf_len; + + uint64_t h[8]; + + uint64_t num_bytes; +} sha512_t; + +void sha512_init(sha512_t * const); +void sha512_push(sha512_t * const, const uint8_t *, size_t); +void sha512_fini(sha512_t * const, uint8_t * const); +void sha512(const uint8_t * const, const size_t, uint8_t * const); + +#define SHA384_HASH_SIZE 48 + +typedef struct { + sha512_t ctx; +} sha384_t; + +void sha384_init(sha384_t * const); +void sha384_push(sha384_t * const, const uint8_t *, size_t); +void sha384_fini(sha384_t * const, uint8_t * const); +void sha384(const uint8_t * const, const size_t, uint8_t * const); + #endif /* SHA2_H_ */ @@ -81,14 +81,85 @@ static const struct { }, }}; +static const struct { + const char * const s; + const uint8_t h[SHA512_HASH_SIZE]; +} SHA512_TESTS[] = {{ + .s = "", + .h = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, + 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, + 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, + 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, + 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, + 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e, + }, +}, { + .s = "abc", + .h = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, + 0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, + 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, + 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, + 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, + 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f, + }, +}, { + .s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .h = { + 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, 0x0c, 0xed, 0x7b, + 0xeb, 0x8e, 0x08, 0xa4, 0x16, 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, + 0x28, 0xa8, 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, 0x96, + 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, 0xaa, 0x1d, 0x3b, 0xea, + 0x57, 0x78, 0x9c, 0xa0, 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, + 0x03, 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45, + }, +}}; + +static const struct { + const char * const s; + const uint8_t h[SHA384_HASH_SIZE]; +} SHA384_TESTS[] = {{ + .s = "", + .h = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, + 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, + 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, + 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, + 0x48, 0x98, 0xb9, 0x5b, + }, +}, { + .s = "abc", + .h = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, + 0x69, 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, + 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, + 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, + 0x34, 0xc8, 0x25, 0xa7, + }, +}, { + .s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + .h = { + 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, 0x37, 0x07, 0xa6, + 0x5b, 0x1b, 0x47, 0x09, 0x39, 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, + 0x05, 0xab, 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, 0xb0, + 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, 0x5f, 0xe9, 0x5b, 0x1f, + 0xe3, 0xc8, 0x45, 0x2b, + }, +}}; + DEF_TEST_FUNC(256) DEF_TEST_FUNC(224) +DEF_TEST_FUNC(512) +DEF_TEST_FUNC(384) unsigned int run_tests(test_fail_cb_t on_fail) { unsigned int r = 0; r += run_sha256_tests(on_fail); r += run_sha224_tests(on_fail); + r += run_sha512_tests(on_fail); + r += run_sha384_tests(on_fail); return r; } |