Crypto routines.

git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@10 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Matt Chapman 2000-08-15 10:32:09 +00:00
parent cd9b5a8761
commit 3adf8de45c
14 changed files with 2795 additions and 0 deletions

4
crypto/README Normal file
View File

@ -0,0 +1,4 @@
The files in this directory implement the encryption algorithms used in
the RDP protocol, and are subject to their respective licenses.
RC4 may also be subject to patent restrictions in some countries.

681
crypto/arith.c Normal file
View File

@ -0,0 +1,681 @@
/*******************************************************************************
* *
* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
* *
* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
* verwendet werden. *
* *
* martin@trillian.megalon.de *
* *
*******************************************************************************/
#include "arith.h"
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!! ACHTUNG !!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Es findet keinerlei Ueberpruefung auf Bereichsueberschreitung
* statt. Alle Werte muessen natuerliche Zahlen aus dem Bereich
* 0 ... (MAXINT+1)^MAXLEN-1 sein.
*
*
* Bei keiner Funktion oder Hilsfunktion werden Annahmen getroffen,
* ueber die Verschiedenheit von Eingabe- & Ausgabe-Werten.
*
*
* Funktionen:
*
* a_add( s1, s2, d )
* NUMBER *s1,*s2,*d;
* *d = *s1 + *s2;
*
* a_assign( *d, *s )
* NUMBER *d,*s;
* *d = *s;
*
* int a_cmp( c1, c2 )
* NUMBER *c1,*c2;
* 1 : falls *c1 > *c2
* 0 : falls *c1 == *c2
* -1 : falls *c1 < *c2
*
* a_div( d1, d2, q, r )
* NUMBER *d1,*d2,*q,*r;
* *q = *d1 / *d2 Rest *r;
*
* a_div2( n )
* NUMBER *n;
* *n /= 2;
*
* a_ggt( a, b, f )
* NUMBER *a,*b,*f;
* *f = ( *a, *b );
*
* a_imult( n, m, d )
* NUMBER *n;
* INT m;
* NUMBER *d;
* *d = *n * m
*
* a_mult( m1, m2, d )
* NUMBER *m1,*m2,*d;
* *d = *m1 * *m2;
*
* a_sub( s1, s2, d )
* NUMBER *s1,*s2,*d;
* *d = *s1 - *s2;
*
* Modulare Funktionen
* m_init( n, o )
* NUMBER *n,*o;
* Initialsierung der Modularen Funktionen
* o != 0 : *o = alter Wert
*
* m_add( s1, s2, d )
* NUMBER *s1, *s2, *d;
* *d = *s1 + *s2;
*
* m_mult( m1, m2, d )
* NUMBER *m1,*m2,*d;
*
* m_exp( x, n, z )
* NUMBER *x,*n,*z;
* *z = *x exp *n;
*
*
* Hilfs-Funktionen:
*
* int n_bits( n, b )
* NUMBER *n;
* int b;
* return( unterste b Bits der Dualdarstellung von n)
*
* n_div( d1, z2, q, r )
* NUMBER *d1,z2[MAXBIT],*q,*r;
* *q = *d1 / z2[0] Rest *r;
* z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
*
* int n_cmp( i1, i2, l )
* INT i1[l], i2[l];
* 1 : falls i1 > i2
* 0 : falls i1 == i2
* -1 : falls i1 < i2
*
* int n_mult( n, m, d, l)
* INT n[l], m, d[];
* d = m * n;
* return( sizeof(d) ); d.h. 'l' oder 'l+1'
*
* int n_sub( p1, p2, p3, l, lo )
* INT p1[l], p2[lo], p3[];
* p3 = p1 - p2;
* return( sizeof(p3) ); d.h. '<= min(l,lo)'
*
* int n_bitlen( n )
* NUMBER *n;
* return( sizeof(n) in bits )
*
*/
/*
* Konstante 1, 2
*/
NUMBER a_one = {
1,
{ (INT)1, },
};
NUMBER a_two = {
#if MAXINT == 1
2,
{ 0, (INT)1, },
#else
1,
{ (INT)2, },
#endif
};
/*
* Vergleiche zwei INT arrays der Laenge l
*/
int n_cmp( i1, i2, l )
INT *i1,*i2;
{
i1 += (l-1); /* Pointer ans Ende */
i2 += (l-1);
for (;l--;)
if ( *i1-- != *i2-- )
return( i1[1] > i2[1] ? 1 : -1 );
return(0);
}
/*
* Vergleiche zwei NUMBER
*/
int a_cmp( c1, c2 )
NUMBER *c1,*c2;
{
int l;
/* bei verschiedener Laenge klar*/
if ( (l=c1->n_len) != c2->n_len)
return( l - c2->n_len);
/* vergleiche als arrays */
return( n_cmp( c1->n_part, c2->n_part, l) );
}
/*
* Zuweisung einer NUMBER (d = s)
*/
void a_assign( d, s )
NUMBER *d,*s;
{
int l;
if (s == d) /* nichts zu kopieren */
return;
if ((l=s->n_len))
memcpy( d->n_part, s->n_part, sizeof(INT)*l);
d->n_len = l;
}
/*
* Addiere zwei NUMBER (d = s1 + s2)
*/
void a_add( s1, s2, d )
NUMBER *s1,*s2,*d;
{
int l,lo,ld,same;
register LONG sum;
register INT *p1,*p2,*p3;
register INT b;
/* setze s1 auch die groessere Zahl */
l = s1->n_len;
if ( (l=s1->n_len) < s2->n_len ) {
NUMBER *tmp = s1;
s1 = s2;
s2 = tmp;
l = s1->n_len;
}
ld = l;
lo = s2->n_len;
p1 = s1->n_part;
p2 = s2->n_part;
p3 = d->n_part;
same = (s1 == d);
sum = 0;
while (l --) {
if (lo) { /* es ist noch was von s2 da */
lo--;
b = *p2++;
}
else
b = 0; /* ansonten 0 nehmen */
sum += (LONG)*p1++ + (LONG)b;
*p3++ = TOINT(sum);
if (sum > (LONG)MAXINT) { /* carry merken */
sum = 1;
}
else
sum = 0;
if (!lo && same && !sum) /* nichts mehr zu tuen */
break;
}
if (sum) { /* letztes carry beruecksichtigen */
ld++;
*p3 = sum;
}
d->n_len = ld; /* Laenge setzen */
}
/*
* Subtrahiere zwei INT arrays. return( Laenge Ergebniss )
* l == Laenge p1
* lo== Laenge p3
*/
int n_sub( p1, p2, p3, l, lo )
INT *p1,*p2,*p3;
int l,lo;
{
int ld,lc,same;
int over = 0;
register LONG dif;
LONG a,b;
same = (p1 == p3); /* frueher Abbruch moeglich */
for (lc=1, ld=0; l--; lc++) {
a = (LONG)*p1++;
if (lo) { /* ist noch was von p2 da ? */
lo--;
b = (LONG)*p2++;
}
else
b=0; /* ansonten 0 nehmen */
if (over) /* frueherer Overflow */
b++;
if ( b > a ) { /* jetzt Overflow ? */
over = 1;
dif = (MAXINT +1) + a;
}
else {
over = 0;
dif = a;
}
dif -= b;
*p3++ = (INT)dif;
if (dif) /* Teil != 0 : Laenge neu */
ld = lc;
if (!lo && same && !over) { /* nichts mehr zu tuen */
if (l > 0) /* Laenge korrigieren */
ld = lc + l;
break;
}
}
return( ld );
}
/*
* Subtrahiere zwei NUMBER (d= s1 - s2)
*/
void a_sub( s1, s2, d )
NUMBER *s1,*s2,*d;
{
d->n_len = n_sub( s1->n_part, s2->n_part, d->n_part
,s1->n_len, s2->n_len );
}
/*
* Mulitipliziere INT array der Laenge l mit einer INT (d = n * m)
* return neue Laenge
*/
int n_mult( n, m, d, l)
register INT *n;
register INT m;
INT *d;
{
int i;
register LONG mul;
for (i=l,mul=0; i; i--) {
mul += (LONG)m * (LONG)*n++;
*d++ = TOINT(mul);
mul = DIVMAX1( mul );
}
if (mul) { /* carry ? */
l++;
*d = mul;
}
return( l );
}
/*
* Mulitipliziere eine NUMBER mit einer INT (d = n * m)
*/
void a_imult( n, m, d )
NUMBER *n;
INT m;
NUMBER *d;
{
if (m == 0)
d->n_len=0;
else if (m == 1)
a_assign( d, n );
else
d->n_len = n_mult( n->n_part, m, d->n_part, n->n_len );
}
/*
* Multipliziere zwei NUMBER (d = m1 * m2)
*/
void a_mult( m1, m2, d )
NUMBER *m1,*m2,*d;
{
static INT id[ MAXLEN ]; /* Zwischenspeicher */
register INT *vp; /* Pointer darin */
register LONG sum; /* Summe fuer jede Stelle */
register LONG tp1; /* Zwischenspeicher fuer m1 */
register INT *p2;
INT *p1;
int l1,l2,ld,lc,l,i,j;
l1 = m1->n_len;
l2 = m2->n_len;
l = l1 + l2;
if (l >= MAXLEN)
abort();
for (i=l, vp=id; i--;)
*vp++ = 0;
/* ohne Uebertrag in Zwischenspeicher multiplizieren */
for ( p1 = m1->n_part, i=0; i < l1 ; i++, p1++ ) {
tp1 = (LONG)*p1;
vp = &id[i];
sum = 0;
for ( p2 = m2->n_part, j = l2; j--;) {
sum += (LONG)*vp + (tp1 * (LONG)*p2++);
*vp++ = TOINT( sum );
sum = DIVMAX1(sum);
}
*vp++ += (INT)sum;
}
/* jetzt alle Uebertraege beruecksichtigen */
ld = 0;
for (lc=0, vp=id, p1=d->n_part; lc++ < l;) {
if (( *p1++ = *vp++ ))
ld = lc;
}
d->n_len = ld;
}
/*
* Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
* z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
* r = 0 : kein Rest
* q = 0 : kein Quotient
*/
void n_div( d1, z2, q, r )
NUMBER *d1,*z2,*q,*r;
{
static NUMBER dummy_rest; /* Dummy Variable, falls r = 0 */
static NUMBER dummy_quot; /* Dummy Variable, falla q = 0 */
INT *i1,*i1e,*i3;
int l2,ld,l,lq;
#if MAXINT != 1
INT z;
int pw,l2t;
#endif
if (!z2->n_len)
abort();
if (!r)
r = &dummy_rest;
if (!q)
q = &dummy_quot;
a_assign( r, d1 ); /* Kopie von d1 in den Rest */
l2= z2->n_len; /* Laenge von z2[0] */
l = r->n_len - l2; /* Laenge des noch ''rechts'' liegenden
Stuecks von d1 */
lq= l +1; /* Laenge des Quotienten */
i3= q->n_part + l;
i1= r->n_part + l;
ld = l2; /* aktuelle Laenge des ''Vergleichsstuecks''
von d1 */
i1e= i1 + (ld-1);
for (; l >= 0; ld++, i1--, i1e--, l--, i3--) {
*i3 = 0;
if (ld == l2 && ! *i1e) {
ld--;
continue;
}
if ( ld > l2 || (ld == l2 && n_cmp( i1, z2->n_part, l2) >= 0 ) ) {
#if MAXINT != 1
/* nach 2er-Potenzen zerlegen */
for (pw=MAXBIT-1, z=(INT)HIGHBIT; pw >= 0; pw--, z /= 2) {
if ( ld > (l2t= z2[pw].n_len)
|| (ld == l2t
&& n_cmp( i1, z2[pw].n_part, ld) >= 0) ) {
ld = n_sub( i1, z2[pw].n_part, i1, ld, l2t );
(*i3) += z;
}
}
#else
/* bei MAXINT == 1 alles viel einfacher */
ld = n_sub( i1, z2->n_part, i1, ld, l2 );
(*i3) ++;
#endif
}
}
/* Korrektur, falls l von Anfang an Negativ war */
l ++;
lq -= l;
ld += l;
if (lq>0 && !q->n_part[lq -1]) /* evtl. Laenge korrigieren */
lq--;
q->n_len = lq;
r->n_len = ld -1;
}
/*
* Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
* z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
* r = 0 : kein Rest
* q = 0 : kein Quotient
*/
void a_div( d1, d2, q, r )
NUMBER *d1,*d2,*q,*r;
{
#if MAXINT != 1
NUMBER z2[MAXBIT];
INT z;
int i;
a_assign( &z2[0], d2 );
for (i=1,z=2; i < MAXBIT; i++, z *= 2)
a_imult( d2, z, &z2[i] );
d2 = z2;
#endif
n_div( d1, d2, q, r );
}
/*
* Dividiere eine NUMBER durch 2
*/
void a_div2( n )
NUMBER *n;
{
#if MAXBIT == LOWBITS
register INT *p;
int i;
#if MAXINT != 1
register INT h;
register int c;
c=0;
i= n->n_len;
p= &n->n_part[i-1];
for (; i--;) {
if (c) {
c = (h= *p) & 1;
h /= 2;
h |= HIGHBIT;
}
else {
c = (h= *p) & 1;
h /= 2;
}
*p-- = h;
}
if ( (i= n->n_len) && n->n_part[i-1] == 0 )
n->n_len = i-1;
#else /* MAXBIT != 1 */
p = n->n_part;
i = n->n_len;
if (i) {
n->n_len = i-1;
for (; --i ; p++)
p[0] = p[1];
}
#endif /* MAXBIT != 1 */
#else /* MAXBIT == LOWBITS */
a_div( n, &a_two, n, NUM0P );
#endif /* MAXBIT == LOWBITS */
}
/*
* MODULO-FUNKTIONEN
*/
static NUMBER mod_z2[ MAXBIT ];
/*
* Init
*/
void m_init( n, o )
NUMBER *n,*o;
{
INT z;
int i;
if (o)
a_assign( o, &mod_z2[0] );
if (! a_cmp( n, &mod_z2[0] ) )
return;
for (i=0,z=1; i < MAXBIT; i++, z *= 2)
a_imult( n, z, &mod_z2[i] );
}
void m_add( s1, s2, d )
NUMBER *s1, *s2, *d;
{
a_add( s1, s2, d );
if (a_cmp( d, mod_z2 ) >= 0)
a_sub( d, mod_z2, d );
}
void m_mult( m1, m2, d )
NUMBER *m1,*m2,*d;
{
a_mult( m1, m2, d );
n_div( d, mod_z2, NUM0P, d );
}
/*
* Restklassen Exponent
*/
void m_exp( x, n, z )
NUMBER *x,*n,*z;
{
NUMBER xt,nt;
a_assign( &nt, n );
a_assign( &xt, x );
a_assign( z, &a_one );
while (nt.n_len) {
while ( ! (nt.n_part[0] & 1) ) {
m_mult( &xt, &xt, &xt );
a_div2( &nt );
}
m_mult( &xt, z, z );
a_sub( &nt, &a_one, &nt );
}
}
/*
* GGT
*/
void a_ggt( a, b, f )
NUMBER *a,*b,*f;
{
NUMBER t[2];
int at,bt, tmp;
a_assign( &t[0], a ); at= 0;
a_assign( &t[1], b ); bt= 1;
if ( a_cmp( &t[at], &t[bt] ) < 0 ) {
tmp= at; at= bt; bt= tmp;
}
/* euklidischer Algorithmus */
while ( t[bt].n_len ) {
a_div( &t[at], &t[bt], NUM0P, &t[at] );
tmp= at; at= bt; bt= tmp;
}
a_assign( f, &t[at] );
}
/*
* die untersten b bits der Dualdarstellung von n
* die bits muessen in ein int passen
*/
int n_bits(n,b)
NUMBER *n;
{
INT *p;
int l;
unsigned r;
int m = (1<<b) -1;
if ( n->n_len == 0)
return(0);
if (LOWBITS >= b)
return( n->n_part[0] & m );
#if LOWBITS != 0
l = (b-1) / LOWBITS;
#else
l = n->n_len -1;
#endif
for (p= &n->n_part[l],r=0; l-- >= 0 && b > 0; b-= LOWBITS, p--) {
r = MULMAX1( r );
r += (unsigned)*p;
}
return( r & m );
}
/*
* Anzahl der bits von n bei Dualdarstellung
*/
int n_bitlen( n )
NUMBER *n;
{
NUMBER b;
int i;
a_assign( &b, &a_one );
for (i=0; a_cmp( &b, n ) <= 0; a_mult( &b, &a_two, &b ), i++)
;
return(i);
}

