blob: 81812292a5ec5be3159be154463c03f1f9911595 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
4 * Copyright (C) 2006-2007 Christophe Devine
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20/*
21 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
22 *
23 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
24 */
25
Paul Bakker40e46942009-01-03 21:51:57 +000026#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Paul Bakker40e46942009-01-03 21:51:57 +000028#if defined(POLARSSL_SHA2_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/sha2.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
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}
432
Paul Bakker40e46942009-01-03 21:51:57 +0000433#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000434/*
435 * FIPS-180-2 test vectors
436 */
437static unsigned char sha2_test_buf[3][57] =
438{
439 { "abc" },
440 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
441 { "" }
442};
443
444static const int sha2_test_buflen[3] =
445{
446 3, 56, 1000
447};
448
449static const unsigned char sha2_test_sum[6][32] =
450{
451 /*
452 * SHA-224 test vectors
453 */
454 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
455 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
456 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
457 0xE3, 0x6C, 0x9D, 0xA7 },
458 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
459 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
460 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
461 0x52, 0x52, 0x25, 0x25 },
462 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
463 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
464 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
465 0x4E, 0xE7, 0xAD, 0x67 },
466
467 /*
468 * SHA-256 test vectors
469 */
470 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
471 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
472 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
473 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
474 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
475 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
476 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
477 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
478 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
479 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
480 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
481 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
482};
483
484/*
485 * RFC 4231 test vectors
486 */
487static unsigned char sha2_hmac_test_key[7][26] =
488{
489 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
490 "\x0B\x0B\x0B\x0B" },
491 { "Jefe" },
492 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
493 "\xAA\xAA\xAA\xAA" },
494 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
495 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
496 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
497 "\x0C\x0C\x0C\x0C" },
498 { "" }, /* 0xAA 131 times */
499 { "" }
500};
501
502static const int sha2_hmac_test_keylen[7] =
503{
504 20, 4, 20, 25, 20, 131, 131
505};
506
507static unsigned char sha2_hmac_test_buf[7][153] =
508{
509 { "Hi There" },
510 { "what do ya want for nothing?" },
511 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
512 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
513 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
514 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
515 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
516 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
517 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
518 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
519 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
520 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
521 { "Test With Truncation" },
522 { "Test Using Larger Than Block-Size Key - Hash Key First" },
523 { "This is a test using a larger than block-size key "
524 "and a larger than block-size data. The key needs to "
525 "be hashed before being used by the HMAC algorithm." }
526};
527
528static const int sha2_hmac_test_buflen[7] =
529{
530 8, 28, 50, 50, 20, 54, 152
531};
532
533static const unsigned char sha2_hmac_test_sum[14][32] =
534{
535 /*
536 * HMAC-SHA-224 test vectors
537 */
538 { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
539 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
540 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
541 0x53, 0x68, 0x4B, 0x22 },
542 { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
543 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
544 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
545 0x8F, 0xD0, 0x5E, 0x44 },
546 { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
547 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
548 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
549 0xEC, 0x83, 0x33, 0xEA },
550 { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
551 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
552 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
553 0xE7, 0xAF, 0xEC, 0x5A },
554 { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
555 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
556 { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
557 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
558 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
559 0x3F, 0xA6, 0x87, 0x0E },
560 { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
561 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
562 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
563 0xF6, 0xF5, 0x65, 0xD1 },
564
565 /*
566 * HMAC-SHA-256 test vectors
567 */
568 { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
569 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
570 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
571 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
572 { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
573 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
574 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
575 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
576 { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
577 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
578 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
579 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
580 { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
581 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
582 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
583 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
584 { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
585 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
586 { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
587 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
588 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
589 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
590 { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
591 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
592 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
593 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
594};
595
596/*
597 * Checkup routine
598 */
599int sha2_self_test( int verbose )
600{
601 int i, j, k, buflen;
602 unsigned char buf[1024];
603 unsigned char sha2sum[32];
604 sha2_context ctx;
605
606 for( i = 0; i < 6; i++ )
607 {
608 j = i % 3;
609 k = i < 3;
610
611 if( verbose != 0 )
612 printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
613
614 sha2_starts( &ctx, k );
615
616 if( j == 2 )
617 {
618 memset( buf, 'a', buflen = 1000 );
619
620 for( j = 0; j < 1000; j++ )
621 sha2_update( &ctx, buf, buflen );
622 }
623 else
624 sha2_update( &ctx, sha2_test_buf[j],
625 sha2_test_buflen[j] );
626
627 sha2_finish( &ctx, sha2sum );
628
629 if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
630 {
631 if( verbose != 0 )
632 printf( "failed\n" );
633
634 return( 1 );
635 }
636
637 if( verbose != 0 )
638 printf( "passed\n" );
639 }
640
641 if( verbose != 0 )
642 printf( "\n" );
643
644 for( i = 0; i < 14; i++ )
645 {
646 j = i % 7;
647 k = i < 7;
648
649 if( verbose != 0 )
650 printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
651
652 if( j == 5 || j == 6 )
653 {
654 memset( buf, '\xAA', buflen = 131 );
655 sha2_hmac_starts( &ctx, buf, buflen, k );
656 }
657 else
658 sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
659 sha2_hmac_test_keylen[j], k );
660
661 sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
662 sha2_hmac_test_buflen[j] );
663
664 sha2_hmac_finish( &ctx, sha2sum );
665
666 buflen = ( j == 4 ) ? 16 : 32 - k * 4;
667
668 if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
669 {
670 if( verbose != 0 )
671 printf( "failed\n" );
672
673 return( 1 );
674 }
675
676 if( verbose != 0 )
677 printf( "passed\n" );
678 }
679
680 if( verbose != 0 )
681 printf( "\n" );
682
683 return( 0 );
684}
685
686#endif
687
688#endif