blob: f09b0f7fe065bdc47b83ad8925737034c74c70bd [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/sha512.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000038#if defined(_MSC_VER) || defined(__WATCOMC__)
39 #define UL64(x) x##ui64
40#else
41 #define UL64(x) x##ULL
42#endif
43
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <string.h>
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_SELF_TEST)
47#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010049#else
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
52#endif /* MBEDTLS_PLATFORM_C */
53#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010054
Paul Bakker34617722014-06-13 17:20:13 +020055/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020057 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
58}
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if !defined(MBEDTLS_SHA512_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020061
Paul Bakker5121ce52009-01-03 21:22:43 +000062/*
63 * 64-bit integer manipulation macros (big endian)
64 */
65#ifndef GET_UINT64_BE
66#define GET_UINT64_BE(n,b,i) \
67{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000068 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
69 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
70 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
71 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
72 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
73 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
74 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
75 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000076}
Paul Bakker9af723c2014-05-01 13:03:14 +020077#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000078
79#ifndef PUT_UINT64_BE
80#define PUT_UINT64_BE(n,b,i) \
81{ \
82 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
83 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
84 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
85 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
86 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
87 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
88 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
89 (b)[(i) + 7] = (unsigned char) ( (n) ); \
90}
Paul Bakker9af723c2014-05-01 13:03:14 +020091#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000092
93/*
94 * Round constants
95 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000096static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +000097{
98 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
99 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
100 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
101 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
102 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
103 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
104 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
105 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
106 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
107 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
108 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
109 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
110 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
111 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
112 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
113 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
114 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
115 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
116 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
117 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
118 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
119 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
120 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
121 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
122 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
123 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
124 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
125 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
126 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
127 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
128 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
129 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
130 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
131 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
132 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
133 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
134 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
135 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
136 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
137 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
138};
139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200141{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200143}
144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200146{
147 if( ctx == NULL )
148 return;
149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200151}
152
Paul Bakker5121ce52009-01-03 21:22:43 +0000153/*
154 * SHA-512 context setup
155 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000157{
158 ctx->total[0] = 0;
159 ctx->total[1] = 0;
160
161 if( is384 == 0 )
162 {
163 /* SHA-512 */
164 ctx->state[0] = UL64(0x6A09E667F3BCC908);
165 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
166 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
167 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
168 ctx->state[4] = UL64(0x510E527FADE682D1);
169 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
170 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
171 ctx->state[7] = UL64(0x5BE0CD19137E2179);
172 }
173 else
174 {
175 /* SHA-384 */
176 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
177 ctx->state[1] = UL64(0x629A292A367CD507);
178 ctx->state[2] = UL64(0x9159015A3070DD17);
179 ctx->state[3] = UL64(0x152FECD8F70E5939);
180 ctx->state[4] = UL64(0x67332667FFC00B31);
181 ctx->state[5] = UL64(0x8EB44A8768581511);
182 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
183 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
184 }
185
186 ctx->is384 = is384;
187}
188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
190void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000191{
192 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000193 uint64_t temp1, temp2, W[80];
194 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000195
196#define SHR(x,n) (x >> n)
197#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
198
199#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
200#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
201
202#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
203#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
204
205#define F0(x,y,z) ((x & y) | (z & (x | y)))
206#define F1(x,y,z) (z ^ (x & (y ^ z)))
207
208#define P(a,b,c,d,e,f,g,h,x,K) \
209{ \
210 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
211 temp2 = S2(a) + F0(a,b,c); \
212 d += temp1; h = temp1 + temp2; \
213}
214
215 for( i = 0; i < 16; i++ )
216 {
217 GET_UINT64_BE( W[i], data, i << 3 );
218 }
219
220 for( ; i < 80; i++ )
221 {
222 W[i] = S1(W[i - 2]) + W[i - 7] +
223 S0(W[i - 15]) + W[i - 16];
224 }
225
226 A = ctx->state[0];
227 B = ctx->state[1];
228 C = ctx->state[2];
229 D = ctx->state[3];
230 E = ctx->state[4];
231 F = ctx->state[5];
232 G = ctx->state[6];
233 H = ctx->state[7];
234 i = 0;
235
236 do
237 {
238 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
239 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
240 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
241 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
242 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
243 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
244 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
245 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
246 }
247 while( i < 80 );
248
249 ctx->state[0] += A;
250 ctx->state[1] += B;
251 ctx->state[2] += C;
252 ctx->state[3] += D;
253 ctx->state[4] += E;
254 ctx->state[5] += F;
255 ctx->state[6] += G;
256 ctx->state[7] += H;
257}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000259
260/*
261 * SHA-512 process buffer
262 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200264 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000265{
Paul Bakker23986e52011-04-24 08:57:21 +0000266 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000267 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
Brian White12895d12014-04-11 11:29:42 -0400269 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 return;
271
Paul Bakkerb8213a12011-07-11 08:16:18 +0000272 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000273 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000274
Paul Bakker5c2364c2012-10-01 14:41:15 +0000275 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Paul Bakker5c2364c2012-10-01 14:41:15 +0000277 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 ctx->total[1]++;
279
280 if( left && ilen >= fill )
281 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200282 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 mbedtls_sha512_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 input += fill;
285 ilen -= fill;
286 left = 0;
287 }
288
289 while( ilen >= 128 )
290 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291 mbedtls_sha512_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 input += 128;
293 ilen -= 128;
294 }
295
296 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200297 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298}
299
Paul Bakker9e36f042013-06-30 14:34:05 +0200300static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000301{
302 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
310};
311
312/*
313 * SHA-512 final digest
314 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000316{
Paul Bakker27fdf462011-06-09 13:55:13 +0000317 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 unsigned char msglen[16];
320
321 high = ( ctx->total[0] >> 61 )
322 | ( ctx->total[1] << 3 );
323 low = ( ctx->total[0] << 3 );
324
325 PUT_UINT64_BE( high, msglen, 0 );
326 PUT_UINT64_BE( low, msglen, 8 );
327
Paul Bakker27fdf462011-06-09 13:55:13 +0000328 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 mbedtls_sha512_update( ctx, sha512_padding, padn );
332 mbedtls_sha512_update( ctx, msglen, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
334 PUT_UINT64_BE( ctx->state[0], output, 0 );
335 PUT_UINT64_BE( ctx->state[1], output, 8 );
336 PUT_UINT64_BE( ctx->state[2], output, 16 );
337 PUT_UINT64_BE( ctx->state[3], output, 24 );
338 PUT_UINT64_BE( ctx->state[4], output, 32 );
339 PUT_UINT64_BE( ctx->state[5], output, 40 );
340
341 if( ctx->is384 == 0 )
342 {
343 PUT_UINT64_BE( ctx->state[6], output, 48 );
344 PUT_UINT64_BE( ctx->state[7], output, 56 );
345 }
346}
347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200349
Paul Bakker5121ce52009-01-03 21:22:43 +0000350/*
351 * output = SHA-512( input buffer )
352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353void mbedtls_sha512( const unsigned char *input, size_t ilen,
Paul Bakker9e36f042013-06-30 14:34:05 +0200354 unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000355{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_sha512_init( &ctx );
359 mbedtls_sha512_starts( &ctx, is384 );
360 mbedtls_sha512_update( &ctx, input, ilen );
361 mbedtls_sha512_finish( &ctx, output );
362 mbedtls_sha512_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000363}
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367/*
368 * FIPS-180-2 test vectors
369 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000370static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000371{
372 { "abc" },
373 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
374 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
375 { "" }
376};
377
Paul Bakker9e36f042013-06-30 14:34:05 +0200378static const int sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000379{
380 3, 112, 1000
381};
382
Paul Bakker9e36f042013-06-30 14:34:05 +0200383static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000384{
385 /*
386 * SHA-384 test vectors
387 */
388 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
389 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
390 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
391 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
392 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
393 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
394 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
395 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
396 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
397 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
398 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
399 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
400 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
401 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
402 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
403 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
404 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
405 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
406
407 /*
408 * SHA-512 test vectors
409 */
410 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
411 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
412 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
413 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
414 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
415 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
416 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
417 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
418 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
419 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
420 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
421 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
422 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
423 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
424 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
425 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
426 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
427 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
428 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
429 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
430 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
431 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
432 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
433 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
434};
435
436/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 * Checkup routine
438 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000440{
Paul Bakker5b4af392014-06-26 12:09:34 +0200441 int i, j, k, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 unsigned char buf[1024];
Paul Bakker9e36f042013-06-30 14:34:05 +0200443 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200447
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 for( i = 0; i < 6; i++ )
449 {
450 j = i % 3;
451 k = i < 3;
452
453 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_sha512_starts( &ctx, k );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458 if( j == 2 )
459 {
460 memset( buf, 'a', buflen = 1000 );
461
462 for( j = 0; j < 1000; j++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 mbedtls_sha512_update( &ctx, buf, buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 }
465 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 mbedtls_sha512_update( &ctx, sha512_test_buf[j],
Paul Bakker9e36f042013-06-30 14:34:05 +0200467 sha512_test_buflen[j] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 mbedtls_sha512_finish( &ctx, sha512sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
Paul Bakker9e36f042013-06-30 14:34:05 +0200471 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 {
473 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Paul Bakker5b4af392014-06-26 12:09:34 +0200476 ret = 1;
477 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000478 }
479
480 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482 }
483
484 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Paul Bakker5b4af392014-06-26 12:09:34 +0200487exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 mbedtls_sha512_free( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200489
490 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491}
492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_SHA512_C */