#
# Makefile for onak.
#
-# $Id: Makefile,v 1.22 2004/05/31 14:16:49 noodles Exp $
+# $Id: Makefile,v 1.23 2004/05/31 22:04:50 noodles Exp $
#
CC = gcc
PROGS = add lookup gpgwww onak splitkeys
CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o keydb_$(DBTYPE).o \
- keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o md5.o \
+ keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha1.o md5.o \
log.o photoid.o wordlist.o
OBJS = merge.o stats.o sendsync.o cleankey.o $(CORE_OBJS)
-SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha.c main.c getcgi.c stats.c \
- keyindex.c mem.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \
+SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha1.c main.c getcgi.c mem.c \
+ keyindex.c stats.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \
gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \
wordlist.c cleankey.c
+++ /dev/null
-/* bithelp.h - Some bit manipulation helpers
- * Copyright (C) 1999 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id: bithelp.h,v 1.4 2003/10/04 10:21:40 noodles Exp $
- */
-
-#ifndef __BITHELP_H__
-#define __BITHELP_H__
-
-/**
- * rol - Rotate a 32 bit integer by n bytes
- * @x: The integer to rotate.
- * @n: The number of bytes to rotate it by.
- */
-static inline unsigned int rol(unsigned int x, int n)
-{
- __asm__("roll %%cl,%0"
- :"=r" (x)
- :"0" (x),"c" (n));
- return x;
-}
-
-#endif /* __BITHELP_H__ */
*
* Copyright 2002 Project Purple
*
- * $Id: keyid.c,v 1.9 2004/05/29 02:52:56 noodles Exp $
+ * $Id: keyid.c,v 1.10 2004/05/31 22:04:51 noodles Exp $
*/
#include <sys/types.h>
+#include "assert.h"
#include "keyid.h"
#include "keystructs.h"
#include "log.h"
#include "md5.h"
-#include "sha.h"
+#include "sha1.h"
/**
unsigned char *fingerprint,
size_t *len)
{
- SHA1_CONTEXT sha_ctx;
- MD5_CONTEXT md5_ctx;
+ SHA1_CTX sha_ctx;
+ struct md5_ctx md5_context;
unsigned char c;
- unsigned char *buff = NULL;
size_t modlen, explen;
assert(fingerprint != NULL);
switch (packet->data[0]) {
case 2:
case 3:
- md5_init(&md5_ctx);
+ md5_init_ctx(&md5_context);
/*
* MD5 the modulus and exponent.
*/
modlen = ((packet->data[8] << 8) +
packet->data[9] + 7) >> 3;
- md5_write(&md5_ctx, &packet->data[10], modlen);
+ md5_process_bytes(&packet->data[10], modlen, &md5_context);
explen = ((packet->data[10+modlen] << 8) +
packet->data[11+modlen] + 7) >> 3;
- md5_write(&md5_ctx, &packet->data[12 + modlen], explen);
-
- md5_final(&md5_ctx);
- buff = md5_read(&md5_ctx);
+ md5_process_bytes(&packet->data[12 + modlen], explen,
+ &md5_context);
+ md5_finish_ctx(&md5_context, fingerprint);
*len = 16;
- memcpy(fingerprint, buff, *len);
break;
case 4:
- sha1_init(&sha_ctx);
+ SHA1Init(&sha_ctx);
/*
* TODO: Can this be 0x99? Are all public key packets old
* format with 2 bytes of length data?
*/
c = 0x99;
- sha1_write(&sha_ctx, &c, sizeof(c));
+ SHA1Update(&sha_ctx, &c, sizeof(c));
c = packet->length >> 8;
- sha1_write(&sha_ctx, &c, sizeof(c));
+ SHA1Update(&sha_ctx, &c, sizeof(c));
c = packet->length & 0xFF;
- sha1_write(&sha_ctx, &c, sizeof(c));
- sha1_write(&sha_ctx, packet->data,
+ SHA1Update(&sha_ctx, &c, sizeof(c));
+ SHA1Update(&sha_ctx, packet->data,
packet->length);
- sha1_final(&sha_ctx);
- buff = sha1_read(&sha_ctx);
-
+ SHA1Final(fingerprint, &sha_ctx);
*len = 20;
- memcpy(fingerprint, buff, *len);
+
break;
default:
logthing(LOGTHING_ERROR, "Unknown key type: %d",
-/* md5.c - MD5 Message-Digest Algorithm
- * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
- *
- * according to the definition of MD5 in RFC 1321 from April 1992.
- * NOTE: This is *not* the same file as the one from glibc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id: md5.c,v 1.4 2004/05/27 22:02:05 noodles Exp $
- */
+/* Functions to compute MD5 message digest of files or memory blocks.
+ according to the definition of MD5 in RFC 1321 from April 1992.
+ Copyright (C) 1995,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
-/* heavily modified for GnuPG by <werner.koch@guug.de> */
-/* Heavily modified for CryptNET KeyServer by V. Alex Brennen <vab@cryptnet.net> */
-
-/* Test values:
- * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
- * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
- * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
- * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
- */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
#include "md5.h"
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n) \
+ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+
+/* This array contains the bytes used to pad the buffer to the next
+ 64-byte boundary. (RFC 1321, 3.1: Step 1) */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
-void md5_init( MD5_CONTEXT *ctx )
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+void
+md5_init_ctx (ctx)
+ struct md5_ctx *ctx;
{
- ctx->A = 0x67452301;
- ctx->B = 0xefcdab89U;
- ctx->C = 0x98badcfeU;
- ctx->D = 0x10325476;
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
- ctx->nblocks = 0;
- ctx->count = 0;
+ ctx->total[0] = ctx->total[1] = 0;
+ ctx->buflen = 0;
}
-/* These are the four functions used in the four steps of the MD5 algorithm
- and defined in the RFC 1321. The first function is a little bit optimized
- (as found in Colin Plumbs public domain implementation). */
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
-#define FG(b, c, d) FF (d, b, c)
-#define FH(b, c, d) (b ^ c ^ d)
-#define FI(b, c, d) (c ^ (b | ~d))
-#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+/* Put result from CTX in first 16 bytes following RESBUF. The result
+ must be in little endian byte order.
-/****************
- * transform n*64 bytes
- */
-static void transform( MD5_CONTEXT *ctx, unsigned char *data )
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+md5_read_ctx (ctx, resbuf)
+ const struct md5_ctx *ctx;
+ void *resbuf;
{
- unsigned int correct_words[16];
- unsigned int A = ctx->A;
- unsigned int B = ctx->B;
- unsigned int C = ctx->C;
- unsigned int D = ctx->D;
- unsigned int *cwp = correct_words;
-
- memcpy( correct_words, data, 64 );
-
-
-#define OP(a, b, c, d, s, T) \
- do \
- { \
- a += FF (b, c, d) + (*cwp++) + T; \
- a = rol(a, s); \
- a += b; \
- } \
- while (0)
-
- /* Before we start, one word about the strange constants.
- They are defined in RFC 1321 as
-
- T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
- */
-
- /* Round 1. */
- OP (A, B, C, D, 7, 0xd76aa478);
- OP (D, A, B, C, 12, 0xe8c7b756);
- OP (C, D, A, B, 17, 0x242070db);
- OP (B, C, D, A, 22, 0xc1bdceee);
- OP (A, B, C, D, 7, 0xf57c0faf);
- OP (D, A, B, C, 12, 0x4787c62a);
- OP (C, D, A, B, 17, 0xa8304613);
- OP (B, C, D, A, 22, 0xfd469501);
- OP (A, B, C, D, 7, 0x698098d8);
- OP (D, A, B, C, 12, 0x8b44f7af);
- OP (C, D, A, B, 17, 0xffff5bb1);
- OP (B, C, D, A, 22, 0x895cd7be);
- OP (A, B, C, D, 7, 0x6b901122);
- OP (D, A, B, C, 12, 0xfd987193);
- OP (C, D, A, B, 17, 0xa679438e);
- OP (B, C, D, A, 22, 0x49b40821);
+ ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+ ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+ ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+ ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
-#undef OP
-#define OP(f, a, b, c, d, k, s, T) \
- do \
- { \
- a += f (b, c, d) + correct_words[k] + T; \
- a = rol(a, s); \
- a += b; \
- } \
- while (0)
-
- /* Round 2. */
- OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
- OP (FG, D, A, B, C, 6, 9, 0xc040b340);
- OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
- OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
- OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
- OP (FG, D, A, B, C, 10, 9, 0x02441453);
- OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
- OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
- OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
- OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
- OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
- OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
- OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
- OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
- OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
- OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-
- /* Round 3. */
- OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
- OP (FH, D, A, B, C, 8, 11, 0x8771f681);
- OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
- OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
- OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
- OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
- OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
- OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
- OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
- OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
- OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
- OP (FH, B, C, D, A, 6, 23, 0x04881d05);
- OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
- OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
- OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
- OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
-
- /* Round 4. */
- OP (FI, A, B, C, D, 0, 6, 0xf4292244);
- OP (FI, D, A, B, C, 7, 10, 0x432aff97);
- OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
- OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
- OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
- OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
- OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
- OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
- OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
- OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
- OP (FI, C, D, A, B, 6, 15, 0xa3014314);
- OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
- OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
- OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
- OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
- OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
-
- /* Put checksum in context given as argument. */
- ctx->A += A;
- ctx->B += B;
- ctx->C += C;
- ctx->D += D;
+ return resbuf;
}
+/* Process the remaining bytes in the internal buffer and the usual
+ prolog according to the standard and write the result to RESBUF.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+void *
+md5_finish_ctx (ctx, resbuf)
+ struct md5_ctx *ctx;
+ void *resbuf;
+{
+ /* Take yet unprocessed bytes into account. */
+ md5_uint32 bytes = ctx->buflen;
+ size_t pad;
+ /* Now count remaining bytes. */
+ ctx->total[0] += bytes;
+ if (ctx->total[0] < bytes)
+ ++ctx->total[1];
+
+ pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+ memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+ /* Put the 64-bit file length in *bits* at the end of the buffer. */
+ *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
+ *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
+ (ctx->total[0] >> 29));
+
+ /* Process last bytes. */
+ md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+ return md5_read_ctx (ctx, resbuf);
+}
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-void md5_write( MD5_CONTEXT *hd, unsigned char *inbuf, size_t inlen)
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+int
+md5_stream (stream, resblock)
+ FILE *stream;
+ void *resblock;
{
- if( hd->count == 64 ) { /* flush the buffer */
- transform( hd, hd->buf );
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
- if( hd->count ) {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- md5_write( hd, NULL, 0 );
- if( !inlen )
- return;
+ /* Important: BLOCKSIZE must be a multiple of 64. */
+#define BLOCKSIZE 4096
+ struct md5_ctx ctx;
+ char buffer[BLOCKSIZE + 72];
+ size_t sum;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ /* Iterate over full file contents. */
+ while (1)
+ {
+ /* We read the file in blocks of BLOCKSIZE bytes. One call of the
+ computation function processes the whole buffer so that with the
+ next round of the loop another block can be read. */
+ size_t n;
+ sum = 0;
+
+ /* Read block. Take care for partial reads. */
+ do
+ {
+ n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+ sum += n;
+ }
+ while (sum < BLOCKSIZE && n != 0);
+ if (n == 0 && ferror (stream))
+ return 1;
+
+ /* If end of file is reached, end the loop. */
+ if (n == 0)
+ break;
+
+ /* Process buffer with BLOCKSIZE bytes. Note that
+ BLOCKSIZE % 64 == 0
+ */
+ md5_process_block (buffer, BLOCKSIZE, &ctx);
}
- while( inlen >= 64 ) {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
+ /* Add the last bytes if necessary. */
+ if (sum > 0)
+ md5_process_bytes (buffer, sum, &ctx);
+ /* Construct result in desired memory. */
+ md5_finish_ctx (&ctx, resblock);
+ return 0;
}
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+void *
+md5_buffer (buffer, len, resblock)
+ const char *buffer;
+ size_t len;
+ void *resblock;
+{
+ struct md5_ctx ctx;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ /* Process whole buffer but last len % 64 bytes. */
+ md5_process_bytes (buffer, len, &ctx);
+ /* Put result in desired memory area. */
+ return md5_finish_ctx (&ctx, resblock);
+}
-/* The routine final terminates the message-digest computation and
- * ends with the desired message digest in mdContext->digest[0...15].
- * The handle is prepared for a new MD5 cycle.
- * Returns 16 bytes representing the digest.
- */
-void md5_final( MD5_CONTEXT *hd )
+void
+md5_process_bytes (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct md5_ctx *ctx;
{
- unsigned int t, msb, lsb;
- unsigned char *p;
-
- md5_write(hd, NULL, 0); /* flush */;
-
- msb = 0;
- t = hd->nblocks;
- if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
- msb++;
- msb += t >> 26;
- t = lsb;
- if( (lsb = t + hd->count) < t ) /* add the count */
- msb++;
- t = lsb;
- if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
- msb++;
- msb += t >> 29;
-
- if( hd->count < 56 ) { /* enough room */
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ /* When we already have some bits in our internal buffer concatenate
+ both inputs first. */
+ if (ctx->buflen != 0)
+ {
+ size_t left_over = ctx->buflen;
+ size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+ memcpy (&ctx->buffer[left_over], buffer, add);
+ ctx->buflen += add;
+
+ if (ctx->buflen > 64)
+ {
+ md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+ ctx->buflen &= 63;
+ /* The regions in the following copy operation cannot overlap. */
+ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+ ctx->buflen);
+ }
+
+ buffer = (const char *) buffer + add;
+ len -= add;
}
- else { /* need one extra block */
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- md5_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+
+ /* Process available complete blocks. */
+ if (len >= 64)
+ {
+#if !_STRING_ARCH_unaligned
+/* To check alignment gcc has an appropriate operator. Other
+ compilers don't. */
+# if __GNUC__ >= 2
+# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
+# else
+# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
+# endif
+ if (UNALIGNED_P (buffer))
+ while (len > 64)
+ {
+ md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+ buffer = (const char *) buffer + 64;
+ len -= 64;
+ }
+ else
+#endif
+ {
+ md5_process_block (buffer, len & ~63, ctx);
+ buffer = (const char *) buffer + (len & ~63);
+ len &= 63;
+ }
}
- /* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform( hd, hd->buf );
-
- p = hd->buf;
- /* little endian */
- /*#define X(a) do { *(u32*)p = hd->##a ; p += 4; } while(0)*/
- /* Unixware's cpp doesn't like the above construct so we do it his way:
- * (reported by Allan Clark) */
-#define X(a) do { *(unsigned int *)p = (*hd).a ; p += 4; } while(0)
- X(A);
- X(B);
- X(C);
- X(D);
-#undef X
+ /* Move remaining bytes in internal buffer. */
+ if (len > 0)
+ {
+ size_t left_over = ctx->buflen;
+
+ memcpy (&ctx->buffer[left_over], buffer, len);
+ left_over += len;
+ if (left_over >= 64)
+ {
+ md5_process_block (ctx->buffer, 64, ctx);
+ left_over -= 64;
+ memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+ }
+ ctx->buflen = left_over;
+ }
}
-unsigned char *md5_read(MD5_CONTEXT *hd)
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+ It is assumed that LEN % 64 == 0. */
+
+void
+md5_process_block (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct md5_ctx *ctx;
{
- return hd->buf;
+ md5_uint32 correct_words[16];
+ const md5_uint32 *words = buffer;
+ size_t nwords = len / sizeof (md5_uint32);
+ const md5_uint32 *endp = words + nwords;
+ md5_uint32 A = ctx->A;
+ md5_uint32 B = ctx->B;
+ md5_uint32 C = ctx->C;
+ md5_uint32 D = ctx->D;
+
+ /* First increment the byte count. RFC 1321 specifies the possible
+ length of the file up to 2^64 bits. Here we only compute the
+ number of bytes. Do a double word increment. */
+ ctx->total[0] += len;
+ if (ctx->total[0] < len)
+ ++ctx->total[1];
+
+ /* Process all bytes in the buffer with 64 bytes in each round of
+ the loop. */
+ while (words < endp)
+ {
+ md5_uint32 *cwp = correct_words;
+ md5_uint32 A_save = A;
+ md5_uint32 B_save = B;
+ md5_uint32 C_save = C;
+ md5_uint32 D_save = D;
+
+ /* First round: using the given function, the context and a constant
+ the next context is computed. Because the algorithms processing
+ unit is a 32-bit word and it is determined to work on words in
+ little endian byte order we perhaps have to change the byte order
+ before the computation. To reduce the work for the next steps
+ we store the swapped words in the array CORRECT_WORDS. */
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
+ ++words; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* It is unfortunate that C does not provide an operator for
+ cyclic rotation. Hope the C compiler is smart enough. */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+ /* Before we start, one word to the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+ /* For the second to fourth round we have the possibly swapped words
+ in CORRECT_WORDS. Redefine the macro to take an additional first
+ argument specifying the function to use. */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Add the starting values of the context. */
+ A += A_save;
+ B += B_save;
+ C += C_save;
+ D += D_save;
+ }
+
+ /* Put checksum in context given as argument. */
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
}
-#ifndef __MD5_H__
-#define __MD5_H__
+/* Declaration of functions and data types used for MD5 sum computing
+ library functions.
+ Copyright (C) 1995,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _MD5_H
+#define _MD5_H 1
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
+#include <sys/types.h>
+typedef u_int32_t md5_uint32;
+typedef size_t md5_uintptr;
+
+/* Structure to save state of computation between the single steps. */
+struct md5_ctx
+{
+ char buffer[128];
+ md5_uint32 A;
+ md5_uint32 B;
+ md5_uint32 C;
+ md5_uint32 D;
+
+ md5_uint32 total[2];
+ md5_uint32 buflen;
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+extern void md5_init_ctx (struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is necessary that LEN is a multiple of 64!!! */
+extern void md5_process_block (const void *buffer, size_t len,
+ struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+ initialization function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is NOT required that LEN is a multiple of 64. */
+extern void md5_process_bytes (const void *buffer, size_t len,
+ struct md5_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+ in first 16 bytes following RESBUF. The result is always in little
+ endian byte order, so that a byte-wise output yields to the wanted
+ ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 16 bytes following RESBUF. The result is
+ always in little endian byte order, so that a byte-wise output yields
+ to the wanted ASCII representation of the message digest.
+
+ IMPORTANT: On some systems it is required that RESBUF is correctly
+ aligned for a 32 bits value. */
+extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf);
-#include "bithelp.h"
-typedef struct {
- unsigned int A,B,C,D; /* chaining variables */
- unsigned int nblocks;
- unsigned char buf[64];
- int count;
-} MD5_CONTEXT;
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+extern int md5_stream (FILE *stream, void *resblock);
-void md5_init(MD5_CONTEXT *);
-void md5_write(MD5_CONTEXT *, unsigned char *, size_t);
-void md5_final(MD5_CONTEXT *);
-unsigned char *md5_read(MD5_CONTEXT *);
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+extern void *md5_buffer (const char *buffer, size_t len,
+ void *resblock);
-#endif /* __MD5_H__ */
+#endif /* md5.h */
+++ /dev/null
-/* sha1.c - SHA1 hash function
- * Copyright (C) 2001 V. Alex Brennen
- *
- * Please see below for more legal information!
- *
- * This file is part of the CryptNET openPGP Public Keyserver (CKS).
- *
- * CKS is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * CKS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * $Id: sha.c,v 1.3 2004/05/27 22:02:06 noodles Exp $
- */
-
-/* This file was copied from GnuPG */
-/* Some portions Copyright (C) 1998 The Free Software Foundation */
-
-#include "sha.h"
-
-
-/* Test vectors:
- *
- * "abc"
- * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D
- *
- * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1
- */
-
-void sha1_init( SHA1_CONTEXT *hd )
-{
- hd->h0 = 0x67452301;
- hd->h1 = 0xefcdab89;
- hd->h2 = 0x98badcfe;
- hd->h3 = 0x10325476;
- hd->h4 = 0xc3d2e1f0;
- hd->nblocks = 0;
- hd->count = 0;
-}
-
-
-/****************
- * Transform the message X which consists of 16 32-bit-words
- */
-static void transform( SHA1_CONTEXT *hd, uint8_t *data )
-{
- uint32_t a,b,c,d,e,tm;
- uint32_t x[16];
-
- /* get values from the chaining vars */
- a = hd->h0;
- b = hd->h1;
- c = hd->h2;
- d = hd->h3;
- e = hd->h4;
-
-#ifdef BIG_ENDIAN_HOST
- memcpy( x, data, 64 );
-#else
- { int i;
- uint8_t *p2;
- for(i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) {
- p2[3] = *data++;
- p2[2] = *data++;
- p2[1] = *data++;
- p2[0] = *data++;
- }
- }
-#endif
-
-
-#define K1 0x5A827999L
-#define K2 0x6ED9EBA1L
-#define K3 0x8F1BBCDCL
-#define K4 0xCA62C1D6L
-#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
-#define F2(x,y,z) ( x ^ y ^ z )
-#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
-#define F4(x,y,z) ( x ^ y ^ z )
-
-
-#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \
- ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
- , (x[i&0x0f] = rol(tm,1)) )
-
-#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
- + f( b, c, d ) \
- + k \
- + m; \
- b = rol( b, 30 ); \
- } while(0)
- R( a, b, c, d, e, F1, K1, x[ 0] );
- R( e, a, b, c, d, F1, K1, x[ 1] );
- R( d, e, a, b, c, F1, K1, x[ 2] );
- R( c, d, e, a, b, F1, K1, x[ 3] );
- R( b, c, d, e, a, F1, K1, x[ 4] );
- R( a, b, c, d, e, F1, K1, x[ 5] );
- R( e, a, b, c, d, F1, K1, x[ 6] );
- R( d, e, a, b, c, F1, K1, x[ 7] );
- R( c, d, e, a, b, F1, K1, x[ 8] );
- R( b, c, d, e, a, F1, K1, x[ 9] );
- R( a, b, c, d, e, F1, K1, x[10] );
- R( e, a, b, c, d, F1, K1, x[11] );
- R( d, e, a, b, c, F1, K1, x[12] );
- R( c, d, e, a, b, F1, K1, x[13] );
- R( b, c, d, e, a, F1, K1, x[14] );
- R( a, b, c, d, e, F1, K1, x[15] );
- R( e, a, b, c, d, F1, K1, M(16) );
- R( d, e, a, b, c, F1, K1, M(17) );
- R( c, d, e, a, b, F1, K1, M(18) );
- R( b, c, d, e, a, F1, K1, M(19) );
- R( a, b, c, d, e, F2, K2, M(20) );
- R( e, a, b, c, d, F2, K2, M(21) );
- R( d, e, a, b, c, F2, K2, M(22) );
- R( c, d, e, a, b, F2, K2, M(23) );
- R( b, c, d, e, a, F2, K2, M(24) );
- R( a, b, c, d, e, F2, K2, M(25) );
- R( e, a, b, c, d, F2, K2, M(26) );
- R( d, e, a, b, c, F2, K2, M(27) );
- R( c, d, e, a, b, F2, K2, M(28) );
- R( b, c, d, e, a, F2, K2, M(29) );
- R( a, b, c, d, e, F2, K2, M(30) );
- R( e, a, b, c, d, F2, K2, M(31) );
- R( d, e, a, b, c, F2, K2, M(32) );
- R( c, d, e, a, b, F2, K2, M(33) );
- R( b, c, d, e, a, F2, K2, M(34) );
- R( a, b, c, d, e, F2, K2, M(35) );
- R( e, a, b, c, d, F2, K2, M(36) );
- R( d, e, a, b, c, F2, K2, M(37) );
- R( c, d, e, a, b, F2, K2, M(38) );
- R( b, c, d, e, a, F2, K2, M(39) );
- R( a, b, c, d, e, F3, K3, M(40) );
- R( e, a, b, c, d, F3, K3, M(41) );
- R( d, e, a, b, c, F3, K3, M(42) );
- R( c, d, e, a, b, F3, K3, M(43) );
- R( b, c, d, e, a, F3, K3, M(44) );
- R( a, b, c, d, e, F3, K3, M(45) );
- R( e, a, b, c, d, F3, K3, M(46) );
- R( d, e, a, b, c, F3, K3, M(47) );
- R( c, d, e, a, b, F3, K3, M(48) );
- R( b, c, d, e, a, F3, K3, M(49) );
- R( a, b, c, d, e, F3, K3, M(50) );
- R( e, a, b, c, d, F3, K3, M(51) );
- R( d, e, a, b, c, F3, K3, M(52) );
- R( c, d, e, a, b, F3, K3, M(53) );
- R( b, c, d, e, a, F3, K3, M(54) );
- R( a, b, c, d, e, F3, K3, M(55) );
- R( e, a, b, c, d, F3, K3, M(56) );
- R( d, e, a, b, c, F3, K3, M(57) );
- R( c, d, e, a, b, F3, K3, M(58) );
- R( b, c, d, e, a, F3, K3, M(59) );
- R( a, b, c, d, e, F4, K4, M(60) );
- R( e, a, b, c, d, F4, K4, M(61) );
- R( d, e, a, b, c, F4, K4, M(62) );
- R( c, d, e, a, b, F4, K4, M(63) );
- R( b, c, d, e, a, F4, K4, M(64) );
- R( a, b, c, d, e, F4, K4, M(65) );
- R( e, a, b, c, d, F4, K4, M(66) );
- R( d, e, a, b, c, F4, K4, M(67) );
- R( c, d, e, a, b, F4, K4, M(68) );
- R( b, c, d, e, a, F4, K4, M(69) );
- R( a, b, c, d, e, F4, K4, M(70) );
- R( e, a, b, c, d, F4, K4, M(71) );
- R( d, e, a, b, c, F4, K4, M(72) );
- R( c, d, e, a, b, F4, K4, M(73) );
- R( b, c, d, e, a, F4, K4, M(74) );
- R( a, b, c, d, e, F4, K4, M(75) );
- R( e, a, b, c, d, F4, K4, M(76) );
- R( d, e, a, b, c, F4, K4, M(77) );
- R( c, d, e, a, b, F4, K4, M(78) );
- R( b, c, d, e, a, F4, K4, M(79) );
-
- /* update chainig vars */
- hd->h0 += a;
- hd->h1 += b;
- hd->h2 += c;
- hd->h3 += d;
- hd->h4 += e;
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-void sha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen)
-{
-
- if( hd->count == 64 ) { /* flush the buffer */
- transform( hd, hd->buf );
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
- if( hd->count ) {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- sha1_write( hd, NULL, 0 );
- if( !inlen )
- return;
- }
-
- while( inlen >= 64 ) {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
-}
-
-
-/* The routine final terminates the computation and
- * returns the digest.
- * The handle is prepared for a new cycle, but adding uint8_ts to the
- * handle will the destroy the returned buffer.
- * Returns: 20 uint8_ts representing the digest.
- */
-
-void sha1_final(SHA1_CONTEXT *hd)
-{
- unsigned int t, msb, lsb;
- unsigned char *p;
-
- sha1_write(hd, NULL, 0); /* flush */;
-
- msb = 0;
- t = hd->nblocks;
- if( (lsb = t << 6) < t ) /* multiply by 64 to make a uint8_t count */
- msb++;
- msb += t >> 26;
- t = lsb;
- if( (lsb = t + hd->count) < t ) /* add the count */
- msb++;
- t = lsb;
- if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
- msb++;
- msb += t >> 29;
-
- if( hd->count < 56 ) { /* enough room */
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
- }
- else { /* need one extra block */
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- sha1_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
- }
- /* append the 64 bit count */
- hd->buf[56] = msb >> 24;
- hd->buf[57] = msb >> 16;
- hd->buf[58] = msb >> 8;
- hd->buf[59] = msb ;
- hd->buf[60] = lsb >> 24;
- hd->buf[61] = lsb >> 16;
- hd->buf[62] = lsb >> 8;
- hd->buf[63] = lsb ;
- transform( hd, hd->buf );
-
- p = hd->buf;
-#ifdef BIG_ENDIAN_HOST
-#define X(a) do { *(uint32_t *)p = hd->h##a ; p += 4; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
- *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
-#endif
- X(0);
- X(1);
- X(2);
- X(3);
- X(4);
-#undef X
-
-}
-
-uint8_t *sha1_read( SHA1_CONTEXT *hd )
-{
- return hd->buf;
-}
+++ /dev/null
-#ifndef __SHA_H__
-#define __SHA_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <inttypes.h>
-
-#include "bithelp.h"
-
-typedef struct {
- uint32_t h0,h1,h2,h3,h4;
- uint32_t nblocks;
- uint8_t buf[64];
- int count;
-} SHA1_CONTEXT;
-
-void sha1_init(SHA1_CONTEXT *);
-void sha1_write(SHA1_CONTEXT *, uint8_t *, size_t);
-void sha1_final(SHA1_CONTEXT *);
-unsigned char *sha1_read(SHA1_CONTEXT *);
-
-#endif /* __SHA_H__ */
--- /dev/null
+/*
+ SHA-1 in C
+
+ By Steve Reid <steve@edmweb.com>, with small changes to make it
+ fit into mutt by Thomas Roessler <roessler@does-not-exist.org>.
+
+ 100% Public Domain.
+
+ Test Vectors (from FIPS PUB 180-1)
+ "abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#define SHA1HANDSOFF
+
+#include <string.h>
+
+#include "sha1.h"
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef WORDS_BIGENDIAN
+# define blk0(i) block->l[i]
+#else
+# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+#endif
+
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
+{
+u_int32_t a, b, c, d, e;
+typedef union {
+ unsigned char c[64];
+ u_int32_t l[16];
+} CHAR64LONG16;
+#ifdef SHA1HANDSOFF
+CHAR64LONG16 block[1]; /* use array to appear as a pointer */
+ memcpy(block, buffer, 64);
+#else
+ /* The following had better never be used because it causes the
+ * pointer-to-const buffer to be cast into a pointer to non-const.
+ * And the result is written through. I threw a "const" in, hoping
+ * this will cause a diagnostic.
+ */
+CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
+#endif
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
+{
+u_int32_t i;
+u_int32_t j;
+
+ j = context->count[0];
+ if ((context->count[0] += len << 3) < j)
+ context->count[1]++;
+ context->count[1] += (len>>29);
+ j = (j >> 3) & 63;
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+unsigned i;
+unsigned char finalcount[8];
+unsigned char c;
+
+#if 0 /* untested "improvement" by DHR */
+ /* Convert context->count to a sequence of bytes
+ * in finalcount. Second element first, but
+ * big-endian order within element.
+ * But we do it all backwards.
+ */
+ unsigned char *fcp = &finalcount[8];
+
+ for (i = 0; i < 2; i++)
+ {
+ u_int32_t t = context->count[i];
+ int j;
+
+ for (j = 0; j < 4; t >>= 8, j++)
+ *--fcp = (unsigned char) t
+ }
+#else
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+#endif
+ c = 0200;
+ SHA1Update(context, &c, 1);
+ while ((context->count[0] & 504) != 448) {
+ c = 0000;
+ SHA1Update(context, &c, 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+}
--- /dev/null
+/*
+ SHA-1 in C
+
+ By Steve Reid <steve@edmweb.com>, with small changes to make it
+ fit into mutt by Thomas Roessler <roessler@does-not-exist.org>.
+
+*/
+
+#ifndef _SHA1_H
+# define _SHA1_H
+
+#include <sys/types.h>
+
+typedef struct {
+ u_int32_t state[5];
+ u_int32_t count[2];
+ unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+
+# define SHA1_Transform SHA1Transform
+# define SHA1_Init SHA1Init
+# define SHA1_Update SHA1Update
+# define SHA1_Final SHA1Final
+
+# define SHA_DIGEST_LENGTH 20
+
+#endif
+