Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

beecrypt/sha1.c

Go to the documentation of this file.
00001 
00010 /*
00011  * Copyright (c) 1997, 1998, 1999, 2000, 2001 Virtual Unlimited B.V.
00012  *
00013  * Author: Bob Deblier <bob@virtualunlimited.com>
00014  *
00015  * This library is free software; you can redistribute it and/or
00016  * modify it under the terms of the GNU Lesser General Public
00017  * License as published by the Free Software Foundation; either
00018  * version 2.1 of the License, or (at your option) any later version.
00019  *
00020  * This library is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00023  * Lesser General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU Lesser General Public
00026  * License along with this library; if not, write to the Free Software
00027  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030  
00031 #include "system.h"
00032 #include "beecrypt.h"
00033 #include "sha1opt.h"
00034 #include "sha1.h"
00035 #include "mp32.h"
00036 #include "endianness.h"
00037 #include "debug.h"
00038 
00041 /*@observer@*/ /*@unchecked@*/
00042 static const uint32 k[4] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
00043 
00046 /*@observer@*/ /*@unchecked@*/
00047 static const uint32 hinit[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
00048 
00049 /*@-sizeoftype@*/
00050 const hashFunction sha1 = { "SHA-1", sizeof(sha1Param), 64, 5 * sizeof(uint32), (hashFunctionReset) sha1Reset, (hashFunctionUpdate) sha1Update, (hashFunctionDigest) sha1Digest };
00051 /*@=sizeoftype@*/
00052 
00053 /*@-boundswrite@*/
00054 int sha1Reset(register sha1Param *p)
00055 {
00056         mp32copy(5, p->h, hinit);
00057         mp32zero(80, p->data);
00058         p->length = 0;
00059         p->offset = 0;
00060         return 0;
00061 }
00062 /*@=boundswrite@*/
00063 
00064 #define SUBROUND1(a, b, c, d, e, w, k) \
00065         e = ROTL32(a, 5) + ((b&(c^d))^d) + e + w + k;   \
00066         b = ROTR32(b, 2)
00067 #define SUBROUND2(a, b, c, d, e, w, k) \
00068         e = ROTL32(a, 5) + (b^c^d) + e + w + k; \
00069         b = ROTR32(b, 2)
00070 #define SUBROUND3(a, b, c, d, e, w, k) \
00071         e = ROTL32(a, 5) + (((b|c)&d)|(b&c)) + e + w + k;       \
00072         b = ROTR32(b, 2)
00073 #define SUBROUND4(a, b, c, d, e, w, k) \
00074         e = ROTL32(a, 5) + (b^c^d) + e + w + k; \
00075         b = ROTR32(b, 2)
00076 
00077 #ifndef ASM_SHA1PROCESS
00078 /*@-boundsread@*/
00079 void sha1Process(register sha1Param *p)
00080 {
00081         register uint32 a, b, c, d, e;
00082         register uint32 *w;
00083         register byte t;
00084         
00085         #if WORDS_BIGENDIAN
00086         w = p->data + 16;
00087         #else
00088         w = p->data;
00089         t = 16;
00090         while (t--)
00091         {
00092                 register uint32 temp = swapu32(*w);
00093                 *(w++) = temp;
00094         }
00095         #endif
00096 
00097         t = 64;
00098         while (t--)
00099         {
00100                 register uint32 temp = w[-3] ^ w[-8] ^ w[-14] ^ w[-16];
00101                 *(w++) = ROTL32(temp, 1);
00102         }
00103 
00104         w = p->data;
00105 
00106         a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3]; e = p->h[4];
00107 
00108         SUBROUND1(a,b,c,d,e,w[ 0],k[0]);
00109         SUBROUND1(e,a,b,c,d,w[ 1],k[0]);
00110         SUBROUND1(d,e,a,b,c,w[ 2],k[0]);
00111         SUBROUND1(c,d,e,a,b,w[ 3],k[0]);
00112         SUBROUND1(b,c,d,e,a,w[ 4],k[0]);
00113         SUBROUND1(a,b,c,d,e,w[ 5],k[0]);
00114         SUBROUND1(e,a,b,c,d,w[ 6],k[0]);
00115         SUBROUND1(d,e,a,b,c,w[ 7],k[0]);
00116         SUBROUND1(c,d,e,a,b,w[ 8],k[0]);
00117         SUBROUND1(b,c,d,e,a,w[ 9],k[0]);
00118         SUBROUND1(a,b,c,d,e,w[10],k[0]);
00119         SUBROUND1(e,a,b,c,d,w[11],k[0]);
00120         SUBROUND1(d,e,a,b,c,w[12],k[0]);
00121         SUBROUND1(c,d,e,a,b,w[13],k[0]);
00122         SUBROUND1(b,c,d,e,a,w[14],k[0]);
00123         SUBROUND1(a,b,c,d,e,w[15],k[0]);
00124         SUBROUND1(e,a,b,c,d,w[16],k[0]);
00125         SUBROUND1(d,e,a,b,c,w[17],k[0]);
00126         SUBROUND1(c,d,e,a,b,w[18],k[0]);
00127         SUBROUND1(b,c,d,e,a,w[19],k[0]);
00128 
00129         SUBROUND2(a,b,c,d,e,w[20],k[1]);
00130         SUBROUND2(e,a,b,c,d,w[21],k[1]);
00131         SUBROUND2(d,e,a,b,c,w[22],k[1]);
00132         SUBROUND2(c,d,e,a,b,w[23],k[1]);
00133         SUBROUND2(b,c,d,e,a,w[24],k[1]);
00134         SUBROUND2(a,b,c,d,e,w[25],k[1]);
00135         SUBROUND2(e,a,b,c,d,w[26],k[1]);
00136         SUBROUND2(d,e,a,b,c,w[27],k[1]);
00137         SUBROUND2(c,d,e,a,b,w[28],k[1]);
00138         SUBROUND2(b,c,d,e,a,w[29],k[1]);
00139         SUBROUND2(a,b,c,d,e,w[30],k[1]);
00140         SUBROUND2(e,a,b,c,d,w[31],k[1]);
00141         SUBROUND2(d,e,a,b,c,w[32],k[1]);
00142         SUBROUND2(c,d,e,a,b,w[33],k[1]);
00143         SUBROUND2(b,c,d,e,a,w[34],k[1]);
00144         SUBROUND2(a,b,c,d,e,w[35],k[1]);
00145         SUBROUND2(e,a,b,c,d,w[36],k[1]);
00146         SUBROUND2(d,e,a,b,c,w[37],k[1]);
00147         SUBROUND2(c,d,e,a,b,w[38],k[1]);
00148         SUBROUND2(b,c,d,e,a,w[39],k[1]);
00149 
00150         SUBROUND3(a,b,c,d,e,w[40],k[2]);
00151         SUBROUND3(e,a,b,c,d,w[41],k[2]);
00152         SUBROUND3(d,e,a,b,c,w[42],k[2]);
00153         SUBROUND3(c,d,e,a,b,w[43],k[2]);
00154         SUBROUND3(b,c,d,e,a,w[44],k[2]);
00155         SUBROUND3(a,b,c,d,e,w[45],k[2]);
00156         SUBROUND3(e,a,b,c,d,w[46],k[2]);
00157         SUBROUND3(d,e,a,b,c,w[47],k[2]);
00158         SUBROUND3(c,d,e,a,b,w[48],k[2]);
00159         SUBROUND3(b,c,d,e,a,w[49],k[2]);
00160         SUBROUND3(a,b,c,d,e,w[50],k[2]);
00161         SUBROUND3(e,a,b,c,d,w[51],k[2]);
00162         SUBROUND3(d,e,a,b,c,w[52],k[2]);
00163         SUBROUND3(c,d,e,a,b,w[53],k[2]);
00164         SUBROUND3(b,c,d,e,a,w[54],k[2]);
00165         SUBROUND3(a,b,c,d,e,w[55],k[2]);
00166         SUBROUND3(e,a,b,c,d,w[56],k[2]);
00167         SUBROUND3(d,e,a,b,c,w[57],k[2]);
00168         SUBROUND3(c,d,e,a,b,w[58],k[2]);
00169         SUBROUND3(b,c,d,e,a,w[59],k[2]);
00170 
00171         SUBROUND4(a,b,c,d,e,w[60],k[3]);
00172         SUBROUND4(e,a,b,c,d,w[61],k[3]);
00173         SUBROUND4(d,e,a,b,c,w[62],k[3]);
00174         SUBROUND4(c,d,e,a,b,w[63],k[3]);
00175         SUBROUND4(b,c,d,e,a,w[64],k[3]);
00176         SUBROUND4(a,b,c,d,e,w[65],k[3]);
00177         SUBROUND4(e,a,b,c,d,w[66],k[3]);
00178         SUBROUND4(d,e,a,b,c,w[67],k[3]);
00179         SUBROUND4(c,d,e,a,b,w[68],k[3]);
00180         SUBROUND4(b,c,d,e,a,w[69],k[3]);
00181         SUBROUND4(a,b,c,d,e,w[70],k[3]);
00182         SUBROUND4(e,a,b,c,d,w[71],k[3]);
00183         SUBROUND4(d,e,a,b,c,w[72],k[3]);
00184         SUBROUND4(c,d,e,a,b,w[73],k[3]);
00185         SUBROUND4(b,c,d,e,a,w[74],k[3]);
00186         SUBROUND4(a,b,c,d,e,w[75],k[3]);
00187         SUBROUND4(e,a,b,c,d,w[76],k[3]);
00188         SUBROUND4(d,e,a,b,c,w[77],k[3]);
00189         SUBROUND4(c,d,e,a,b,w[78],k[3]);
00190         SUBROUND4(b,c,d,e,a,w[79],k[3]);
00191 
00192         p->h[0] += a;
00193         p->h[1] += b;
00194         p->h[2] += c;
00195         p->h[3] += d;
00196         p->h[4] += e;
00197 }
00198 /*@=boundsread@*/
00199 #endif
00200 
00201 /*@-boundswrite@*/
00202 int sha1Update(register sha1Param *p, const byte *data, int size)
00203 {
00204         register int proclength;
00205 
00206         p->length += size;
00207         while (size > 0)
00208         {
00209                 proclength = ((p->offset + size) > 64) ? (64 - p->offset) : size;
00210                 memmove(((byte *) p->data) + p->offset, data, proclength);
00211                 size -= proclength;
00212                 data += proclength;
00213                 p->offset += proclength;
00214 
00215                 if (p->offset == 64)
00216                 {
00217                         sha1Process(p);
00218                         p->offset = 0;
00219                 }
00220         }
00221         return 0;
00222 }
00223 /*@=boundswrite@*/
00224 
00227 /*@-boundswrite@*/
00228 static void sha1Finish(register sha1Param *p)
00229         /*@modifies p @*/
00230 {
00231         register byte *ptr = ((byte *) p->data) + p->offset++;
00232 
00233         *(ptr++) = 0x80;
00234 
00235         if (p->offset > 56)
00236         {
00237                 while (p->offset++ < 64)
00238                         *(ptr++) = 0;
00239 
00240                 sha1Process(p);
00241                 p->offset = 0;
00242         }
00243 
00244         ptr = ((byte *) p->data) + p->offset;
00245         while (p->offset++ < 56)
00246                 *(ptr++) = 0;
00247 
00248         #if WORDS_BIGENDIAN
00249         p->data[14] = ((uint32)(p->length >> 29));
00250         p->data[15] = ((uint32)((p->length << 3) & 0xffffffff));
00251         #else
00252         p->data[14] = swapu32((uint32)(p->length >> 29));
00253         p->data[15] = swapu32((uint32)((p->length << 3) & 0xffffffff));
00254         #endif
00255 
00256         sha1Process(p);
00257         p->offset = 0;
00258 }
00259 /*@=boundswrite@*/
00260 
00261 /*@-boundswrite@*/
00262 int sha1Digest(register sha1Param *p, uint32 *data)
00263 {
00264         sha1Finish(p);
00265         mp32copy(5, data, p->h);
00266         (void) sha1Reset(p);
00267         return 0;
00268 }
00269 /*@=boundswrite@*/

Generated on Tue Sep 17 15:56:37 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002