blob: af610bb43f095646d0e0ca4f3a8d5881b4963c8a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
23 *
24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
25 */
26
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/sha512.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000037#if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
39#else
40 #define UL64(x) x##ULL
41#endif
42
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_PLATFORM_C */
52#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020054#if !defined(MBEDTLS_SHA512_ALT)
55
Paul Bakker34617722014-06-13 17:20:13 +020056/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020058 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
59}
60
Paul Bakker5121ce52009-01-03 21:22:43 +000061/*
62 * 64-bit integer manipulation macros (big endian)
63 */
64#ifndef GET_UINT64_BE
65#define GET_UINT64_BE(n,b,i) \
66{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
68 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
69 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
70 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
71 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
72 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
73 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
74 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000075}
Paul Bakker9af723c2014-05-01 13:03:14 +020076#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000077
78#ifndef PUT_UINT64_BE
79#define PUT_UINT64_BE(n,b,i) \
80{ \
81 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
82 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
83 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
84 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
85 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
86 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
87 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
88 (b)[(i) + 7] = (unsigned char) ( (n) ); \
89}
Paul Bakker9af723c2014-05-01 13:03:14 +020090#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000091
92/*
93 * Round constants
94 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000095static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +000096{
97 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
98 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
99 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
100 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
101 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
102 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
103 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
104 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
105 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
106 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
107 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
108 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
109 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
110 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
111 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
112 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
113 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
114 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
115 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
116 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
117 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
118 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
119 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
120 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
121 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
122 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
123 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
124 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
125 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
126 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
127 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
128 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
129 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
130 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
131 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
132 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
133 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
134 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
135 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
136 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
137};
138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200140{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200142}
143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200145{
146 if( ctx == NULL )
147 return;
148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200150}
151
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200152void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
153 const mbedtls_sha512_context *src )
154{
155 *dst = *src;
156}
157
Paul Bakker5121ce52009-01-03 21:22:43 +0000158/*
159 * SHA-512 context setup
160 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000162{
163 ctx->total[0] = 0;
164 ctx->total[1] = 0;
165
166 if( is384 == 0 )
167 {
168 /* SHA-512 */
169 ctx->state[0] = UL64(0x6A09E667F3BCC908);
170 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
171 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
172 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
173 ctx->state[4] = UL64(0x510E527FADE682D1);
174 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
175 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
176 ctx->state[7] = UL64(0x5BE0CD19137E2179);
177 }
178 else
179 {
180 /* SHA-384 */
181 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
182 ctx->state[1] = UL64(0x629A292A367CD507);
183 ctx->state[2] = UL64(0x9159015A3070DD17);
184 ctx->state[3] = UL64(0x152FECD8F70E5939);
185 ctx->state[4] = UL64(0x67332667FFC00B31);
186 ctx->state[5] = UL64(0x8EB44A8768581511);
187 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
188 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
189 }
190
191 ctx->is384 = is384;
192}
193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200194#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
195void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000196{
197 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000198 uint64_t temp1, temp2, W[80];
199 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000200
201#define SHR(x,n) (x >> n)
202#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
203
204#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
205#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
206
207#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
208#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
209
210#define F0(x,y,z) ((x & y) | (z & (x | y)))
211#define F1(x,y,z) (z ^ (x & (y ^ z)))
212
213#define P(a,b,c,d,e,f,g,h,x,K) \
214{ \
215 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
216 temp2 = S2(a) + F0(a,b,c); \
217 d += temp1; h = temp1 + temp2; \
218}
219
220 for( i = 0; i < 16; i++ )
221 {
222 GET_UINT64_BE( W[i], data, i << 3 );
223 }
224
225 for( ; i < 80; i++ )
226 {
227 W[i] = S1(W[i - 2]) + W[i - 7] +
228 S0(W[i - 15]) + W[i - 16];
229 }
230
231 A = ctx->state[0];
232 B = ctx->state[1];
233 C = ctx->state[2];
234 D = ctx->state[3];
235 E = ctx->state[4];
236 F = ctx->state[5];
237 G = ctx->state[6];
238 H = ctx->state[7];
239 i = 0;
240
241 do
242 {
243 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
244 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
245 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
246 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
247 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
248 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
249 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
250 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
251 }
252 while( i < 80 );
253
254 ctx->state[0] += A;
255 ctx->state[1] += B;
256 ctx->state[2] += C;
257 ctx->state[3] += D;
258 ctx->state[4] += E;
259 ctx->state[5] += F;
260 ctx->state[6] += G;
261 ctx->state[7] += H;
262}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265/*
266 * SHA-512 process buffer
267 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200269 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270{
Paul Bakker23986e52011-04-24 08:57:21 +0000271 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000272 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Brian White12895d12014-04-11 11:29:42 -0400274 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 return;
276
Paul Bakkerb8213a12011-07-11 08:16:18 +0000277 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000278 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
Paul Bakker5c2364c2012-10-01 14:41:15 +0000282 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 ctx->total[1]++;
284
285 if( left && ilen >= fill )
286 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200287 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288 mbedtls_sha512_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 input += fill;
290 ilen -= fill;
291 left = 0;
292 }
293
294 while( ilen >= 128 )
295 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296 mbedtls_sha512_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 input += 128;
298 ilen -= 128;
299 }
300
301 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200302 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303}
304
Paul Bakker9e36f042013-06-30 14:34:05 +0200305static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000306{
307 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
315};
316
317/*
318 * SHA-512 final digest
319 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000321{
Paul Bakker27fdf462011-06-09 13:55:13 +0000322 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 unsigned char msglen[16];
325
326 high = ( ctx->total[0] >> 61 )
327 | ( ctx->total[1] << 3 );
328 low = ( ctx->total[0] << 3 );
329
330 PUT_UINT64_BE( high, msglen, 0 );
331 PUT_UINT64_BE( low, msglen, 8 );
332
Paul Bakker27fdf462011-06-09 13:55:13 +0000333 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 mbedtls_sha512_update( ctx, sha512_padding, padn );
337 mbedtls_sha512_update( ctx, msglen, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 PUT_UINT64_BE( ctx->state[0], output, 0 );
340 PUT_UINT64_BE( ctx->state[1], output, 8 );
341 PUT_UINT64_BE( ctx->state[2], output, 16 );
342 PUT_UINT64_BE( ctx->state[3], output, 24 );
343 PUT_UINT64_BE( ctx->state[4], output, 32 );
344 PUT_UINT64_BE( ctx->state[5], output, 40 );
345
346 if( ctx->is384 == 0 )
347 {
348 PUT_UINT64_BE( ctx->state[6], output, 48 );
349 PUT_UINT64_BE( ctx->state[7], output, 56 );
350 }
351}
352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200354
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * output = SHA-512( input buffer )
357 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358void mbedtls_sha512( const unsigned char *input, size_t ilen,
Paul Bakker9e36f042013-06-30 14:34:05 +0200359 unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000360{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_sha512_init( &ctx );
364 mbedtls_sha512_starts( &ctx, is384 );
365 mbedtls_sha512_update( &ctx, input, ilen );
366 mbedtls_sha512_finish( &ctx, output );
367 mbedtls_sha512_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000368}
369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
372/*
373 * FIPS-180-2 test vectors
374 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000375static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000376{
377 { "abc" },
378 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
379 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
380 { "" }
381};
382
Paul Bakker9e36f042013-06-30 14:34:05 +0200383static const int sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000384{
385 3, 112, 1000
386};
387
Paul Bakker9e36f042013-06-30 14:34:05 +0200388static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000389{
390 /*
391 * SHA-384 test vectors
392 */
393 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
394 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
395 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
396 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
397 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
398 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
399 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
400 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
401 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
402 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
403 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
404 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
405 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
406 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
407 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
408 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
409 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
410 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
411
412 /*
413 * SHA-512 test vectors
414 */
415 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
416 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
417 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
418 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
419 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
420 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
421 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
422 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
423 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
424 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
425 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
426 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
427 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
428 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
429 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
430 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
431 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
432 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
433 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
434 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
435 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
436 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
437 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
438 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
439};
440
441/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 * Checkup routine
443 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000445{
Paul Bakker5b4af392014-06-26 12:09:34 +0200446 int i, j, k, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 unsigned char buf[1024];
Paul Bakker9e36f042013-06-30 14:34:05 +0200448 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200452
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 for( i = 0; i < 6; i++ )
454 {
455 j = i % 3;
456 k = i < 3;
457
458 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_sha512_starts( &ctx, k );
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( j == 2 )
464 {
465 memset( buf, 'a', buflen = 1000 );
466
467 for( j = 0; j < 1000; j++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_sha512_update( &ctx, buf, buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 }
470 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 mbedtls_sha512_update( &ctx, sha512_test_buf[j],
Paul Bakker9e36f042013-06-30 14:34:05 +0200472 sha512_test_buflen[j] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_sha512_finish( &ctx, sha512sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Paul Bakker9e36f042013-06-30 14:34:05 +0200476 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000477 {
478 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Paul Bakker5b4af392014-06-26 12:09:34 +0200481 ret = 1;
482 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000483 }
484
485 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 }
488
489 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Paul Bakker5b4af392014-06-26 12:09:34 +0200492exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 mbedtls_sha512_free( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200494
495 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000496}
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#endif /* MBEDTLS_SHA512_C */