Merge native DKIM support (from DEVEL_PDKIM)
[exim.git] / src / src / pdkim / sha1.c
CommitLineData
80a47a2c
TK
1/*
2 * FIPS-180-1 compliant SHA-1 implementation
3 *
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The SHA-1 standard was published by NIST in 1993.
24 *
25 * http://www.itl.nist.gov/fipspubs/fip180-1.htm
26 */
27
28/* $Cambridge: exim/src/src/pdkim/sha1.c,v 1.2 2009/06/10 07:34:05 tom Exp $ */
29
30#include "sha1.h"
31
32#include <string.h>
33#include <stdio.h>
34
35/*
36 * 32-bit integer manipulation macros (big endian)
37 */
38#ifndef GET_ULONG_BE
39#define GET_ULONG_BE(n,b,i) \
40{ \
41 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
42 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
43 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
44 | ( (unsigned long) (b)[(i) + 3] ); \
45}
46#endif
47
48#ifndef PUT_ULONG_BE
49#define PUT_ULONG_BE(n,b,i) \
50{ \
51 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
52 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
53 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
54 (b)[(i) + 3] = (unsigned char) ( (n) ); \
55}
56#endif
57
58/*
59 * SHA-1 context setup
60 */
61void sha1_starts( sha1_context *ctx )
62{
63 ctx->total[0] = 0;
64 ctx->total[1] = 0;
65
66 ctx->state[0] = 0x67452301;
67 ctx->state[1] = 0xEFCDAB89;
68 ctx->state[2] = 0x98BADCFE;
69 ctx->state[3] = 0x10325476;
70 ctx->state[4] = 0xC3D2E1F0;
71}
72
73static void sha1_process( sha1_context *ctx, unsigned char data[64] )
74{
75 unsigned long temp, W[16], A, B, C, D, E;
76
77 GET_ULONG_BE( W[ 0], data, 0 );
78 GET_ULONG_BE( W[ 1], data, 4 );
79 GET_ULONG_BE( W[ 2], data, 8 );
80 GET_ULONG_BE( W[ 3], data, 12 );
81 GET_ULONG_BE( W[ 4], data, 16 );
82 GET_ULONG_BE( W[ 5], data, 20 );
83 GET_ULONG_BE( W[ 6], data, 24 );
84 GET_ULONG_BE( W[ 7], data, 28 );
85 GET_ULONG_BE( W[ 8], data, 32 );
86 GET_ULONG_BE( W[ 9], data, 36 );
87 GET_ULONG_BE( W[10], data, 40 );
88 GET_ULONG_BE( W[11], data, 44 );
89 GET_ULONG_BE( W[12], data, 48 );
90 GET_ULONG_BE( W[13], data, 52 );
91 GET_ULONG_BE( W[14], data, 56 );
92 GET_ULONG_BE( W[15], data, 60 );
93
94#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
95
96#define R(t) \
97( \
98 temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
99 W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
100 ( W[t & 0x0F] = S(temp,1) ) \
101)
102
103#define P(a,b,c,d,e,x) \
104{ \
105 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
106}
107
108 A = ctx->state[0];
109 B = ctx->state[1];
110 C = ctx->state[2];
111 D = ctx->state[3];
112 E = ctx->state[4];
113
114#define F(x,y,z) (z ^ (x & (y ^ z)))
115#define K 0x5A827999
116
117 P( A, B, C, D, E, W[0] );
118 P( E, A, B, C, D, W[1] );
119 P( D, E, A, B, C, W[2] );
120 P( C, D, E, A, B, W[3] );
121 P( B, C, D, E, A, W[4] );
122 P( A, B, C, D, E, W[5] );
123 P( E, A, B, C, D, W[6] );
124 P( D, E, A, B, C, W[7] );
125 P( C, D, E, A, B, W[8] );
126 P( B, C, D, E, A, W[9] );
127 P( A, B, C, D, E, W[10] );
128 P( E, A, B, C, D, W[11] );
129 P( D, E, A, B, C, W[12] );
130 P( C, D, E, A, B, W[13] );
131 P( B, C, D, E, A, W[14] );
132 P( A, B, C, D, E, W[15] );
133 P( E, A, B, C, D, R(16) );
134 P( D, E, A, B, C, R(17) );
135 P( C, D, E, A, B, R(18) );
136 P( B, C, D, E, A, R(19) );
137
138#undef K
139#undef F
140
141#define F(x,y,z) (x ^ y ^ z)
142#define K 0x6ED9EBA1
143
144 P( A, B, C, D, E, R(20) );
145 P( E, A, B, C, D, R(21) );
146 P( D, E, A, B, C, R(22) );
147 P( C, D, E, A, B, R(23) );
148 P( B, C, D, E, A, R(24) );
149 P( A, B, C, D, E, R(25) );
150 P( E, A, B, C, D, R(26) );
151 P( D, E, A, B, C, R(27) );
152 P( C, D, E, A, B, R(28) );
153 P( B, C, D, E, A, R(29) );
154 P( A, B, C, D, E, R(30) );
155 P( E, A, B, C, D, R(31) );
156 P( D, E, A, B, C, R(32) );
157 P( C, D, E, A, B, R(33) );
158 P( B, C, D, E, A, R(34) );
159 P( A, B, C, D, E, R(35) );
160 P( E, A, B, C, D, R(36) );
161 P( D, E, A, B, C, R(37) );
162 P( C, D, E, A, B, R(38) );
163 P( B, C, D, E, A, R(39) );
164
165#undef K
166#undef F
167
168#define F(x,y,z) ((x & y) | (z & (x | y)))
169#define K 0x8F1BBCDC
170
171 P( A, B, C, D, E, R(40) );
172 P( E, A, B, C, D, R(41) );
173 P( D, E, A, B, C, R(42) );
174 P( C, D, E, A, B, R(43) );
175 P( B, C, D, E, A, R(44) );
176 P( A, B, C, D, E, R(45) );
177 P( E, A, B, C, D, R(46) );
178 P( D, E, A, B, C, R(47) );
179 P( C, D, E, A, B, R(48) );
180 P( B, C, D, E, A, R(49) );
181 P( A, B, C, D, E, R(50) );
182 P( E, A, B, C, D, R(51) );
183 P( D, E, A, B, C, R(52) );
184 P( C, D, E, A, B, R(53) );
185 P( B, C, D, E, A, R(54) );
186 P( A, B, C, D, E, R(55) );
187 P( E, A, B, C, D, R(56) );
188 P( D, E, A, B, C, R(57) );
189 P( C, D, E, A, B, R(58) );
190 P( B, C, D, E, A, R(59) );
191
192#undef K
193#undef F
194
195#define F(x,y,z) (x ^ y ^ z)
196#define K 0xCA62C1D6
197
198 P( A, B, C, D, E, R(60) );
199 P( E, A, B, C, D, R(61) );
200 P( D, E, A, B, C, R(62) );
201 P( C, D, E, A, B, R(63) );
202 P( B, C, D, E, A, R(64) );
203 P( A, B, C, D, E, R(65) );
204 P( E, A, B, C, D, R(66) );
205 P( D, E, A, B, C, R(67) );
206 P( C, D, E, A, B, R(68) );
207 P( B, C, D, E, A, R(69) );
208 P( A, B, C, D, E, R(70) );
209 P( E, A, B, C, D, R(71) );
210 P( D, E, A, B, C, R(72) );
211 P( C, D, E, A, B, R(73) );
212 P( B, C, D, E, A, R(74) );
213 P( A, B, C, D, E, R(75) );
214 P( E, A, B, C, D, R(76) );
215 P( D, E, A, B, C, R(77) );
216 P( C, D, E, A, B, R(78) );
217 P( B, C, D, E, A, R(79) );
218
219#undef K
220#undef F
221
222 ctx->state[0] += A;
223 ctx->state[1] += B;
224 ctx->state[2] += C;
225 ctx->state[3] += D;
226 ctx->state[4] += E;
227}
228
229/*
230 * SHA-1 process buffer
231 */
232void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
233{
234 int fill;
235 unsigned long left;
236
237 if( ilen <= 0 )
238 return;
239
240 left = ctx->total[0] & 0x3F;
241 fill = 64 - left;
242
243 ctx->total[0] += ilen;
244 ctx->total[0] &= 0xFFFFFFFF;
245
246 if( ctx->total[0] < (unsigned long) ilen )
247 ctx->total[1]++;
248
249 if( left && ilen >= fill )
250 {
251 memcpy( (void *) (ctx->buffer + left),
252 (void *) input, fill );
253 sha1_process( ctx, ctx->buffer );
254 input += fill;
255 ilen -= fill;
256 left = 0;
257 }
258
259 while( ilen >= 64 )
260 {
261 sha1_process( ctx, input );
262 input += 64;
263 ilen -= 64;
264 }
265
266 if( ilen > 0 )
267 {
268 memcpy( (void *) (ctx->buffer + left),
269 (void *) input, ilen );
270 }
271}
272
273static const unsigned char sha1_padding[64] =
274{
275 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
279};
280
281/*
282 * SHA-1 final digest
283 */
284void sha1_finish( sha1_context *ctx, unsigned char output[20] )
285{
286 unsigned long last, padn;
287 unsigned long high, low;
288 unsigned char msglen[8];
289
290 high = ( ctx->total[0] >> 29 )
291 | ( ctx->total[1] << 3 );
292 low = ( ctx->total[0] << 3 );
293
294 PUT_ULONG_BE( high, msglen, 0 );
295 PUT_ULONG_BE( low, msglen, 4 );
296
297 last = ctx->total[0] & 0x3F;
298 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
299
300 sha1_update( ctx, (unsigned char *) sha1_padding, padn );
301 sha1_update( ctx, msglen, 8 );
302
303 PUT_ULONG_BE( ctx->state[0], output, 0 );
304 PUT_ULONG_BE( ctx->state[1], output, 4 );
305 PUT_ULONG_BE( ctx->state[2], output, 8 );
306 PUT_ULONG_BE( ctx->state[3], output, 12 );
307 PUT_ULONG_BE( ctx->state[4], output, 16 );
308}
309
310/*
311 * output = SHA-1( input buffer )
312 */
313void sha1_oneshot( unsigned char *input, int ilen, unsigned char output[20] )
314{
315 sha1_context ctx;
316
317 sha1_starts( &ctx );
318 sha1_update( &ctx, input, ilen );
319 sha1_finish( &ctx, output );
320
321 memset( &ctx, 0, sizeof( sha1_context ) );
322}
323
324/*
325 * output = SHA-1( file contents )
326 */
327int sha1_file( char *path, unsigned char output[20] )
328{
329 FILE *f;
330 size_t n;
331 sha1_context ctx;
332 unsigned char buf[1024];
333
334 if( ( f = fopen( path, "rb" ) ) == NULL )
335 return( 1 );
336
337 sha1_starts( &ctx );
338
339 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
340 sha1_update( &ctx, buf, (int) n );
341
342 sha1_finish( &ctx, output );
343
344 memset( &ctx, 0, sizeof( sha1_context ) );
345
346 if( ferror( f ) != 0 )
347 {
348 fclose( f );
349 return( 2 );
350 }
351
352 fclose( f );
353 return( 0 );
354}
355
356/*
357 * SHA-1 HMAC context setup
358 */
359void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
360{
361 int i;
362 unsigned char sum[20];
363
364 if( keylen > 64 )
365 {
366 sha1_oneshot( key, keylen, sum );
367 keylen = 20;
368 key = sum;
369 }
370
371 memset( ctx->ipad, 0x36, 64 );
372 memset( ctx->opad, 0x5C, 64 );
373
374 for( i = 0; i < keylen; i++ )
375 {
376 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
377 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
378 }
379
380 sha1_starts( ctx );
381 sha1_update( ctx, ctx->ipad, 64 );
382
383 memset( sum, 0, sizeof( sum ) );
384}
385
386/*
387 * SHA-1 HMAC process buffer
388 */
389void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
390{
391 sha1_update( ctx, input, ilen );
392}
393
394/*
395 * SHA-1 HMAC final digest
396 */
397void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
398{
399 unsigned char tmpbuf[20];
400
401 sha1_finish( ctx, tmpbuf );
402 sha1_starts( ctx );
403 sha1_update( ctx, ctx->opad, 64 );
404 sha1_update( ctx, tmpbuf, 20 );
405 sha1_finish( ctx, output );
406
407 memset( tmpbuf, 0, sizeof( tmpbuf ) );
408}
409
410/*
411 * output = HMAC-SHA-1( hmac key, input buffer )
412 */
413void sha1_hmac( unsigned char *key, int keylen,
414 unsigned char *input, int ilen,
415 unsigned char output[20] )
416{
417 sha1_context ctx;
418
419 sha1_hmac_starts( &ctx, key, keylen );
420 sha1_hmac_update( &ctx, input, ilen );
421 sha1_hmac_finish( &ctx, output );
422
423 memset( &ctx, 0, sizeof( sha1_context ) );
424}