1 /*
2  *  FIPS-180-2 compliant SHA-384/512 implementation
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  */
19 /*
20  *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
21  *
22  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23  */
24 
25 #include "common.h"
26 
27 #if defined(MBEDTLS_SHA512_C)
28 
29 #include "mbedtls/sha512.h"
30 #include "mbedtls/platform_util.h"
31 #include "mbedtls/error.h"
32 
33 #if defined(_MSC_VER) || defined(__WATCOMC__)
34   #define UL64(x) x##ui64
35 #else
36   #define UL64(x) x##ULL
37 #endif
38 
39 #include <string.h>
40 
41 #if defined(MBEDTLS_SELF_TEST)
42 #if defined(MBEDTLS_PLATFORM_C)
43 #include "mbedtls/platform.h"
44 #else
45 #include <stdio.h>
46 #include <stdlib.h>
47 #define mbedtls_printf printf
48 #define mbedtls_calloc    calloc
49 #define mbedtls_free       free
50 #endif /* MBEDTLS_PLATFORM_C */
51 #endif /* MBEDTLS_SELF_TEST */
52 
53 #define SHA512_VALIDATE_RET(cond)                           \
54     MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
55 #define SHA512_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
56 
57 #if !defined(MBEDTLS_SHA512_ALT)
58 
59 /*
60  * 64-bit integer manipulation macros (big endian)
61  */
62 #ifndef GET_UINT64_BE
63 #define GET_UINT64_BE(n,b,i)                            \
64 {                                                       \
65     (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
66         | ( (uint64_t) (b)[(i) + 1] << 48 )       \
67         | ( (uint64_t) (b)[(i) + 2] << 40 )       \
68         | ( (uint64_t) (b)[(i) + 3] << 32 )       \
69         | ( (uint64_t) (b)[(i) + 4] << 24 )       \
70         | ( (uint64_t) (b)[(i) + 5] << 16 )       \
71         | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
72         | ( (uint64_t) (b)[(i) + 7]       );      \
73 }
74 #endif /* GET_UINT64_BE */
75 
76 #ifndef PUT_UINT64_BE
77 #define PUT_UINT64_BE(n,b,i)                            \
78 {                                                       \
79     (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
80     (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
81     (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
82     (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
83     (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
84     (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
85     (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
86     (b)[(i) + 7] = (unsigned char) ( (n)       );       \
87 }
88 #endif /* PUT_UINT64_BE */
89 
90 #if defined(MBEDTLS_SHA512_SMALLER)
sha512_put_uint64_be(uint64_t n,unsigned char * b,uint8_t i)91 static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
92 {
93     PUT_UINT64_BE(n, b, i);
94 }
95 #else
96 #define sha512_put_uint64_be    PUT_UINT64_BE
97 #endif /* MBEDTLS_SHA512_SMALLER */
98 
mbedtls_sha512_init(mbedtls_sha512_context * ctx)99 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
100 {
101     SHA512_VALIDATE( ctx != NULL );
102 
103     memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
104 }
105 
mbedtls_sha512_free(mbedtls_sha512_context * ctx)106 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
107 {
108     if( ctx == NULL )
109         return;
110 
111     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
112 }
113 
mbedtls_sha512_clone(mbedtls_sha512_context * dst,const mbedtls_sha512_context * src)114 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
115                            const mbedtls_sha512_context *src )
116 {
117     SHA512_VALIDATE( dst != NULL );
118     SHA512_VALIDATE( src != NULL );
119 
120     *dst = *src;
121 }
122 
123 /*
124  * SHA-512 context setup
125  */
mbedtls_sha512_starts_ret(mbedtls_sha512_context * ctx,int is384)126 int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
127 {
128     SHA512_VALIDATE_RET( ctx != NULL );
129 #if !defined(MBEDTLS_SHA512_NO_SHA384)
130     SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
131 #else
132     SHA512_VALIDATE_RET( is384 == 0 );
133 #endif
134 
135     ctx->total[0] = 0;
136     ctx->total[1] = 0;
137 
138     if( is384 == 0 )
139     {
140         /* SHA-512 */
141         ctx->state[0] = UL64(0x6A09E667F3BCC908);
142         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
143         ctx->state[2] = UL64(0x3C6EF372FE94F82B);
144         ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
145         ctx->state[4] = UL64(0x510E527FADE682D1);
146         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
147         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
148         ctx->state[7] = UL64(0x5BE0CD19137E2179);
149     }
150     else
151     {
152 #if defined(MBEDTLS_SHA512_NO_SHA384)
153         return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
154 #else
155         /* SHA-384 */
156         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
157         ctx->state[1] = UL64(0x629A292A367CD507);
158         ctx->state[2] = UL64(0x9159015A3070DD17);
159         ctx->state[3] = UL64(0x152FECD8F70E5939);
160         ctx->state[4] = UL64(0x67332667FFC00B31);
161         ctx->state[5] = UL64(0x8EB44A8768581511);
162         ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
163         ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
164 #endif /* MBEDTLS_SHA512_NO_SHA384 */
165     }
166 
167 #if !defined(MBEDTLS_SHA512_NO_SHA384)
168     ctx->is384 = is384;
169 #endif
170 
171     return( 0 );
172 }
173 
174 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_starts(mbedtls_sha512_context * ctx,int is384)175 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
176                             int is384 )
177 {
178     mbedtls_sha512_starts_ret( ctx, is384 );
179 }
180 #endif
181 
182 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
183 
184 /*
185  * Round constants
186  */
187 static const uint64_t K[80] =
188 {
189     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
190     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
191     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
192     UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
193     UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
194     UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
195     UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
196     UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
197     UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
198     UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
199     UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
200     UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
201     UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
202     UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
203     UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
204     UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
205     UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
206     UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
207     UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
208     UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
209     UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
210     UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
211     UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
212     UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
213     UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
214     UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
215     UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
216     UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
217     UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
218     UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
219     UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
220     UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
221     UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
222     UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
223     UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
224     UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
225     UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
226     UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
227     UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
228     UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
229 };
230 
mbedtls_internal_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])231 int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
232                                      const unsigned char data[128] )
233 {
234     int i;
235     struct
236     {
237         uint64_t temp1, temp2, W[80];
238         uint64_t A[8];
239     } local;
240 
241     SHA512_VALIDATE_RET( ctx != NULL );
242     SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
243 
244 #define  SHR(x,n) ((x) >> (n))
245 #define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
246 
247 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
248 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
249 
250 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
251 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
252 
253 #define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
254 #define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
255 
256 #define P(a,b,c,d,e,f,g,h,x,K)                                      \
257     do                                                              \
258     {                                                               \
259         local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x);    \
260         local.temp2 = S2(a) + F0((a),(b),(c));                      \
261         (d) += local.temp1; (h) = local.temp1 + local.temp2;        \
262     } while( 0 )
263 
264     for( i = 0; i < 8; i++ )
265         local.A[i] = ctx->state[i];
266 
267 #if defined(MBEDTLS_SHA512_SMALLER)
268     for( i = 0; i < 80; i++ )
269     {
270         if( i < 16 )
271         {
272             GET_UINT64_BE( local.W[i], data, i << 3 );
273         }
274         else
275         {
276             local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
277                    S0(local.W[i - 15]) + local.W[i - 16];
278         }
279 
280         P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
281            local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
282 
283         local.temp1 = local.A[7]; local.A[7] = local.A[6];
284         local.A[6] = local.A[5]; local.A[5] = local.A[4];
285         local.A[4] = local.A[3]; local.A[3] = local.A[2];
286         local.A[2] = local.A[1]; local.A[1] = local.A[0];
287         local.A[0] = local.temp1;
288     }
289 #else /* MBEDTLS_SHA512_SMALLER */
290     for( i = 0; i < 16; i++ )
291     {
292         GET_UINT64_BE( local.W[i], data, i << 3 );
293     }
294 
295     for( ; i < 80; i++ )
296     {
297         local.W[i] = S1(local.W[i -  2]) + local.W[i -  7] +
298                S0(local.W[i - 15]) + local.W[i - 16];
299     }
300 
301     i = 0;
302     do
303     {
304         P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
305            local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
306         P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
307            local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
308         P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
309            local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
310         P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
311            local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
312         P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
313            local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
314         P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
315            local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
316         P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
317            local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
318         P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
319            local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
320     }
321     while( i < 80 );
322 #endif /* MBEDTLS_SHA512_SMALLER */
323 
324     for( i = 0; i < 8; i++ )
325         ctx->state[i] += local.A[i];
326 
327     /* Zeroise buffers and variables to clear sensitive data from memory. */
328     mbedtls_platform_zeroize( &local, sizeof( local ) );
329 
330     return( 0 );
331 }
332 
333 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_process(mbedtls_sha512_context * ctx,const unsigned char data[128])334 void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
335                              const unsigned char data[128] )
336 {
337     mbedtls_internal_sha512_process( ctx, data );
338 }
339 #endif
340 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
341 
342 /*
343  * SHA-512 process buffer
344  */
mbedtls_sha512_update_ret(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)345 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
346                                const unsigned char *input,
347                                size_t ilen )
348 {
349     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
350     size_t fill;
351     unsigned int left;
352 
353     SHA512_VALIDATE_RET( ctx != NULL );
354     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
355 
356     if( ilen == 0 )
357         return( 0 );
358 
359     left = (unsigned int) (ctx->total[0] & 0x7F);
360     fill = 128 - left;
361 
362     ctx->total[0] += (uint64_t) ilen;
363 
364     if( ctx->total[0] < (uint64_t) ilen )
365         ctx->total[1]++;
366 
367     if( left && ilen >= fill )
368     {
369         memcpy( (void *) (ctx->buffer + left), input, fill );
370 
371         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
372             return( ret );
373 
374         input += fill;
375         ilen  -= fill;
376         left = 0;
377     }
378 
379     while( ilen >= 128 )
380     {
381         if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
382             return( ret );
383 
384         input += 128;
385         ilen  -= 128;
386     }
387 
388     if( ilen > 0 )
389         memcpy( (void *) (ctx->buffer + left), input, ilen );
390 
391     return( 0 );
392 }
393 
394 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_update(mbedtls_sha512_context * ctx,const unsigned char * input,size_t ilen)395 void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
396                             const unsigned char *input,
397                             size_t ilen )
398 {
399     mbedtls_sha512_update_ret( ctx, input, ilen );
400 }
401 #endif
402 
403 /*
404  * SHA-512 final digest
405  */
mbedtls_sha512_finish_ret(mbedtls_sha512_context * ctx,unsigned char output[64])406 int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
407                                unsigned char output[64] )
408 {
409     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
410     unsigned used;
411     uint64_t high, low;
412 
413     SHA512_VALIDATE_RET( ctx != NULL );
414     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
415 
416     /*
417      * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
418      */
419     used = ctx->total[0] & 0x7F;
420 
421     ctx->buffer[used++] = 0x80;
422 
423     if( used <= 112 )
424     {
425         /* Enough room for padding + length in current block */
426         memset( ctx->buffer + used, 0, 112 - used );
427     }
428     else
429     {
430         /* We'll need an extra block */
431         memset( ctx->buffer + used, 0, 128 - used );
432 
433         if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
434             return( ret );
435 
436         memset( ctx->buffer, 0, 112 );
437     }
438 
439     /*
440      * Add message length
441      */
442     high = ( ctx->total[0] >> 61 )
443          | ( ctx->total[1] <<  3 );
444     low  = ( ctx->total[0] <<  3 );
445 
446     sha512_put_uint64_be( high, ctx->buffer, 112 );
447     sha512_put_uint64_be( low,  ctx->buffer, 120 );
448 
449     if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
450         return( ret );
451 
452     /*
453      * Output final state
454      */
455     sha512_put_uint64_be( ctx->state[0], output,  0 );
456     sha512_put_uint64_be( ctx->state[1], output,  8 );
457     sha512_put_uint64_be( ctx->state[2], output, 16 );
458     sha512_put_uint64_be( ctx->state[3], output, 24 );
459     sha512_put_uint64_be( ctx->state[4], output, 32 );
460     sha512_put_uint64_be( ctx->state[5], output, 40 );
461 
462 #if !defined(MBEDTLS_SHA512_NO_SHA384)
463     if( ctx->is384 == 0 )
464 #endif
465     {
466         sha512_put_uint64_be( ctx->state[6], output, 48 );
467         sha512_put_uint64_be( ctx->state[7], output, 56 );
468     }
469 
470     return( 0 );
471 }
472 
473 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512_finish(mbedtls_sha512_context * ctx,unsigned char output[64])474 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
475                             unsigned char output[64] )
476 {
477     mbedtls_sha512_finish_ret( ctx, output );
478 }
479 #endif
480 
481 #endif /* !MBEDTLS_SHA512_ALT */
482 
483 /*
484  * output = SHA-512( input buffer )
485  */
mbedtls_sha512_ret(const unsigned char * input,size_t ilen,unsigned char output[64],int is384)486 int mbedtls_sha512_ret( const unsigned char *input,
487                     size_t ilen,
488                     unsigned char output[64],
489                     int is384 )
490 {
491     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
492     mbedtls_sha512_context ctx;
493 
494 #if !defined(MBEDTLS_SHA512_NO_SHA384)
495     SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
496 #else
497     SHA512_VALIDATE_RET( is384 == 0 );
498 #endif
499     SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
500     SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
501 
502     mbedtls_sha512_init( &ctx );
503 
504     if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
505         goto exit;
506 
507     if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
508         goto exit;
509 
510     if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
511         goto exit;
512 
513 exit:
514     mbedtls_sha512_free( &ctx );
515 
516     return( ret );
517 }
518 
519 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_sha512(const unsigned char * input,size_t ilen,unsigned char output[64],int is384)520 void mbedtls_sha512( const unsigned char *input,
521                      size_t ilen,
522                      unsigned char output[64],
523                      int is384 )
524 {
525     mbedtls_sha512_ret( input, ilen, output, is384 );
526 }
527 #endif
528 
529 #if defined(MBEDTLS_SELF_TEST)
530 
531 /*
532  * FIPS-180-2 test vectors
533  */
534 static const unsigned char sha512_test_buf[3][113] =
535 {
536     { "abc" },
537     { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
538     { "" }
539 };
540 
541 static const size_t sha512_test_buflen[3] =
542 {
543     3, 112, 1000
544 };
545 
546 static const unsigned char sha512_test_sum[][64] =
547 {
548 #if !defined(MBEDTLS_SHA512_NO_SHA384)
549     /*
550      * SHA-384 test vectors
551      */
552     { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
553       0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
554       0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
555       0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
556       0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
557       0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
558     { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
559       0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
560       0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
561       0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
562       0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
563       0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
564     { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
565       0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
566       0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
567       0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
568       0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
569       0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
570 #endif /* !MBEDTLS_SHA512_NO_SHA384 */
571 
572     /*
573      * SHA-512 test vectors
574      */
575     { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
576       0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
577       0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
578       0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
579       0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
580       0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
581       0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
582       0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
583     { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
584       0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
585       0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
586       0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
587       0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
588       0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
589       0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
590       0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
591     { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
592       0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
593       0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
594       0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
595       0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
596       0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
597       0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
598       0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
599 };
600 
601 #define ARRAY_LENGTH( a )   ( sizeof( a ) / sizeof( ( a )[0] ) )
602 
603 /*
604  * Checkup routine
605  */
mbedtls_sha512_self_test(int verbose)606 int mbedtls_sha512_self_test( int verbose )
607 {
608     int i, j, k, buflen, ret = 0;
609     unsigned char *buf;
610     unsigned char sha512sum[64];
611     mbedtls_sha512_context ctx;
612 
613     buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
614     if( NULL == buf )
615     {
616         if( verbose != 0 )
617             mbedtls_printf( "Buffer allocation failed\n" );
618 
619         return( 1 );
620     }
621 
622     mbedtls_sha512_init( &ctx );
623 
624     for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
625     {
626         j = i % 3;
627 #if !defined(MBEDTLS_SHA512_NO_SHA384)
628         k = i < 3;
629 #else
630         k = 0;
631 #endif
632 
633         if( verbose != 0 )
634             mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
635 
636         if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
637             goto fail;
638 
639         if( j == 2 )
640         {
641             memset( buf, 'a', buflen = 1000 );
642 
643             for( j = 0; j < 1000; j++ )
644             {
645                 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
646                 if( ret != 0 )
647                     goto fail;
648             }
649         }
650         else
651         {
652             ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
653                                              sha512_test_buflen[j] );
654             if( ret != 0 )
655                 goto fail;
656         }
657 
658         if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
659             goto fail;
660 
661         if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
662         {
663             ret = 1;
664             goto fail;
665         }
666 
667         if( verbose != 0 )
668             mbedtls_printf( "passed\n" );
669     }
670 
671     if( verbose != 0 )
672         mbedtls_printf( "\n" );
673 
674     goto exit;
675 
676 fail:
677     if( verbose != 0 )
678         mbedtls_printf( "failed\n" );
679 
680 exit:
681     mbedtls_sha512_free( &ctx );
682     mbedtls_free( buf );
683 
684     return( ret );
685 }
686 
687 #undef ARRAY_LENGTH
688 
689 #endif /* MBEDTLS_SELF_TEST */
690 
691 #endif /* MBEDTLS_SHA512_C */
692