diff options
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/sha256.c')
-rw-r--r-- | plugins/MirOTR/Libgcrypt/cipher/sha256.c | 244 |
1 files changed, 118 insertions, 126 deletions
diff --git a/plugins/MirOTR/Libgcrypt/cipher/sha256.c b/plugins/MirOTR/Libgcrypt/cipher/sha256.c index 8063592f75..d92303cdc7 100644 --- a/plugins/MirOTR/Libgcrypt/cipher/sha256.c +++ b/plugins/MirOTR/Libgcrypt/cipher/sha256.c @@ -19,7 +19,7 @@ /* Test vectors: - + "abc" SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7 SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad @@ -27,7 +27,7 @@ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525 SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1 - + "a" one million times SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67 SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0 @@ -42,22 +42,40 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" + +/* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */ +#undef USE_SSSE3 +#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \ + defined(HAVE_GCC_INLINE_ASM_SSSE3) && \ + defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) +# define USE_SSSE3 1 +#endif + + typedef struct { + gcry_md_block_ctx_t bctx; u32 h0,h1,h2,h3,h4,h5,h6,h7; - u32 nblocks; - byte buf[64]; - int count; +#ifdef USE_SSSE3 + unsigned int use_ssse3:1; +#endif } SHA256_CONTEXT; +static unsigned int +transform (void *c, const unsigned char *data); + + static void -sha256_init (void *context) +sha256_init (void *context, unsigned int flags) { SHA256_CONTEXT *hd = context; + (void)flags; + hd->h0 = 0x6a09e667; hd->h1 = 0xbb67ae85; hd->h2 = 0x3c6ef372; @@ -67,16 +85,25 @@ sha256_init (void *context) hd->h6 = 0x1f83d9ab; hd->h7 = 0x5be0cd19; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.nblocks_high = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.bwrite = transform; + +#ifdef USE_SSSE3 + hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0; +#endif } static void -sha224_init (void *context) +sha224_init (void *context, unsigned int flags) { SHA256_CONTEXT *hd = context; + (void)flags; + hd->h0 = 0xc1059ed8; hd->h1 = 0x367cd507; hd->h2 = 0x3070dd17; @@ -86,8 +113,15 @@ sha224_init (void *context) hd->h6 = 0x64f98fa7; hd->h7 = 0xbefa4fa4; - hd->nblocks = 0; - hd->count = 0; + hd->bctx.nblocks = 0; + hd->bctx.nblocks_high = 0; + hd->bctx.count = 0; + hd->bctx.blocksize = 64; + hd->bctx.bwrite = transform; + +#ifdef USE_SSSE3 + hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0; +#endif } @@ -123,7 +157,7 @@ Maj (u32 x, u32 y, u32 z) { return ((x & y) | (z & (x|y))); } - + /* (4.4) */ static inline u32 Sum0 (u32 x) @@ -138,15 +172,16 @@ Sum1 (u32 x) return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25)); } - -static void -transform (SHA256_CONTEXT *hd, const unsigned char *data) + +static unsigned int +_transform (void *ctx, const unsigned char *data) { + SHA256_CONTEXT *hd = ctx; static const u32 K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, @@ -162,10 +197,9 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) }; u32 a,b,c,d,e,f,g,h,t1,t2; - u32 x[16]; u32 w[64]; int i; - + a = hd->h0; b = hd->h1; c = hd->h2; @@ -174,25 +208,9 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) f = hd->h5; g = hd->h6; h = hd->h7; - -#ifdef WORDS_BIGENDIAN - memcpy (x, data, 64); -#else - { - byte *p2; - - for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) - { - p2[3] = *data++; - p2[2] = *data++; - p2[1] = *data++; - p2[0] = *data++; - } - } -#endif for (i=0; i < 16; i++) - w[i] = x[i]; + w[i] = buf_get_be32(data + i * 4); for (; i < 64; i++) w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; @@ -202,7 +220,7 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) R(a,b,c,d,e,f,g,h,K[i],w[i]); i++; #else - t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i]; + t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i]; t2 = Sum0 (a) + Maj (a, b, c); d += t1; h = t1 + t2; @@ -254,49 +272,32 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) hd->h5 += f; hd->h6 += g; hd->h7 += h; + + return /*burn_stack*/ 74*4+32; } #undef S0 #undef S1 #undef R -/* Update the message digest with the contents of INBUF with length - INLEN. */ -static void -sha256_write (void *context, const void *inbuf_arg, size_t inlen) +#ifdef USE_SSSE3 +unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data, + u32 state[8], size_t num_blks); +#endif + + +static unsigned int +transform (void *ctx, const unsigned char *data) { - const unsigned char *inbuf = inbuf_arg; - SHA256_CONTEXT *hd = context; + SHA256_CONTEXT *hd = ctx; - if (hd->count == 64) - { /* flush the buffer */ - transform (hd, hd->buf); - _gcry_burn_stack (74*4+32); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; - if (hd->count) - { - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; - sha256_write (hd, NULL, 0); - if (!inlen) - return; - } +#ifdef USE_SSSE3 + if (hd->use_ssse3) + return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, 1) + + 4 * sizeof(void*); +#endif - while (inlen >= 64) - { - transform (hd, inbuf); - hd->count = 0; - hd->nblocks++; - inlen -= 64; - inbuf += 64; - } - _gcry_burn_stack (74*4+32); - for (; inlen && hd->count < 64; inlen--) - hd->buf[hd->count++] = *inbuf++; + return _transform (hd, data); } @@ -309,18 +310,24 @@ static void sha256_final(void *context) { SHA256_CONTEXT *hd = context; - u32 t, msb, lsb; + u32 t, th, msb, lsb; byte *p; - - sha256_write (hd, NULL, 0); /* flush */; + unsigned int burn; + + _gcry_md_block_write (hd, NULL, 0); /* flush */; + + t = hd->bctx.nblocks; + if (sizeof t == sizeof hd->bctx.nblocks) + th = hd->bctx.nblocks_high; + else + th = hd->bctx.nblocks >> 32; - t = hd->nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; - msb = t >> 26; + msb = (th << 6) | (t >> 26); /* add the count */ t = lsb; - if ((lsb += hd->count) < t) + if ((lsb += hd->bctx.count) < t) msb++; /* multiply by 8 to make a bit count */ t = lsb; @@ -328,39 +335,28 @@ sha256_final(void *context) msb <<= 3; msb |= t >> 29; - if (hd->count < 56) + if (hd->bctx.count < 56) { /* enough room */ - hd->buf[hd->count++] = 0x80; /* pad */ - while (hd->count < 56) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while (hd->bctx.count < 56) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else { /* need one extra block */ - hd->buf[hd->count++] = 0x80; /* pad character */ - while (hd->count < 64) - hd->buf[hd->count++] = 0; - sha256_write (hd, NULL, 0); /* flush */; - memset (hd->buf, 0, 56 ); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while (hd->bctx.count < 64) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write (hd, NULL, 0); /* flush */; + memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ - hd->buf[56] = msb >> 24; - hd->buf[57] = msb >> 16; - hd->buf[58] = msb >> 8; - hd->buf[59] = msb; - hd->buf[60] = lsb >> 24; - hd->buf[61] = lsb >> 16; - hd->buf[62] = lsb >> 8; - hd->buf[63] = lsb; - transform (hd, hd->buf); - _gcry_burn_stack (74*4+32); - - p = hd->buf; -#ifdef WORDS_BIGENDIAN -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) -#else /* little endian */ -#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ - *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) -#endif + buf_put_be32(hd->bctx.buf + 56, msb); + buf_put_be32(hd->bctx.buf + 60, lsb); + burn = transform (hd, hd->bctx.buf); + _gcry_burn_stack (burn); + + p = hd->bctx.buf; +#define X(a) do { *(u32*)p = be_bswap32(hd->h##a); p += 4; } while(0) X(0); X(1); X(2); @@ -377,12 +373,12 @@ sha256_read (void *context) { SHA256_CONTEXT *hd = context; - return hd->buf; + return hd->bctx.buf; } -/* +/* Self-test section. */ @@ -392,10 +388,10 @@ selftests_sha224 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; - + what = "short string"; errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA224, 0, + (GCRY_MD_SHA224, 0, "abc", 3, "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28); @@ -406,13 +402,13 @@ selftests_sha224 (int extended, selftest_report_func_t report) { what = "long string"; errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA224, 0, + (GCRY_MD_SHA224, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); if (errtxt) goto failed; - + what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA224, 1, @@ -436,10 +432,10 @@ selftests_sha256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; - + what = "short string"; errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA256, 0, + (GCRY_MD_SHA256, 0, "abc", 3, "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32); @@ -450,14 +446,14 @@ selftests_sha256 (int extended, selftest_report_func_t report) { what = "long string"; errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA256, 0, + (GCRY_MD_SHA256, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1", 32); if (errtxt) goto failed; - + what = "one million \"a\""; errtxt = _gcry_hash_selftest_check_one (GCRY_MD_SHA256, 1, @@ -495,7 +491,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report) default: ec = GPG_ERR_DIGEST_ALGO; break; - + } return ec; } @@ -512,7 +508,7 @@ static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */ static gcry_md_oid_spec_t oid_spec_sha224[] = { /* From RFC3874, Section 4 */ - { "2.16.840.1.101.3.4.2.4" }, + { "2.16.840.1.101.3.4.2.4" }, { NULL }, }; @@ -524,7 +520,7 @@ static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */ static gcry_md_oid_spec_t oid_spec_sha256[] = { /* According to the OpenPGP draft rfc2440-bis06 */ - { "2.16.840.1.101.3.4.2.1" }, + { "2.16.840.1.101.3.4.2.1" }, /* PKCS#1 sha256WithRSAEncryption */ { "1.2.840.113549.1.1.11" }, @@ -533,22 +529,18 @@ static gcry_md_oid_spec_t oid_spec_sha256[] = gcry_md_spec_t _gcry_digest_spec_sha224 = { + GCRY_MD_SHA224, {0, 1}, "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28, - sha224_init, sha256_write, sha256_final, sha256_read, - sizeof (SHA256_CONTEXT) - }; -md_extra_spec_t _gcry_digest_extraspec_sha224 = - { + sha224_init, _gcry_md_block_write, sha256_final, sha256_read, + sizeof (SHA256_CONTEXT), run_selftests }; gcry_md_spec_t _gcry_digest_spec_sha256 = { + GCRY_MD_SHA256, {0, 1}, "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32, - sha256_init, sha256_write, sha256_final, sha256_read, - sizeof (SHA256_CONTEXT) - }; -md_extra_spec_t _gcry_digest_extraspec_sha256 = - { + sha256_init, _gcry_md_block_write, sha256_final, sha256_read, + sizeof (SHA256_CONTEXT), run_selftests }; |