Browse Source

SHA-224 is to SHA-256 as SHA-384 is to SHA-512. It was added in a

later revision of FIPS-180.  OK miod@ jmc@ guenther@ djm@
OPENBSD_5_4
millert 11 years ago
parent
commit
e648dc1623
4 changed files with 113 additions and 17 deletions
  1. +22
    -2
      src/include/sha2.h
  2. +10
    -2
      src/lib/libc/hash/Makefile.inc
  3. +23
    -4
      src/lib/libc/hash/sha2.3
  4. +58
    -9
      src/lib/libc/hash/sha2.c

+ 22
- 2
src/include/sha2.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: sha2.h,v 1.8 2012/12/05 23:19:57 deraadt Exp $ */
/* $OpenBSD: sha2.h,v 1.9 2013/04/15 15:54:17 millert Exp $ */
/*
* FILE: sha2.h
@ -39,6 +39,9 @@
/*** 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_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
@ -50,7 +53,7 @@
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structure *******************************/
/*** SHA-224/256/384/512 Context Structure *******************************/
typedef struct _SHA2_CTX {
union {
u_int32_t st32[8];
@ -61,6 +64,23 @@ typedef struct _SHA2_CTX {
} SHA2_CTX;
__BEGIN_DECLS
void SHA224Init(SHA2_CTX *);
void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]);
void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t)
__attribute__((__bounded__(__string__,2,3)));
void SHA224Pad(SHA2_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)


+ 10
- 2
src/lib/libc/hash/Makefile.inc View File

@ -1,9 +1,9 @@
# $OpenBSD: Makefile.inc,v 1.18 2008/09/06 12:00:19 djm Exp $
# $OpenBSD: Makefile.inc,v 1.19 2013/04/15 15:54:17 millert Exp $
# hash functions
.PATH: ${LIBCSRCDIR}/hash
HELPER= md4hl.c md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c
HELPER= md4hl.c md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c
SRCS+= md4.c md5.c rmd160.c sha1.c sha2.c ${HELPER}
MAN+= md4.3 md5.3 rmd160.3 sha1.3 sha2.3
@ -19,6 +19,9 @@ MLINKS+=rmd160.3 RMD160FileChunk.3 rmd160.3 RMD160Pad.3 rmd160.3 RMD160Data.3
MLINKS+=sha1.3 SHA1Transform.3 sha1.3 SHA1Init.3 sha1.3 SHA1Final.3
MLINKS+=sha1.3 SHA1Update.3 sha1.3 SHA1End.3 sha1.3 SHA1File.3
MLINKS+=sha1.3 SHA1FileChunk.3 sha1.3 SHA1Pad.3 sha1.3 SHA1Data.3
MLINKS+=sha2.3 SHA224Init.3 sha2.3 SHA224Update.3 sha2.3 SHA224Pad.3
MLINKS+=sha2.3 SHA224Final.3 sha2.3 SHA224Transform.3 sha2.3 SHA224End.3
MLINKS+=sha2.3 SHA224File.3 sha2.3 SHA224FileChunk.3 sha2.3 SHA224Data.3
MLINKS+=sha2.3 SHA256Init.3 sha2.3 SHA256Update.3 sha2.3 SHA256Pad.3
MLINKS+=sha2.3 SHA256Final.3 sha2.3 SHA256Transform.3 sha2.3 SHA256End.3
MLINKS+=sha2.3 SHA256File.3 sha2.3 SHA256FileChunk.3 sha2.3 SHA256Data.3
@ -52,6 +55,11 @@ rmd160hl.c: helper.c
sha1hl.c: helper.c
sed -e 's/hashinc/sha1.h/g' -e 's/HASH/SHA1/g' $> > $@
sha224hl.c: helper.c
sed -e 's/hashinc/sha2.h/g' \
-e 's/HASH/SHA224/g' \
-e 's/SHA[0-9][0-9][0-9]_CTX/SHA2_CTX/g' $> > $@
sha256hl.c: helper.c
sed -e 's/hashinc/sha2.h/g' \
-e 's/HASH/SHA256/g' \


+ 23
- 4
src/lib/libc/hash/sha2.3 View File

