Ensure version numbers all updated
[exim.git] / src / src / pdkim / sha2.c
CommitLineData
80a47a2c
TK
1/*
2 * FIPS-180-2 compliant SHA-256 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-256 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
28/* $Cambridge: exim/src/src/pdkim/sha2.c,v 1.2 2009/06/10 07:34:05 tom Exp $ */
29
30#include "sha2.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-256 context setup
60 */
61void sha2_starts( sha2_context *ctx, int is224 )
62{
63 ctx->total[0] = 0;
64 ctx->total[1] = 0;
65
66 if( is224 == 0 )
67 {
68 /* SHA-256 */
69 ctx->state[0] = 0x6A09E667;
70 ctx->state[1] = 0xBB67AE85;
71 ctx->state[2] = 0x3C6EF372;
72 ctx->state[3] = 0xA54FF53A;
73 ctx->state[4] = 0x510E527F;
74 ctx->state[5] = 0x9B05688C;
75 ctx->state[6] = 0x1F83D9AB;
76 ctx->state[7] = 0x5BE0CD19;
77 }
78 else
79 {
80 /* SHA-224 */
81 ctx->state[0] = 0xC1059ED8;
82 ctx->state[1] = 0x367CD507;
83 ctx->state[2] = 0x3070DD17;
84 ctx->state[3] = 0xF70E5939;
85 ctx->state[4] = 0xFFC00B31;
86 ctx->state[5] = 0x68581511;
87 ctx->state[6] = 0x64F98FA7;
88 ctx->state[7] = 0xBEFA4FA4;
89 }
90
91 ctx->is224 = is224;
92}
93
94static void sha2_process( sha2_context *ctx, unsigned char data[64] )
95{
96 unsigned long temp1, temp2, W[64];
97 unsigned long A, B, C, D, E, F, G, H;
98
99 GET_ULONG_BE( W[ 0], data, 0 );
100 GET_ULONG_BE( W[ 1], data, 4 );
101 GET_ULONG_BE( W[ 2], data, 8 );
102 GET_ULONG_BE( W[ 3], data, 12 );
103 GET_ULONG_BE( W[ 4], data, 16 );
104 GET_ULONG_BE( W[ 5], data, 20 );
105 GET_ULONG_BE( W[ 6], data, 24 );
106 GET_ULONG_BE( W[ 7], data, 28 );
107 GET_ULONG_BE( W[ 8], data, 32 );
108 GET_ULONG_BE( W[ 9], data, 36 );
109 GET_ULONG_BE( W[10], data, 40 );
110 GET_ULONG_BE( W[11], data, 44 );
111 GET_ULONG_BE( W[12], data, 48 );
112 GET_ULONG_BE( W[13], data, 52 );
113 GET_ULONG_BE( W[14], data, 56 );
114 GET_ULONG_BE( W[15], data, 60 );
115
116#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
117#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
118
119#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
120#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
121
122#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
123#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
124
125#define F0(x,y,z) ((x & y) | (z & (x | y)))
126#define F1(x,y,z) (z ^ (x & (y ^ z)))
127
128#define R(t) \
129( \
130 W[t] = S1(W[t - 2]) + W[t - 7] + \
131 S0(W[t - 15]) + W[t - 16] \
132)
133
134#define P(a,b,c,d,e,f,g,h,x,K) \
135{ \
136 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
137 temp2 = S2(a) + F0(a,b,c); \
138 d += temp1; h = temp1 + temp2; \
139}
140
141 A = ctx->state[0];
142 B = ctx->state[1];
143 C = ctx->state[2];
144 D = ctx->state[3];
145 E = ctx->state[4];
146 F = ctx->state[5];
147 G = ctx->state[6];
148 H = ctx->state[7];
149
150 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
151 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
152 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
153 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
154 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
155 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
156 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
157 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
158 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
159 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
160 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
161 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
162 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
163 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
164 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
165 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
166 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
167 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
168 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
169 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
170 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
171 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
172 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
173 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
174 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
175 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
176 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
177 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
178 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
179 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
180 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
181 P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
182 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
183 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
184 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
185 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
186 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
187 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
188 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
189 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
190 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
191 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
192 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
193 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
194 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
195 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
196 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
197 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
198 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
199 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
200 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
201 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
202 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
203 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
204 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
205 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
206 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
207 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
208 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
209 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
210 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
211 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
212 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
213 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
214
215 ctx->state[0] += A;
216 ctx->state[1] += B;
217 ctx->state[2] += C;
218 ctx->state[3] += D;
219 ctx->state[4] += E;
220 ctx->state[5] += F;
221 ctx->state[6] += G;
222 ctx->state[7] += H;
223}
224
225/*
226 * SHA-256 process buffer
227 */
228void sha2_update( sha2_context *ctx, unsigned char *input, int ilen )
229{
230 int fill;
231 unsigned long left;
232
233 if( ilen <= 0 )
234 return;
235
236 left = ctx->total[0] & 0x3F;
237 fill = 64 - left;
238
239 ctx->total[0] += ilen;
240 ctx->total[0] &= 0xFFFFFFFF;
241
242 if( ctx->total[0] < (unsigned long) ilen )
243 ctx->total[1]++;
244
245 if( left && ilen >= fill )
246 {
247 memcpy( (void *) (ctx->buffer + left),
248 (void *) input, fill );
249 sha2_process( ctx, ctx->buffer );
250 input += fill;
251 ilen -= fill;
252 left = 0;
253 }
254
255 while( ilen >= 64 )
256 {
257 sha2_process( ctx, input );
258 input += 64;
259 ilen -= 64;
260 }
261
262 if( ilen > 0 )
263 {
264 memcpy( (void *) (ctx->buffer + left),
265 (void *) input, ilen );
266 }
267}
268
269static const unsigned char sha2_padding[64] =
270{
271 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
275};
276
277/*
278 * SHA-256 final digest
279 */
280void sha2_finish( sha2_context *ctx, unsigned char output[32] )
281{
282 unsigned long last, padn;
283 unsigned long high, low;
284 unsigned char msglen[8];
285
286 high = ( ctx->total[0] >> 29 )
287 | ( ctx->total[1] << 3 );
288 low = ( ctx->total[0] << 3 );
289
290 PUT_ULONG_BE( high, msglen, 0 );
291 PUT_ULONG_BE( low, msglen, 4 );
292
293 last = ctx->total[0] & 0x3F;
294 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
295
296 sha2_update( ctx, (unsigned char *) sha2_padding, padn );
297 sha2_update( ctx, msglen, 8 );
298
299 PUT_ULONG_BE( ctx->state[0], output, 0 );
300 PUT_ULONG_BE( ctx->state[1], output, 4 );
301 PUT_ULONG_BE( ctx->state[2], output, 8 );
302 PUT_ULONG_BE( ctx->state[3], output, 12 );
303 PUT_ULONG_BE( ctx->state[4], output, 16 );
304 PUT_ULONG_BE( ctx->state[5], output, 20 );
305 PUT_ULONG_BE( ctx->state[6], output, 24 );
306
307 if( ctx->is224 == 0 )
308 PUT_ULONG_BE( ctx->state[7], output, 28 );
309}
310
311/*
312 * output = SHA-256( input buffer )
313 */
314void sha2( unsigned char *input, int ilen,
315 unsigned char output[32], int is224 )
316{
317 sha2_context ctx;
318
319 sha2_starts( &ctx, is224 );
320 sha2_update( &ctx, input, ilen );
321 sha2_finish( &ctx, output );
322
323 memset( &ctx, 0, sizeof( sha2_context ) );
324}
325
326/*
327 * output = SHA-256( file contents )
328 */
329int sha2_file( char *path, unsigned char output[32], int is224 )
330{
331 FILE *f;
332 size_t n;
333 sha2_context ctx;
334 unsigned char buf[1024];
335
336 if( ( f = fopen( path, "rb" ) ) == NULL )
337 return( 1 );
338
339 sha2_starts( &ctx, is224 );
340
341 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
342 sha2_update( &ctx, buf, (int) n );
343
344 sha2_finish( &ctx, output );
345
346 memset( &ctx, 0, sizeof( sha2_context ) );
347
348 if( ferror( f ) != 0 )
349 {
350 fclose( f );
351 return( 2 );
352 }
353
354 fclose( f );
355 return( 0 );
356}
357
358/*
359 * SHA-256 HMAC context setup
360 */
361void sha2_hmac_starts( sha2_context *ctx, unsigned char *key, int keylen,
362 int is224 )
363{
364 int i;
365 unsigned char sum[32];
366
367 if( keylen > 64 )
368 {
369 sha2( key, keylen, sum, is224 );
370 keylen = ( is224 ) ? 28 : 32;
371 key = sum;
372 }
373
374 memset( ctx->ipad, 0x36, 64 );
375 memset( ctx->opad, 0x5C, 64 );
376
377 for( i = 0; i < keylen; i++ )
378 {
379 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
380 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
381 }
382
383 sha2_starts( ctx, is224 );
384 sha2_update( ctx, ctx->ipad, 64 );
385
386 memset( sum, 0, sizeof( sum ) );
387}
388
389/*
390 * SHA-256 HMAC process buffer
391 */
392void sha2_hmac_update( sha2_context *ctx, unsigned char *input, int ilen )
393{
394 sha2_update( ctx, input, ilen );
395}
396
397/*
398 * SHA-256 HMAC final digest
399 */
400void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
401{
402 int is224, hlen;
403 unsigned char tmpbuf[32];
404
405 is224 = ctx->is224;
406 hlen = ( is224 == 0 ) ? 32 : 28;
407
408 sha2_finish( ctx, tmpbuf );
409 sha2_starts( ctx, is224 );
410 sha2_update( ctx, ctx->opad, 64 );
411 sha2_update( ctx, tmpbuf, hlen );
412 sha2_finish( ctx, output );
413
414 memset( tmpbuf, 0, sizeof( tmpbuf ) );
415}
416
417/*
418 * output = HMAC-SHA-256( hmac key, input buffer )
419 */
420void sha2_hmac( unsigned char *key, int keylen,
421 unsigned char *input, int ilen,
422 unsigned char output[32], int is224 )
423{
424 sha2_context ctx;
425
426 sha2_hmac_starts( &ctx, key, keylen, is224 );
427 sha2_hmac_update( &ctx, input, ilen );
428 sha2_hmac_finish( &ctx, output );
429
430 memset( &ctx, 0, sizeof( sha2_context ) );
431}