blob: 7a99170c975defc9fe5a5f1e777c499cb07efa9c [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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.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>
Russ Butlerbb83b422016-10-12 17:36:50 -050051#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050053#define mbedtls_calloc calloc
54#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020058#if !defined(MBEDTLS_SHA512_ALT)
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060/*
61 * 64-bit integer manipulation macros (big endian)
62 */
63#ifndef GET_UINT64_BE
64#define GET_UINT64_BE(n,b,i) \
65{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000066 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
67 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
68 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
69 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
70 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
71 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
72 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
73 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000074}
Paul Bakker9af723c2014-05-01 13:03:14 +020075#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77#ifndef PUT_UINT64_BE
78#define PUT_UINT64_BE(n,b,i) \
79{ \
80 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
81 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
82 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
83 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
84 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
85 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
86 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
87 (b)[(i) + 7] = (unsigned char) ( (n) ); \
88}
Paul Bakker9af723c2014-05-01 13:03:14 +020089#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000091#define MBEDTLS_SHA512_VALIDATE_RET(cond) \
92 MBEDTLS_VALIDATE_RET( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA, cond )
93#define MBEDTLS_SHA512_VALIDATE(cond) MBEDTLS_VALIDATE( cond )
94
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{
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000097 MBEDTLS_SHA512_VALIDATE( ctx != NULL );
98
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200100}
101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200103{
104 if( ctx == NULL )
105 return;
106
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500107 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200108}
109
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200110void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
111 const mbedtls_sha512_context *src )
112{
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000113 MBEDTLS_SHA512_VALIDATE( dst != NULL );
114 MBEDTLS_SHA512_VALIDATE( src != NULL );
115
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200116 *dst = *src;
117}
118
Paul Bakker5121ce52009-01-03 21:22:43 +0000119/*
120 * SHA-512 context setup
121 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100122int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000123{
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000124 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
125
Paul Bakker5121ce52009-01-03 21:22:43 +0000126 ctx->total[0] = 0;
127 ctx->total[1] = 0;
128
129 if( is384 == 0 )
130 {
131 /* SHA-512 */
132 ctx->state[0] = UL64(0x6A09E667F3BCC908);
133 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
134 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
135 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
136 ctx->state[4] = UL64(0x510E527FADE682D1);
137 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
138 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
139 ctx->state[7] = UL64(0x5BE0CD19137E2179);
140 }
141 else
142 {
143 /* SHA-384 */
144 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
145 ctx->state[1] = UL64(0x629A292A367CD507);
146 ctx->state[2] = UL64(0x9159015A3070DD17);
147 ctx->state[3] = UL64(0x152FECD8F70E5939);
148 ctx->state[4] = UL64(0x67332667FFC00B31);
149 ctx->state[5] = UL64(0x8EB44A8768581511);
150 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
151 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
152 }
153
154 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100155
156 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000157}
158
Jaeden Amero041039f2018-02-19 15:28:08 +0000159#if !defined(MBEDTLS_DEPRECATED_REMOVED)
160void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
161 int is384 )
162{
163 mbedtls_sha512_starts_ret( ctx, is384 );
164}
165#endif
166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200168
169/*
170 * Round constants
171 */
172static const uint64_t K[80] =
173{
174 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
175 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
176 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
177 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
178 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
179 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
180 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
181 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
182 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
183 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
184 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
185 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
186 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
187 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
188 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
189 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
190 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
191 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
192 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
193 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
194 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
195 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
196 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
197 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
198 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
199 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
200 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
201 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
202 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
203 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
204 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
205 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
206 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
207 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
208 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
209 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
210 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
211 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
212 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
213 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
214};
215
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100216int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
217 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000218{
219 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220 uint64_t temp1, temp2, W[80];
221 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000223 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
224 MBEDTLS_SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
225
Paul Bakker5121ce52009-01-03 21:22:43 +0000226#define SHR(x,n) (x >> n)
227#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
228
229#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
230#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
231
232#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
233#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
234
235#define F0(x,y,z) ((x & y) | (z & (x | y)))
236#define F1(x,y,z) (z ^ (x & (y ^ z)))
237
238#define P(a,b,c,d,e,f,g,h,x,K) \
239{ \
240 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
241 temp2 = S2(a) + F0(a,b,c); \
242 d += temp1; h = temp1 + temp2; \
243}
244
245 for( i = 0; i < 16; i++ )
246 {
247 GET_UINT64_BE( W[i], data, i << 3 );
248 }
249
250 for( ; i < 80; i++ )
251 {
252 W[i] = S1(W[i - 2]) + W[i - 7] +
253 S0(W[i - 15]) + W[i - 16];
254 }
255
256 A = ctx->state[0];
257 B = ctx->state[1];
258 C = ctx->state[2];
259 D = ctx->state[3];
260 E = ctx->state[4];
261 F = ctx->state[5];
262 G = ctx->state[6];
263 H = ctx->state[7];
264 i = 0;
265
266 do
267 {
268 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
269 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
270 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
271 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
272 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
273 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
274 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
275 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
276 }
277 while( i < 80 );
278
279 ctx->state[0] += A;
280 ctx->state[1] += B;
281 ctx->state[2] += C;
282 ctx->state[3] += D;
283 ctx->state[4] += E;
284 ctx->state[5] += F;
285 ctx->state[6] += G;
286 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100287
288 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289}
Jaeden Amero041039f2018-02-19 15:28:08 +0000290
291#if !defined(MBEDTLS_DEPRECATED_REMOVED)
292void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
293 const unsigned char data[128] )
294{
295 mbedtls_internal_sha512_process( ctx, data );
296}
297#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
300/*
301 * SHA-512 process buffer
302 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100303int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100304 const unsigned char *input,
305 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000306{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100307 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000308 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000309 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
Brian White12895d12014-04-11 11:29:42 -0400311 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100312 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000314 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
315 MBEDTLS_SHA512_VALIDATE_RET( input != NULL );
316
Paul Bakkerb8213a12011-07-11 08:16:18 +0000317 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000318 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
Paul Bakker5c2364c2012-10-01 14:41:15 +0000320 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000323 ctx->total[1]++;
324
325 if( left && ilen >= fill )
326 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200327 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100328
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100329 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100330 return( ret );
331
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 input += fill;
333 ilen -= fill;
334 left = 0;
335 }
336
337 while( ilen >= 128 )
338 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100339 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100340 return( ret );
341
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 input += 128;
343 ilen -= 128;
344 }
345
346 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200347 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100348
349 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350}
351
Jaeden Amero041039f2018-02-19 15:28:08 +0000352#if !defined(MBEDTLS_DEPRECATED_REMOVED)
353void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
354 const unsigned char *input,
355 size_t ilen )
356{
357 mbedtls_sha512_update_ret( ctx, input, ilen );
358}
359#endif
360
Paul Bakker5121ce52009-01-03 21:22:43 +0000361/*
362 * SHA-512 final digest
363 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100364int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100365 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100367 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200368 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000369 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000371 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
372 MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
373
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200374 /*
375 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
376 */
377 used = ctx->total[0] & 0x7F;
378
379 ctx->buffer[used++] = 0x80;
380
381 if( used <= 112 )
382 {
383 /* Enough room for padding + length in current block */
384 memset( ctx->buffer + used, 0, 112 - used );
385 }
386 else
387 {
388 /* We'll need an extra block */
389 memset( ctx->buffer + used, 0, 128 - used );
390
391 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
392 return( ret );
393
394 memset( ctx->buffer, 0, 112 );
395 }
396
397 /*
398 * Add message length
399 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000400 high = ( ctx->total[0] >> 61 )
401 | ( ctx->total[1] << 3 );
402 low = ( ctx->total[0] << 3 );
403
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200404 PUT_UINT64_BE( high, ctx->buffer, 112 );
405 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200407 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
408 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200410 /*
411 * Output final state
412 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 PUT_UINT64_BE( ctx->state[0], output, 0 );
414 PUT_UINT64_BE( ctx->state[1], output, 8 );
415 PUT_UINT64_BE( ctx->state[2], output, 16 );
416 PUT_UINT64_BE( ctx->state[3], output, 24 );
417 PUT_UINT64_BE( ctx->state[4], output, 32 );
418 PUT_UINT64_BE( ctx->state[5], output, 40 );
419
420 if( ctx->is384 == 0 )
421 {
422 PUT_UINT64_BE( ctx->state[6], output, 48 );
423 PUT_UINT64_BE( ctx->state[7], output, 56 );
424 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100425
426 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427}
428
Jaeden Amero041039f2018-02-19 15:28:08 +0000429#if !defined(MBEDTLS_DEPRECATED_REMOVED)
430void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
431 unsigned char output[64] )
432{
433 mbedtls_sha512_finish_ret( ctx, output );
434}
435#endif
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200438
Paul Bakker5121ce52009-01-03 21:22:43 +0000439/*
440 * output = SHA-512( input buffer )
441 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100442int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100443 size_t ilen,
444 unsigned char output[64],
445 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000446{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100447 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000450 MBEDTLS_SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
451 MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100454
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100455 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100456 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100457
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100458 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100459 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100460
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100461 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100462 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100463
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100464exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100467 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468}
469
Jaeden Amero041039f2018-02-19 15:28:08 +0000470#if !defined(MBEDTLS_DEPRECATED_REMOVED)
471void mbedtls_sha512( const unsigned char *input,
472 size_t ilen,
473 unsigned char output[64],
474 int is384 )
475{
476 mbedtls_sha512_ret( input, ilen, output, is384 );
477}
478#endif
479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
482/*
483 * FIPS-180-2 test vectors
484 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000485static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000486{
487 { "abc" },
488 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
489 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
490 { "" }
491};
492
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100493static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000494{
495 3, 112, 1000
496};
497
Paul Bakker9e36f042013-06-30 14:34:05 +0200498static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000499{
500 /*
501 * SHA-384 test vectors
502 */
503 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
504 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
505 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
506 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
507 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
508 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
509 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
510 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
511 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
512 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
513 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
514 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
515 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
516 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
517 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
518 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
519 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
520 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
521
522 /*
523 * SHA-512 test vectors
524 */
525 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
526 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
527 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
528 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
529 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
530 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
531 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
532 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
533 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
534 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
535 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
536 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
537 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
538 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
539 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
540 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
541 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
542 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
543 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
544 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
545 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
546 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
547 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
548 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
549};
550
551/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 * Checkup routine
553 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000555{
Paul Bakker5b4af392014-06-26 12:09:34 +0200556 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500557 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200558 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
Russ Butlerbb83b422016-10-12 17:36:50 -0500561 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
562 if( NULL == buf )
563 {
564 if( verbose != 0 )
565 mbedtls_printf( "Buffer allocation failed\n" );
566
567 return( 1 );
568 }
569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200571
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 for( i = 0; i < 6; i++ )
573 {
574 j = i % 3;
575 k = i < 3;
576
577 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100580 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100581 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 if( j == 2 )
584 {
585 memset( buf, 'a', buflen = 1000 );
586
587 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100588 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100589 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100590 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100591 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100592 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 }
594 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100595 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100596 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100597 sha512_test_buflen[j] );
598 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100599 goto fail;
600 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100602 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100603 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Paul Bakker9e36f042013-06-30 14:34:05 +0200605 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100606 {
607 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100608 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100609 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
611 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 }
614
615 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100618 goto exit;
619
620fail:
621 if( verbose != 0 )
622 mbedtls_printf( "failed\n" );
623
Paul Bakker5b4af392014-06-26 12:09:34 +0200624exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500626 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200627
628 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000629}
630
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#endif /* MBEDTLS_SHA512_C */