Separate PolarSSL from PDKIM. Bug 1192
[exim.git] / src / src / pdkim / sha2.c
CommitLineData
80a47a2c
TK
1/*
2 * FIPS-180-2 compliant SHA-256 implementation
3 *
62d3e98d
TK
4 * Copyright (C) 2006-2010, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
80a47a2c 8 *
62d3e98d 9 * All rights reserved.
80a47a2c
TK
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The SHA-256 Secure Hash Standard was published by NIST in 2002.
27 *
28 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
29 */
30
ac3ad426
AM
31#include "polarssl/config.h"
32
33#if defined(POLARSSL_SHA2_C)
34
35#include "polarssl/sha2.h"
80a47a2c
TK
36
37#include <string.h>
38#include <stdio.h>
39
40/*
41 * 32-bit integer manipulation macros (big endian)
42 */
43#ifndef GET_ULONG_BE
44#define GET_ULONG_BE(n,b,i) \
45{ \
46 (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
47 | ( (unsigned long) (b)[(i) + 1] << 16 ) \
48 | ( (unsigned long) (b)[(i) + 2] << 8 ) \
49 | ( (unsigned long) (b)[(i) + 3] ); \
50}
51#endif
52
53#ifndef PUT_ULONG_BE
54#define PUT_ULONG_BE(n,b,i) \
55{ \
56 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
57 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
58 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
59 (b)[(i) + 3] = (unsigned char) ( (n) ); \
60}
61#endif
62
63/*
64 * SHA-256 context setup
65 */
66void sha2_starts( sha2_context *ctx, int is224 )
67{
68 ctx->total[0] = 0;
69 ctx->total[1] = 0;
70
71 if( is224 == 0 )
72 {
73 /* SHA-256 */
74 ctx->state[0] = 0x6A09E667;
75 ctx->state[1] = 0xBB67AE85;
76 ctx->state[2] = 0x3C6EF372;
77 ctx->state[3] = 0xA54FF53A;
78 ctx->state[4] = 0x510E527F;
79 ctx->state[5] = 0x9B05688C;
80 ctx->state[6] = 0x1F83D9AB;
81 ctx->state[7] = 0x5BE0CD19;
82 }
83 else
84 {
85 /* SHA-224 */
86 ctx->state[0] = 0xC1059ED8;
87 ctx->state[1] = 0x367CD507;
88 ctx->state[2] = 0x3070DD17;
89 ctx->state[3] = 0xF70E5939;
90 ctx->state[4] = 0xFFC00B31;
91 ctx->state[5] = 0x68581511;
92 ctx->state[6] = 0x64F98FA7;
93 ctx->state[7] = 0xBEFA4FA4;
94 }
95
96 ctx->is224 = is224;
97}
98
62d3e98d 99static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
80a47a2c
TK
100{
101 unsigned long temp1, temp2, W[64];
102 unsigned long A, B, C, D, E, F, G, H;
103
104 GET_ULONG_BE( W[ 0], data, 0 );
105 GET_ULONG_BE( W[ 1], data, 4 );
106 GET_ULONG_BE( W[ 2], data, 8 );
107 GET_ULONG_BE( W[ 3], data, 12 );
108 GET_ULONG_BE( W[ 4], data, 16 );
109 GET_ULONG_BE( W[ 5], data, 20 );
110 GET_ULONG_BE( W[ 6], data, 24 );
111 GET_ULONG_BE( W[ 7], data, 28 );
112 GET_ULONG_BE( W[ 8], data, 32 );
113 GET_ULONG_BE( W[ 9], data, 36 );
114 GET_ULONG_BE( W[10], data, 40 );
115 GET_ULONG_BE( W[11], data, 44 );
116 GET_ULONG_BE( W[12], data, 48 );
117 GET_ULONG_BE( W[13], data, 52 );
118 GET_ULONG_BE( W[14], data, 56 );
119 GET_ULONG_BE( W[15], data, 60 );
120
121#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
122#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
123
124#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
125#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
126
127#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
128#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
129
130#define F0(x,y,z) ((x & y) | (z & (x | y)))
131#define F1(x,y,z) (z ^ (x & (y ^ z)))
132
133#define R(t) \
134( \
135 W[t] = S1(W[t - 2]) + W[t - 7] + \
136 S0(W[t - 15]) + W[t - 16] \
137)
138
139#define P(a,b,c,d,e,f,g,h,x,K) \
140{ \
141 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
142 temp2 = S2(a) + F0(a,b,c); \
143 d += temp1; h = temp1 + temp2; \
144}
145
146 A = ctx->state[0];
147 B = ctx->state[1];
148 C = ctx->state[2];
149 D = ctx->state[3];
150 E = ctx->state[4];
151 F = ctx->state[5];
152 G = ctx->state[6];
153 H = ctx->state[7];
154
155 P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
156 P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
157 P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
158 P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
159 P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
160 P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
161 P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
162 P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
163 P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
164 P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
165 P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
166 P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
167 P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
168 P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
169 P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
170 P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
171 P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
172 P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
173 P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
174 P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
175 P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
176 P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
177 P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
178 P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
179 P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
180 P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
181 P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
182 P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
183 P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
184 P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
185 P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
186 P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
187 P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
188 P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
189 P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
190 P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
191 P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
192 P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
193 P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
194 P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
195 P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
196 P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
197 P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
198 P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
199 P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
200 P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
201 P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
202 P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
203 P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
204 P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
205 P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
206 P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
207 P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
208 P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
209 P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
210 P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
211 P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
212 P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
213 P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
214 P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
215 P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
216 P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
217 P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
218 P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
219
220 ctx->state[0] += A;
221 ctx->state[1] += B;
222 ctx->state[2] += C;
223 ctx->state[3] += D;
224 ctx->state[4] += E;
225 ctx->state[5] += F;
226 ctx->state[6] += G;
227 ctx->state[7] += H;
228}
229
230/*
231 * SHA-256 process buffer
232 */
62d3e98d 233void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen )
80a47a2c
TK
234{
235 int fill;
236 unsigned long left;
237
238 if( ilen <= 0 )
239 return;
240
241 left = ctx->total[0] & 0x3F;
242 fill = 64 - left;
243
244 ctx->total[0] += ilen;
245 ctx->total[0] &= 0xFFFFFFFF;
246
247 if( ctx->total[0] < (unsigned long) ilen )
248 ctx->total[1]++;
249
250 if( left && ilen >= fill )
251 {
252 memcpy( (void *) (ctx->buffer + left),
253 (void *) input, fill );
254 sha2_process( ctx, ctx->buffer );
255 input += fill;
256 ilen -= fill;
257 left = 0;
258 }
259
260 while( ilen >= 64 )
261 {
262 sha2_process( ctx, input );
263 input += 64;
264 ilen -= 64;
265 }
266
267 if( ilen > 0 )
268 {
269 memcpy( (void *) (ctx->buffer + left),
270 (void *) input, ilen );
271 }
272}
273
274static const unsigned char sha2_padding[64] =
275{
276 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
280};
281
282/*
283 * SHA-256 final digest
284 */
285void sha2_finish( sha2_context *ctx, unsigned char output[32] )
286{
287 unsigned long last, padn;
288 unsigned long high, low;
289 unsigned char msglen[8];
290
291 high = ( ctx->total[0] >> 29 )
292 | ( ctx->total[1] << 3 );
293 low = ( ctx->total[0] << 3 );
294
295 PUT_ULONG_BE( high, msglen, 0 );
296 PUT_ULONG_BE( low, msglen, 4 );
297
298 last = ctx->total[0] & 0x3F;
299 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
300
301 sha2_update( ctx, (unsigned char *) sha2_padding, padn );
302 sha2_update( ctx, msglen, 8 );
303
304 PUT_ULONG_BE( ctx->state[0], output, 0 );
305 PUT_ULONG_BE( ctx->state[1], output, 4 );
306 PUT_ULONG_BE( ctx->state[2], output, 8 );
307 PUT_ULONG_BE( ctx->state[3], output, 12 );
308 PUT_ULONG_BE( ctx->state[4], output, 16 );
309 PUT_ULONG_BE( ctx->state[5], output, 20 );
310 PUT_ULONG_BE( ctx->state[6], output, 24 );
311
312 if( ctx->is224 == 0 )
313 PUT_ULONG_BE( ctx->state[7], output, 28 );
314}
315
316/*
317 * output = SHA-256( input buffer )
318 */
62d3e98d 319void sha2( const unsigned char *input, int ilen,
80a47a2c
TK
320 unsigned char output[32], int is224 )
321{
322 sha2_context ctx;
323
324 sha2_starts( &ctx, is224 );
325 sha2_update( &ctx, input, ilen );
326 sha2_finish( &ctx, output );
327
328 memset( &ctx, 0, sizeof( sha2_context ) );
329}
330
331/*
332 * output = SHA-256( file contents )
333 */
62d3e98d 334int sha2_file( const char *path, unsigned char output[32], int is224 )
80a47a2c
TK
335{
336 FILE *f;
337 size_t n;
338 sha2_context ctx;
339 unsigned char buf[1024];
340
341 if( ( f = fopen( path, "rb" ) ) == NULL )
342 return( 1 );
343
344 sha2_starts( &ctx, is224 );
345
346 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
347 sha2_update( &ctx, buf, (int) n );
348
349 sha2_finish( &ctx, output );
350
351 memset( &ctx, 0, sizeof( sha2_context ) );
352
353 if( ferror( f ) != 0 )
354 {
355 fclose( f );
356 return( 2 );
357 }
358
359 fclose( f );
360 return( 0 );
361}
362
363/*
364 * SHA-256 HMAC context setup
365 */
62d3e98d 366void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
80a47a2c
TK
367 int is224 )
368{
369 int i;
370 unsigned char sum[32];
371
372 if( keylen > 64 )
373 {
374 sha2( key, keylen, sum, is224 );
375 keylen = ( is224 ) ? 28 : 32;
376 key = sum;
377 }
378
379 memset( ctx->ipad, 0x36, 64 );
380 memset( ctx->opad, 0x5C, 64 );
381
382 for( i = 0; i < keylen; i++ )
383 {
384 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
385 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
386 }
387
388 sha2_starts( ctx, is224 );
389 sha2_update( ctx, ctx->ipad, 64 );
390
391 memset( sum, 0, sizeof( sum ) );
392}
393
394/*
395 * SHA-256 HMAC process buffer
396 */
62d3e98d 397void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen )
80a47a2c
TK
398{
399 sha2_update( ctx, input, ilen );
400}
401
402/*
403 * SHA-256 HMAC final digest
404 */
405void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
406{
407 int is224, hlen;
408 unsigned char tmpbuf[32];
409
410 is224 = ctx->is224;
411 hlen = ( is224 == 0 ) ? 32 : 28;
412
413 sha2_finish( ctx, tmpbuf );
414 sha2_starts( ctx, is224 );
415 sha2_update( ctx, ctx->opad, 64 );
416 sha2_update( ctx, tmpbuf, hlen );
417 sha2_finish( ctx, output );
418
419 memset( tmpbuf, 0, sizeof( tmpbuf ) );
420}
421
62d3e98d
TK
422/*
423 * SHA-256 HMAC context reset
424 */
425void sha2_hmac_reset( sha2_context *ctx )
426{
427 sha2_starts( ctx, ctx->is224 );
428 sha2_update( ctx, ctx->ipad, 64 );
429}
430
80a47a2c
TK
431/*
432 * output = HMAC-SHA-256( hmac key, input buffer )
433 */
62d3e98d
TK
434void sha2_hmac( const unsigned char *key, int keylen,
435 const unsigned char *input, int ilen,
80a47a2c
TK
436 unsigned char output[32], int is224 )
437{
438 sha2_context ctx;
439
440 sha2_hmac_starts( &ctx, key, keylen, is224 );
441 sha2_hmac_update( &ctx, input, ilen );
442 sha2_hmac_finish( &ctx, output );
443
444 memset( &ctx, 0, sizeof( sha2_context ) );
445}
ac3ad426
AM
446
447#if defined(POLARSSL_SELF_TEST)
448/*
449 * FIPS-180-2 test vectors
450 */
451static unsigned char sha2_test_buf[3][57] =
452{
453 { "abc" },
454 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
455 { "" }
456};
457
458static const int sha2_test_buflen[3] =
459{
460 3, 56, 1000
461};
462
463static const unsigned char sha2_test_sum[6][32] =
464{
465 /*
466 * SHA-224 test vectors
467 */
468 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
469 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
470 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
471 0xE3, 0x6C, 0x9D, 0xA7 },
472 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
473 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
474 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
475 0x52, 0x52, 0x25, 0x25 },
476 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
477 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
478 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
479 0x4E, 0xE7, 0xAD, 0x67 },
480
481 /*
482 * SHA-256 test vectors
483 */
484 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
485 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
486 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
487 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
488 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
489 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
490 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
491 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
492 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
493 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
494 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
495 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
496};
497
498/*
499 * RFC 4231 test vectors
500 */
501static unsigned char sha2_hmac_test_key[7][26] =
502{
503 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
504 "\x0B\x0B\x0B\x0B" },
505 { "Jefe" },
506 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
507 "\xAA\xAA\xAA\xAA" },
508 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
509 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
510 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
511 "\x0C\x0C\x0C\x0C" },
512 { "" }, /* 0xAA 131 times */
513 { "" }
514};
515
516static const int sha2_hmac_test_keylen[7] =
517{
518 20, 4, 20, 25, 20, 131, 131
519};
520
521static unsigned char sha2_hmac_test_buf[7][153] =
522{
523 { "Hi There" },
524 { "what do ya want for nothing?" },
525 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
526 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
527 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
528 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
529 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
530 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
531 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
532 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
533 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
534 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
535 { "Test With Truncation" },
536 { "Test Using Larger Than Block-Size Key - Hash Key First" },
537 { "This is a test using a larger than block-size key "
538 "and a larger than block-size data. The key needs to "
539 "be hashed before being used by the HMAC algorithm." }
540};
541
542static const int sha2_hmac_test_buflen[7] =
543{
544 8, 28, 50, 50, 20, 54, 152
545};
546
547static const unsigned char sha2_hmac_test_sum[14][32] =
548{
549 /*
550 * HMAC-SHA-224 test vectors
551 */
552 { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
553 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
554 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
555 0x53, 0x68, 0x4B, 0x22 },
556 { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
557 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
558 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
559 0x8F, 0xD0, 0x5E, 0x44 },
560 { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
561 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
562 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
563 0xEC, 0x83, 0x33, 0xEA },
564 { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
565 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
566 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
567 0xE7, 0xAF, 0xEC, 0x5A },
568 { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
569 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
570 { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
571 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
572 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
573 0x3F, 0xA6, 0x87, 0x0E },
574 { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
575 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
576 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
577 0xF6, 0xF5, 0x65, 0xD1 },
578
579 /*
580 * HMAC-SHA-256 test vectors
581 */
582 { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
583 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
584 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
585 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
586 { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
587 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
588 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
589 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
590 { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
591 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
592 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
593 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
594 { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
595 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
596 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
597 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
598 { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
599 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
600 { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
601 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
602 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
603 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
604 { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
605 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
606 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
607 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
608};
609
610/*
611 * Checkup routine
612 */
613int sha2_self_test( int verbose )
614{
615 int i, j, k, buflen;
616 unsigned char buf[1024];
617 unsigned char sha2sum[32];
618 sha2_context ctx;
619
620 for( i = 0; i < 6; i++ )
621 {
622 j = i % 3;
623 k = i < 3;
624
625 if( verbose != 0 )
626 printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
627
628 sha2_starts( &ctx, k );
629
630 if( j == 2 )
631 {
632 memset( buf, 'a', buflen = 1000 );
633
634 for( j = 0; j < 1000; j++ )
635 sha2_update( &ctx, buf, buflen );
636 }
637 else
638 sha2_update( &ctx, sha2_test_buf[j],
639 sha2_test_buflen[j] );
640
641 sha2_finish( &ctx, sha2sum );
642
643 if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
644 {
645 if( verbose != 0 )
646 printf( "failed\n" );
647
648 return( 1 );
649 }
650
651 if( verbose != 0 )
652 printf( "passed\n" );
653 }
654
655 if( verbose != 0 )
656 printf( "\n" );
657
658 for( i = 0; i < 14; i++ )
659 {
660 j = i % 7;
661 k = i < 7;
662
663 if( verbose != 0 )
664 printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
665
666 if( j == 5 || j == 6 )
667 {
668 memset( buf, '\xAA', buflen = 131 );
669 sha2_hmac_starts( &ctx, buf, buflen, k );
670 }
671 else
672 sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
673 sha2_hmac_test_keylen[j], k );
674
675 sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
676 sha2_hmac_test_buflen[j] );
677
678 sha2_hmac_finish( &ctx, sha2sum );
679
680 buflen = ( j == 4 ) ? 16 : 32 - k * 4;
681
682 if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
683 {
684 if( verbose != 0 )
685 printf( "failed\n" );
686
687 return( 1 );
688 }
689
690 if( verbose != 0 )
691 printf( "passed\n" );
692 }
693
694 if( verbose != 0 )
695 printf( "\n" );
696
697 return( 0 );
698}
699
700#endif
701
702#endif