Add SHA384 functions to libmd.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 19 Dec 2010 10:32:24 +0000 (00:32 -1000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sun, 19 Dec 2010 12:49:51 +0000 (02:49 -1000)
lib/libmd/Makefile
lib/libmd/sha384.3 [new file with mode: 0644]
lib/libmd/sha512.h
lib/libmd/sha512c.c

index c7b2d04..3f8273a 100644 (file)
@@ -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 (file)
index 0000000..f0e459b
--- /dev/null
@@ -0,0 +1,77 @@
+.\"
+.\" ----------------------------------------------------------------------------
+.\" "THE BEER-WARE LICENSE" (Revision 42):
+.\" <phk@FreeBSD.org> 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.
index eeaf339..dc8c68c 100644 (file)
@@ -31,6 +31,9 @@
 #define _SHA512_H_
 
 #include <sys/types.h>
+#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 *);
index 4f3bb48..da8d616 100644 (file)
@@ -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