blob: db2617ebdf55619ad2a2ba0f5d78df50b9f5dae6 [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>
Russ Butlerbb83b422016-10-12 17:36:50 -050050#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050052#define mbedtls_calloc calloc
53#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#endif /* MBEDTLS_PLATFORM_C */
55#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010056
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020057#if !defined(MBEDTLS_SHA512_ALT)
58
Paul Bakker34617722014-06-13 17:20:13 +020059/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020061 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
62}
63
Paul Bakker5121ce52009-01-03 21:22:43 +000064/*
65 * 64-bit integer manipulation macros (big endian)
66 */
67#ifndef GET_UINT64_BE
68#define GET_UINT64_BE(n,b,i) \
69{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000070 (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] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000078}
Paul Bakker9af723c2014-05-01 13:03:14 +020079#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000080
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}
Paul Bakker9af723c2014-05-01 13:03:14 +020093#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020096{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020098}
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200101{
102 if( ctx == NULL )
103 return;
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200106}
107
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200108void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
109 const mbedtls_sha512_context *src )
110{
111 *dst = *src;
112}
113
Paul Bakker5121ce52009-01-03 21:22:43 +0000114/*
115 * SHA-512 context setup
116 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100117int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000118{
119 ctx->total[0] = 0;
120 ctx->total[1] = 0;
121
122 if( is384 == 0 )
123 {
124 /* SHA-512 */
125 ctx->state[0] = UL64(0x6A09E667F3BCC908);
126 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
127 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
128 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
129 ctx->state[4] = UL64(0x510E527FADE682D1);
130 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
131 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
132 ctx->state[7] = UL64(0x5BE0CD19137E2179);
133 }
134 else
135 {
136 /* SHA-384 */
137 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
138 ctx->state[1] = UL64(0x629A292A367CD507);
139 ctx->state[2] = UL64(0x9159015A3070DD17);
140 ctx->state[3] = UL64(0x152FECD8F70E5939);
141 ctx->state[4] = UL64(0x67332667FFC00B31);
142 ctx->state[5] = UL64(0x8EB44A8768581511);
143 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
144 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
145 }
146
147 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100148
149 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000150}
151
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000152#if !defined(MBEDTLS_DEPRECATED_REMOVED)
153void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
154 int is384 )
155{
156 mbedtls_sha512_starts_ret( ctx, is384 );
157}
158#endif
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200161
162/*
163 * Round constants
164 */
165static const uint64_t K[80] =
166{
167 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
168 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
169 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
170 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
171 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
172 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
173 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
174 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
175 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
176 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
177 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
178 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
179 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
180 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
181 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
182 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
183 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
184 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
185 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
186 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
187 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
188 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
189 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
190 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
191 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
192 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
193 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
194 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
195 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
196 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
197 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
198 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
199 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
200 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
201 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
202 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
203 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
204 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
205 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
206 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
207};
208
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100209int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
210 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000211{
212 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213 uint64_t temp1, temp2, W[80];
214 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000215
216#define SHR(x,n) (x >> n)
217#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
218
219#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
220#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
221
222#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
223#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
224
225#define F0(x,y,z) ((x & y) | (z & (x | y)))
226#define F1(x,y,z) (z ^ (x & (y ^ z)))
227
228#define P(a,b,c,d,e,f,g,h,x,K) \
229{ \
230 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
231 temp2 = S2(a) + F0(a,b,c); \
232 d += temp1; h = temp1 + temp2; \
233}
234
235 for( i = 0; i < 16; i++ )
236 {
237 GET_UINT64_BE( W[i], data, i << 3 );
238 }
239
240 for( ; i < 80; i++ )
241 {
242 W[i] = S1(W[i - 2]) + W[i - 7] +
243 S0(W[i - 15]) + W[i - 16];
244 }
245
246 A = ctx->state[0];
247 B = ctx->state[1];
248 C = ctx->state[2];
249 D = ctx->state[3];
250 E = ctx->state[4];
251 F = ctx->state[5];
252 G = ctx->state[6];
253 H = ctx->state[7];
254 i = 0;
255
256 do
257 {
258 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
259 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
260 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
261 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
262 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
263 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
264 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
265 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
266 }
267 while( i < 80 );
268
269 ctx->state[0] += A;
270 ctx->state[1] += B;
271 ctx->state[2] += C;
272 ctx->state[3] += D;
273 ctx->state[4] += E;
274 ctx->state[5] += F;
275 ctx->state[6] += G;
276 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100277
278 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000279}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000280
281#if !defined(MBEDTLS_DEPRECATED_REMOVED)
282void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
283 const unsigned char data[128] )
284{
285 mbedtls_internal_sha512_process( ctx, data );
286}
287#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000289
290/*
291 * SHA-512 process buffer
292 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100293int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100294 const unsigned char *input,
295 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100297 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000298 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000299 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
Brian White12895d12014-04-11 11:29:42 -0400301 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100302 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Paul Bakkerb8213a12011-07-11 08:16:18 +0000304 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000305 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
Paul Bakker5c2364c2012-10-01 14:41:15 +0000309 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 ctx->total[1]++;
311
312 if( left && ilen >= fill )
313 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200314 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100315
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100316 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100317 return( ret );
318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 input += fill;
320 ilen -= fill;
321 left = 0;
322 }
323
324 while( ilen >= 128 )
325 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100326 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100327 return( ret );
328
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 input += 128;
330 ilen -= 128;
331 }
332
333 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200334 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100335
336 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337}
338
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000339#if !defined(MBEDTLS_DEPRECATED_REMOVED)
340void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
341 const unsigned char *input,
342 size_t ilen )
343{
344 mbedtls_sha512_update_ret( ctx, input, ilen );
345}
346#endif
347
Paul Bakker5121ce52009-01-03 21:22:43 +0000348/*
349 * SHA-512 final digest
350 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100351int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100352 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100354 int ret;
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200355 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000356 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200358 /*
359 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
360 */
361 used = ctx->total[0] & 0x7F;
362
363 ctx->buffer[used++] = 0x80;
364
365 if( used <= 112 )
366 {
367 /* Enough room for padding + length in current block */
368 memset( ctx->buffer + used, 0, 112 - used );
369 }
370 else
371 {
372 /* We'll need an extra block */
373 memset( ctx->buffer + used, 0, 128 - used );
374
375 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
376 return( ret );
377
378 memset( ctx->buffer, 0, 112 );
379 }
380
381 /*
382 * Add message length
383 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 high = ( ctx->total[0] >> 61 )
385 | ( ctx->total[1] << 3 );
386 low = ( ctx->total[0] << 3 );
387
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200388 PUT_UINT64_BE( high, ctx->buffer, 112 );
389 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200391 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
392 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200394 /*
395 * Output final state
396 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 PUT_UINT64_BE( ctx->state[0], output, 0 );
398 PUT_UINT64_BE( ctx->state[1], output, 8 );
399 PUT_UINT64_BE( ctx->state[2], output, 16 );
400 PUT_UINT64_BE( ctx->state[3], output, 24 );
401 PUT_UINT64_BE( ctx->state[4], output, 32 );
402 PUT_UINT64_BE( ctx->state[5], output, 40 );
403
404 if( ctx->is384 == 0 )
405 {
406 PUT_UINT64_BE( ctx->state[6], output, 48 );
407 PUT_UINT64_BE( ctx->state[7], output, 56 );
408 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100409
410 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411}
412
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000413#if !defined(MBEDTLS_DEPRECATED_REMOVED)
414void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
415 unsigned char output[64] )
416{
417 mbedtls_sha512_finish_ret( ctx, output );
418}
419#endif
420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200422
Paul Bakker5121ce52009-01-03 21:22:43 +0000423/*
424 * output = SHA-512( input buffer )
425 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100426int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100427 size_t ilen,
428 unsigned char output[64],
429 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000430{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100431 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100435
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100436 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100437 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100438
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100439 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100440 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100441
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100442 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100443 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100444
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100445exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100447
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100448 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449}
450
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000451#if !defined(MBEDTLS_DEPRECATED_REMOVED)
452void mbedtls_sha512( const unsigned char *input,
453 size_t ilen,
454 unsigned char output[64],
455 int is384 )
456{
457 mbedtls_sha512_ret( input, ilen, output, is384 );
458}
459#endif
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463/*
464 * FIPS-180-2 test vectors
465 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000466static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000467{
468 { "abc" },
469 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
470 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
471 { "" }
472};
473
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100474static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000475{
476 3, 112, 1000
477};
478
Paul Bakker9e36f042013-06-30 14:34:05 +0200479static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000480{
481 /*
482 * SHA-384 test vectors
483 */
484 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
485 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
486 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
487 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
488 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
489 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
490 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
491 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
492 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
493 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
494 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
495 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
496 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
497 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
498 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
499 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
500 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
501 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
502
503 /*
504 * SHA-512 test vectors
505 */
506 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
507 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
508 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
509 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
510 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
511 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
512 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
513 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
514 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
515 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
516 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
517 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
518 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
519 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
520 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
521 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
522 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
523 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
524 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
525 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
526 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
527 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
528 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
529 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
530};
531
532/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 * Checkup routine
534 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000536{
Paul Bakker5b4af392014-06-26 12:09:34 +0200537 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500538 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200539 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
Russ Butlerbb83b422016-10-12 17:36:50 -0500542 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
543 if( NULL == buf )
544 {
545 if( verbose != 0 )
546 mbedtls_printf( "Buffer allocation failed\n" );
547
548 return( 1 );
549 }
550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200552
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 for( i = 0; i < 6; i++ )
554 {
555 j = i % 3;
556 k = i < 3;
557
558 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100561 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100562 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
564 if( j == 2 )
565 {
566 memset( buf, 'a', buflen = 1000 );
567
568 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100569 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100570 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100571 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100572 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100573 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000574 }
575 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100576 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100577 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100578 sha512_test_buflen[j] );
579 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100580 goto fail;
581 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100583 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100584 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
Paul Bakker9e36f042013-06-30 14:34:05 +0200586 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100587 {
588 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100589 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100590 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000594 }
595
596 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100599 goto exit;
600
601fail:
602 if( verbose != 0 )
603 mbedtls_printf( "failed\n" );
604
Paul Bakker5b4af392014-06-26 12:09:34 +0200605exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500607 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200608
609 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000610}
611
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614#endif /* MBEDTLS_SHA512_C */