diff options
author | Igor Gnatenko <ignatenko@src.gnome.org> | 2016-09-26 19:40:22 +0200 |
---|---|---|
committer | Igor Gnatenko <ignatenko@src.gnome.org> | 2016-09-26 19:47:44 +0200 |
commit | 614620249f0eed4773da4785fd61712eef0c39ed (patch) | |
tree | c457e5afc937730c324e97699025db3bae27606e /glib/gchecksum.c | |
parent | 34751ad17ac8e73558c530d15a3398273a5f4f67 (diff) | |
download | glib-ignatenko/sha384.tar.gz |
gchecksum: Adds SHA-384 supportignatenko/sha384
Signed-off-by: Igor Gnatenko <ignatenko@src.gnome.org>
Diffstat (limited to 'glib/gchecksum.c')
-rw-r--r-- | glib/gchecksum.c | 129 |
1 files changed, 92 insertions, 37 deletions
diff --git a/glib/gchecksum.c b/glib/gchecksum.c index 9107e78b5..400ccab66 100644 --- a/glib/gchecksum.c +++ b/glib/gchecksum.c @@ -100,14 +100,16 @@ typedef struct guchar digest[SHA256_DIGEST_LEN]; } Sha256sum; -#define SHA512_BLOCK_LEN 128 /* 1024 bits message block */ +/* SHA2 is common thing for SHA-384, SHA-512, SHA-512/224 and SHA-512/256 */ +#define SHA2_BLOCK_LEN 128 /* 1024 bits message block */ +#define SHA384_DIGEST_LEN 48 #define SHA512_DIGEST_LEN 64 typedef struct { guint64 H[8]; - guint8 block[SHA512_BLOCK_LEN]; + guint8 block[SHA2_BLOCK_LEN]; guint8 block_len; guint64 data_len[2]; @@ -1084,16 +1086,17 @@ sha256_sum_digest (Sha256sum *sha256, } /* - * SHA-512 Checksum + * SHA-384, SHA-512, SHA-512/224 and SHA-512/256 Checksums * - * Implemented following FIPS-180-2 standard at - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf. + * Implemented following FIPS-180-4 standard at + * http://csrc.nist.gov/publications/fips/fips180-4/fips180-4.pdf. * References in the form [§x.y.z] map to sections in that document. * - * Author: Eduardo Lima Mitev <elima@igalia.com> + * Author(s): Eduardo Lima Mitev <elima@igalia.com> + * Igor Gnatenko <ignatenko@src.gnome.org> */ -/* SHA-384 and SHA-512 functions [§4.1.3] */ +/* SHA-384, SHA-512, SHA-512/224 and SHA-512/256 functions [§4.1.3] */ #define Ch(x,y,z) ((x & y) ^ (~x & z)) #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) #define SHR(n,x) (x >> n) @@ -1113,27 +1116,8 @@ sha256_sum_digest (Sha256sum *sha256, (b)[(i) + 6] = (guint8) (n >> 8); \ (b)[(i) + 7] = (guint8) (n ); } G_STMT_END -static void -sha512_sum_init (Sha512sum *sha512) -{ - /* Initial Hash Value [§5.3.4] */ - sha512->H[0] = 0x6a09e667f3bcc908; - sha512->H[1] = 0xbb67ae8584caa73b; - sha512->H[2] = 0x3c6ef372fe94f82b; - sha512->H[3] = 0xa54ff53a5f1d36f1; - sha512->H[4] = 0x510e527fade682d1; - sha512->H[5] = 0x9b05688c2b3e6c1f; - sha512->H[6] = 0x1f83d9abfb41bd6b; - sha512->H[7] = 0x5be0cd19137e2179; - - sha512->block_len = 0; - - sha512->data_len[0] = 0; - sha512->data_len[1] = 0; -} - /* SHA-384 and SHA-512 constants [§4.2.3] */ -static const guint64 SHA512_K[80] = { +static const guint64 SHA2_K[80] = { 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, @@ -1176,9 +1160,48 @@ static const guint64 SHA512_K[80] = { 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 }; + +static void +sha384_sum_init (Sha512sum *sha512) +{ + /* Initial Hash Value [§5.3.4] */ + sha512->H[0] = 0xcbbb9d5dc1059ed8; + sha512->H[1] = 0x629a292a367cd507; + sha512->H[2] = 0x9159015a3070dd17; + sha512->H[3] = 0x152fecd8f70e5939; + sha512->H[4] = 0x67332667ffc00b31; + sha512->H[5] = 0x8eb44a8768581511; + sha512->H[6] = 0xdb0c2e0d64f98fa7; + sha512->H[7] = 0x47b5481dbefa4fa4; + + sha512->block_len = 0; + + sha512->data_len[0] = 0; + sha512->data_len[1] = 0; +} + +static void +sha512_sum_init (Sha512sum *sha512) +{ + /* Initial Hash Value [§5.3.5] */ + sha512->H[0] = 0x6a09e667f3bcc908; + sha512->H[1] = 0xbb67ae8584caa73b; + sha512->H[2] = 0x3c6ef372fe94f82b; + sha512->H[3] = 0xa54ff53a5f1d36f1; + sha512->H[4] = 0x510e527fade682d1; + sha512->H[5] = 0x9b05688c2b3e6c1f; + sha512->H[6] = 0x1f83d9abfb41bd6b; + sha512->H[7] = 0x5be0cd19137e2179; + + sha512->block_len = 0; + + sha512->data_len[0] = 0; + sha512->data_len[1] = 0; +} + static void sha512_transform (guint64 H[8], - guint8 const data[SHA512_BLOCK_LEN]) + guint8 const data[SHA2_BLOCK_LEN]) { gint i; gint t; @@ -1186,7 +1209,7 @@ sha512_transform (guint64 H[8], guint64 M[16]; guint64 W[80]; - /* SHA-512 hash computation [§6.3.2] */ + /* SHA-512 hash computation [§6.4.2] */ /* prepare the message schedule */ for (i = 0; i < 16; i++) @@ -1224,7 +1247,7 @@ sha512_transform (guint64 H[8], { guint64 T1, T2; - T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA512_K[t] + W[t]; + T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA2_K[t] + W[t]; T2 = SIGMA0 (a) + Maj (a, b, c); h = g; g = f; @@ -1262,7 +1285,7 @@ sha512_sum_update (Sha512sum *sha512, sha512->data_len[1]++; /* try to fill current block */ - block_left = SHA512_BLOCK_LEN - sha512->block_len; + block_left = SHA2_BLOCK_LEN - sha512->block_len; if (block_left > 0) { gsize fill_len; @@ -1273,7 +1296,7 @@ sha512_sum_update (Sha512sum *sha512, length -= fill_len; offset += fill_len; - if (sha512->block_len == SHA512_BLOCK_LEN) + if (sha512->block_len == SHA2_BLOCK_LEN) { sha512_transform (sha512->H, sha512->block); sha512->block_len = 0; @@ -1281,14 +1304,14 @@ sha512_sum_update (Sha512sum *sha512, } /* process complete blocks */ - while (length >= SHA512_BLOCK_LEN) + while (length >= SHA2_BLOCK_LEN) { - memcpy (sha512->block, buffer + offset, SHA512_BLOCK_LEN); + memcpy (sha512->block, buffer + offset, SHA2_BLOCK_LEN); sha512_transform (sha512->H, sha512->block); - length -= SHA512_BLOCK_LEN; - offset += SHA512_BLOCK_LEN; + length -= SHA2_BLOCK_LEN; + offset += SHA2_BLOCK_LEN; } /* keep remaining data for next block */ @@ -1304,7 +1327,7 @@ sha512_sum_close (Sha512sum *sha512) { guint l; gint zeros; - guint8 pad[SHA512_BLOCK_LEN * 2] = { 0, }; + guint8 pad[SHA2_BLOCK_LEN * 2] = { 0, }; guint pad_len = 0; gint i; @@ -1339,12 +1362,25 @@ sha512_sum_close (Sha512sum *sha512) } static gchar * +sha384_sum_to_string (Sha512sum *sha512) +{ + return digest_to_string (sha512->digest, SHA384_DIGEST_LEN); +} + +static gchar * sha512_sum_to_string (Sha512sum *sha512) { return digest_to_string (sha512->digest, SHA512_DIGEST_LEN); } static void +sha384_sum_digest (Sha512sum *sha512, + guint8 *digest) +{ + memcpy (digest, sha512->digest, SHA384_DIGEST_LEN); +} + +static void sha512_sum_digest (Sha512sum *sha512, guint8 *digest) { @@ -1393,6 +1429,9 @@ g_checksum_type_get_length (GChecksumType checksum_type) case G_CHECKSUM_SHA256: len = SHA256_DIGEST_LEN; break; + case G_CHECKSUM_SHA384: + len = SHA384_DIGEST_LEN; + break; case G_CHECKSUM_SHA512: len = SHA512_DIGEST_LEN; break; @@ -1470,6 +1509,9 @@ g_checksum_reset (GChecksum *checksum) case G_CHECKSUM_SHA256: sha256_sum_init (&(checksum->sum.sha256)); break; + case G_CHECKSUM_SHA384: + sha384_sum_init (&(checksum->sum.sha512)); + break; case G_CHECKSUM_SHA512: sha512_sum_init (&(checksum->sum.sha512)); break; @@ -1568,6 +1610,7 @@ g_checksum_update (GChecksum *checksum, case G_CHECKSUM_SHA256: sha256_sum_update (&(checksum->sum.sha256), data, length); break; + case G_CHECKSUM_SHA384: case G_CHECKSUM_SHA512: sha512_sum_update (&(checksum->sum.sha512), data, length); break; @@ -1618,6 +1661,10 @@ g_checksum_get_string (GChecksum *checksum) sha256_sum_close (&(checksum->sum.sha256)); str = sha256_sum_to_string (&(checksum->sum.sha256)); break; + case G_CHECKSUM_SHA384: + sha512_sum_close (&(checksum->sum.sha512)); + str = sha384_sum_to_string (&(checksum->sum.sha512)); + break; case G_CHECKSUM_SHA512: sha512_sum_close (&(checksum->sum.sha512)); str = sha512_sum_to_string (&(checksum->sum.sha512)); @@ -1689,6 +1736,14 @@ g_checksum_get_digest (GChecksum *checksum, } sha256_sum_digest (&(checksum->sum.sha256), buffer); break; + case G_CHECKSUM_SHA384: + if (checksum_open) + { + sha512_sum_close (&(checksum->sum.sha512)); + str = sha384_sum_to_string (&(checksum->sum.sha512)); + } + sha384_sum_digest (&(checksum->sum.sha512), buffer); + break; case G_CHECKSUM_SHA512: if (checksum_open) { |