Commit 73d252fe authored by Thomas Roessler's avatar Thomas Roessler

Replace the BSD-licensed sha-1 from SSLeay with a public domain

version in order to satisfy GPL license zelots.
parent d6398b43
......@@ -64,15 +64,15 @@ DEFS=-DSHAREDIR=\"$(sharedir)\" -DSYSCONFDIR=\"$(sysconfdir)\" \
INCLUDES=-I$(top_srcdir) -I. $(IMAP_INCLUDES) \
-Iintl -I$(includedir)
non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c \
gnupgparse.c sha.h sha_locl.h \
non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c \
gnupgparse.c sha1.h \
doc/language.txt doc/language50.txt OPS.PGP doc/PGP-Notes.txt \
OPS.MIX remailer.c remailer.h pgpewrap \
contrib/pgp2.rc contrib/pgp5.rc contrib/gpg.rc \
mutt_ssl.c mutt_ssl.h README.SSL
EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
pop.c pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c gnupgparse.c \
pop.c pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c gnupgparse.c \
resize.c dotlock.c remailer.c browser.h mbyte.h remailer.h url.h
EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
......@@ -91,7 +91,7 @@ mutt_dotlock_SOURCES = mutt_dotlock.c
mutt_dotlock_LDADD = @LIBOBJS@
mutt_dotlock_DEPENDENCIES = @LIBOBJS@
pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1dgst.c
pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c
pgpring_LDADD = @LIBOBJS@ $(INTLLIBS)
pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
......
/*
* Copyright (C) 1999-2000 Thomas Roessler <roessler@guug.de>
* Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
* All rights reserved.
*
* 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 of the License, or
* (at your option) any later version.
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 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.
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* 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, USA.
*/
/* Check various types for their respective length */
/* Check various types for their respective length, and for Endianness */
#include <stdio.h>
......@@ -27,10 +45,26 @@
puts (" #define UINT" #a " " #b); \
}
#define CHECK_ENDIAN(TYPE) \
if (!have_endian && sizeof (TYPE) == 2) \
{ \
TYPE end_test = (TYPE) 0x1234; \
ep = (char *) &end_test; \
have_endian = 1; \
if (*ep == 0x34) \
puts (" #define M_LITTLE_ENDIAN"); \
else \
puts (" #define M_BIG_ENDIAN"); \
}
int main (int argc, char *argv[])
{
short have_UINT2 = 0;
short have_UINT4 = 0;
short have_endian = 0;
char *ep;
puts ("/* This is a generated file. Don't edit! */");
puts ("#ifndef _TYPES_H");
......@@ -41,7 +75,10 @@ int main (int argc, char *argv[])
CHECK_TYPE (4, unsigned short int)
CHECK_TYPE (4, unsigned int)
CHECK_TYPE (4, unsigned long int)
CHECK_ENDIAN (unsigned short int)
CHECK_ENDIAN (unsigned int)
puts ("#endif");
if (!have_UINT2 || !have_UINT4)
......
......@@ -74,23 +74,6 @@ fixes, and suggestions.\n\
along with this program; if not, write to the Free Software\n\
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.\n\
");
#ifdef HAVE_PGP
const char* ShaCopyright = N_("\n\
SHA1 implementation Copyright (C) 1995-1997 Eric A. Young <eay@cryptsoft.com>\n\
\n\
Redistribution and use in source and binary forms, with or without\n\
modification, are permitted under certain conditions.\n\
\n\
The SHA1 implementation comes AS IS, and ANY EXPRESS OR IMPLIED\n\
WARRANTIES, including, but not limited to, the implied warranties of\n\
merchantability and fitness for a particular purpose ARE DISCLAIMED.\n\
\n\
You should have received a copy of the full distribution terms\n\
along with this program; if not, write to the program's developers.\n\
");
#endif
void mutt_exit (int code)
{
......@@ -595,9 +578,6 @@ int main (int argc, char **argv)
default:
printf ("Mutt %s (%s)\n", MUTT_VERSION, ReleaseDate);
puts (_(Copyright));
#ifdef HAVE_PGP
puts(_(ShaCopyright));
#endif
puts (_(ReachingUs));
exit (0);
}
......
......@@ -49,7 +49,7 @@
extern char *optarg;
extern int optind;
#include "sha.h"
#include "sha1.h"
#include "lib.h"
#include "pgplib.h"
......@@ -448,7 +448,7 @@ static void pgp_make_pgp3_fingerprint (unsigned char *buff, size_t l,
unsigned char *digest)
{
unsigned char dummy;
SHA_CTX context;
SHA1_CTX context;
SHA1_Init (&context);
......
/* crypto/sha/sha.h */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_SHA_H
#define HEADER_SHA_H
#ifdef __cplusplus
extern "C" {
#endif
#define SHA_CBLOCK 64
#define SHA_LBLOCK 16
#define SHA_BLOCK 16
#define SHA_LAST_BLOCK 56
#define SHA_LENGTH_BLOCK 8
#define SHA_DIGEST_LENGTH 20
typedef struct SHAstate_st
{
unsigned long h0,h1,h2,h3,h4;
unsigned long Nl,Nh;
unsigned long data[SHA_LBLOCK];
int num;
} SHA_CTX;
#ifndef NOPROTO
void SHA_Init(SHA_CTX *c);
void SHA_Update(SHA_CTX *c, unsigned char *data, unsigned long len);
void SHA_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA(unsigned char *d, unsigned long n,unsigned char *md);
void SHA1_Init(SHA_CTX *c);
void SHA1_Update(SHA_CTX *c, unsigned char *data, unsigned long len);
void SHA1_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA1(unsigned char *d, unsigned long n,unsigned char *md);
#else
void SHA_Init();
void SHA_Update();
void SHA_Final();
unsigned char *SHA();
void SHA1_Init();
void SHA1_Update();
void SHA1_Final();
unsigned char *SHA1();
#endif
#ifdef __cplusplus
}
#endif
#endif
/*
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 <sys/types.h> /* for u_int*_t */
#include "sha1.h"
#include "types.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 M_LITTLE_ENDIAN
# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
# define blk0(i) block->l[i]
#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(UINT4 state[5], const unsigned char buffer[64])
{
UINT4 a, b, c, d, e;
typedef union {
unsigned char c[64];
UINT4 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;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block));
#endif
}
/* 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, UINT4 len)
{
UINT4 i;
UINT4 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++)
{
UINT4 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);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
}
/*
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 "types.h"
typedef struct {
UINT4 state[5];
UINT4 count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(UINT4 state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, const unsigned char* data, UINT4 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
/* crypto/sha/sha1dgst.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#undef SHA_0
#define SHA_1
#include "sha.h"
#include "sha_locl.h"
char *SHA1_version="SHA1 part of SSLeay 0.8.1 19-Jul-1997";
/* Implemented from SHA-1 document - The Secure Hash Algorithm
*/
#define INIT_DATA_h0 (unsigned long)0x67452301L
#define INIT_DATA_h1 (unsigned long)0xefcdab89L
#define INIT_DATA_h2 (unsigned long)0x98badcfeL
#define INIT_DATA_h3 (unsigned long)0x10325476L
#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L
#define K_00_19 0x5a827999L
#define K_20_39 0x6ed9eba1L
#define K_40_59 0x8f1bbcdcL
#define K_60_79 0xca62c1d6L
#ifndef NOPROTO
static void sha1_block(SHA_CTX *c, register unsigned long *p);
#else
static void sha1_block();
#endif
void SHA1_Init(c)
SHA_CTX *c;
{
c->h0=INIT_DATA_h0;
c->h1=INIT_DATA_h1;
c->h2=INIT_DATA_h2;
c->h3=INIT_DATA_h3;
c->h4=INIT_DATA_h4;
c->Nl=0;
c->Nh=0;
c->num=0;
}
void SHA1_Update(c, data, len)
SHA_CTX *c;
register unsigned char *data;
unsigned long len;
{
register ULONG *p;
int ew,ec,sw,sc;
ULONG l;
if (len == 0) return;
l=(c->Nl+(len<<3))&0xffffffff;
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(len>>29);
c->Nl=l;
if (c->num != 0)
{
p=c->data;
sw=c->num>>2;
sc=c->num&0x03;
if ((c->num+len) >= SHA_CBLOCK)
{
l= p[sw];
p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw<SHA_LBLOCK; sw++)
{
c2nl(data,l);
p[sw]=l;
}
len-=(SHA_CBLOCK-c->num);
sha1_block(c,p);
c->num=0;
/* drop through and do the rest */
}
else
{
c->num+=(int)len;
if ((sc+len) < 4) /* ugly, add char's to a word */
{
l= p[sw];
p_c2nl_p(data,l,sc,len);
p[sw]=l;
}
else
{
ew=(c->num>>2);
ec=(c->num&0x03);
l= p[sw];
p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw < ew; sw++)
{ c2nl(data,l); p[sw]=l; }
if (ec)
{
c2nl_p(data,l,ec);
p[sw]=l;
}
}
return;
}
}
/* we now can process the input data in blocks of SHA_CBLOCK
* chars and save the leftovers to c->data. */
p=c->data;
while (len >= SHA_CBLOCK)
{
#if defined(B_ENDIAN) || defined(L_ENDIAN)
memcpy(p,data,SHA_CBLOCK);
data+=SHA_CBLOCK;
#ifdef L_ENDIAN
for (sw=(SHA_LBLOCK/4); sw; sw--)
{
Endian_Reverse32(p[0]);
Endian_Reverse32(p[1]);
Endian_Reverse32(p[2]);
Endian_Reverse32(p[3]);
p+=4;
}
#endif
#else
for (sw=(SHA_BLOCK/4); sw; sw--)
{
c2nl(data,l); *(p++)=l;
c2nl(data,l); *(p++)=l;
c2nl(data,l); *(p++)=l;
c2nl(data,l); *(p++)=l;
}
#endif
p=c->data;
sha1_block(c,p);
len-=SHA_CBLOCK;
}
ec=(int)len;
c->num=ec;
ew=(ec>>2);
ec&=0x03;
for (sw=0; sw < ew; sw++)
{ c2nl(data,l); p[sw]=l; }
c2nl_p(data,l,ec);
p[sw]=l;
}
static void sha1_block(c, X)
SHA_CTX *c;
register unsigned long *X;
{
register ULONG A,B,C,D,E,T;
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
BODY_00_15( 0,A,B,C,D,E,T);
BODY_00_15( 1,T,A,B,C,D,E);
BODY_00_15( 2,E,T,A,B,C,D);
BODY_00_15( 3,D,E,T,A,B,C);
BODY_00_15( 4,C,D,E,T,A,B);
BODY_00_15( 5,B,C,D,E,T,A);
BODY_00_15( 6,A,B,C,D,E,T);
BODY_00_15( 7,T,A,B,C,D,E);
BODY_00_15( 8,E,T,A,B,C,D);
BODY_00_15( 9,D,E,T,A,B,C);
BODY_00_15(10,C,D,E,T,A,B);
BODY_00_15(11,B,C,D,E,T,A);
BODY_00_15(12,A,B,C,D,E,T);
BODY_00_15(13,T,A,B,C,D,E);
BODY_00_15(14,E,T,A,B,C,D);
BODY_00_15(15,D,E,T,A,B,C);
BODY_16_19(16,C,D,E,T,A,B);