Changeset View
Changeset View
Standalone View
Standalone View
sys/crypto/sha2/sha512c.c
- This file was moved from lib/libmd/sha512c.c.
Show All 24 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD: head/lib/libmd/sha512c.c 282774 2015-05-11 16:45:33Z thomas $"); | __FBSDID("$FreeBSD: head/lib/libmd/sha512c.c 282774 2015-05-11 16:45:33Z thomas $"); | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#ifdef _KERNEL | |||||
#include <sys/systm.h> | |||||
#else | |||||
#include <string.h> | #include <string.h> | ||||
#endif | |||||
#include "sha512.h" | #include "sha512.h" | ||||
#include "sha384.h" | |||||
#if BYTE_ORDER == BIG_ENDIAN | #if BYTE_ORDER == BIG_ENDIAN | ||||
/* Copy a vector of big-endian uint64_t into a vector of bytes */ | /* Copy a vector of big-endian uint64_t into a vector of bytes */ | ||||
#define be64enc_vect(dst, src, len) \ | #define be64enc_vect(dst, src, len) \ | ||||
memcpy((void *)dst, (const void *)src, (size_t)len) | memcpy((void *)dst, (const void *)src, (size_t)len) | ||||
/* Copy a vector of bytes into a vector of big-endian uint64_t */ | /* Copy a vector of bytes into a vector of big-endian uint64_t */ | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | RND(S[(80 - i) % 8], S[(81 - i) % 8], \ | ||||
S[(86 - i) % 8], S[(87 - i) % 8], \ | S[(86 - i) % 8], S[(87 - i) % 8], \ | ||||
W[i] + k) | W[i] + k) | ||||
/* | /* | ||||
* SHA512 block compression function. The 512-bit state is transformed via | * SHA512 block compression function. The 512-bit state is transformed via | ||||
* the 512-bit input block to produce a new state. | * the 512-bit input block to produce a new state. | ||||
*/ | */ | ||||
static void | static void | ||||
SHA512_Transform(uint64_t * state, const unsigned char block[128]) | SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH]) | ||||
{ | { | ||||
uint64_t W[80]; | uint64_t W[80]; | ||||
uint64_t S[8]; | uint64_t S[8]; | ||||
uint64_t t0, t1; | uint64_t t0, t1; | ||||
int i; | int i; | ||||
/* 1. Prepare message schedule W. */ | /* 1. Prepare message schedule W. */ | ||||
be64dec_vect(W, block, 128); | be64dec_vect(W, block, SHA512_BLOCK_LENGTH); | ||||
for (i = 16; i < 80; i++) | for (i = 16; i < 80; i++) | ||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; | W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; | ||||
/* 2. Initialize working variables. */ | /* 2. Initialize working variables. */ | ||||
memcpy(S, state, 64); | memcpy(S, state, SHA512_DIGEST_LENGTH); | ||||
/* 3. Mix. */ | /* 3. Mix. */ | ||||
RNDr(S, W, 0, 0x428a2f98d728ae22ULL); | RNDr(S, W, 0, 0x428a2f98d728ae22ULL); | ||||
RNDr(S, W, 1, 0x7137449123ef65cdULL); | RNDr(S, W, 1, 0x7137449123ef65cdULL); | ||||
RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL); | RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL); | ||||
RNDr(S, W, 3, 0xe9b5dba58189dbbcULL); | RNDr(S, W, 3, 0xe9b5dba58189dbbcULL); | ||||
RNDr(S, W, 4, 0x3956c25bf348b538ULL); | RNDr(S, W, 4, 0x3956c25bf348b538ULL); | ||||
RNDr(S, W, 5, 0x59f111f1b605d019ULL); | RNDr(S, W, 5, 0x59f111f1b605d019ULL); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH]) | ||||
RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL); | RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL); | ||||
RNDr(S, W, 79, 0x6c44198c4a475817ULL); | RNDr(S, W, 79, 0x6c44198c4a475817ULL); | ||||
/* 4. Mix local working variables into global state */ | /* 4. Mix local working variables into global state */ | ||||
for (i = 0; i < 8; i++) | for (i = 0; i < 8; i++) | ||||
state[i] += S[i]; | state[i] += S[i]; | ||||
} | } | ||||
static unsigned char PAD[128] = { | static unsigned char PAD[SHA512_BLOCK_LENGTH] = { | ||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 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, | 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, | 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 | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len) | ||||
bitlen[0] = ((uint64_t)len) >> 61; | bitlen[0] = ((uint64_t)len) >> 61; | ||||
/* Update number of bits */ | /* Update number of bits */ | ||||
if ((ctx->count[1] += bitlen[1]) < bitlen[1]) | if ((ctx->count[1] += bitlen[1]) < bitlen[1]) | ||||
ctx->count[0]++; | ctx->count[0]++; | ||||
ctx->count[0] += bitlen[0]; | ctx->count[0] += bitlen[0]; | ||||
/* Handle the case where we don't need to perform any transforms */ | /* Handle the case where we don't need to perform any transforms */ | ||||
if (len < 128 - r) { | if (len < SHA512_BLOCK_LENGTH - r) { | ||||
memcpy(&ctx->buf[r], src, len); | memcpy(&ctx->buf[r], src, len); | ||||
return; | return; | ||||
} | } | ||||
/* Finish the current block */ | /* Finish the current block */ | ||||
memcpy(&ctx->buf[r], src, 128 - r); | memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r); | ||||
SHA512_Transform(ctx->state, ctx->buf); | SHA512_Transform(ctx->state, ctx->buf); | ||||
src += 128 - r; | src += SHA512_BLOCK_LENGTH - r; | ||||
len -= 128 - r; | len -= SHA512_BLOCK_LENGTH - r; | ||||
/* Perform complete blocks */ | /* Perform complete blocks */ | ||||
while (len >= 128) { | while (len >= SHA512_BLOCK_LENGTH) { | ||||
SHA512_Transform(ctx->state, src); | SHA512_Transform(ctx->state, src); | ||||
src += 128; | src += SHA512_BLOCK_LENGTH; | ||||
len -= 128; | len -= SHA512_BLOCK_LENGTH; | ||||
} | } | ||||
/* Copy left over data into buffer */ | /* Copy left over data into buffer */ | ||||
memcpy(ctx->buf, src, len); | memcpy(ctx->buf, src, len); | ||||
} | } | ||||
/* | /* | ||||
* SHA-512 finalization. Pads the input data, exports the hash value, | * SHA-512 finalization. Pads the input data, exports the hash value, | ||||
* and clears the context state. | * and clears the context state. | ||||
*/ | */ | ||||
void | void | ||||
SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx) | SHA512_Final(unsigned char digest[SHA512_DIGEST_LENGTH], SHA512_CTX * ctx) | ||||
{ | { | ||||
/* Add padding */ | /* Add padding */ | ||||
SHA512_Pad(ctx); | SHA512_Pad(ctx); | ||||
/* Write the hash */ | /* Write the hash */ | ||||
be64enc_vect(digest, ctx->state, 64); | be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH); | ||||
/* Clear the context state */ | /* Clear the context state */ | ||||
memset((void *)ctx, 0, sizeof(*ctx)); | memset((void *)ctx, 0, sizeof(*ctx)); | ||||
} | } | ||||
/*** SHA-384: *********************************************************/ | |||||
/* | |||||
* the SHA384 and SHA512 transforms are identical, so SHA384 is skipped | |||||
*/ | |||||
/* SHA-384 initialization. Begins a SHA-384 operation. */ | |||||
void | |||||
SHA384_Init(SHA384_CTX * ctx) | |||||
{ | |||||
/* Zero bits processed so far */ | |||||
ctx->count[0] = ctx->count[1] = 0; | |||||
/* Magic initialization constants */ | |||||
ctx->state[0] = 0xcbbb9d5dc1059ed8ULL; | |||||
ctx->state[1] = 0x629a292a367cd507ULL; | |||||
ctx->state[2] = 0x9159015a3070dd17ULL; | |||||
ctx->state[3] = 0x152fecd8f70e5939ULL; | |||||
ctx->state[4] = 0x67332667ffc00b31ULL; | |||||
ctx->state[5] = 0x8eb44a8768581511ULL; | |||||
ctx->state[6] = 0xdb0c2e0d64f98fa7ULL; | |||||
ctx->state[7] = 0x47b5481dbefa4fa4ULL; | |||||
} | |||||
/* Add bytes into the SHA-384 hash */ | |||||
void | |||||
SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len) | |||||
{ | |||||
SHA512_Update((SHA512_CTX *)ctx, in, len); | |||||
} | |||||
/* | |||||
* SHA-384 finalization. Pads the input data, exports the hash value, | |||||
* and clears the context state. | |||||
*/ | |||||
void | |||||
SHA384_Final(unsigned char digest[SHA384_DIGEST_LENGTH], SHA384_CTX * ctx) | |||||
{ | |||||
/* Add padding */ | |||||
SHA512_Pad((SHA512_CTX *)ctx); | |||||
/* Write the hash */ | |||||
be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH); | |||||
/* Clear the context state */ | |||||
memset((void *)ctx, 0, sizeof(*ctx)); | |||||
} | |||||
#ifdef WEAK_REFS | #ifdef WEAK_REFS | ||||
/* When building libmd, provide weak references. Note: this is not | /* When building libmd, provide weak references. Note: this is not | ||||
activated in the context of compiling these sources for internal | activated in the context of compiling these sources for internal | ||||
use in libcrypt. | use in libcrypt. | ||||
*/ | */ | ||||
#undef SHA512_Init | #undef SHA512_Init | ||||
__weak_reference(_libmd_SHA512_Init, SHA512_Init); | __weak_reference(_libmd_SHA512_Init, SHA512_Init); | ||||
#undef SHA512_Update | #undef SHA512_Update | ||||
__weak_reference(_libmd_SHA512_Update, SHA512_Update); | __weak_reference(_libmd_SHA512_Update, SHA512_Update); | ||||
#undef SHA512_Final | #undef SHA512_Final | ||||
__weak_reference(_libmd_SHA512_Final, SHA512_Final); | __weak_reference(_libmd_SHA512_Final, SHA512_Final); | ||||
#undef SHA512_Transform | #undef SHA512_Transform | ||||
__weak_reference(_libmd_SHA512_Transform, SHA512_Transform); | __weak_reference(_libmd_SHA512_Transform, SHA512_Transform); | ||||
#undef SHA384_Init | |||||
__weak_reference(_libmd_SHA384_Init, SHA384_Init); | |||||
#undef SHA384_Update | |||||
__weak_reference(_libmd_SHA384_Update, SHA384_Update); | |||||
#undef SHA384_Final | |||||
__weak_reference(_libmd_SHA384_Final, SHA384_Final); | |||||
#endif | #endif |