46
crypto/arith.h Normal file
View File

@ -0,0 +1,46 @@
/*******************************************************************************
* *
* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
* *
* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
* verwendet werden. *
* *
* martin@trillian.megalon.de *
* *
*******************************************************************************/
#ifndef _arith_h_
#define _arith_h_
#ifndef _conf_h_
#include "conf.h"
#endif
extern NUMBER a_one,a_two;
/*
* Prototypes
*/
void a_add P(( NUMBER*, NUMBER*, NUMBER* ));
void a_assign P(( NUMBER*, NUMBER* ));
int a_cmp P(( NUMBER*, NUMBER* ));
void a_div P(( NUMBER*, NUMBER*, NUMBER*, NUMBER* ));
void a_div2 P(( NUMBER* ));
void a_ggt P(( NUMBER*, NUMBER*, NUMBER* ));
void a_imult P(( NUMBER*, INT, NUMBER* ));
void a_mult P(( NUMBER*, NUMBER*, NUMBER* ));
void a_sub P(( NUMBER*, NUMBER*, NUMBER* ));
void m_init P(( NUMBER*, NUMBER* ));
void m_add P(( NUMBER*, NUMBER*, NUMBER* ));
void m_mult P(( NUMBER*, NUMBER*, NUMBER* ));
void m_exp P(( NUMBER*, NUMBER*, NUMBER* ));
int n_bits P(( NUMBER*, int));
void n_div P(( NUMBER*, NUMBER*, NUMBER*, NUMBER* ));
int n_cmp P(( INT*, INT*, int ));
int n_mult P(( INT*, INT, INT*, int ));
int n_sub P(( INT*, INT*, INT*, int, int ));
int n_bitlen P(( NUMBER* ));
#endif

