/* * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512 * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef FREEBL_NO_DEPEND #include"stubs.h" #endif
#include"prcpucfg.h" #ifdefined(NSS_X86) || defined(SHA_NO_LONG_LONG) #define NOUNROLL512 1 #undef HAVE_LONG_LONG #endif #include"prtypes.h"/* for PRUintXX */ #include"prlong.h" #include"secport.h"/* for PORT_XXX */ #include"blapi.h" #include"blapii.h" #include"secerr.h" #include"sha256.h"/* for struct SHA256ContextStr */ #include"crypto_primitives.h" #include"ppc-crypto.h"/* for USE_PPC_CRYPTO */
/* ============= Common constants and defines ======================= */
#define W ctx->u.w #define B ctx->u.b #define H ctx->h
#define SHR(x, n) (x >> n) #define SHL(x, n) (x << n) #define Ch(x, y, z) ((x & y) ^ (~x & z)) #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) #define SHA_MIN(a, b) (a < b ? a : b)
/* Padding used with all flavors of SHA */ staticconst PRUint8 pad[240] = {
0x80, 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 /* compiler will fill the rest in with zeros */
};
#define ROUND(n, a, b, c, d, e, f, g, h) \
h += S1(e) + Ch(e, f, g) + K256[n] + W[n]; \
d += h; \
h += S0(a) + Maj(a, b, c);
#endif
#define SHA256_UNROLLED_ROUNDS \
ROUND(0, a, b, c, d, e, f, g, h) \
ROUND(1, h, a, b, c, d, e, f, g) \
ROUND(2, g, h, a, b, c, d, e, f) \
ROUND(3, f, g, h, a, b, c, d, e) \
ROUND(4, e, f, g, h, a, b, c, d) \
ROUND(5, d, e, f, g, h, a, b, c) \
ROUND(6, c, d, e, f, g, h, a, b) \
ROUND(7, b, c, d, e, f, g, h, a) \
\
ROUND(8, a, b, c, d, e, f, g, h) \
ROUND(9, h, a, b, c, d, e, f, g) \
ROUND(10, g, h, a, b, c, d, e, f) \
ROUND(11, f, g, h, a, b, c, d, e) \
ROUND(12, e, f, g, h, a, b, c, d) \
ROUND(13, d, e, f, g, h, a, b, c) \
ROUND(14, c, d, e, f, g, h, a, b) \
ROUND(15, b, c, d, e, f, g, h, a) \
\
ROUND(16, a, b, c, d, e, f, g, h) \
ROUND(17, h, a, b, c, d, e, f, g) \
ROUND(18, g, h, a, b, c, d, e, f) \
ROUND(19, f, g, h, a, b, c, d, e) \
ROUND(20, e, f, g, h, a, b, c, d) \
ROUND(21, d, e, f, g, h, a, b, c) \
ROUND(22, c, d, e, f, g, h, a, b) \
ROUND(23, b, c, d, e, f, g, h, a) \
\
ROUND(24, a, b, c, d, e, f, g, h) \
ROUND(25, h, a, b, c, d, e, f, g) \
ROUND(26, g, h, a, b, c, d, e, f) \
ROUND(27, f, g, h, a, b, c, d, e) \
ROUND(28, e, f, g, h, a, b, c, d) \
ROUND(29, d, e, f, g, h, a, b, c) \
ROUND(30, c, d, e, f, g, h, a, b) \
ROUND(31, b, c, d, e, f, g, h, a) \
\
ROUND(32, a, b, c, d, e, f, g, h) \
ROUND(33, h, a, b, c, d, e, f, g) \
ROUND(34, g, h, a, b, c, d, e, f) \
ROUND(35, f, g, h, a, b, c, d, e) \
ROUND(36, e, f, g, h, a, b, c, d) \
ROUND(37, d, e, f, g, h, a, b, c) \
ROUND(38, c, d, e, f, g, h, a, b) \
ROUND(39, b, c, d, e, f, g, h, a) \
\
ROUND(40, a, b, c, d, e, f, g, h) \
ROUND(41, h, a, b, c, d, e, f, g) \
ROUND(42, g, h, a, b, c, d, e, f) \
ROUND(43, f, g, h, a, b, c, d, e) \
ROUND(44, e, f, g, h, a, b, c, d) \
ROUND(45, d, e, f, g, h, a, b, c) \
ROUND(46, c, d, e, f, g, h, a, b) \
ROUND(47, b, c, d, e, f, g, h, a) \
\
ROUND(48, a, b, c, d, e, f, g, h) \
ROUND(49, h, a, b, c, d, e, f, g) \
ROUND(50, g, h, a, b, c, d, e, f) \
ROUND(51, f, g, h, a, b, c, d, e) \
ROUND(52, e, f, g, h, a, b, c, d) \
ROUND(53, d, e, f, g, h, a, b, c) \
ROUND(54, c, d, e, f, g, h, a, b) \
ROUND(55, b, c, d, e, f, g, h, a) \
\
ROUND(56, a, b, c, d, e, f, g, h) \
ROUND(57, h, a, b, c, d, e, f, g) \
ROUND(58, g, h, a, b, c, d, e, f) \
ROUND(59, f, g, h, a, b, c, d, e) \
ROUND(60, e, f, g, h, a, b, c, d) \
ROUND(61, d, e, f, g, h, a, b, c) \
ROUND(62, c, d, e, f, g, h, a, b) \
ROUND(63, b, c, d, e, f, g, h, a)
for (i = 0; i < 16; i++) {
w[i] += vec_ld(0, &K256[i * 4]);
}
vec_u32 a, b, c, d, e, f, g, h;
a = vec_splats(H[0]);
b = vec_splats(H[1]);
c = vec_splats(H[2]);
d = vec_splats(H[3]);
e = vec_splats(H[4]);
f = vec_splats(H[5]);
g = vec_splats(H[6]);
h = vec_splats(H[7]);
/* Add inputLen into the count of bytes processed, before processing */ if ((ctx->sizeLo += inputLen) < inputLen)
ctx->sizeHi++;
/* if data already in buffer, attemp to fill rest of buffer */ if (inBuf) { unsignedint todo = SHA256_BLOCK_LENGTH - inBuf; if (inputLen < todo)
todo = inputLen;
memcpy(B + inBuf, input, todo);
input += todo;
inputLen -= todo; if (inBuf + todo == SHA256_BLOCK_LENGTH)
SHA256_Compress_Generic(ctx);
}
/* if enough data to fill one or more whole buffers, process them. */ while (inputLen >= SHA256_BLOCK_LENGTH) {
memcpy(B, input, SHA256_BLOCK_LENGTH);
input += SHA256_BLOCK_LENGTH;
inputLen -= SHA256_BLOCK_LENGTH;
SHA256_Compress_Generic(ctx);
} /* if data left over, fill it into buffer */ if (inputLen)
memcpy(B, input, inputLen);
}
INITW(70);
INITW(71);
INITW(72);
INITW(73);
INITW(74);
INITW(75);
INITW(76);
INITW(77);
INITW(78);
INITW(79); #endif
} #ifdef SHA512_TRACE
{ int i; for (i = 0; i < 80; ++i) { #ifdef HAVE_LONG_LONG
printf("W[%2d] = %016lx\n", i, W[i]); #else
printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo); #endif
}
} #endif
{
PRUint64 a, b, c, d, e, f, g, h;
a = H[0];
b = H[1];
c = H[2];
d = H[3];
e = H[4];
f = H[5];
g = H[6];
h = H[7];
#ifdef NOUNROLL512
{ int t; for (t = 0; t < 80; t += 8) {
ROUND(t + 0, a, b, c, d, e, f, g, h)
ROUND(t + 1, h, a, b, c, d, e, f, g)
ROUND(t + 2, g, h, a, b, c, d, e, f)
ROUND(t + 3, f, g, h, a, b, c, d, e)
ROUND(t + 4, e, f, g, h, a, b, c, d)
ROUND(t + 5, d, e, f, g, h, a, b, c)
ROUND(t + 6, c, d, e, f, g, h, a, b)
ROUND(t + 7, b, c, d, e, f, g, h, a)
}
} #else
ROUND(0, a, b, c, d, e, f, g, h)
ROUND(1, h, a, b, c, d, e, f, g)
ROUND(2, g, h, a, b, c, d, e, f)
ROUND(3, f, g, h, a, b, c, d, e)
ROUND(4, e, f, g, h, a, b, c, d)
ROUND(5, d, e, f, g, h, a, b, c)
ROUND(6, c, d, e, f, g, h, a, b)
ROUND(7, b, c, d, e, f, g, h, a)
ROUND(8, a, b, c, d, e, f, g, h)
ROUND(9, h, a, b, c, d, e, f, g)
ROUND(10, g, h, a, b, c, d, e, f)
ROUND(11, f, g, h, a, b, c, d, e)
ROUND(12, e, f, g, h, a, b, c, d)
ROUND(13, d, e, f, g, h, a, b, c)
ROUND(14, c, d, e, f, g, h, a, b)
ROUND(15, b, c, d, e, f, g, h, a)
ROUND(16, a, b, c, d, e, f, g, h)
ROUND(17, h, a, b, c, d, e, f, g)
ROUND(18, g, h, a, b, c, d, e, f)
ROUND(19, f, g, h, a, b, c, d, e)
ROUND(20, e, f, g, h, a, b, c, d)
ROUND(21, d, e, f, g, h, a, b, c)
ROUND(22, c, d, e, f, g, h, a, b)
ROUND(23, b, c, d, e, f, g, h, a)
ROUND(24, a, b, c, d, e, f, g, h)
ROUND(25, h, a, b, c, d, e, f, g)
ROUND(26, g, h, a, b, c, d, e, f)
ROUND(27, f, g, h, a, b, c, d, e)
ROUND(28, e, f, g, h, a, b, c, d)
ROUND(29, d, e, f, g, h, a, b, c)
ROUND(30, c, d, e, f, g, h, a, b)
ROUND(31, b, c, d, e, f, g, h, a)
ROUND(32, a, b, c, d, e, f, g, h)
ROUND(33, h, a, b, c, d, e, f, g)
ROUND(34, g, h, a, b, c, d, e, f)
ROUND(35, f, g, h, a, b, c, d, e)
ROUND(36, e, f, g, h, a, b, c, d)
ROUND(37, d, e, f, g, h, a, b, c)
ROUND(38, c, d, e, f, g, h, a, b)
ROUND(39, b, c, d, e, f, g, h, a)
ROUND(40, a, b, c, d, e, f, g, h)
ROUND(41, h, a, b, c, d, e, f, g)
ROUND(42, g, h, a, b, c, d, e, f)
ROUND(43, f, g, h, a, b, c, d, e)
ROUND(44, e, f, g, h, a, b, c, d)
ROUND(45, d, e, f, g, h, a, b, c)
ROUND(46, c, d, e, f, g, h, a, b)
ROUND(47, b, c, d, e, f, g, h, a)
ROUND(48, a, b, c, d, e, f, g, h)
ROUND(49, h, a, b, c, d, e, f, g)
ROUND(50, g, h, a, b, c, d, e, f)
ROUND(51, f, g, h, a, b, c, d, e)
ROUND(52, e, f, g, h, a, b, c, d)
ROUND(53, d, e, f, g, h, a, b, c)
ROUND(54, c, d, e, f, g, h, a, b)
ROUND(55, b, c, d, e, f, g, h, a)
ROUND(56, a, b, c, d, e, f, g, h)
ROUND(57, h, a, b, c, d, e, f, g)
ROUND(58, g, h, a, b, c, d, e, f)
ROUND(59, f, g, h, a, b, c, d, e)
ROUND(60, e, f, g, h, a, b, c, d)
ROUND(61, d, e, f, g, h, a, b, c)
ROUND(62, c, d, e, f, g, h, a, b)
ROUND(63, b, c, d, e, f, g, h, a)
ROUND(64, a, b, c, d, e, f, g, h)
ROUND(65, h, a, b, c, d, e, f, g)
ROUND(66, g, h, a, b, c, d, e, f)
ROUND(67, f, g, h, a, b, c, d, e)
ROUND(68, e, f, g, h, a, b, c, d)
ROUND(69, d, e, f, g, h, a, b, c)
ROUND(70, c, d, e, f, g, h, a, b)
ROUND(71, b, c, d, e, f, g, h, a)
ROUND(72, a, b, c, d, e, f, g, h)
ROUND(73, h, a, b, c, d, e, f, g)
ROUND(74, g, h, a, b, c, d, e, f)
ROUND(75, f, g, h, a, b, c, d, e)
ROUND(76, e, f, g, h, a, b, c, d)
ROUND(77, d, e, f, g, h, a, b, c)
ROUND(78, c, d, e, f, g, h, a, b)
ROUND(79, b, c, d, e, f, g, h, a) #endif
#ifdefined(HAVE_LONG_LONG)
inBuf = (unsignedint)ctx->sizeLo & 0x7f; /* Add inputLen into the count of bytes processed, before processing */
ctx->sizeLo += inputLen; #else
inBuf = (unsignedint)ctx->sizeLo.lo & 0x7f;
ctx->sizeLo.lo += inputLen; if (ctx->sizeLo.lo < inputLen)
ctx->sizeLo.hi++; #endif
/* if data already in buffer, attemp to fill rest of buffer */ if (inBuf) { unsignedint todo = SHA512_BLOCK_LENGTH - inBuf; if (inputLen < todo)
todo = inputLen;
memcpy(B + inBuf, input, todo);
input += todo;
inputLen -= todo; if (inBuf + todo == SHA512_BLOCK_LENGTH)
SHA512_Compress(ctx);
}
/* if enough data to fill one or more whole buffers, process them. */ while (inputLen >= SHA512_BLOCK_LENGTH) {
memcpy(B, input, SHA512_BLOCK_LENGTH);
input += SHA512_BLOCK_LENGTH;
inputLen -= SHA512_BLOCK_LENGTH;
SHA512_Compress(ctx);
} /* if data left over, fill it into buffer */ if (inputLen)
memcpy(B, input, inputLen);
}
/* ======================================================================= */ /* SHA384 uses a SHA512Context as the real context. ** The only differences between SHA384 an SHA512 are: ** a) the intialization values for the context, and ** b) the number of bytes of data produced as output.
*/
/* to hash one million 'a's perform 1000 * sha224 updates on a buffer with 1000 'a's
*/
memset(a1000times, 'a', 1000);
printf("SHA224, input = %s\n", "a one million times");
SHA224_Begin(&ctx); for (i = 0; i < 1000; i++)
SHA224_Update(&ctx, a1000times, 1000);
SHA224_End(&ctx, outBuf, &outLen, SHA224_LENGTH);
dumpHash32(outBuf, sizeof outBuf);
}
void
dumpHash64(constunsignedchar *buf, unsignedint bufLen)
{ unsignedint i; for (i = 0; i < bufLen; i += 8) { if (i % 32 == 0)
printf("\n");
printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
buf[i], buf[i + 1], buf[i + 2], buf[i + 3],
buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
}
printf("\n");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.