source: trunk/library/sha4.c @ 1159

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

What are you looking for?