96
crypto/conf.h Normal file
View File

@ -0,0 +1,96 @@
/*******************************************************************************
* *
* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
* *
* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
* verwendet werden. *
* *
* martin@trillian.megalon.de *
* *
*******************************************************************************/
#ifndef _conf_h_
#define _conf_h_
typedef unsigned short INT; /* muss MAXINT fassen */
typedef unsigned long LONG; /* muss (MAXINT+1)^2 -1 fassen */
#if defined( M_XENIX )
#define P(x) x /* Funktions Prototypen an */
#else
#define P(x) () /* Funktions Prototypen aus */
#endif
/*
* (MAXINT+1)-adic Zahlen
*/
/*
* MAXINT Maximale Zahl pro Elemenmt (muss int sein)
* MAXBIT Maximales Bit von MAXINT
* LOWBITS Anzahl der consekutiven low Bits von MAXINT
* HIGHBIT Hoechsten Bit von MAXINT
* TOINT muss (INT)( (x) % MAXINT) ergeben
* MAXLEN Laenge der INT Array in jeder NUMBER
*/
#define MAXINT 0xFFFF
#if MAXINT == 99
#define MAXBIT 7
#define LOWBITS 2
#endif
#if MAXINT == 9
#define MAXBIT 4
#define LOWBITS 1
#endif
#if MAXINT == 1
#define MAXBIT 1
#endif
#if MAXINT == 0xFF
#define MAXBIT 8
#define TOINT(x) ((INT)(x)) /* ACHTUNG !!!!! */
#endif
#if MAXINT == 0xFFFF
#define MAXBIT 16
#define TOINT(x) ((INT)(x)) /* ACHTUNG !!!!! */
#endif
#ifndef MAXBIT
#include "<< ERROR: MAXBIT must be defined >>"
#endif
#ifndef LOWBITS
#if MAXINT == (1 << MAXBIT) - 1
#define LOWBITS MAXBIT
#else
#include "<< ERROR: LOWBITS must be defined >>"
#endif
#endif
#define MAXLEN (300*8/(MAXBIT + 1))
#define STRLEN (MAXLEN*MAXBIT/4)
#define HIGHBIT (1 << (MAXBIT-1) )
#if LOWBITS == MAXBIT
#define DIVMAX1(x) ((x) >> MAXBIT)
#define MODMAX1(x) ((x) & MAXINT)
#define MULMAX1(x) ((x) << MAXBIT)
#else
#define DIVMAX1(x) ((x) / (MAXINT+1))
#define MODMAX1(x) ((x) % (MAXINT+1))
#define MULMAX1(x) ((x) * (unsigned)(MAXINT+1))
#endif
#ifndef TOINT
#define TOINT(x) ((INT)MODMAX1(x))
#endif
typedef struct {
int n_len; /* Hoechster benutzter Index */
INT n_part[MAXLEN];
} NUMBER;
#define NUM0P ((NUMBER *)0) /* Abkuerzung */
#endif

