Import current sha2.c and sha2.h from OpenBSD.

These are not changed from their original state, the next commit will
re-apply the portable changes.
This commit is contained in:
Darren Tucker 2019-07-23 20:27:51 +10:00
parent 2e6035b900
commit 09159594a3
2 changed files with 285 additions and 192 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sha2.c,v 1.11 2005/08/08 08:05:35 espie Exp */ /* $OpenBSD: sha2.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $ */
/* /*
* FILE: sha2.c * FILE: sha2.c
@ -34,22 +34,10 @@
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
*/ */
/* OPENBSD ORIGINAL: lib/libc/hash/sha2.c */ #include <sys/types.h>
#include "includes.h"
#ifdef WITH_OPENSSL
# include <openssl/opensslv.h>
# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
# define _NEED_SHA2 1
# endif
#else
# define _NEED_SHA2 1
#endif
#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE)
#include <string.h> #include <string.h>
#include <sha2.h>
/* /*
* UNROLLED TRANSFORM LOOP NOTE: * UNROLLED TRANSFORM LOOP NOTE:
@ -64,15 +52,20 @@
* #define SHA2_UNROLL_TRANSFORM * #define SHA2_UNROLL_TRANSFORM
* *
*/ */
#ifndef SHA2_SMALL
#if defined(__amd64__) || defined(__i386__)
#define SHA2_UNROLL_TRANSFORM
#endif
#endif
/*** SHA-256/384/512 Machine Architecture Definitions *****************/ /*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
/* /*
* BYTE_ORDER NOTE: * BYTE_ORDER NOTE:
* *
* Please make sure that your system defines BYTE_ORDER. If your * Please make sure that your system defines BYTE_ORDER. If your
* architecture is little-endian, make sure it also defines * architecture is little-endian, make sure it also defines
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
* equivalent. * equivilent.
* *
* If your system does not define the above, then you can do so by * If your system does not define the above, then you can do so by
* hand like this: * hand like this:
@ -98,8 +91,9 @@
#endif #endif
/*** SHA-256/384/512 Various Length Definitions ***********************/ /*** SHA-224/256/384/512 Various Length Definitions ***********************/
/* NOTE: Most of these are in sha2.h */ /* NOTE: Most of these are in sha2.h */
#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8)
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
@ -152,22 +146,22 @@
* Bit shifting and rotation (used by the six SHA-XYZ logical functions: * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
* *
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
* S is a ROTATION) because the SHA-256/384/512 description document * S is a ROTATION) because the SHA-224/256/384/512 description document
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
* same "backwards" definition. * same "backwards" definition.
*/ */
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ /* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
#define R(b,x) ((x) >> (b)) #define R(b,x) ((x) >> (b))
/* 32-bit Rotate-right (used in SHA-256): */ /* 32-bit Rotate-right (used in SHA-224 and SHA-256): */
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ /* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
/* Four of six logical functions used in SHA-256: */ /* Four of six logical functions used in SHA-224 and SHA-256: */
#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
@ -181,8 +175,8 @@
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
/* Hash constant words K for SHA-256: */ /* Hash constant words K for SHA-224 and SHA-256: */
const static u_int32_t K256[64] = { static const u_int32_t K256[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
@ -202,7 +196,7 @@ const static u_int32_t K256[64] = {
}; };
/* Initial hash value H for SHA-256: */ /* Initial hash value H for SHA-256: */
const static u_int32_t sha256_initial_hash_value[8] = { static const u_int32_t sha256_initial_hash_value[8] = {
0x6a09e667UL, 0x6a09e667UL,
0xbb67ae85UL, 0xbb67ae85UL,
0x3c6ef372UL, 0x3c6ef372UL,
@ -214,7 +208,7 @@ const static u_int32_t sha256_initial_hash_value[8] = {
}; };
/* Hash constant words K for SHA-384 and SHA-512: */ /* Hash constant words K for SHA-384 and SHA-512: */
const static u_int64_t K512[80] = { static const u_int64_t K512[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
@ -257,20 +251,8 @@ const static u_int64_t K512[80] = {
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
}; };
/* Initial hash value H for SHA-384 */
const static u_int64_t sha384_initial_hash_value[8] = {
0xcbbb9d5dc1059ed8ULL,
0x629a292a367cd507ULL,
0x9159015a3070dd17ULL,
0x152fecd8f70e5939ULL,
0x67332667ffc00b31ULL,
0x8eb44a8768581511ULL,
0xdb0c2e0d64f98fa7ULL,
0x47b5481dbefa4fa4ULL
};
/* Initial hash value H for SHA-512 */ /* Initial hash value H for SHA-512 */
const static u_int64_t sha512_initial_hash_value[8] = { static const u_int64_t sha512_initial_hash_value[8] = {
0x6a09e667f3bcc908ULL, 0x6a09e667f3bcc908ULL,
0xbb67ae8584caa73bULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0x3c6ef372fe94f82bULL,
@ -281,18 +263,90 @@ const static u_int64_t sha512_initial_hash_value[8] = {
0x5be0cd19137e2179ULL 0x5be0cd19137e2179ULL
}; };
#if !defined(SHA2_SMALL)
/* Initial hash value H for SHA-224: */
static const u_int32_t sha224_initial_hash_value[8] = {
0xc1059ed8UL,
0x367cd507UL,
0x3070dd17UL,
0xf70e5939UL,
0xffc00b31UL,
0x68581511UL,
0x64f98fa7UL,
0xbefa4fa4UL
};
/* Initial hash value H for SHA-384 */
static const u_int64_t sha384_initial_hash_value[8] = {
0xcbbb9d5dc1059ed8ULL,
0x629a292a367cd507ULL,
0x9159015a3070dd17ULL,
0x152fecd8f70e5939ULL,
0x67332667ffc00b31ULL,
0x8eb44a8768581511ULL,
0xdb0c2e0d64f98fa7ULL,
0x47b5481dbefa4fa4ULL
};
/* Initial hash value H for SHA-512-256 */
static const u_int64_t sha512_256_initial_hash_value[8] = {
0x22312194fc2bf72cULL,
0x9f555fa3c84c64c2ULL,
0x2393b86b6f53b151ULL,
0x963877195940eabdULL,
0x96283ee2a88effe3ULL,
0xbe5e1e2553863992ULL,
0x2b0199fc2c85b8aaULL,
0x0eb72ddc81c52ca2ULL
};
/*** SHA-224: *********************************************************/
void
SHA224Init(SHA2_CTX *context)
{
memcpy(context->state.st32, sha224_initial_hash_value,
sizeof(sha224_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = 0;
}
DEF_WEAK(SHA224Init);
MAKE_CLONE(SHA224Transform, SHA256Transform);
MAKE_CLONE(SHA224Update, SHA256Update);
MAKE_CLONE(SHA224Pad, SHA256Pad);
DEF_WEAK(SHA224Transform);
DEF_WEAK(SHA224Update);
DEF_WEAK(SHA224Pad);
void
SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context)
{
SHA224Pad(context);
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
/* Convert TO host byte order */
for (i = 0; i < 7; i++)
BE_32_TO_8(digest + i * 4, context->state.st32[i]);
#else
memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH);
#endif
explicit_bzero(context, sizeof(*context));
}
DEF_WEAK(SHA224Final);
#endif /* !defined(SHA2_SMALL) */
/*** SHA-256: *********************************************************/ /*** SHA-256: *********************************************************/
void void
SHA256_Init(SHA256_CTX *context) SHA256Init(SHA2_CTX *context)
{ {
if (context == NULL) memcpy(context->state.st32, sha256_initial_hash_value,
return;
memcpy(context->state, sha256_initial_hash_value,
sizeof(sha256_initial_hash_value)); sizeof(sha256_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer)); memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount = 0; context->bitcount[0] = 0;
} }
DEF_WEAK(SHA256Init);
#ifdef SHA2_UNROLL_TRANSFORM #ifdef SHA2_UNROLL_TRANSFORM
@ -320,7 +374,7 @@ SHA256_Init(SHA256_CTX *context)
} while(0) } while(0)
void void
SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
{ {
u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t a, b, c, d, e, f, g, h, s0, s1;
u_int32_t T1, W256[16]; u_int32_t T1, W256[16];
@ -378,7 +432,7 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
#else /* SHA2_UNROLL_TRANSFORM */ #else /* SHA2_UNROLL_TRANSFORM */
void void
SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
{ {
u_int32_t a, b, c, d, e, f, g, h, s0, s1; u_int32_t a, b, c, d, e, f, g, h, s0, s1;
u_int32_t T1, T2, W256[16]; u_int32_t T1, T2, W256[16];
@ -451,17 +505,18 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
} }
#endif /* SHA2_UNROLL_TRANSFORM */ #endif /* SHA2_UNROLL_TRANSFORM */
DEF_WEAK(SHA256Transform);
void void
SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len) SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
{ {
size_t freespace, usedspace; u_int64_t freespace, usedspace;
/* Calling with no data is valid (we do nothing) */ /* Calling with no data is valid (we do nothing) */
if (len == 0) if (len == 0)
return; return;
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) { if (usedspace > 0) {
/* Calculate how much free space is available in the buffer */ /* Calculate how much free space is available in the buffer */
freespace = SHA256_BLOCK_LENGTH - usedspace; freespace = SHA256_BLOCK_LENGTH - usedspace;
@ -469,14 +524,14 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len)
if (len >= freespace) { if (len >= freespace) {
/* Fill the buffer completely and process it */ /* Fill the buffer completely and process it */
memcpy(&context->buffer[usedspace], data, freespace); memcpy(&context->buffer[usedspace], data, freespace);
context->bitcount += freespace << 3; context->bitcount[0] += freespace << 3;
len -= freespace; len -= freespace;
data += freespace; data += freespace;
SHA256_Transform(context->state, context->buffer); SHA256Transform(context->state.st32, context->buffer);
} else { } else {
/* The buffer is not yet full */ /* The buffer is not yet full */
memcpy(&context->buffer[usedspace], data, len); memcpy(&context->buffer[usedspace], data, len);
context->bitcount += len << 3; context->bitcount[0] += (u_int64_t)len << 3;
/* Clean up: */ /* Clean up: */
usedspace = freespace = 0; usedspace = freespace = 0;
return; return;
@ -484,26 +539,27 @@ SHA256_Update(SHA256_CTX *context, const u_int8_t *data, size_t len)
} }
while (len >= SHA256_BLOCK_LENGTH) { while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */ /* Process as many complete blocks as we can */
SHA256_Transform(context->state, data); SHA256Transform(context->state.st32, data);
context->bitcount += SHA256_BLOCK_LENGTH << 3; context->bitcount[0] += SHA256_BLOCK_LENGTH << 3;
len -= SHA256_BLOCK_LENGTH; len -= SHA256_BLOCK_LENGTH;
data += SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH;
} }
if (len > 0) { if (len > 0) {
/* There's left-overs, so save 'em */ /* There's left-overs, so save 'em */
memcpy(context->buffer, data, len); memcpy(context->buffer, data, len);
context->bitcount += len << 3; context->bitcount[0] += len << 3;
} }
/* Clean up: */ /* Clean up: */
usedspace = freespace = 0; usedspace = freespace = 0;
} }
DEF_WEAK(SHA256Update);
void void
SHA256_Pad(SHA256_CTX *context) SHA256Pad(SHA2_CTX *context)
{ {
unsigned int usedspace; unsigned int usedspace;
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) { if (usedspace > 0) {
/* Begin padding with a 1 bit: */ /* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80; context->buffer[usedspace++] = 0x80;
@ -518,7 +574,7 @@ SHA256_Pad(SHA256_CTX *context)
SHA256_BLOCK_LENGTH - usedspace); SHA256_BLOCK_LENGTH - usedspace);
} }
/* Do second-to-last transform: */ /* Do second-to-last transform: */
SHA256_Transform(context->state, context->buffer); SHA256Transform(context->state.st32, context->buffer);
/* Prepare for last transform: */ /* Prepare for last transform: */
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
@ -532,47 +588,45 @@ SHA256_Pad(SHA256_CTX *context)
} }
/* Store the length of input data (in bits) in big endian format: */ /* Store the length of input data (in bits) in big endian format: */
BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
context->bitcount); context->bitcount[0]);
/* Final transform: */ /* Final transform: */
SHA256_Transform(context->state, context->buffer); SHA256Transform(context->state.st32, context->buffer);
/* Clean up: */ /* Clean up: */
usedspace = 0; usedspace = 0;
} }
DEF_WEAK(SHA256Pad);
void void
SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context) SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)
{ {
SHA256_Pad(context); SHA256Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
int i; int i;
/* Convert TO host byte order */ /* Convert TO host byte order */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
BE_32_TO_8(digest + i * 4, context->state[i]); BE_32_TO_8(digest + i * 4, context->state.st32[i]);
#else #else
memcpy(digest, context->state, SHA256_DIGEST_LENGTH); memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);
#endif #endif
memset(context, 0, sizeof(*context)); explicit_bzero(context, sizeof(*context));
}
} }
DEF_WEAK(SHA256Final);
/*** SHA-512: *********************************************************/ /*** SHA-512: *********************************************************/
void void
SHA512_Init(SHA512_CTX *context) SHA512Init(SHA2_CTX *context)
{ {
if (context == NULL) memcpy(context->state.st64, sha512_initial_hash_value,
return;
memcpy(context->state, sha512_initial_hash_value,
sizeof(sha512_initial_hash_value)); sizeof(sha512_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer)); memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = context->bitcount[1] = 0; context->bitcount[0] = context->bitcount[1] = 0;
} }
DEF_WEAK(SHA512Init);
#ifdef SHA2_UNROLL_TRANSFORM #ifdef SHA2_UNROLL_TRANSFORM
@ -601,7 +655,7 @@ SHA512_Init(SHA512_CTX *context)
} while(0) } while(0)
void void
SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
{ {
u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t a, b, c, d, e, f, g, h, s0, s1;
u_int64_t T1, W512[16]; u_int64_t T1, W512[16];
@ -659,7 +713,7 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
#else /* SHA2_UNROLL_TRANSFORM */ #else /* SHA2_UNROLL_TRANSFORM */
void void
SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
{ {
u_int64_t a, b, c, d, e, f, g, h, s0, s1; u_int64_t a, b, c, d, e, f, g, h, s0, s1;
u_int64_t T1, T2, W512[16]; u_int64_t T1, T2, W512[16];
@ -732,9 +786,10 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
} }
#endif /* SHA2_UNROLL_TRANSFORM */ #endif /* SHA2_UNROLL_TRANSFORM */
DEF_WEAK(SHA512Transform);
void void
SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
{ {
size_t freespace, usedspace; size_t freespace, usedspace;
@ -753,7 +808,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
ADDINC128(context->bitcount, freespace << 3); ADDINC128(context->bitcount, freespace << 3);
len -= freespace; len -= freespace;
data += freespace; data += freespace;
SHA512_Transform(context->state, context->buffer); SHA512Transform(context->state.st64, context->buffer);
} else { } else {
/* The buffer is not yet full */ /* The buffer is not yet full */
memcpy(&context->buffer[usedspace], data, len); memcpy(&context->buffer[usedspace], data, len);
@ -765,7 +820,7 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
} }
while (len >= SHA512_BLOCK_LENGTH) { while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */ /* Process as many complete blocks as we can */
SHA512_Transform(context->state, data); SHA512Transform(context->state.st64, data);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH; len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH;
@ -778,9 +833,10 @@ SHA512_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
/* Clean up: */ /* Clean up: */
usedspace = freespace = 0; usedspace = freespace = 0;
} }
DEF_WEAK(SHA512Update);
void void
SHA512_Pad(SHA512_CTX *context) SHA512Pad(SHA2_CTX *context)
{ {
unsigned int usedspace; unsigned int usedspace;
@ -797,7 +853,7 @@ SHA512_Pad(SHA512_CTX *context)
memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
} }
/* Do second-to-last transform: */ /* Do second-to-last transform: */
SHA512_Transform(context->state, context->buffer); SHA512Transform(context->state.st64, context->buffer);
/* And set-up for the last transform: */ /* And set-up for the last transform: */
memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
@ -816,89 +872,104 @@ SHA512_Pad(SHA512_CTX *context)
context->bitcount[0]); context->bitcount[0]);
/* Final transform: */ /* Final transform: */
SHA512_Transform(context->state, context->buffer); SHA512Transform(context->state.st64, context->buffer);
/* Clean up: */ /* Clean up: */
usedspace = 0; usedspace = 0;
} }
DEF_WEAK(SHA512Pad);
void void
SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)
{ {
SHA512_Pad(context); SHA512Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
int i; int i;
/* Convert TO host byte order */ /* Convert TO host byte order */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
BE_64_TO_8(digest + i * 8, context->state[i]); BE_64_TO_8(digest + i * 8, context->state.st64[i]);
#else #else
memcpy(digest, context->state, SHA512_DIGEST_LENGTH); memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);
#endif #endif
memset(context, 0, sizeof(*context)); explicit_bzero(context, sizeof(*context));
}
} }
DEF_WEAK(SHA512Final);
#if !defined(SHA2_SMALL)
/*** SHA-384: *********************************************************/ /*** SHA-384: *********************************************************/
void void
SHA384_Init(SHA384_CTX *context) SHA384Init(SHA2_CTX *context)
{ {
if (context == NULL) memcpy(context->state.st64, sha384_initial_hash_value,
return;
memcpy(context->state, sha384_initial_hash_value,
sizeof(sha384_initial_hash_value)); sizeof(sha384_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer)); memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = context->bitcount[1] = 0; context->bitcount[0] = context->bitcount[1] = 0;
} }
DEF_WEAK(SHA384Init);
#if 0 MAKE_CLONE(SHA384Transform, SHA512Transform);
__weak_alias(SHA384_Transform, SHA512_Transform); MAKE_CLONE(SHA384Update, SHA512Update);
__weak_alias(SHA384_Update, SHA512_Update); MAKE_CLONE(SHA384Pad, SHA512Pad);
__weak_alias(SHA384_Pad, SHA512_Pad); DEF_WEAK(SHA384Transform);
#endif DEF_WEAK(SHA384Update);
DEF_WEAK(SHA384Pad);
void void
SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)
{ {
return SHA512_Transform(state, data); SHA384Pad(context);
}
void
SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len)
{
SHA512_Update(context, data, len);
}
void
SHA384_Pad(SHA512_CTX *context)
{
SHA512_Pad(context);
}
void
SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context)
{
SHA384_Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN #if BYTE_ORDER == LITTLE_ENDIAN
int i; int i;
/* Convert TO host byte order */ /* Convert TO host byte order */
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
BE_64_TO_8(digest + i * 8, context->state[i]); BE_64_TO_8(digest + i * 8, context->state.st64[i]);
#else #else
memcpy(digest, context->state, SHA384_DIGEST_LENGTH); memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);
#endif #endif
}
/* Zero out state data */ /* Zero out state data */
memset(context, 0, sizeof(*context)); explicit_bzero(context, sizeof(*context));
} }
DEF_WEAK(SHA384Final);
#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ /*** SHA-512/256: *********************************************************/
void
SHA512_256Init(SHA2_CTX *context)
{
memcpy(context->state.st64, sha512_256_initial_hash_value,
sizeof(sha512_256_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = context->bitcount[1] = 0;
}
DEF_WEAK(SHA512_256Init);
MAKE_CLONE(SHA512_256Transform, SHA512Transform);
MAKE_CLONE(SHA512_256Update, SHA512Update);
MAKE_CLONE(SHA512_256Pad, SHA512Pad);
DEF_WEAK(SHA512_256Transform);
DEF_WEAK(SHA512_256Update);
DEF_WEAK(SHA512_256Pad);
void
SHA512_256Final(u_int8_t digest[SHA512_256_DIGEST_LENGTH], SHA2_CTX *context)
{
SHA512_256Pad(context);
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
/* Convert TO host byte order */
for (i = 0; i < 4; i++)
BE_64_TO_8(digest + i * 8, context->state.st64[i]);
#else
memcpy(digest, context->state.st64, SHA512_256_DIGEST_LENGTH);
#endif
/* Zero out state data */
explicit_bzero(context, sizeof(*context));
}
DEF_WEAK(SHA512_256Final);
#endif /* !defined(SHA2_SMALL) */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sha2.h,v 1.6 2004/06/22 01:57:30 jfb Exp */ /* $OpenBSD: sha2.h,v 1.10 2016/09/03 17:00:29 tedu Exp $ */
/* /*
* FILE: sha2.h * FILE: sha2.h
@ -34,25 +34,14 @@
* $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
*/ */
/* OPENBSD ORIGINAL: include/sha2.h */ #ifndef _SHA2_H
#define _SHA2_H
#ifndef _SSHSHA2_H
#define _SSHSHA2_H
#include "includes.h"
#ifdef WITH_OPENSSL
# include <openssl/opensslv.h>
# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
# define _NEED_SHA2 1
# endif
#else
# define _NEED_SHA2 1
#endif
#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE)
/*** SHA-256/384/512 Various Length Definitions ***********************/ /*** SHA-256/384/512 Various Length Definitions ***********************/
#define SHA224_BLOCK_LENGTH 64
#define SHA224_DIGEST_LENGTH 28
#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
#define SHA256_BLOCK_LENGTH 64 #define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
@ -62,73 +51,106 @@
#define SHA512_BLOCK_LENGTH 128 #define SHA512_BLOCK_LENGTH 128
#define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
#define SHA512_256_BLOCK_LENGTH 128
#define SHA512_256_DIGEST_LENGTH 32
#define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structures *******************************/ /*** SHA-224/256/384/512 Context Structure *******************************/
typedef struct _SHA256_CTX { typedef struct _SHA2_CTX {
u_int32_t state[8]; union {
u_int64_t bitcount; u_int32_t st32[8];
u_int8_t buffer[SHA256_BLOCK_LENGTH]; u_int64_t st64[8];
} SHA256_CTX; } state;
typedef struct _SHA512_CTX {
u_int64_t state[8];
u_int64_t bitcount[2]; u_int64_t bitcount[2];
u_int8_t buffer[SHA512_BLOCK_LENGTH]; u_int8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX; } SHA2_CTX;
typedef SHA512_CTX SHA384_CTX; __BEGIN_DECLS
void SHA224Init(SHA2_CTX *);
void SHA256_Init(SHA256_CTX *); void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]);
void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t)
void SHA256_Update(SHA256_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3))); __attribute__((__bounded__(__string__,2,3)));
void SHA256_Pad(SHA256_CTX *); void SHA224Pad(SHA2_CTX *);
void SHA256_Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA256_CTX *) void SHA224Final(u_int8_t [SHA224_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA224_DIGEST_LENGTH)));
char *SHA224End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
char *SHA224File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
char *SHA224FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH)));
char *SHA224Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA224_DIGEST_STRING_LENGTH)));
void SHA256Init(SHA2_CTX *);
void SHA256Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]);
void SHA256Update(SHA2_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3)));
void SHA256Pad(SHA2_CTX *);
void SHA256Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH))); __attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH)));
char *SHA256_End(SHA256_CTX *, char *) char *SHA256End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH)));
char *SHA256_File(const char *, char *) char *SHA256File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH)));
char *SHA256_FileChunk(const char *, char *, off_t, off_t) char *SHA256FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH)));
char *SHA256_Data(const u_int8_t *, size_t, char *) char *SHA256Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH)));
void SHA384_Init(SHA384_CTX *); void SHA384Init(SHA2_CTX *);
void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); void SHA384Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]);
void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) void SHA384Update(SHA2_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3))); __attribute__((__bounded__(__string__,2,3)));
void SHA384_Pad(SHA384_CTX *); void SHA384Pad(SHA2_CTX *);
void SHA384_Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA384_CTX *) void SHA384Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH))); __attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH)));
char *SHA384_End(SHA384_CTX *, char *) char *SHA384End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH)));
char *SHA384_File(const char *, char *) char *SHA384File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH)));
char *SHA384_FileChunk(const char *, char *, off_t, off_t) char *SHA384FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH)));
char *SHA384_Data(const u_int8_t *, size_t, char *) char *SHA384Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH)));
void SHA512_Init(SHA512_CTX *); void SHA512Init(SHA2_CTX *);
void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); void SHA512Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]);
void SHA512_Update(SHA512_CTX *, const u_int8_t *, size_t) void SHA512Update(SHA2_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3))); __attribute__((__bounded__(__string__,2,3)));
void SHA512_Pad(SHA512_CTX *); void SHA512Pad(SHA2_CTX *);
void SHA512_Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA512_CTX *) void SHA512Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH))); __attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH)));
char *SHA512_End(SHA512_CTX *, char *) char *SHA512End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH)));
char *SHA512_File(const char *, char *) char *SHA512File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH)));
char *SHA512_FileChunk(const char *, char *, off_t, off_t) char *SHA512FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH)));
char *SHA512_Data(const u_int8_t *, size_t, char *) char *SHA512Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH)));
#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ void SHA512_256Init(SHA2_CTX *);
void SHA512_256Transform(u_int64_t state[8], const u_int8_t [SHA512_256_BLOCK_LENGTH]);
void SHA512_256Update(SHA2_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3)));
void SHA512_256Pad(SHA2_CTX *);
void SHA512_256Final(u_int8_t [SHA512_256_DIGEST_LENGTH], SHA2_CTX *)
__attribute__((__bounded__(__minbytes__,1,SHA512_256_DIGEST_LENGTH)));
char *SHA512_256End(SHA2_CTX *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
char *SHA512_256File(const char *, char *)
__attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
char *SHA512_256FileChunk(const char *, char *, off_t, off_t)
__attribute__((__bounded__(__minbytes__,2,SHA512_256_DIGEST_STRING_LENGTH)));
char *SHA512_256Data(const u_int8_t *, size_t, char *)
__attribute__((__bounded__(__string__,1,2)))
__attribute__((__bounded__(__minbytes__,3,SHA512_256_DIGEST_STRING_LENGTH)));
__END_DECLS
#endif /* _SSHSHA2_H */ #endif /* _SHA2_H */