1/*
2 *  FIPS-180-1 compliant SHA-1 implementation
3 *
4 *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
5 *
6 *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
7 *
8 *  All rights reserved.
9 *
10 *  Redistribution and use in source and binary forms, with or without
11 *  modification, are permitted provided that the following conditions
12 *  are met:
13 *
14 *    * Redistributions of source code must retain the above copyright
15 *      notice, this list of conditions and the following disclaimer.
16 *    * Redistributions in binary form must reproduce the above copyright
17 *      notice, this list of conditions and the following disclaimer in the
18 *      documentation and/or other materials provided with the distribution.
19 *    * Neither the names of PolarSSL or XySSL nor the names of its contributors
20 *      may be used to endorse or promote products derived from this software
21 *      without specific prior written permission.
22 *
23 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35/*
36 *  The SHA-1 standard was published by NIST in 1993.
37 *
38 *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
39 */
40
41#include "polarssl/config.h"
42
43#if defined(POLARSSL_SHA1_C)
44
45#include "polarssl/sha1.h"
46
47#include <string.h>
48#include <stdio.h>
49
50/*
51 * 32-bit integer manipulation macros (big endian)
52 */
53#ifndef GET_ULONG_BE
54#define GET_ULONG_BE(n,b,i)                             \
55{                                                       \
56    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
57        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
58        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
59        | ( (unsigned long) (b)[(i) + 3]       );       \
60}
61#endif
62
63#ifndef PUT_ULONG_BE
64#define PUT_ULONG_BE(n,b,i)                             \
65{                                                       \
66    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
67    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
68    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
69    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
70}
71#endif
72
73/*
74 * SHA-1 context setup
75 */
76void sha1_starts( sha1_context *ctx )
77{
78    ctx->total[0] = 0;
79    ctx->total[1] = 0;
80
81    ctx->state[0] = 0x67452301;
82    ctx->state[1] = 0xEFCDAB89;
83    ctx->state[2] = 0x98BADCFE;
84    ctx->state[3] = 0x10325476;
85    ctx->state[4] = 0xC3D2E1F0;
86}
87
88static void sha1_process( sha1_context *ctx, unsigned char data[64] )
89{
90    unsigned long temp, W[16], A, B, C, D, E;
91
92    GET_ULONG_BE( W[ 0], data,  0 );
93    GET_ULONG_BE( W[ 1], data,  4 );
94    GET_ULONG_BE( W[ 2], data,  8 );
95    GET_ULONG_BE( W[ 3], data, 12 );
96    GET_ULONG_BE( W[ 4], data, 16 );
97    GET_ULONG_BE( W[ 5], data, 20 );
98    GET_ULONG_BE( W[ 6], data, 24 );
99    GET_ULONG_BE( W[ 7], data, 28 );
100    GET_ULONG_BE( W[ 8], data, 32 );
101    GET_ULONG_BE( W[ 9], data, 36 );
102    GET_ULONG_BE( W[10], data, 40 );
103    GET_ULONG_BE( W[11], data, 44 );
104    GET_ULONG_BE( W[12], data, 48 );
105    GET_ULONG_BE( W[13], data, 52 );
106    GET_ULONG_BE( W[14], data, 56 );
107    GET_ULONG_BE( W[15], data, 60 );
108
109#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
110
111#define R(t)                                            \
112(                                                       \
113    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
114           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
115    ( W[t & 0x0F] = S(temp,1) )                         \
116)
117
118#define P(a,b,c,d,e,x)                                  \
119{                                                       \
120    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
121}
122
123    A = ctx->state[0];
124    B = ctx->state[1];
125    C = ctx->state[2];
126    D = ctx->state[3];
127    E = ctx->state[4];
128
129#define F(x,y,z) (z ^ (x & (y ^ z)))
130#define K 0x5A827999
131
132    P( A, B, C, D, E, W[0]  );
133    P( E, A, B, C, D, W[1]  );
134    P( D, E, A, B, C, W[2]  );
135    P( C, D, E, A, B, W[3]  );
136    P( B, C, D, E, A, W[4]  );
137    P( A, B, C, D, E, W[5]  );
138    P( E, A, B, C, D, W[6]  );
139    P( D, E, A, B, C, W[7]  );
140    P( C, D, E, A, B, W[8]  );
141    P( B, C, D, E, A, W[9]  );
142    P( A, B, C, D, E, W[10] );
143    P( E, A, B, C, D, W[11] );
144    P( D, E, A, B, C, W[12] );
145    P( C, D, E, A, B, W[13] );
146    P( B, C, D, E, A, W[14] );
147    P( A, B, C, D, E, W[15] );
148    P( E, A, B, C, D, R(16) );
149    P( D, E, A, B, C, R(17) );
150    P( C, D, E, A, B, R(18) );
151    P( B, C, D, E, A, R(19) );
152
153#undef K
154#undef F
155
156#define F(x,y,z) (x ^ y ^ z)
157#define K 0x6ED9EBA1
158
159    P( A, B, C, D, E, R(20) );
160    P( E, A, B, C, D, R(21) );
161    P( D, E, A, B, C, R(22) );
162    P( C, D, E, A, B, R(23) );
163    P( B, C, D, E, A, R(24) );
164    P( A, B, C, D, E, R(25) );
165    P( E, A, B, C, D, R(26) );
166    P( D, E, A, B, C, R(27) );
167    P( C, D, E, A, B, R(28) );
168    P( B, C, D, E, A, R(29) );
169    P( A, B, C, D, E, R(30) );
170    P( E, A, B, C, D, R(31) );
171    P( D, E, A, B, C, R(32) );
172    P( C, D, E, A, B, R(33) );
173    P( B, C, D, E, A, R(34) );
174    P( A, B, C, D, E, R(35) );
175    P( E, A, B, C, D, R(36) );
176    P( D, E, A, B, C, R(37) );
177    P( C, D, E, A, B, R(38) );
178    P( B, C, D, E, A, R(39) );
179
180#undef K
181#undef F
182
183#define F(x,y,z) ((x & y) | (z & (x | y)))
184#define K 0x8F1BBCDC
185
186    P( A, B, C, D, E, R(40) );
187    P( E, A, B, C, D, R(41) );
188    P( D, E, A, B, C, R(42) );
189    P( C, D, E, A, B, R(43) );
190    P( B, C, D, E, A, R(44) );
191    P( A, B, C, D, E, R(45) );
192    P( E, A, B, C, D, R(46) );
193    P( D, E, A, B, C, R(47) );
194    P( C, D, E, A, B, R(48) );
195    P( B, C, D, E, A, R(49) );
196    P( A, B, C, D, E, R(50) );
197    P( E, A, B, C, D, R(51) );
198    P( D, E, A, B, C, R(52) );
199    P( C, D, E, A, B, R(53) );
200    P( B, C, D, E, A, R(54) );
201    P( A, B, C, D, E, R(55) );
202    P( E, A, B, C, D, R(56) );
203    P( D, E, A, B, C, R(57) );
204    P( C, D, E, A, B, R(58) );
205    P( B, C, D, E, A, R(59) );
206
207#undef K
208#undef F
209
210#define F(x,y,z) (x ^ y ^ z)
211#define K 0xCA62C1D6
212
213    P( A, B, C, D, E, R(60) );
214    P( E, A, B, C, D, R(61) );
215    P( D, E, A, B, C, R(62) );
216    P( C, D, E, A, B, R(63) );
217    P( B, C, D, E, A, R(64) );
218    P( A, B, C, D, E, R(65) );
219    P( E, A, B, C, D, R(66) );
220    P( D, E, A, B, C, R(67) );
221    P( C, D, E, A, B, R(68) );
222    P( B, C, D, E, A, R(69) );
223    P( A, B, C, D, E, R(70) );
224    P( E, A, B, C, D, R(71) );
225    P( D, E, A, B, C, R(72) );
226    P( C, D, E, A, B, R(73) );
227    P( B, C, D, E, A, R(74) );
228    P( A, B, C, D, E, R(75) );
229    P( E, A, B, C, D, R(76) );
230    P( D, E, A, B, C, R(77) );
231    P( C, D, E, A, B, R(78) );
232    P( B, C, D, E, A, R(79) );
233
234#undef K
235#undef F
236
237    ctx->state[0] += A;
238    ctx->state[1] += B;
239    ctx->state[2] += C;
240    ctx->state[3] += D;
241    ctx->state[4] += E;
242}
243
244/*
245 * SHA-1 process buffer
246 */
247void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
248{
249    int fill;
250    unsigned long left;
251
252    if( ilen <= 0 )
253        return;
254
255    left = ctx->total[0] & 0x3F;
256    fill = 64 - left;
257
258    ctx->total[0] += ilen;
259    ctx->total[0] &= 0xFFFFFFFF;
260
261    if( ctx->total[0] < (unsigned long) ilen )
262        ctx->total[1]++;
263
264    if( left && ilen >= fill )
265    {
266        memcpy( (void *) (ctx->buffer + left),
267                (void *) input, fill );
268        sha1_process( ctx, ctx->buffer );
269        input += fill;
270        ilen  -= fill;
271        left = 0;
272    }
273
274    while( ilen >= 64 )
275    {
276        sha1_process( ctx, input );
277        input += 64;
278        ilen  -= 64;
279    }
280
281    if( ilen > 0 )
282    {
283        memcpy( (void *) (ctx->buffer + left),
284                (void *) input, ilen );
285    }
286}
287
288static const unsigned char sha1_padding[64] =
289{
290 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
294};
295
296/*
297 * SHA-1 final digest
298 */
299void sha1_finish( sha1_context *ctx, unsigned char output[20] )
300{
301    unsigned long last, padn;
302    unsigned long high, low;
303    unsigned char msglen[8];
304
305    high = ( ctx->total[0] >> 29 )
306         | ( ctx->total[1] <<  3 );
307    low  = ( ctx->total[0] <<  3 );
308
309    PUT_ULONG_BE( high, msglen, 0 );
310    PUT_ULONG_BE( low,  msglen, 4 );
311
312    last = ctx->total[0] & 0x3F;
313    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
314
315    sha1_update( ctx, (unsigned char *) sha1_padding, padn );
316    sha1_update( ctx, msglen, 8 );
317
318    PUT_ULONG_BE( ctx->state[0], output,  0 );
319    PUT_ULONG_BE( ctx->state[1], output,  4 );
320    PUT_ULONG_BE( ctx->state[2], output,  8 );
321    PUT_ULONG_BE( ctx->state[3], output, 12 );
322    PUT_ULONG_BE( ctx->state[4], output, 16 );
323}
324
325/*
326 * output = SHA-1( input buffer )
327 */
328void sha1( unsigned char *input, int ilen, unsigned char output[20] )
329{
330    sha1_context ctx;
331
332    sha1_starts( &ctx );
333    sha1_update( &ctx, input, ilen );
334    sha1_finish( &ctx, output );
335
336    memset( &ctx, 0, sizeof( sha1_context ) );
337}
338
339/*
340 * output = SHA-1( file contents )
341 */
342int sha1_file( char *path, unsigned char output[20] )
343{
344    FILE *f;
345    size_t n;
346    sha1_context ctx;
347    unsigned char buf[1024];
348
349    if( ( f = fopen( path, "rb" ) ) == NULL )
350        return( 1 );
351
352    sha1_starts( &ctx );
353
354    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
355        sha1_update( &ctx, buf, (int) n );
356
357    sha1_finish( &ctx, output );
358
359    memset( &ctx, 0, sizeof( sha1_context ) );
360
361    if( ferror( f ) != 0 )
362    {
363        fclose( f );
364        return( 2 );
365    }
366
367    fclose( f );
368    return( 0 );
369}
370
371/*
372 * SHA-1 HMAC context setup
373 */
374void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
375{
376    int i;
377    unsigned char sum[20];
378
379    if( keylen > 64 )
380    {
381        sha1( key, keylen, sum );
382        keylen = 20;
383        key = sum;
384    }
385
386    memset( ctx->ipad, 0x36, 64 );
387    memset( ctx->opad, 0x5C, 64 );
388
389    for( i = 0; i < keylen; i++ )
390    {
391        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
392        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
393    }
394
395    sha1_starts( ctx );
396    sha1_update( ctx, ctx->ipad, 64 );
397
398    memset( sum, 0, sizeof( sum ) );
399}
400
401/*
402 * SHA-1 HMAC process buffer
403 */
404void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
405{
406    sha1_update( ctx, input, ilen );
407}
408
409/*
410 * SHA-1 HMAC final digest
411 */
412void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
413{
414    unsigned char tmpbuf[20];
415
416    sha1_finish( ctx, tmpbuf );
417    sha1_starts( ctx );
418    sha1_update( ctx, ctx->opad, 64 );
419    sha1_update( ctx, tmpbuf, 20 );
420    sha1_finish( ctx, output );
421
422    memset( tmpbuf, 0, sizeof( tmpbuf ) );
423}
424
425/*
426 * output = HMAC-SHA-1( hmac key, input buffer )
427 */
428void sha1_hmac( unsigned char *key, int keylen,
429                unsigned char *input, int ilen,
430                unsigned char output[20] )
431{
432    sha1_context ctx;
433
434    sha1_hmac_starts( &ctx, key, keylen );
435    sha1_hmac_update( &ctx, input, ilen );
436    sha1_hmac_finish( &ctx, output );
437
438    memset( &ctx, 0, sizeof( sha1_context ) );
439}
440
441#if defined(POLARSSL_SELF_TEST)
442/*
443 * FIPS-180-1 test vectors
444 */
445static unsigned char sha1_test_buf[3][57] =
446{
447    { "abc" },
448    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
449    { "" }
450};
451
452static const int sha1_test_buflen[3] =
453{
454    3, 56, 1000
455};
456
457static const unsigned char sha1_test_sum[3][20] =
458{
459    { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
460      0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
461    { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
462      0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
463    { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
464      0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
465};
466
467/*
468 * RFC 2202 test vectors
469 */
470static unsigned char sha1_hmac_test_key[7][26] =
471{
472    { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
473      "\x0B\x0B\x0B\x0B" },
474    { "Jefe" },
475    { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
476      "\xAA\xAA\xAA\xAA" },
477    { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
478      "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
479    { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
480      "\x0C\x0C\x0C\x0C" },
481    { "" }, /* 0xAA 80 times */
482    { "" }
483};
484
485static const int sha1_hmac_test_keylen[7] =
486{
487    20, 4, 20, 25, 20, 80, 80
488};
489
490static unsigned char sha1_hmac_test_buf[7][74] =
491{
492    { "Hi There" },
493    { "what do ya want for nothing?" },
494    { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
495      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
496      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
497      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
498      "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
499    { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
500      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
501      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
502      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
503      "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
504    { "Test With Truncation" },
505    { "Test Using Larger Than Block-Size Key - Hash Key First" },
506    { "Test Using Larger Than Block-Size Key and Larger"
507      " Than One Block-Size Data" }
508};
509
510static const int sha1_hmac_test_buflen[7] =
511{
512    8, 28, 50, 50, 20, 54, 73
513};
514
515static const unsigned char sha1_hmac_test_sum[7][20] =
516{
517    { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
518      0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
519    { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
520      0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
521    { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
522      0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
523    { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
524      0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
525    { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
526      0x7B, 0xE1 },
527    { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
528      0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
529    { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
530      0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
531};
532
533/*
534 * Checkup routine
535 */
536int sha1_self_test( int verbose )
537{
538    int i, j, buflen;
539    unsigned char buf[1024];
540    unsigned char sha1sum[20];
541    sha1_context ctx;
542
543    /*
544     * SHA-1
545     */
546    for( i = 0; i < 3; i++ )
547    {
548        if( verbose != 0 )
549            printf( "  SHA-1 test #%d: ", i + 1 );
550
551        sha1_starts( &ctx );
552
553        if( i == 2 )
554        {
555            memset( buf, 'a', buflen = 1000 );
556
557            for( j = 0; j < 1000; j++ )
558                sha1_update( &ctx, buf, buflen );
559        }
560        else
561            sha1_update( &ctx, sha1_test_buf[i],
562                               sha1_test_buflen[i] );
563
564        sha1_finish( &ctx, sha1sum );
565
566        if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
567        {
568            if( verbose != 0 )
569                printf( "failed\n" );
570
571            return( 1 );
572        }
573
574        if( verbose != 0 )
575            printf( "passed\n" );
576    }
577
578    if( verbose != 0 )
579        printf( "\n" );
580
581    for( i = 0; i < 7; i++ )
582    {
583        if( verbose != 0 )
584            printf( "  HMAC-SHA-1 test #%d: ", i + 1 );
585
586        if( i == 5 || i == 6 )
587        {
588            memset( buf, '\xAA', buflen = 80 );
589            sha1_hmac_starts( &ctx, buf, buflen );
590        }
591        else
592            sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
593                                    sha1_hmac_test_keylen[i] );
594
595        sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
596                                sha1_hmac_test_buflen[i] );
597
598        sha1_hmac_finish( &ctx, sha1sum );
599
600        buflen = ( i == 4 ) ? 12 : 20;
601
602        if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
603        {
604            if( verbose != 0 )
605                printf( "failed\n" );
606
607            return( 1 );
608        }
609
610        if( verbose != 0 )
611            printf( "passed\n" );
612    }
613
614    if( verbose != 0 )
615        printf( "\n" );
616
617    return( 0 );
618}
619
620#endif
621
622#endif
623