From e9d0c5cc5038a9c202207078c01f9d20dd355334 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sun, 19 Dec 2010 00:32:24 -1000 Subject: [PATCH] Add SHA384 functions to libmd. --- lib/libmd/Makefile | 4 ++- lib/libmd/sha384.3 | 77 +++++++++++++++++++++++++++++++++++++++ lib/libmd/sha512.h | 7 ++++ lib/libmd/sha512c.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 lib/libmd/sha384.3 diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile index c7b2d048ae..3f8273abdb 100644 --- a/lib/libmd/Makefile +++ b/lib/libmd/Makefile @@ -9,7 +9,7 @@ SRCS= md2c.c md4c.c md5c.c md2hl.c md4hl.c md5hl.c \ INCS= md2.h md4.h md5.h ripemd.h sha.h sha256.h sha512.h WARNS?= 2 -MAN+= md2.3 md4.3 md5.3 ripemd.3 sha.3 sha256.3 sha512.3 +MAN+= md2.3 md4.3 md5.3 ripemd.3 sha.3 sha256.3 sha384.3 sha512.3 MLINKS+=md2.3 MD2Init.3 md2.3 MD2Update.3 md2.3 MD2Pad.3 md2.3 MD2Final.3 MLINKS+=md2.3 MD2End.3 md2.3 MD2File.3 md2.3 MD2FileChunk.3 MLINKS+=md2.3 MD2Data.3 @@ -33,6 +33,8 @@ MLINKS+=sha256.3 SHA256_Init.3 sha256.3 SHA256_Update.3 MLINKS+=sha256.3 SHA256_Final.3 sha256.3 SHA256_End.3 MLINKS+=sha256.3 SHA256_File.3 sha256.3 SHA256_FileChunk.3 MLINKS+=sha256.3 SHA256_Data.3 +MLINKS+=sha384.3 SHA384_Init.3 sha384.3 SHA384_Update.3 +MLINKS+=sha384.3 SHA384_Final.3 MLINKS+=sha512.3 SHA512_Init.3 sha512.3 SHA512_Update.3 MLINKS+=sha512.3 SHA512_Final.3 sha512.3 SHA512_End.3 MLINKS+=sha512.3 SHA512_File.3 sha512.3 SHA512_FileChunk.3 diff --git a/lib/libmd/sha384.3 b/lib/libmd/sha384.3 new file mode 100644 index 0000000000..f0e459b372 --- /dev/null +++ b/lib/libmd/sha384.3 @@ -0,0 +1,77 @@ +.\" +.\" ---------------------------------------------------------------------------- +.\" "THE BEER-WARE LICENSE" (Revision 42): +.\" wrote this file. As long as you retain this notice you +.\" can do whatever you want with this stuff. If we meet some day, and you think +.\" this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +.\" ---------------------------------------------------------------------------- +.\" +.\" From: Id: mdX.3,v 1.14 1999/02/11 20:31:49 wollman Exp +.\" $FreeBSD: src/lib/libmd/sha512.3,v 1.4 2005/11/17 13:00:00 ru Exp $ +.\" $DragonFly: src/lib/libmd/sha512.3,v 1.2 2008/09/11 20:25:34 swildner Exp $ +.\" +.Dd July 4, 2010 +.Dt SHA384 3 +.Os +.Sh NAME +.Nm SHA384_Init , +.Nm SHA384_Update , +.Nm SHA384_Final +.Nd calculate the FIPS 180-2 ``SHA-384'' message digest +.Sh LIBRARY +.Lb libmd +.Sh SYNOPSIS +.In sys/types.h +.In sha512.h +.Ft void +.Fn SHA384_Init "SHA384_CTX *context" +.Ft void +.Fn SHA384_Update "SHA384_CTX *context" "const u_int8_t *data" "size_t len" +.Ft void +.Fn SHA384_Final "u_int8_t digest[48]" "SHA384_CTX *context" +.Sh DESCRIPTION +The +.Li SHA384_ +functions calculate a 384-bit cryptographic checksum (digest) +for any number of input bytes. +A cryptographic checksum is a one-way +hash function; that is, it is computationally impractical to find +the input corresponding to a particular output. +This net result is +a +.Dq fingerprint +of the input-data, which does not disclose the actual input. +.Pp +The +.Fn SHA384_Init , +.Fn SHA384_Update , +and +.Fn SHA384_Final +functions are the core functions. +Allocate an +.Vt SHA384_CTX , +initialize it with +.Fn SHA384_Init , +run over the data with +.Fn SHA384_Update , +and finally extract the result using +.Fn SHA384_Final . +.Pp +.Sh SEE ALSO +.Xr md2 3 , +.Xr md4 3 , +.Xr md5 3 , +.Xr ripemd 3 , +.Xr sha 3 +.Sh HISTORY +These functions appeared in +.Dx 2.9 . +.Sh AUTHORS +The core hash routines were implemented by Colin Percival based on +the published +.Tn FIPS 180-2 +standard. +.Sh BUGS +No method is known to exist which finds two files having the same hash value, +nor to find a file with a specific hash value. +There is on the other hand no guarantee that such a method does not exist. diff --git a/lib/libmd/sha512.h b/lib/libmd/sha512.h index eeaf339100..dc8c68c323 100644 --- a/lib/libmd/sha512.h +++ b/lib/libmd/sha512.h @@ -31,6 +31,9 @@ #define _SHA512_H_ #include +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) @@ -41,8 +44,12 @@ typedef struct _SHA512_CTX { u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; +typedef SHA512_CTX SHA384_CTX; __BEGIN_DECLS +void SHA384_Init(SHA384_CTX *); +void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX *); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const void *, size_t); void SHA512_Final(unsigned char [SHA512_DIGEST_LENGTH], SHA512_CTX *); diff --git a/lib/libmd/sha512c.c b/lib/libmd/sha512c.c index 4f3bb48947..da8d616116 100644 --- a/lib/libmd/sha512c.c +++ b/lib/libmd/sha512c.c @@ -94,6 +94,18 @@ typedef u_int8_t sha2_byte; /* Exactly 1 byte */ typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ +/* Initial hash value H for SHA-384 */ +static const sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + /* Initial hash value H for SHA-512 */ static const sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, @@ -409,3 +421,78 @@ char* SHA512_Data(const void *data, size_t len, char *digest) { #endif +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA384_CTX* context) { + if (context == NULL) { + return; + } + bcopy(sha384_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); + bzero(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != NULL); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != NULL) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + bcopy(context->state, d, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + bzero(context, sizeof(*context)); +} + +#if 0 +char *SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != NULL); + + if (buffer != NULL) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + bzero(context, sizeof(*context)); + } + bzero(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} +#endif -- 2.41.0