99
crypto/md5.h Normal file
View File

@ -0,0 +1,99 @@
/* crypto/md5/md5.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_MD5_H
#define HEADER_MD5_H
#ifdef __cplusplus
extern "C" {
#endif
#define MD5_CBLOCK 64
#define MD5_LBLOCK 16
#define MD5_BLOCK 16
#define MD5_LAST_BLOCK 56
#define MD5_LENGTH_BLOCK 8
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
unsigned long A,B,C,D;
unsigned long Nl,Nh;
unsigned long data[MD5_LBLOCK];
int num;
} MD5_CTX;
#ifndef NOPROTO
void MD5_Init(MD5_CTX *c);
void MD5_Update(MD5_CTX *c, unsigned char *data, unsigned long len);
void MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, unsigned char *b);
#else
void MD5_Init();
void MD5_Update();
void MD5_Final();
unsigned char *MD5();
void MD5_Transform();
#endif
#ifdef __cplusplus
}
#endif
#endif

440
crypto/md5_dgst.c Normal file
View File

@ -0,0 +1,440 @@
/* crypto/md5/md5_dgst.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>
#include "md5_locl.h"
/* char *MD5_version="MD5 part of SSLeay 0.8.2b 08-Jan-1998"; */
/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
*/
#define INIT_DATA_A (unsigned long)0x67452301L
#define INIT_DATA_B (unsigned long)0xefcdab89L
#define INIT_DATA_C (unsigned long)0x98badcfeL
#define INIT_DATA_D (unsigned long)0x10325476L
#ifndef NOPROTO
# ifdef MD5_ASM
void md5_block_x86(MD5_CTX *c, unsigned long *p,int num);
# define md5_block md5_block_x86
# else
static void md5_block(MD5_CTX *c, unsigned long *p,int num);
# endif
#else
# ifdef MD5_ASM
void md5_block_x86();
# define md5_block md5_block_x86
# else
static void md5_block();
# endif
#endif
void MD5_Init(c)
MD5_CTX *c;
{
c->A=INIT_DATA_A;
c->B=INIT_DATA_B;
c->C=INIT_DATA_C;
c->D=INIT_DATA_D;
c->Nl=0;
c->Nh=0;
c->num=0;
}
void MD5_Update(c, data, len)
MD5_CTX *c;
register unsigned char *data;
unsigned long len;
{
register ULONG *p;
int sw,sc;
ULONG l;
if (len == 0) return;
l=(c->Nl+(len<<3))&0xffffffffL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
* Wei Dai <weidai@eskimo.com> for pointing it out. */
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) >= MD5_CBLOCK)
{
l= p[sw];
p_c2l(data,l,sc);
p[sw++]=l;
for (; sw<MD5_LBLOCK; sw++)
{
c2l(data,l);
p[sw]=l;
}
len-=(MD5_CBLOCK-c->num);
md5_block(c,p,64);
c->num=0;
/* drop through and do the rest */
}
else
{
int ew,ec;
c->num+=(int)len;
if ((sc+len) < 4) /* ugly, add char's to a word */
{
l= p[sw];
p_c2l_p(data,l,sc,len);
p[sw]=l;
}
else
{
ew=(c->num>>2);
ec=(c->num&0x03);
l= p[sw];
p_c2l(data,l,sc);
p[sw++]=l;
for (; sw < ew; sw++)
{ c2l(data,l); p[sw]=l; }
if (ec)
{
c2l_p(data,l,ec);
p[sw]=l;
}
}
return;
}
}
/* we now can process the input data in blocks of MD5_CBLOCK
* chars and save the leftovers to c->data. */
#ifdef L_ENDIAN
if ((((unsigned long)data)%sizeof(ULONG)) == 0)
{
sw=(int)len/MD5_CBLOCK;
if (sw > 0)
{
sw*=MD5_CBLOCK;
md5_block(c,(ULONG *)data,sw);
data+=sw;
len-=sw;
}
}
#endif
p=c->data;
while (len >= MD5_CBLOCK)
{
#if defined(L_ENDIAN) || defined(B_ENDIAN)
if (p != (unsigned long *)data)
memcpy(p,data,MD5_CBLOCK);
data+=MD5_CBLOCK;
#ifdef B_ENDIAN
for (sw=(MD5_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=(MD5_LBLOCK/4); sw; sw--)
{
c2l(data,l); *(p++)=l;
c2l(data,l); *(p++)=l;
c2l(data,l); *(p++)=l;
c2l(data,l); *(p++)=l;
}
#endif
p=c->data;
md5_block(c,p,64);
len-=MD5_CBLOCK;
}
sc=(int)len;
c->num=sc;
if (sc)
{
sw=sc>>2; /* words to copy */
#ifdef L_ENDIAN
p[sw]=0;
memcpy(p,data,sc);
#else
sc&=0x03;
for ( ; sw; sw--)
{ c2l(data,l); *(p++)=l; }
c2l_p(data,l,sc);
*p=l;
#endif
}
}
void MD5_Transform(c,b)
MD5_CTX *c;
unsigned char *b;
{
ULONG p[16];
#if !defined(L_ENDIAN)
ULONG *q;
int i;
#endif
#if defined(B_ENDIAN) || defined(L_ENDIAN)
memcpy(p,b,64);
#ifdef B_ENDIAN
q=p;
for (i=(MD5_LBLOCK/4); i; i--)
{
Endian_Reverse32(q[0]);
Endian_Reverse32(q[1]);
Endian_Reverse32(q[2]);
Endian_Reverse32(q[3]);
q+=4;
}
#endif
#else
q=p;
for (i=(MD5_LBLOCK/4); i; i--)
{
ULONG l;
c2l(b,l); *(q++)=l;
c2l(b,l); *(q++)=l;
c2l(b,l); *(q++)=l;
c2l(b,l); *(q++)=l;
}
#endif
md5_block(c,p,64);
}
#ifndef MD5_ASM
static void md5_block(c, X, num)
MD5_CTX *c;
register ULONG *X;
int num;
{
register ULONG A,B,C,D;
A=c->A;
B=c->B;
C=c->C;
D=c->D;
for (;;)
{
/* Round 0 */
R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
R0(C,D,A,B,X[ 2],17,0x242070dbL);
R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
R0(D,A,B,C,X[ 5],12,0x4787c62aL);
R0(C,D,A,B,X[ 6],17,0xa8304613L);
R0(B,C,D,A,X[ 7],22,0xfd469501L);
R0(A,B,C,D,X[ 8], 7,0x698098d8L);
R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
R0(C,D,A,B,X[10],17,0xffff5bb1L);
R0(B,C,D,A,X[11],22,0x895cd7beL);
R0(A,B,C,D,X[12], 7,0x6b901122L);
R0(D,A,B,C,X[13],12,0xfd987193L);
R0(C,D,A,B,X[14],17,0xa679438eL);
R0(B,C,D,A,X[15],22,0x49b40821L);
/* Round 1 */
R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
R1(D,A,B,C,X[ 6], 9,0xc040b340L);
R1(C,D,A,B,X[11],14,0x265e5a51L);
R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
R1(D,A,B,C,X[10], 9,0x02441453L);
R1(C,D,A,B,X[15],14,0xd8a1e681L);
R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
R1(D,A,B,C,X[14], 9,0xc33707d6L);
R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
R1(B,C,D,A,X[ 8],20,0x455a14edL);
R1(A,B,C,D,X[13], 5,0xa9e3e905L);
R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
R1(C,D,A,B,X[ 7],14,0x676f02d9L);
R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
/* Round 2 */
R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
R2(D,A,B,C,X[ 8],11,0x8771f681L);
R2(C,D,A,B,X[11],16,0x6d9d6122L);
R2(B,C,D,A,X[14],23,0xfde5380cL);
R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
R2(B,C,D,A,X[10],23,0xbebfbc70L);
R2(A,B,C,D,X[13], 4,0x289b7ec6L);
R2(D,A,B,C,X[ 0],11,0xeaa127faL);
R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
R2(B,C,D,A,X[ 6],23,0x04881d05L);
R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
R2(D,A,B,C,X[12],11,0xe6db99e5L);
R2(C,D,A,B,X[15],16,0x1fa27cf8L);
R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
/* Round 3 */
R3(A,B,C,D,X[ 0], 6,0xf4292244L);
R3(D,A,B,C,X[ 7],10,0x432aff97L);
R3(C,D,A,B,X[14],15,0xab9423a7L);
R3(B,C,D,A,X[ 5],21,0xfc93a039L);
R3(A,B,C,D,X[12], 6,0x655b59c3L);
R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
R3(C,D,A,B,X[10],15,0xffeff47dL);
R3(B,C,D,A,X[ 1],21,0x85845dd1L);
R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
R3(C,D,A,B,X[ 6],15,0xa3014314L);
R3(B,C,D,A,X[13],21,0x4e0811a1L);
R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
R3(D,A,B,C,X[11],10,0xbd3af235L);
R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
R3(B,C,D,A,X[ 9],21,0xeb86d391L);
A+=c->A&0xffffffffL;
B+=c->B&0xffffffffL;
c->A=A;
c->B=B;
C+=c->C&0xffffffffL;
D+=c->D&0xffffffffL;
c->C=C;
c->D=D;
X+=16;
num-=64;
if (num <= 0) break;
}
}
#endif
void MD5_Final(md, c)
unsigned char *md;
MD5_CTX *c;
{
register int i,j;
register ULONG l;
register ULONG *p;
static unsigned char end[4]={0x80,0x00,0x00,0x00};
unsigned char *cp=end;
/* c->num should definitly have room for at least one more byte. */
p=c->data;
j=c->num;
i=j>>2;
/* purify often complains about the following line as an
* Uninitialized Memory Read. While this can be true, the
* following p_c2l macro will reset l when that case is true.
* This is because j&0x03 contains the number of 'valid' bytes
* already in p[i]. If and only if j&0x03 == 0, the UMR will
* occur but this is also the only time p_c2l will do
* l= *(cp++) instead of l|= *(cp++)
* Many thanks to Alex Tang <altitude@cic.net> for pickup this
* 'potential bug' */
#ifdef PURIFY
if ((j&0x03) == 0) p[i]=0;
#endif
l=p[i];
p_c2l(cp,l,j&0x03);
p[i]=l;
i++;
/* i is the next 'undefined word' */
if (c->num >= MD5_LAST_BLOCK)
{
for (; i<MD5_LBLOCK; i++)
p[i]=0;
md5_block(c,p,64);
i=0;
}
for (; i<(MD5_LBLOCK-2); i++)
p[i]=0;
p[MD5_LBLOCK-2]=c->Nl;
p[MD5_LBLOCK-1]=c->Nh;
md5_block(c,p,64);
cp=md;
l=c->A; l2c(l,cp);
l=c->B; l2c(l,cp);
l=c->C; l2c(l,cp);
l=c->D; l2c(l,cp);
/* clear stuff, md5_block may be leaving some stuff on the stack
* but I'm not worried :-) */
c->num=0;
/* memset((char *)&c,0,sizeof(c));*/
}
#ifdef undef
int printit(l)
unsigned long *l;
{
int i,ii;
for (i=0; i<2; i++)
{
for (ii=0; ii<8; ii++)
{
fprintf(stderr,"%08lx ",l[i*8+ii]);
}
fprintf(stderr,"\n");
}
}
#endif

