blob: 51c9a239be47bc0ced81edc3356ac23be2ea9c0c [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * FIPS-180-2 compliant SHA-384/512 implementation
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
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
27#if !defined(MBEDTLS_CONFIG_FILE)
28#include "mbedtls/config.h"
29#else
30#include MBEDTLS_CONFIG_FILE
31#endif
32
33#if defined(MBEDTLS_SHA512_C)
34
35#include "mbedtls/sha512.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036#include "mbedtls/platform_util.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020037
38#if defined(_MSC_VER) || defined(__WATCOMC__)
39 #define UL64(x) x##ui64
40#else
41 #define UL64(x) x##ULL
42#endif
43
44#include <string.h>
45
46#if defined(MBEDTLS_SELF_TEST)
47#if defined(MBEDTLS_PLATFORM_C)
48#include "mbedtls/platform.h"
49#else
50#include <stdio.h>
51#include <stdlib.h>
52#define mbedtls_printf printf
53#define mbedtls_calloc calloc
54#define mbedtls_free free
55#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST */
57
Jens Wiklander3d3b0592019-03-20 15:30:29 +010058#define SHA512_VALIDATE_RET(cond) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
60#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020061
Jens Wiklander3d3b0592019-03-20 15:30:29 +010062#if !defined(MBEDTLS_SHA512_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +020063
64/*
65 * 64-bit integer manipulation macros (big endian)
66 */
67#ifndef GET_UINT64_BE
68#define GET_UINT64_BE(n,b,i) \
69{ \
70 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
71 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
72 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
73 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
74 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
75 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
76 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
77 | ( (uint64_t) (b)[(i) + 7] ); \
78}
79#endif /* GET_UINT64_BE */
80
81#ifndef PUT_UINT64_BE
82#define PUT_UINT64_BE(n,b,i) \
83{ \
84 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
85 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
86 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
87 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
88 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
89 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
90 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
91 (b)[(i) + 7] = (unsigned char) ( (n) ); \
92}
93#endif /* PUT_UINT64_BE */
94
95void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
96{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010097 SHA512_VALIDATE( ctx != NULL );
98
Jens Wiklander817466c2018-05-22 13:49:31 +020099 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
100}
101
102void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
103{
104 if( ctx == NULL )
105 return;
106
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100107 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200108}
109
110void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
111 const mbedtls_sha512_context *src )
112{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100113 SHA512_VALIDATE( dst != NULL );
114 SHA512_VALIDATE( src != NULL );
115
Jens Wiklander817466c2018-05-22 13:49:31 +0200116 *dst = *src;
117}
118
119/*
120 * SHA-512 context setup
121 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100122int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200123{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100124 SHA512_VALIDATE_RET( ctx != NULL );
125 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
126
Jens Wiklander817466c2018-05-22 13:49:31 +0200127 ctx->total[0] = 0;
128 ctx->total[1] = 0;
129
130 if( is384 == 0 )
131 {
132 /* SHA-512 */
133 ctx->state[0] = UL64(0x6A09E667F3BCC908);
134 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
135 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
136 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
137 ctx->state[4] = UL64(0x510E527FADE682D1);
138 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
139 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
140 ctx->state[7] = UL64(0x5BE0CD19137E2179);
141 }
142 else
143 {
144 /* SHA-384 */
145 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
146 ctx->state[1] = UL64(0x629A292A367CD507);
147 ctx->state[2] = UL64(0x9159015A3070DD17);
148 ctx->state[3] = UL64(0x152FECD8F70E5939);
149 ctx->state[4] = UL64(0x67332667FFC00B31);
150 ctx->state[5] = UL64(0x8EB44A8768581511);
151 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
152 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
153 }
154
155 ctx->is384 = is384;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100156
157 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200158}
159
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100160#if !defined(MBEDTLS_DEPRECATED_REMOVED)
161void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
162 int is384 )
163{
164 mbedtls_sha512_starts_ret( ctx, is384 );
165}
166#endif
167
Jens Wiklander817466c2018-05-22 13:49:31 +0200168#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
169
170/*
171 * Round constants
172 */
173static const uint64_t K[80] =
174{
175 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
176 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
177 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
178 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
179 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
180 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
181 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
182 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
183 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
184 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
185 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
186 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
187 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
188 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
189 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
190 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
191 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
192 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
193 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
194 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
195 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
196 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
197 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
198 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
199 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
200 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
201 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
202 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
203 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
204 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
205 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
206 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
207 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
208 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
209 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
210 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
211 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
212 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
213 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
214 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
215};
216
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100217int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
218 const unsigned char data[128] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200219{
220 int i;
221 uint64_t temp1, temp2, W[80];
222 uint64_t A, B, C, D, E, F, G, H;
223
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100224 SHA512_VALIDATE_RET( ctx != NULL );
225 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
226
Jerome Forissier5b25c762020-04-07 11:18:49 +0200227#define SHR(x,n) ((x) >> (n))
228#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200229
230#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
231#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
232
233#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
234#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
235
Jerome Forissier5b25c762020-04-07 11:18:49 +0200236#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
237#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200238
Jerome Forissier5b25c762020-04-07 11:18:49 +0200239#define P(a,b,c,d,e,f,g,h,x,K) \
240 do \
241 { \
242 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
243 temp2 = S2(a) + F0((a),(b),(c)); \
244 (d) += temp1; (h) = temp1 + temp2; \
245 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200246
247 for( i = 0; i < 16; i++ )
248 {
249 GET_UINT64_BE( W[i], data, i << 3 );
250 }
251
252 for( ; i < 80; i++ )
253 {
254 W[i] = S1(W[i - 2]) + W[i - 7] +
255 S0(W[i - 15]) + W[i - 16];
256 }
257
258 A = ctx->state[0];
259 B = ctx->state[1];
260 C = ctx->state[2];
261 D = ctx->state[3];
262 E = ctx->state[4];
263 F = ctx->state[5];
264 G = ctx->state[6];
265 H = ctx->state[7];
266 i = 0;
267
268 do
269 {
270 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
271 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
272 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
273 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
274 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
275 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
276 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
277 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
278 }
279 while( i < 80 );
280
281 ctx->state[0] += A;
282 ctx->state[1] += B;
283 ctx->state[2] += C;
284 ctx->state[3] += D;
285 ctx->state[4] += E;
286 ctx->state[5] += F;
287 ctx->state[6] += G;
288 ctx->state[7] += H;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100289
290 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200291}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100292
293#if !defined(MBEDTLS_DEPRECATED_REMOVED)
294void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
295 const unsigned char data[128] )
296{
297 mbedtls_internal_sha512_process( ctx, data );
298}
299#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200300#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
301
302/*
303 * SHA-512 process buffer
304 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100305int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
306 const unsigned char *input,
307 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200308{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100309 int ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200310 size_t fill;
311 unsigned int left;
312
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100313 SHA512_VALIDATE_RET( ctx != NULL );
314 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
315
Jens Wiklander817466c2018-05-22 13:49:31 +0200316 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100317 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200318
319 left = (unsigned int) (ctx->total[0] & 0x7F);
320 fill = 128 - left;
321
322 ctx->total[0] += (uint64_t) ilen;
323
324 if( ctx->total[0] < (uint64_t) ilen )
325 ctx->total[1]++;
326
327 if( left && ilen >= fill )
328 {
329 memcpy( (void *) (ctx->buffer + left), input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100330
331 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
332 return( ret );
333
Jens Wiklander817466c2018-05-22 13:49:31 +0200334 input += fill;
335 ilen -= fill;
336 left = 0;
337 }
338
339 while( ilen >= 128 )
340 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100341 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
342 return( ret );
343
Jens Wiklander817466c2018-05-22 13:49:31 +0200344 input += 128;
345 ilen -= 128;
346 }
347
348 if( ilen > 0 )
349 memcpy( (void *) (ctx->buffer + left), input, ilen );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100350
351 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200352}
353
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100354#if !defined(MBEDTLS_DEPRECATED_REMOVED)
355void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
356 const unsigned char *input,
357 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200358{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100359 mbedtls_sha512_update_ret( ctx, input, ilen );
360}
361#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200362
363/*
364 * SHA-512 final digest
365 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100366int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
367 unsigned char output[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200368{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100369 int ret;
370 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200371 uint64_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200372
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100373 SHA512_VALIDATE_RET( ctx != NULL );
374 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
375
376 /*
377 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
378 */
379 used = ctx->total[0] & 0x7F;
380
381 ctx->buffer[used++] = 0x80;
382
383 if( used <= 112 )
384 {
385 /* Enough room for padding + length in current block */
386 memset( ctx->buffer + used, 0, 112 - used );
387 }
388 else
389 {
390 /* We'll need an extra block */
391 memset( ctx->buffer + used, 0, 128 - used );
392
393 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
394 return( ret );
395
396 memset( ctx->buffer, 0, 112 );
397 }
398
399 /*
400 * Add message length
401 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200402 high = ( ctx->total[0] >> 61 )
403 | ( ctx->total[1] << 3 );
404 low = ( ctx->total[0] << 3 );
405
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100406 PUT_UINT64_BE( high, ctx->buffer, 112 );
407 PUT_UINT64_BE( low, ctx->buffer, 120 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200408
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100409 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
410 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200411
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100412 /*
413 * Output final state
414 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200415 PUT_UINT64_BE( ctx->state[0], output, 0 );
416 PUT_UINT64_BE( ctx->state[1], output, 8 );
417 PUT_UINT64_BE( ctx->state[2], output, 16 );
418 PUT_UINT64_BE( ctx->state[3], output, 24 );
419 PUT_UINT64_BE( ctx->state[4], output, 32 );
420 PUT_UINT64_BE( ctx->state[5], output, 40 );
421
422 if( ctx->is384 == 0 )
423 {
424 PUT_UINT64_BE( ctx->state[6], output, 48 );
425 PUT_UINT64_BE( ctx->state[7], output, 56 );
426 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100427
428 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200429}
430
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100431#if !defined(MBEDTLS_DEPRECATED_REMOVED)
432void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
433 unsigned char output[64] )
434{
435 mbedtls_sha512_finish_ret( ctx, output );
436}
437#endif
438
Jens Wiklander817466c2018-05-22 13:49:31 +0200439#endif /* !MBEDTLS_SHA512_ALT */
440
441/*
442 * output = SHA-512( input buffer )
443 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100444int mbedtls_sha512_ret( const unsigned char *input,
445 size_t ilen,
446 unsigned char output[64],
447 int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200448{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100449 int ret;
Jens Wiklander817466c2018-05-22 13:49:31 +0200450 mbedtls_sha512_context ctx;
451
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100452 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
453 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
454 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
455
Jens Wiklander817466c2018-05-22 13:49:31 +0200456 mbedtls_sha512_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100457
458 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
459 goto exit;
460
461 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
462 goto exit;
463
464 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
465 goto exit;
466
467exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200468 mbedtls_sha512_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100469
470 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200471}
472
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100473#if !defined(MBEDTLS_DEPRECATED_REMOVED)
474void mbedtls_sha512( const unsigned char *input,
475 size_t ilen,
476 unsigned char output[64],
477 int is384 )
478{
479 mbedtls_sha512_ret( input, ilen, output, is384 );
480}
481#endif
482
Jens Wiklander817466c2018-05-22 13:49:31 +0200483#if defined(MBEDTLS_SELF_TEST)
484
485/*
486 * FIPS-180-2 test vectors
487 */
488static const unsigned char sha512_test_buf[3][113] =
489{
490 { "abc" },
491 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
492 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
493 { "" }
494};
495
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100496static const size_t sha512_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200497{
498 3, 112, 1000
499};
500
501static const unsigned char sha512_test_sum[6][64] =
502{
503 /*
504 * SHA-384 test vectors
505 */
506 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
507 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
508 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
509 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
510 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
511 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
512 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
513 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
514 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
515 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
516 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
517 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
518 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
519 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
520 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
521 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
522 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
523 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
524
525 /*
526 * SHA-512 test vectors
527 */
528 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
529 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
530 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
531 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
532 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
533 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
534 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
535 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
536 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
537 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
538 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
539 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
540 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
541 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
542 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
543 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
544 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
545 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
546 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
547 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
548 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
549 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
550 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
551 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
552};
553
554/*
555 * Checkup routine
556 */
557int mbedtls_sha512_self_test( int verbose )
558{
559 int i, j, k, buflen, ret = 0;
560 unsigned char *buf;
561 unsigned char sha512sum[64];
562 mbedtls_sha512_context ctx;
563
564 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
565 if( NULL == buf )
566 {
567 if( verbose != 0 )
568 mbedtls_printf( "Buffer allocation failed\n" );
569
570 return( 1 );
571 }
572
573 mbedtls_sha512_init( &ctx );
574
575 for( i = 0; i < 6; i++ )
576 {
577 j = i % 3;
578 k = i < 3;
579
580 if( verbose != 0 )
581 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
582
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100583 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
584 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200585
586 if( j == 2 )
587 {
588 memset( buf, 'a', buflen = 1000 );
589
590 for( j = 0; j < 1000; j++ )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100591 {
592 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
593 if( ret != 0 )
594 goto fail;
595 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200596 }
597 else
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100598 {
599 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
600 sha512_test_buflen[j] );
601 if( ret != 0 )
602 goto fail;
603 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200604
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100605 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
606 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200607
608 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
609 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200610 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100611 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200612 }
613
614 if( verbose != 0 )
615 mbedtls_printf( "passed\n" );
616 }
617
618 if( verbose != 0 )
619 mbedtls_printf( "\n" );
620
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100621 goto exit;
622
623fail:
624 if( verbose != 0 )
625 mbedtls_printf( "failed\n" );
626
Jens Wiklander817466c2018-05-22 13:49:31 +0200627exit:
628 mbedtls_sha512_free( &ctx );
629 mbedtls_free( buf );
630
631 return( ret );
632}
633
634#endif /* MBEDTLS_SELF_TEST */
635
636#endif /* MBEDTLS_SHA512_C */