blob: a0f87ecb9d1dfc54bbfb9aa0932328073d8f2e6b [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Paul Bakker4087c472013-06-12 16:49:10 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * 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-512 Secure Hash Standard was published by NIST in 2002.
27 *
28 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
29 */
30
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakker40e46942009-01-03 21:51:57 +000033#if defined(POLARSSL_SHA4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/sha4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker335db3f2011-04-25 15:28:35 +000037#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000038#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000039#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker312da332014-06-13 17:20:13 +020041/* Implementation that should never be optimized out by the compiler */
42static void polarssl_zeroize( void *v, size_t n ) {
43 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
44}
45
Paul Bakker4087c472013-06-12 16:49:10 +020046#if !defined(POLARSSL_SHA4_ALT)
47
Paul Bakker5121ce52009-01-03 21:22:43 +000048/*
49 * 64-bit integer manipulation macros (big endian)
50 */
51#ifndef GET_UINT64_BE
52#define GET_UINT64_BE(n,b,i) \
53{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000054 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
55 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
56 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
57 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
58 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
59 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
60 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
61 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000062}
63#endif
64
65#ifndef PUT_UINT64_BE
66#define PUT_UINT64_BE(n,b,i) \
67{ \
68 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
69 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
70 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
71 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
72 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
73 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
74 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
75 (b)[(i) + 7] = (unsigned char) ( (n) ); \
76}
77#endif
78
79/*
80 * Round constants
81 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000082static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +000083{
84 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
85 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
86 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
87 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
88 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
89 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
90 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
91 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
92 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
93 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
94 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
95 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
96 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
97 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
98 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
99 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
100 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
101 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
102 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
103 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
104 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
105 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
106 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
107 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
108 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
109 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
110 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
111 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
112 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
113 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
114 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
115 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
116 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
117 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
118 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
119 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
120 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
121 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
122 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
123 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
124};
125
126/*
127 * SHA-512 context setup
128 */
129void sha4_starts( sha4_context *ctx, int is384 )
130{
131 ctx->total[0] = 0;
132 ctx->total[1] = 0;
133
134 if( is384 == 0 )
135 {
136 /* SHA-512 */
137 ctx->state[0] = UL64(0x6A09E667F3BCC908);
138 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
139 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
140 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
141 ctx->state[4] = UL64(0x510E527FADE682D1);
142 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
143 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
144 ctx->state[7] = UL64(0x5BE0CD19137E2179);
145 }
146 else
147 {
148 /* SHA-384 */
149 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
150 ctx->state[1] = UL64(0x629A292A367CD507);
151 ctx->state[2] = UL64(0x9159015A3070DD17);
152 ctx->state[3] = UL64(0x152FECD8F70E5939);
153 ctx->state[4] = UL64(0x67332667FFC00B31);
154 ctx->state[5] = UL64(0x8EB44A8768581511);
155 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
156 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
157 }
158
159 ctx->is384 = is384;
160}
161
Paul Bakkerff60ee62010-03-16 21:09:09 +0000162static void sha4_process( sha4_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000163{
164 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165 uint64_t temp1, temp2, W[80];
166 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000167
168#define SHR(x,n) (x >> n)
169#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
170
171#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
172#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
173
174#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
175#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
176
177#define F0(x,y,z) ((x & y) | (z & (x | y)))
178#define F1(x,y,z) (z ^ (x & (y ^ z)))
179
180#define P(a,b,c,d,e,f,g,h,x,K) \
181{ \
182 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
183 temp2 = S2(a) + F0(a,b,c); \
184 d += temp1; h = temp1 + temp2; \
185}
186
187 for( i = 0; i < 16; i++ )
188 {
189 GET_UINT64_BE( W[i], data, i << 3 );
190 }
191
192 for( ; i < 80; i++ )
193 {
194 W[i] = S1(W[i - 2]) + W[i - 7] +
195 S0(W[i - 15]) + W[i - 16];
196 }
197
198 A = ctx->state[0];
199 B = ctx->state[1];
200 C = ctx->state[2];
201 D = ctx->state[3];
202 E = ctx->state[4];
203 F = ctx->state[5];
204 G = ctx->state[6];
205 H = ctx->state[7];
206 i = 0;
207
208 do
209 {
210 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
211 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
212 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
213 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
214 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
215 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
216 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
217 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
218 }
219 while( i < 80 );
220
221 ctx->state[0] += A;
222 ctx->state[1] += B;
223 ctx->state[2] += C;
224 ctx->state[3] += D;
225 ctx->state[4] += E;
226 ctx->state[5] += F;
227 ctx->state[6] += G;
228 ctx->state[7] += H;
229}
230
231/*
232 * SHA-512 process buffer
233 */
Paul Bakker23986e52011-04-24 08:57:21 +0000234void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000235{
Paul Bakker23986e52011-04-24 08:57:21 +0000236 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000237 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 if( ilen <= 0 )
240 return;
241
Paul Bakkerb8213a12011-07-11 08:16:18 +0000242 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000243 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 ctx->total[1]++;
249
250 if( left && ilen >= fill )
251 {
Paul Bakkereae09db2013-06-06 12:35:54 +0200252 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 sha4_process( ctx, ctx->buffer );
254 input += fill;
255 ilen -= fill;
256 left = 0;
257 }
258
259 while( ilen >= 128 )
260 {
261 sha4_process( ctx, input );
262 input += 128;
263 ilen -= 128;
264 }
265
266 if( ilen > 0 )
Paul Bakkereae09db2013-06-06 12:35:54 +0200267 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268}
269
270static const unsigned char sha4_padding[128] =
271{
272 0x80, 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 0, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
280};
281
282/*
283 * SHA-512 final digest
284 */
285void sha4_finish( sha4_context *ctx, unsigned char output[64] )
286{
Paul Bakker27fdf462011-06-09 13:55:13 +0000287 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 unsigned char msglen[16];
290
291 high = ( ctx->total[0] >> 61 )
292 | ( ctx->total[1] << 3 );
293 low = ( ctx->total[0] << 3 );
294
295 PUT_UINT64_BE( high, msglen, 0 );
296 PUT_UINT64_BE( low, msglen, 8 );
297
Paul Bakker27fdf462011-06-09 13:55:13 +0000298 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
300
Paul Bakkereae09db2013-06-06 12:35:54 +0200301 sha4_update( ctx, sha4_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 sha4_update( ctx, msglen, 16 );
303
304 PUT_UINT64_BE( ctx->state[0], output, 0 );
305 PUT_UINT64_BE( ctx->state[1], output, 8 );
306 PUT_UINT64_BE( ctx->state[2], output, 16 );
307 PUT_UINT64_BE( ctx->state[3], output, 24 );
308 PUT_UINT64_BE( ctx->state[4], output, 32 );
309 PUT_UINT64_BE( ctx->state[5], output, 40 );
310
311 if( ctx->is384 == 0 )
312 {
313 PUT_UINT64_BE( ctx->state[6], output, 48 );
314 PUT_UINT64_BE( ctx->state[7], output, 56 );
315 }
316}
317
Paul Bakker4087c472013-06-12 16:49:10 +0200318#endif /* !POLARSSL_SHA4_ALT */
319
Paul Bakker5121ce52009-01-03 21:22:43 +0000320/*
321 * output = SHA-512( input buffer )
322 */
Paul Bakker23986e52011-04-24 08:57:21 +0000323void sha4( const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 unsigned char output[64], int is384 )
325{
326 sha4_context ctx;
327
328 sha4_starts( &ctx, is384 );
329 sha4_update( &ctx, input, ilen );
330 sha4_finish( &ctx, output );
331
Paul Bakker312da332014-06-13 17:20:13 +0200332 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333}
334
Paul Bakker335db3f2011-04-25 15:28:35 +0000335#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000336/*
337 * output = SHA-512( file contents )
338 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000339int sha4_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000340{
341 FILE *f;
342 size_t n;
343 sha4_context ctx;
344 unsigned char buf[1024];
345
346 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000347 return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
349 sha4_starts( &ctx, is384 );
350
351 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000352 sha4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
354 sha4_finish( &ctx, output );
355
Paul Bakker312da332014-06-13 17:20:13 +0200356 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
358 if( ferror( f ) != 0 )
359 {
360 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000361 return( POLARSSL_ERR_SHA4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000362 }
363
364 fclose( f );
365 return( 0 );
366}
Paul Bakker335db3f2011-04-25 15:28:35 +0000367#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
369/*
370 * SHA-512 HMAC context setup
371 */
Paul Bakker23986e52011-04-24 08:57:21 +0000372void sha4_hmac_starts( sha4_context *ctx, const unsigned char *key, size_t keylen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 int is384 )
374{
Paul Bakker23986e52011-04-24 08:57:21 +0000375 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 unsigned char sum[64];
377
378 if( keylen > 128 )
379 {
380 sha4( key, keylen, sum, is384 );
381 keylen = ( is384 ) ? 48 : 64;
382 key = sum;
383 }
384
385 memset( ctx->ipad, 0x36, 128 );
386 memset( ctx->opad, 0x5C, 128 );
387
388 for( i = 0; i < keylen; i++ )
389 {
390 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
391 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
392 }
393
394 sha4_starts( ctx, is384 );
395 sha4_update( ctx, ctx->ipad, 128 );
396
Paul Bakker312da332014-06-13 17:20:13 +0200397 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398}
399
400/*
401 * SHA-512 HMAC process buffer
402 */
403void sha4_hmac_update( sha4_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000404 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000405{
406 sha4_update( ctx, input, ilen );
407}
408
409/*
410 * SHA-512 HMAC final digest
411 */
412void sha4_hmac_finish( sha4_context *ctx, unsigned char output[64] )
413{
414 int is384, hlen;
415 unsigned char tmpbuf[64];
416
417 is384 = ctx->is384;
418 hlen = ( is384 == 0 ) ? 64 : 48;
419
420 sha4_finish( ctx, tmpbuf );
421 sha4_starts( ctx, is384 );
422 sha4_update( ctx, ctx->opad, 128 );
423 sha4_update( ctx, tmpbuf, hlen );
424 sha4_finish( ctx, output );
425
Paul Bakker312da332014-06-13 17:20:13 +0200426 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427}
428
429/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000430 * SHA-512 HMAC context reset
431 */
432void sha4_hmac_reset( sha4_context *ctx )
433{
434 sha4_starts( ctx, ctx->is384 );
435 sha4_update( ctx, ctx->ipad, 128 );
436}
437
438/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 * output = HMAC-SHA-512( hmac key, input buffer )
440 */
Paul Bakker23986e52011-04-24 08:57:21 +0000441void sha4_hmac( const unsigned char *key, size_t keylen,
442 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 unsigned char output[64], int is384 )
444{
445 sha4_context ctx;
446
447 sha4_hmac_starts( &ctx, key, keylen, is384 );
448 sha4_hmac_update( &ctx, input, ilen );
449 sha4_hmac_finish( &ctx, output );
450
Paul Bakker312da332014-06-13 17:20:13 +0200451 polarssl_zeroize( &ctx, sizeof( sha4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452}
453
Paul Bakker40e46942009-01-03 21:51:57 +0000454#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456/*
457 * FIPS-180-2 test vectors
458 */
459static unsigned char sha4_test_buf[3][113] =
460{
461 { "abc" },
462 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
463 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
464 { "" }
465};
466
467static const int sha4_test_buflen[3] =
468{
469 3, 112, 1000
470};
471
472static const unsigned char sha4_test_sum[6][64] =
473{
474 /*
475 * SHA-384 test vectors
476 */
477 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
478 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
479 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
480 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
481 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
482 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
483 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
484 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
485 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
486 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
487 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
488 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
489 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
490 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
491 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
492 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
493 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
494 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
495
496 /*
497 * SHA-512 test vectors
498 */
499 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
500 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
501 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
502 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
503 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
504 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
505 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
506 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
507 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
508 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
509 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
510 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
511 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
512 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
513 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
514 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
515 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
516 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
517 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
518 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
519 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
520 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
521 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
522 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
523};
524
525/*
526 * RFC 4231 test vectors
527 */
528static unsigned char sha4_hmac_test_key[7][26] =
529{
530 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
531 "\x0B\x0B\x0B\x0B" },
532 { "Jefe" },
533 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
534 "\xAA\xAA\xAA\xAA" },
535 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
536 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
537 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
538 "\x0C\x0C\x0C\x0C" },
539 { "" }, /* 0xAA 131 times */
540 { "" }
541};
542
543static const int sha4_hmac_test_keylen[7] =
544{
545 20, 4, 20, 25, 20, 131, 131
546};
547
548static unsigned char sha4_hmac_test_buf[7][153] =
549{
550 { "Hi There" },
551 { "what do ya want for nothing?" },
552 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
553 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
554 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
555 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
556 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
557 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
558 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
559 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
560 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
561 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
562 { "Test With Truncation" },
563 { "Test Using Larger Than Block-Size Key - Hash Key First" },
564 { "This is a test using a larger than block-size key "
565 "and a larger than block-size data. The key needs to "
566 "be hashed before being used by the HMAC algorithm." }
567};
568
569static const int sha4_hmac_test_buflen[7] =
570{
571 8, 28, 50, 50, 20, 54, 152
572};
573
574static const unsigned char sha4_hmac_test_sum[14][64] =
575{
576 /*
577 * HMAC-SHA-384 test vectors
578 */
579 { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62,
580 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F,
581 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6,
582 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C,
583 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F,
584 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 },
585 { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31,
586 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B,
587 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47,
588 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E,
589 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7,
590 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 },
591 { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A,
592 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F,
593 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB,
594 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B,
595 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9,
596 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 },
597 { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85,
598 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7,
599 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C,
600 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E,
601 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79,
602 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB },
603 { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23,
604 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 },
605 { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90,
606 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4,
607 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F,
608 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6,
609 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82,
610 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 },
611 { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D,
612 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C,
613 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A,
614 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5,
615 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D,
616 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E },
617
618 /*
619 * HMAC-SHA-512 test vectors
620 */
621 { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D,
622 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0,
623 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78,
624 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE,
625 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02,
626 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4,
627 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70,
628 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 },
629 { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2,
630 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3,
631 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6,
632 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54,
633 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A,
634 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD,
635 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B,
636 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 },
637 { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84,
638 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9,
639 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36,
640 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39,
641 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8,
642 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07,
643 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26,
644 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB },
645 { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69,
646 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7,
647 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D,
648 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB,
649 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4,
650 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63,
651 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D,
652 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD },
653 { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53,
654 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 },
655 { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB,
656 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4,
657 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1,
658 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52,
659 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98,
660 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52,
661 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC,
662 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 },
663 { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA,
664 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD,
665 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86,
666 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44,
667 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1,
668 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15,
669 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60,
670 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 }
671};
672
673/*
674 * Checkup routine
675 */
676int sha4_self_test( int verbose )
677{
678 int i, j, k, buflen;
679 unsigned char buf[1024];
680 unsigned char sha4sum[64];
681 sha4_context ctx;
682
683 for( i = 0; i < 6; i++ )
684 {
685 j = i % 3;
686 k = i < 3;
687
688 if( verbose != 0 )
689 printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
690
691 sha4_starts( &ctx, k );
692
693 if( j == 2 )
694 {
695 memset( buf, 'a', buflen = 1000 );
696
697 for( j = 0; j < 1000; j++ )
698 sha4_update( &ctx, buf, buflen );
699 }
700 else
701 sha4_update( &ctx, sha4_test_buf[j],
702 sha4_test_buflen[j] );
703
704 sha4_finish( &ctx, sha4sum );
705
706 if( memcmp( sha4sum, sha4_test_sum[i], 64 - k * 16 ) != 0 )
707 {
708 if( verbose != 0 )
709 printf( "failed\n" );
710
711 return( 1 );
712 }
713
714 if( verbose != 0 )
715 printf( "passed\n" );
716 }
717
718 if( verbose != 0 )
719 printf( "\n" );
720
721 for( i = 0; i < 14; i++ )
722 {
723 j = i % 7;
724 k = i < 7;
725
726 if( verbose != 0 )
727 printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 );
728
729 if( j == 5 || j == 6 )
730 {
731 memset( buf, '\xAA', buflen = 131 );
732 sha4_hmac_starts( &ctx, buf, buflen, k );
733 }
734 else
735 sha4_hmac_starts( &ctx, sha4_hmac_test_key[j],
736 sha4_hmac_test_keylen[j], k );
737
738 sha4_hmac_update( &ctx, sha4_hmac_test_buf[j],
739 sha4_hmac_test_buflen[j] );
740
741 sha4_hmac_finish( &ctx, sha4sum );
742
743 buflen = ( j == 4 ) ? 16 : 64 - k * 16;
744
745 if( memcmp( sha4sum, sha4_hmac_test_sum[i], buflen ) != 0 )
746 {
747 if( verbose != 0 )
748 printf( "failed\n" );
749
750 return( 1 );
751 }
752
753 if( verbose != 0 )
754 printf( "passed\n" );
755 }
756
757 if( verbose != 0 )
758 printf( "\n" );
759
760 return( 0 );
761}
762
763#endif
764
765#endif