195
crypto/md5_locl.h Normal file
View File

@ -0,0 +1,195 @@
/* crypto/md5/md5_locl.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.]
*/
/* On sparc, this actually slows things down :-( */
#if defined(sun)
#undef B_ENDIAN
#endif
#include <stdlib.h>
#include <string.h>
#include "md5.h"
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#if defined(NOCONST)
#define const
#endif
#undef c2l
#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24))
#undef p_c2l
#define p_c2l(c,l,n) { \
switch (n) { \
case 0: l =((unsigned long)(*((c)++))); \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
case 3: l|=((unsigned long)(*((c)++)))<<24; \
} \
}
/* NOTE the pointer is not incremented at the end of this */
#undef c2l_p
#define c2l_p(c,l,n) { \
l=0; \
(c)+=n; \
switch (n) { \
case 3: l =((unsigned long)(*(--(c))))<<16; \
case 2: l|=((unsigned long)(*(--(c))))<< 8; \
case 1: l|=((unsigned long)(*(--(c)))) ; \
} \
}
#undef p_c2l_p
#define p_c2l_p(c,l,sc,len) { \
switch (sc) \
{ \
case 0: l =((unsigned long)(*((c)++))); \
if (--len == 0) break; \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
if (--len == 0) break; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff))
/* NOTE - c is not incremented as per l2c */
#undef l2cn
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
#if defined(WIN32)
/* 5 instructions with rotate instruction, else 9 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
(a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
}
#else
/* 6 instructions with rotate instruction, else 8 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
(a)=ROTATE(l,16L); \
}
#endif
/*
#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
*/
/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
* simplified to the code below. Wei attributes these optimisations
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
*/
#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
#define H(b,c,d) ((b) ^ (c) ^ (d))
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
#undef ROTATE
#if defined(WIN32)
#define ROTATE(a,n) _lrotl(a,n)
#else
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#endif
#define R0(a,b,c,d,k,s,t) { \
a+=((k)+(t)+F((b),(c),(d))); \
a=ROTATE(a,s); \
a+=b; };\
#define R1(a,b,c,d,k,s,t) { \
a+=((k)+(t)+G((b),(c),(d))); \
a=ROTATE(a,s); \
a+=b; };
#define R2(a,b,c,d,k,s,t) { \
a+=((k)+(t)+H((b),(c),(d))); \
a=ROTATE(a,s); \
a+=b; };
#define R3(a,b,c,d,k,s,t) { \
a+=((k)+(t)+I((b),(c),(d))); \
a=ROTATE(a,s); \
a+=b; };