@ -1,4 +1,4 @@
.\" $OpenBSD: sha2.3,v 1.17 2012/09/07 23:11:51 tedu Exp $
.\" $OpenBSD: sha2.3,v 1.18 2013/04/15 15:54:17 millert Exp $
.\"
.\" Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@ -20,7 +20,7 @@
.\"
.\" See http://www.nist.gov/sha/ for the detailed standard
.\"
.Dd $Mdocdate: September 7 2012 $
.Dd $Mdocdate: April 15 2013 $
.Dt SHA2 3
.Os
.Sh NAME
@ -38,6 +38,24 @@
.Fd #include <sys/types.h>
.Fd #include <sha2.h>
.Ft void
.Fn SHA224Init "SHA2_CTX *context"
.Ft void
.Fn SHA224Update "SHA2_CTX *context" "const u_int8_t *data" "size_t len"
.Ft void
.Fn SHA224Pad "SHA2_CTX *context"
.Ft void
.Fn SHA224Final "u_int8_t digest[SHA224_DIGEST_LENGTH]" "SHA2_CTX *context"
.Ft void
.Fn SHA224Transform "u_int32_t state[8]" "const u_int8_t buffer[SHA224_BLOCK_LENGTH]"
.Ft "char *"
.Fn SHA224End "SHA2_CTX *context" "char *buf"
.Ft "char *"
.Fn SHA224File "const char *filename" "char *buf"
.Ft "char *"
.Fn SHA224FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
.Ft "char *"
.Fn SHA224Data "const u_int8_t *data" "size_t len" "char *buf"
.Ft void
.Fn SHA256Init "SHA2_CTX *context"
.Ft void
.Fn SHA256Update "SHA2_CTX *context" "const u_int8_t *data" "size_t len"
@ -98,7 +116,7 @@ The SHA2 functions are used to generate a condensed representation of a
message called a message digest, suitable for use as a digital signature.
There are three families of functions, with names corresponding to
the number of bits in the resulting message digest.
The SHA-256 functions are limited to processing a message of less
The SHA-224 and SHA-256 functions are limited to processing a message of less
than 2^64 bits as input.
The SHA-384 and SHA-512 functions can process a message of at most 2^128 - 1
bits as input.
@ -106,7 +124,7 @@ bits as input.
The SHA2 functions are considered to be more secure than the
.Xr sha1 3
functions with which they share a similar interface.
The 256, 384, and 512-bit versions of SHA2 share the same interface.
The 224, 256, 384, and 512-bit versions of SHA2 share the same interface.
For brevity, only the 256-bit variants are described below.
.Pp
The
@ -204,6 +222,7 @@ functions the
.Ar buf
parameter should either be a string large enough to hold the resulting digest
(e.g.\&
.Ev SHA224_DIGEST_STRING_LENGTH ,
.Ev SHA256_DIGEST_STRING_LENGTH ,
.Ev SHA384_DIGEST_STRING_LENGTH ,
or


+ 58
- 9
src/lib/libc/hash/sha2.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: sha2.c,v 1.13 2009/04/15 00:55:52 djm Exp $ */
/* $OpenBSD: sha2.c,v 1.14 2013/04/15 15:54:17 millert Exp $ */
/*
* FILE: sha2.c
@ -53,7 +53,7 @@
*
*/
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
/*
* BYTE_ORDER NOTE:
*
@ -86,8 +86,9 @@
#endif
/*** SHA-256/384/512 Various Length Definitions ***********************/
/*** SHA-224/256/384/512 Various Length Definitions ***********************/
/* 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 SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
@ -140,22 +141,22 @@
* 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
* 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
* 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))
/* 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))))
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
#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 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 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)))
@ -169,7 +170,7 @@
/*** 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] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
@ -189,6 +190,18 @@ const static u_int32_t K256[64] = {
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
/* Initial hash value H for SHA-224: */
const static u_int32_t sha224_initial_hash_value[8] = {
0xc1059ed8UL,
0x367cd507UL,
0x3070dd17UL,
0xf70e5939UL,
0xffc00b31UL,
0x68581511UL,
0x64f98fa7UL,
0xbefa4fa4UL
};
/* Initial hash value H for SHA-256: */
const static u_int32_t sha256_initial_hash_value[8] = {
0x6a09e667UL,
@ -269,6 +282,42 @@ const static u_int64_t sha512_initial_hash_value[8] = {
0x1f83d9abfb41bd6bULL,
0x5be0cd19137e2179ULL
};
/*** SHA-224: *********************************************************/
void
SHA224Init(SHA2_CTX *context)
{
if (context == NULL)
return;
memcpy(context->state.st32, sha224_initial_hash_value,
sizeof(sha224_initial_hash_value));
memset(context->buffer, 0, sizeof(context->buffer));
context->bitcount[0] = 0;
}
__weak_alias(SHA224Transform, SHA256Transform);
__weak_alias(SHA224Update, SHA256Update);
__weak_alias(SHA224Pad, SHA256Pad);
void
SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context)
{
SHA224Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#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
memset(context, 0, sizeof(*context));
}
}
#endif /* SHA256_ONLY */
/*** SHA-256: *********************************************************/


Loading…
Cancel
Save