]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libcrypt/shs.c
The new crypt code breaks "make world". Back it out.
[FreeBSD/FreeBSD.git] / lib / libcrypt / shs.c
1 /*
2  ********************************************************************
3  *     SHS 180-1 Reference Implementation (with unrolled loops)     *
4  *             Copyright 1995-6 by Paul C. Kocher.                  *
5  *                                                                  *
6  *  This file is provided as-is, without warranty of any kind;      *
7  *     use at your own risk.  This file may be copied and used,     *
8  *     even for commercial purposes, for free.  For information,    *
9  *     updates, updates, or consulting help, send e-mail to the     *
10  *     author at pck@cryptography.com.                              *
11  *                                                                  *
12  *  EXPORT STATUS:  In informal discussions, the U.S. National      *
13  *     Security Agency has indicated to me that source code for     *
14  *     can be exported from the U.S. freely, but programs using     *
15  *     or incorporating this code may be restricted.  Please make   *
16  *     sure you understand the applicable export regulations        *
17  *     before doing any work with cryptography.                     *
18  *                                                                  *
19  *  For links to other cryptography source code, papers, etc. see   *
20  *     http://www.cryptography.com.                                 *
21  ********************************************************************
22  */
23
24 #include "shs.h"
25
26 static void shsCompress(SHS_CTX *ctx);
27
28 #define SHS_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
29 #define SHS_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
30 #define SHS_F2(X,Y,Z) ((X)^(Y)^(Z))
31 #define SHS_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
32 #define SHS_F4(X,Y,Z) ((X)^(Y)^(Z))
33
34
35 /*
36  *  SHS: Initialize context
37  */
38 void shsInit(SHS_CTX *ctx) {
39   ctx->lenW = 0;
40   ctx->sizeHi = ctx->sizeLo = 0;
41
42   /*
43    *  Initialize H with constants from FIPS180-1.
44    */
45   ctx->H[0] = 0x67452301L;
46   ctx->H[1] = 0xefcdab89L;
47   ctx->H[2] = 0x98badcfeL;
48   ctx->H[3] = 0x10325476L;
49   ctx->H[4] = 0xc3d2e1f0L;
50 }
51
52
53 /*
54  *  SHS: Add data to context.
55  */
56 void shsUpdate(SHS_CTX *ctx, const unsigned char * dataIn, int len) {
57   /*
58    *  Read the data into W and process blocks as they get full
59    *
60    *  NOTE: The shifts can be eliminated on big-endian machines, since 
61    *      the byte-to-word transformation can be done with a copy.  In 
62    *      assembly language on 80486+ computers, the BSWAP instruction 
63    *      can be used.
64    */
65   ctx->sizeLo += 8*len;
66   ctx->sizeHi += (ctx->sizeLo < 8*len) + (len >> 29);
67   while (len--) {
68     ctx->W[ctx->lenW / 4] <<= 8;
69     ctx->W[ctx->lenW / 4] |= *(dataIn++);
70     if (((++ctx->lenW) & 63) == 0) {
71       shsCompress(ctx);
72       ctx->lenW = 0;
73     }
74   }
75 }
76
77
78 /*
79  *  SHS: Generate hash value from context
80  */
81 void shsFinal(SHS_CTX * ctx, unsigned char hashOut[20]) {
82   static unsigned char bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0,
83           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
84           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  };
85   unsigned char length_pad[8];
86   int i;
87
88   /*
89    *  Pad with a binary 1 (e.g. 0x80), then zeroes, then length
90    */
91   length_pad[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
92   length_pad[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
93   length_pad[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
94   length_pad[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
95   length_pad[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
96   length_pad[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
97   length_pad[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
98   length_pad[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
99   shsUpdate(ctx, bulk_pad, ((56+64) - ctx->lenW) & 63);
100   shsUpdate(ctx, length_pad, 8);
101
102   /*
103    *  Output hash
104    */
105   for (i = 0; i < 5; i++) {
106     *(hashOut++) = ((unsigned char)(ctx->H[i] >> 24)) & 255;
107     *(hashOut++) = ((unsigned char)(ctx->H[i] >> 16)) & 255;
108     *(hashOut++) = ((unsigned char)(ctx->H[i] >>  8)) & 255;
109     *(hashOut++) = ((unsigned char)(ctx->H[i]      )) & 255;
110   }
111
112   /*
113    *  Re-initialize the context (also zeroizes contents)
114    */
115   shsInit(ctx);
116 }
117
118
119 /*
120  *  SHS: Hash a block in memory
121  */
122 void shsBlock(const unsigned char *dataIn, int len, unsigned char hashOut[20]) {
123   SHS_CTX ctx;
124
125   shsInit(&ctx);
126   shsUpdate(&ctx, dataIn, len);
127   shsFinal(&ctx, hashOut);
128 }
129
130
131 /*
132  *  SHS: Compression function, unrolled.
133  */
134 static void shsCompress(SHS_CTX *ctx) {
135   int t;
136   register unsigned long A,B,C,D,E;
137
138   /*
139    *  This can be moved into the main code block below, but doing
140    *  so can cause some compilers to run out of registers and resort
141    *  to storing intermediates in RAM.
142    */
143   for (t = 16; t <= 79; t++)
144     ctx->W[t] =
145       SHS_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
146
147   A = ctx->H[0];
148   B = ctx->H[1];
149   C = ctx->H[2];
150   D = ctx->H[3];
151   E = ctx->H[4];
152
153   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[ 0]+0x5a827999L; B=SHS_ROTL(B,30); 
154   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[ 1]+0x5a827999L; A=SHS_ROTL(A,30); 
155   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[ 2]+0x5a827999L; E=SHS_ROTL(E,30); 
156   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[ 3]+0x5a827999L; D=SHS_ROTL(D,30); 
157   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[ 4]+0x5a827999L; C=SHS_ROTL(C,30); 
158   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[ 5]+0x5a827999L; B=SHS_ROTL(B,30); 
159   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[ 6]+0x5a827999L; A=SHS_ROTL(A,30); 
160   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[ 7]+0x5a827999L; E=SHS_ROTL(E,30); 
161   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[ 8]+0x5a827999L; D=SHS_ROTL(D,30); 
162   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[ 9]+0x5a827999L; C=SHS_ROTL(C,30); 
163   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[10]+0x5a827999L; B=SHS_ROTL(B,30); 
164   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[11]+0x5a827999L; A=SHS_ROTL(A,30); 
165   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[12]+0x5a827999L; E=SHS_ROTL(E,30); 
166   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[13]+0x5a827999L; D=SHS_ROTL(D,30); 
167   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[14]+0x5a827999L; C=SHS_ROTL(C,30); 
168   E = SHS_ROTL(A,5)+SHS_F1(B,C,D)+E+ctx->W[15]+0x5a827999L; B=SHS_ROTL(B,30); 
169   D = SHS_ROTL(E,5)+SHS_F1(A,B,C)+D+ctx->W[16]+0x5a827999L; A=SHS_ROTL(A,30); 
170   C = SHS_ROTL(D,5)+SHS_F1(E,A,B)+C+ctx->W[17]+0x5a827999L; E=SHS_ROTL(E,30); 
171   B = SHS_ROTL(C,5)+SHS_F1(D,E,A)+B+ctx->W[18]+0x5a827999L; D=SHS_ROTL(D,30); 
172   A = SHS_ROTL(B,5)+SHS_F1(C,D,E)+A+ctx->W[19]+0x5a827999L; C=SHS_ROTL(C,30); 
173
174   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[20]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
175   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[21]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
176   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[22]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
177   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[23]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
178   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[24]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
179   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[25]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
180   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[26]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
181   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[27]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
182   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[28]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
183   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[29]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
184   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[30]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
185   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[31]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
186   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[32]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
187   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[33]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
188   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[34]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
189   E = SHS_ROTL(A,5)+SHS_F2(B,C,D)+E+ctx->W[35]+0x6ed9eba1L; B=SHS_ROTL(B,30); 
190   D = SHS_ROTL(E,5)+SHS_F2(A,B,C)+D+ctx->W[36]+0x6ed9eba1L; A=SHS_ROTL(A,30); 
191   C = SHS_ROTL(D,5)+SHS_F2(E,A,B)+C+ctx->W[37]+0x6ed9eba1L; E=SHS_ROTL(E,30); 
192   B = SHS_ROTL(C,5)+SHS_F2(D,E,A)+B+ctx->W[38]+0x6ed9eba1L; D=SHS_ROTL(D,30); 
193   A = SHS_ROTL(B,5)+SHS_F2(C,D,E)+A+ctx->W[39]+0x6ed9eba1L; C=SHS_ROTL(C,30); 
194
195   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[40]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
196   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[41]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
197   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[42]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
198   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[43]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
199   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[44]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
200   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[45]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
201   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[46]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
202   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[47]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
203   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[48]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
204   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[49]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
205   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[50]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
206   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[51]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
207   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[52]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
208   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[53]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
209   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[54]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
210   E = SHS_ROTL(A,5)+SHS_F3(B,C,D)+E+ctx->W[55]+0x8f1bbcdcL; B=SHS_ROTL(B,30); 
211   D = SHS_ROTL(E,5)+SHS_F3(A,B,C)+D+ctx->W[56]+0x8f1bbcdcL; A=SHS_ROTL(A,30); 
212   C = SHS_ROTL(D,5)+SHS_F3(E,A,B)+C+ctx->W[57]+0x8f1bbcdcL; E=SHS_ROTL(E,30); 
213   B = SHS_ROTL(C,5)+SHS_F3(D,E,A)+B+ctx->W[58]+0x8f1bbcdcL; D=SHS_ROTL(D,30); 
214   A = SHS_ROTL(B,5)+SHS_F3(C,D,E)+A+ctx->W[59]+0x8f1bbcdcL; C=SHS_ROTL(C,30); 
215
216   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[60]+0xca62c1d6L; B=SHS_ROTL(B,30); 
217   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[61]+0xca62c1d6L; A=SHS_ROTL(A,30); 
218   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[62]+0xca62c1d6L; E=SHS_ROTL(E,30); 
219   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[63]+0xca62c1d6L; D=SHS_ROTL(D,30); 
220   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[64]+0xca62c1d6L; C=SHS_ROTL(C,30); 
221   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[65]+0xca62c1d6L; B=SHS_ROTL(B,30); 
222   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[66]+0xca62c1d6L; A=SHS_ROTL(A,30); 
223   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[67]+0xca62c1d6L; E=SHS_ROTL(E,30); 
224   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[68]+0xca62c1d6L; D=SHS_ROTL(D,30); 
225   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[69]+0xca62c1d6L; C=SHS_ROTL(C,30); 
226   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[70]+0xca62c1d6L; B=SHS_ROTL(B,30); 
227   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[71]+0xca62c1d6L; A=SHS_ROTL(A,30); 
228   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[72]+0xca62c1d6L; E=SHS_ROTL(E,30); 
229   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[73]+0xca62c1d6L; D=SHS_ROTL(D,30); 
230   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[74]+0xca62c1d6L; C=SHS_ROTL(C,30); 
231   E = SHS_ROTL(A,5)+SHS_F4(B,C,D)+E+ctx->W[75]+0xca62c1d6L; B=SHS_ROTL(B,30); 
232   D = SHS_ROTL(E,5)+SHS_F4(A,B,C)+D+ctx->W[76]+0xca62c1d6L; A=SHS_ROTL(A,30); 
233   C = SHS_ROTL(D,5)+SHS_F4(E,A,B)+C+ctx->W[77]+0xca62c1d6L; E=SHS_ROTL(E,30); 
234   B = SHS_ROTL(C,5)+SHS_F4(D,E,A)+B+ctx->W[78]+0xca62c1d6L; D=SHS_ROTL(D,30); 
235   A = SHS_ROTL(B,5)+SHS_F4(C,D,E)+A+ctx->W[79]+0xca62c1d6L; C=SHS_ROTL(C,30); 
236
237   ctx->H[0] += A;
238   ctx->H[1] += B;
239   ctx->H[2] += C;
240   ctx->H[3] += D;
241   ctx->H[4] += E;
242 }
243