Coverage Report

Created: 2025-07-11 06:28

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