103
crypto/rc4.h Normal file
View File

@ -0,0 +1,103 @@
/* crypto/rc4/rc4.org */
/* 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.]
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify rc4.org since rc4.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#ifndef HEADER_RC4_H
#define HEADER_RC4_H
#ifdef __cplusplus
extern "C" {
#endif
/* using int types make the structure larger but make the code faster
* on most boxes I have tested - up to %20 faster. */
#define RC4_INT unsigned int
typedef struct rc4_key_st
{
RC4_INT x,y;
RC4_INT data[256];
} RC4_KEY;
#ifndef NOPROTO
char *RC4_options(void);
void RC4_set_key(RC4_KEY *key, int len, unsigned char *data);
void RC4(RC4_KEY *key, unsigned long len, unsigned char *indata,
unsigned char *outdata);
#else
char *RC4_options();
void RC4_set_key();
void RC4();
#endif
#ifdef __cplusplus
}
#endif
#endif

135
crypto/rc4_enc.c Normal file
View File

@ -0,0 +1,135 @@
/* crypto/rc4/rc4_enc.org */
/* 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 "rc4.h"
#include "rc4_locl.h"
/* RC4 as implemented from a posting from
* Newsgroups: sci.crypt
* From: sterndark@netcom.com (David Sterndark)
* Subject: RC4 Algorithm revealed.
* Message-ID: <sternCvKL4B.Hyy@netcom.com>
* Date: Wed, 14 Sep 1994 06:35:31 GMT
*/
void RC4(key, len, indata, outdata)
RC4_KEY *key;
unsigned long len;
unsigned char *indata;
unsigned char *outdata;
{
register RC4_INT *d;
register RC4_INT x,y,tx,ty;
int i;
x=key->x;
y=key->y;
d=key->data;
#define LOOP(in,out) \
x=((x+1)&0xff); \
tx=d[x]; \
y=(tx+y)&0xff; \
d[x]=ty=d[y]; \
d[y]=tx; \
(out) = d[(tx+ty)&0xff]^ (in);
#ifndef RC4_INDEX
#define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++))
#else
#define RC4_LOOP(a,b,i) LOOP(a[i],b[i])
#endif
i= -(int)len;
i=(int)(len>>3L);
if (i)
{
for (;;)
{
RC4_LOOP(indata,outdata,0);
RC4_LOOP(indata,outdata,1);
RC4_LOOP(indata,outdata,2);
RC4_LOOP(indata,outdata,3);
RC4_LOOP(indata,outdata,4);
RC4_LOOP(indata,outdata,5);
RC4_LOOP(indata,outdata,6);
RC4_LOOP(indata,outdata,7);
#ifdef RC4_INDEX
indata+=8;
outdata+=8;
#endif
if (--i == 0) break;
}
}
i=(int)len&0x07;
if (i)
{
for (;;)
{
RC4_LOOP(indata,outdata,0); if (--i == 0) break;
RC4_LOOP(indata,outdata,1); if (--i == 0) break;
RC4_LOOP(indata,outdata,2); if (--i == 0) break;
RC4_LOOP(indata,outdata,3); if (--i == 0) break;
RC4_LOOP(indata,outdata,4); if (--i == 0) break;
RC4_LOOP(indata,outdata,5); if (--i == 0) break;
RC4_LOOP(indata,outdata,6); if (--i == 0) break;
}
}
key->x=x;
key->y=y;
}

70
crypto/rc4_locl.h Normal file
View File

@ -0,0 +1,70 @@
/* crypto/rc4/rc4_locl.org */
/* 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.]
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify bf_locl.org since bf_locl.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
/* if this is defined data[i] is used instead of *data, this is a %20
* speedup on x86 */
#define RC4_INDEX

104
crypto/rc4_skey.c Normal file
View File

@ -0,0 +1,104 @@
/* crypto/rc4/rc4_enc.org */
/* 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 "rc4.h"
#include "rc4_locl.h"
/* char *RC4_version="RC4 part of SSLeay 0.8.2b 08-Jan-1998"; */
/* RC4 as implemented from a posting from
* Newsgroups: sci.crypt
* From: sterndark@netcom.com (David Sterndark)
* Subject: RC4 Algorithm revealed.
* Message-ID: <sternCvKL4B.Hyy@netcom.com>
* Date: Wed, 14 Sep 1994 06:35:31 GMT
*/
void RC4_set_key(key, len, data)
RC4_KEY *key;
int len;
register unsigned char *data;
{
register RC4_INT tmp;
register int id1,id2;
register RC4_INT *d;
unsigned int i;
d= &(key->data[0]);
for (i=0; i<256; i++)
d[i]=i;
key->x = 0;
key->y = 0;
id1=id2=0;
#define SK_LOOP(n) { \
tmp=d[(n)]; \
id2 = (data[id1] + tmp + id2) & 0xff; \
if (++id1 == len) id1=0; \
d[(n)]=d[id2]; \
d[id2]=tmp; }
for (i=0; i < 256; i+=4)
{
SK_LOOP(i+0);
SK_LOOP(i+1);
SK_LOOP(i+2);
SK_LOOP(i+3);
}
}

109
crypto/sha.h Normal file
View File

