summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgcrypt/cipher/sha256.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/sha256.c')
-rw-r--r--plugins/MirOTR/Libgcrypt/cipher/sha256.c244
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
};