@ -0,0 +1,109 @@
/* 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 SHA_Transform(SHA_CTX *c, unsigned char *data);
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);
void SHA1_Transform(SHA_CTX *c, unsigned char *data);
#else
void SHA_Init();
void SHA_Update();
void SHA_Final();
unsigned char *SHA();
void SHA_Transform();
void SHA1_Init();
void SHA1_Update();
void SHA1_Final();
unsigned char *SHA1();
void SHA1_Transform();
#endif
#ifdef __cplusplus
}
#endif
#endif

467
crypto/sha1dgst.c Normal file
View File

@ -0,0 +1,467 @@
/* 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>
#include <string.h>
#undef SHA_0
#define SHA_1
#include "sha.h"
#include "sha_locl.h"
/* char *SHA1_version="SHA1 part of SSLeay 0.8.2b 08-Jan-1998"; */
/* 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
# ifdef SHA1_ASM
void sha1_block_x86(SHA_CTX *c, register unsigned long *p, int num);
# define sha1_block sha1_block_x86
# else
void sha1_block(SHA_CTX *c, register unsigned long *p, int num);
# endif
#else
# ifdef SHA1_ASM
void sha1_block_x86();
# define sha1_block sha1_block_x86
# else
void sha1_block();
# endif
#endif
#if defined(L_ENDIAN) && defined(SHA1_ASM)
# define M_c2nl c2l
# define M_p_c2nl p_c2l
# define M_c2nl_p c2l_p
# define M_p_c2nl_p p_c2l_p
# define M_nl2c l2c
#else
# define M_c2nl c2nl
# define M_p_c2nl p_c2nl
# define M_c2nl_p c2nl_p
# define M_p_c2nl_p p_c2nl_p
# define M_nl2c nl2c
#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))&0xffffffffL;
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];
M_p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw<SHA_LBLOCK; sw++)
{
M_c2nl(data,l);
p[sw]=l;
}
len-=(SHA_CBLOCK-c->num);
sha1_block(c,p,64);
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];
M_p_c2nl_p(data,l,sc,len);
p[sw]=l;
}
else
{
ew=(c->num>>2);
ec=(c->num&0x03);
l= p[sw];
M_p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw < ew; sw++)
{ M_c2nl(data,l); p[sw]=l; }
if (ec)
{
M_c2nl_p(data,l,ec);
p[sw]=l;
}
}
return;
}
}
/* We can only do the following code for assember, the reason
* being that the sha1_block 'C' version changes the values
* in the 'data' array. The assember code avoids this and
* copies it to a local array. I should be able to do this for
* the C version as well....
*/
#if 1
#if defined(B_ENDIAN) || defined(SHA1_ASM)
if ((((unsigned int)data)%sizeof(ULONG)) == 0)
{
sw=len/SHA_CBLOCK;
if (sw)
{
sw*=SHA_CBLOCK;
sha1_block(c,(ULONG *)data,sw);
data+=sw;
len-=sw;
}
}
#endif
#endif
/* 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)
if (p != (unsigned long *)data)
memcpy(p,data,SHA_CBLOCK);
data+=SHA_CBLOCK;
# ifdef L_ENDIAN
# ifndef SHA1_ASM /* Will not happen */
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;
}
p=c->data;
# endif
# endif
#else
for (sw=(SHA_BLOCK/4); sw; sw--)
{
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
}
p=c->data;
#endif
sha1_block(c,p,64);
len-=SHA_CBLOCK;
}
ec=(int)len;
c->num=ec;
ew=(ec>>2);
ec&=0x03;
for (sw=0; sw < ew; sw++)
{ M_c2nl(data,l); p[sw]=l; }
M_c2nl_p(data,l,ec);
p[sw]=l;
}
void SHA1_Transform(c,b)
SHA_CTX *c;
unsigned char *b;
{
ULONG p[16];
#ifndef B_ENDIAN
ULONG *q;
int i;
#endif
#if defined(B_ENDIAN) || defined(L_ENDIAN)
memcpy(p,b,64);
#ifdef L_ENDIAN
q=p;
for (i=(SHA_LBLOCK/4); i; i--)
{
Endian_Reverse32(q[0]);
Endian_Reverse32(q[1]);
Endian_Reverse32(q[2]);
Endian_Reverse32(q[3]);
q+=4;
}
#endif
#else
q=p;
for (i=(SHA_LBLOCK/4); i; i--)
{
ULONG l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
}
#endif
sha1_block(c,p,64);
}
#ifndef SHA1_ASM
void sha1_block(c, W, num)
SHA_CTX *c;
register unsigned long *W;
int num;
{
register ULONG A,B,C,D,E,T;
ULONG X[16];
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
for (;;)
{
BODY_00_15( 0,A,B,C,D,E,T,W);
BODY_00_15( 1,T,A,B,C,D,E,W);
BODY_00_15( 2,E,T,A,B,C,D,W);
BODY_00_15( 3,D,E,T,A,B,C,W);
BODY_00_15( 4,C,D,E,T,A,B,W);
BODY_00_15( 5,B,C,D,E,T,A,W);
BODY_00_15( 6,A,B,C,D,E,T,W);
BODY_00_15( 7,T,A,B,C,D,E,W);
BODY_00_15( 8,E,T,A,B,C,D,W);
BODY_00_15( 9,D,E,T,A,B,C,W);
BODY_00_15(10,C,D,E,T,A,B,W);
BODY_00_15(11,B,C,D,E,T,A,W);
BODY_00_15(12,A,B,C,D,E,T,W);
BODY_00_15(13,T,A,B,C,D,E,W);
BODY_00_15(14,E,T,A,B,C,D,W);
BODY_00_15(15,D,E,T,A,B,C,W);
BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
BODY_32_39(32,E,T,A,B,C,D,X);
BODY_32_39(33,D,E,T,A,B,C,X);
BODY_32_39(34,C,D,E,T,A,B,X);
BODY_32_39(35,B,C,D,E,T,A,X);
BODY_32_39(36,A,B,C,D,E,T,X);
BODY_32_39(37,T,A,B,C,D,E,X);
BODY_32_39(38,E,T,A,B,C,D,X);
BODY_32_39(39,D,E,T,A,B,C,X);
BODY_40_59(40,C,D,E,T,A,B,X);
BODY_40_59(41,B,C,D,E,T,A,X);
BODY_40_59(42,A,B,C,D,E,T,X);
BODY_40_59(43,T,A,B,C,D,E,X);
BODY_40_59(44,E,T,A,B,C,D,X);
BODY_40_59(45,D,E,T,A,B,C,X);
BODY_40_59(46,C,D,E,T,A,B,X);
BODY_40_59(47,B,C,D,E,T,A,X);
BODY_40_59(48,A,B,C,D,E,T,X);
BODY_40_59(49,T,A,B,C,D,E,X);
BODY_40_59(50,E,T,A,B,C,D,X);
BODY_40_59(51,D,E,T,A,B,C,X);
BODY_40_59(52,C,D,E,T,A,B,X);
BODY_40_59(53,B,C,D,E,T,A,X);
BODY_40_59(54,A,B,C,D,E,T,X);
BODY_40_59(55,T,A,B,C,D,E,X);
BODY_40_59(56,E,T,A,B,C,D,X);
BODY_40_59(57,D,E,T,A,B,C,X);
BODY_40_59(58,C,D,E,T,A,B,X);
BODY_40_59(59,B,C,D,E,T,A,X);
BODY_60_79(60,A,B,C,D,E,T,X);
BODY_60_79(61,T,A,B,C,D,E,X);
BODY_60_79(62,E,T,A,B,C,D,X);
BODY_60_79(63,D,E,T,A,B,C,X);
BODY_60_79(64,C,D,E,T,A,B,X);
BODY_60_79(65,B,C,D,E,T,A,X);
BODY_60_79(66,A,B,C,D,E,T,X);
BODY_60_79(67,T,A,B,C,D,E,X);
BODY_60_79(68,E,T,A,B,C,D,X);
BODY_60_79(69,D,E,T,A,B,C,X);
BODY_60_79(70,C,D,E,T,A,B,X);
BODY_60_79(71,B,C,D,E,T,A,X);
BODY_60_79(72,A,B,C,D,E,T,X);
BODY_60_79(73,T,A,B,C,D,E,X);
BODY_60_79(74,E,T,A,B,C,D,X);
BODY_60_79(75,D,E,T,A,B,C,X);
BODY_60_79(76,C,D,E,T,A,B,X);
BODY_60_79(77,B,C,D,E,T,A,X);
BODY_60_79(78,A,B,C,D,E,T,X);
BODY_60_79(79,T,A,B,C,D,E,X);
c->h0=(c->h0+E)&0xffffffffL;
c->h1=(c->h1+T)&0xffffffffL;
c->h2=(c->h2+A)&0xffffffffL;
c->h3=(c->h3+B)&0xffffffffL;
c->h4=(c->h4+C)&0xffffffffL;
num-=64;
if (num <= 0) break;
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
W+=16;
}
}
#endif
void SHA1_Final(md, c)
unsigned char *md;
SHA_CTX *c;
{
register int i,j;
register ULONG l;
register ULONG *p;
static unsigned char end[4]={0x80,0x00,0x00,0x00};
unsigned char *cp=end;
/* c->num should definitly have room for at least one more byte. */
p=c->data;
j=c->num;
i=j>>2;
#ifdef PURIFY
if ((j&0x03) == 0) p[i]=0;
#endif
l=p[i];
M_p_c2nl(cp,l,j&0x03);
p[i]=l;
i++;
/* i is the next 'undefined word' */
if (c->num >= SHA_LAST_BLOCK)
{
for (; i<SHA_LBLOCK; i++)
p[i]=0;
sha1_block(c,p,64);
i=0;
}
for (; i<(SHA_LBLOCK-2); i++)
p[i]=0;
p[SHA_LBLOCK-2]=c->Nh;
p[SHA_LBLOCK-1]=c->Nl;
#if defined(L_ENDIAN) && defined(SHA1_ASM)
Endian_Reverse32(p[SHA_LBLOCK-2]);
Endian_Reverse32(p[SHA_LBLOCK-1]);
#endif
sha1_block(c,p,64);
cp=md;
l=c->h0; nl2c(l,cp);
l=c->h1; nl2c(l,cp);
l=c->h2; nl2c(l,cp);
l=c->h3; nl2c(l,cp);
l=c->h4; nl2c(l,cp);
/* clear stuff, sha1_block may be leaving some stuff on the stack
* but I'm not worried :-) */
c->num=0;
/* memset((char *)&c,0,sizeof(c));*/
}

246
crypto/sha_locl.h Normal file
View File

@ -0,0 +1,246 @@
/* crypto/sha/sha_locl.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.]
*/
#include <stdlib.h>
#include <string.h>
#ifdef undef
/* one or the other needs to be defined */
#ifndef SHA_1 /* FIPE 180-1 */
#define SHA_0 /* FIPS 180 */
#endif
#endif
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#ifdef NOCONST
#define const
#endif
#undef c2nl
#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++))) ))
#undef p_c2nl
#define p_c2nl(c,l,n) { \
switch (n) { \
case 0: l =((unsigned long)(*((c)++)))<<24; \
case 1: l|=((unsigned long)(*((c)++)))<<16; \
case 2: l|=((unsigned long)(*((c)++)))<< 8; \
case 3: l|=((unsigned long)(*((c)++))); \
} \
}
#undef c2nl_p
/* NOTE the pointer is not incremented at the end of this */
#define c2nl_p(c,l,n) { \
l=0; \
(c)+=n; \
switch (n) { \
case 3: l =((unsigned long)(*(--(c))))<< 8; \
case 2: l|=((unsigned long)(*(--(c))))<<16; \
case 1: l|=((unsigned long)(*(--(c))))<<24; \
} \
}
#undef p_c2nl_p
#define p_c2nl_p(c,l,sc,len) { \
switch (sc) \
{ \
case 0: l =((unsigned long)(*((c)++)))<<24; \
if (--len == 0) break; \
case 1: l|=((unsigned long)(*((c)++)))<<16; \
if (--len == 0) break; \
case 2: l|=((unsigned long)(*((c)++)))<< 8; \
} \
}
#undef nl2c
#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
#undef c2l
#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24))
#undef p_c2l
#define p_c2l(c,l,n) { \
switch (n) { \
case 0: l =((unsigned long)(*((c)++))); \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
case 3: l|=((unsigned long)(*((c)++)))<<24; \
} \
}
#undef c2l_p
/* NOTE the pointer is not incremented at the end of this */
#define c2l_p(c,l,n) { \
l=0; \
(c)+=n; \
switch (n) { \
case 3: l =((unsigned long)(*(--(c))))<<16; \
case 2: l|=((unsigned long)(*(--(c))))<< 8; \
case 1: l|=((unsigned long)(*(--(c)))); \
} \
}
#undef p_c2l_p
#define p_c2l_p(c,l,sc,len) { \
switch (sc) \
{ \
case 0: l =((unsigned long)(*((c)++))); \
if (--len == 0) break; \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
if (--len == 0) break; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff))
#undef ROTATE
#if defined(WIN32)
#define ROTATE(a,n) _lrotl(a,n)
#else
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#endif
/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
#if defined(WIN32)
/* 5 instructions with rotate instruction, else 9 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
(a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
}
#else
/* 6 instructions with rotate instruction, else 8 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
(a)=ROTATE(l,16L); \
}
#endif
/* As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
* simplified to the code in F_00_19. Wei attributes these optimisations
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
* #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
* I've just become aware of another tweak to be made, again from Wei Dai,
* in F_40_59, (x&a)|(y&a) -> (x|y)&a
*/
#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
#define F_60_79(b,c,d) F_20_39(b,c,d)
#ifdef SHA_0
#undef Xupdate
#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\
(ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);
#endif
#ifdef SHA_1
#undef Xupdate
#define Xupdate(a,i,ia,ib,ic,id) (a)=\
(ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\
X[(i)&0x0f]=(a)=ROTATE((a),1);
#endif
#define BODY_00_15(i,a,b,c,d,e,f,xa) \
(f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_32_39(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_40_59(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_60_79(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
(b)=ROTATE((b),30);