blob: 8260f32a65c5d020eeea0d0c8bc63340c699c28f [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) \
Hanno Beckerca6f4582018-12-18 15:37:22 +000092 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
93#define MBEDTLS_SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
Andres Amaya Garciaba519b92018-12-09 20:58:36 +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{
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 );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000125 MBEDTLS_SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000126
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 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;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100156
157 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000158}
159
Jaeden Amero041039f2018-02-19 15:28:08 +0000160#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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200169
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
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100217int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
218 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219{
220 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000221 uint64_t temp1, temp2, W[80];
222 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000223
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000224 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
225 MBEDTLS_SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
226
Paul Bakker5121ce52009-01-03 21:22:43 +0000227#define SHR(x,n) (x >> n)
228#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
229
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
236#define F0(x,y,z) ((x & y) | (z & (x | y)))
237#define F1(x,y,z) (z ^ (x & (y ^ z)))
238
239#define P(a,b,c,d,e,f,g,h,x,K) \
240{ \
241 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
242 temp2 = S2(a) + F0(a,b,c); \
243 d += temp1; h = temp1 + temp2; \
244}
245
246 for( i = 0; i < 16; i++ )
247 {
248 GET_UINT64_BE( W[i], data, i << 3 );
249 }
250
251 for( ; i < 80; i++ )
252 {
253 W[i] = S1(W[i - 2]) + W[i - 7] +
254 S0(W[i - 15]) + W[i - 16];
255 }
256
257 A = ctx->state[0];
258 B = ctx->state[1];
259 C = ctx->state[2];
260 D = ctx->state[3];
261 E = ctx->state[4];
262 F = ctx->state[5];
263 G = ctx->state[6];
264 H = ctx->state[7];
265 i = 0;
266
267 do
268 {
269 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
270 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
271 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
272 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
273 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
274 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
275 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
276 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
277 }
278 while( i < 80 );
279
280 ctx->state[0] += A;
281 ctx->state[1] += B;
282 ctx->state[2] += C;
283 ctx->state[3] += D;
284 ctx->state[4] += E;
285 ctx->state[5] += F;
286 ctx->state[6] += G;
287 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100288
289 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000290}
Jaeden Amero041039f2018-02-19 15:28:08 +0000291
292#if !defined(MBEDTLS_DEPRECATED_REMOVED)
293void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
294 const unsigned char data[128] )
295{
296 mbedtls_internal_sha512_process( ctx, data );
297}
298#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301/*
302 * SHA-512 process buffer
303 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100304int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100305 const unsigned char *input,
306 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000307{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100308 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000309 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000310 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
Hanno Beckerca6f4582018-12-18 15:37:22 +0000312 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
313 MBEDTLS_SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
314
Brian White12895d12014-04-11 11:29:42 -0400315 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100316 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
Paul Bakkerb8213a12011-07-11 08:16:18 +0000318 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000319 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 ctx->total[1]++;
325
326 if( left && ilen >= fill )
327 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200328 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100329
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100330 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100331 return( ret );
332
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 input += fill;
334 ilen -= fill;
335 left = 0;
336 }
337
338 while( ilen >= 128 )
339 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100340 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100341 return( ret );
342
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 input += 128;
344 ilen -= 128;
345 }
346
347 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200348 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100349
350 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351}
352
Jaeden Amero041039f2018-02-19 15:28:08 +0000353#if !defined(MBEDTLS_DEPRECATED_REMOVED)
354void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
355 const unsigned char *input,
356 size_t ilen )
357{
358 mbedtls_sha512_update_ret( ctx, input, ilen );
359}
360#endif
361
Paul Bakker5121ce52009-01-03 21:22:43 +0000362/*
363 * SHA-512 final digest
364 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100365int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100366 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100368 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200369 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000370 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000372 MBEDTLS_SHA512_VALIDATE_RET( ctx != NULL );
373 MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
374
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200375 /*
376 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
377 */
378 used = ctx->total[0] & 0x7F;
379
380 ctx->buffer[used++] = 0x80;
381
382 if( used <= 112 )
383 {
384 /* Enough room for padding + length in current block */
385 memset( ctx->buffer + used, 0, 112 - used );
386 }
387 else
388 {
389 /* We'll need an extra block */
390 memset( ctx->buffer + used, 0, 128 - used );
391
392 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
393 return( ret );
394
395 memset( ctx->buffer, 0, 112 );
396 }
397
398 /*
399 * Add message length
400 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 high = ( ctx->total[0] >> 61 )
402 | ( ctx->total[1] << 3 );
403 low = ( ctx->total[0] << 3 );
404
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200405 PUT_UINT64_BE( high, ctx->buffer, 112 );
406 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200408 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
409 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200411 /*
412 * Output final state
413 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 PUT_UINT64_BE( ctx->state[0], output, 0 );
415 PUT_UINT64_BE( ctx->state[1], output, 8 );
416 PUT_UINT64_BE( ctx->state[2], output, 16 );
417 PUT_UINT64_BE( ctx->state[3], output, 24 );
418 PUT_UINT64_BE( ctx->state[4], output, 32 );
419 PUT_UINT64_BE( ctx->state[5], output, 40 );
420
421 if( ctx->is384 == 0 )
422 {
423 PUT_UINT64_BE( ctx->state[6], output, 48 );
424 PUT_UINT64_BE( ctx->state[7], output, 56 );
425 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100426
427 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428}
429
Jaeden Amero041039f2018-02-19 15:28:08 +0000430#if !defined(MBEDTLS_DEPRECATED_REMOVED)
431void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
432 unsigned char output[64] )
433{
434 mbedtls_sha512_finish_ret( ctx, output );
435}
436#endif
437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200439
Paul Bakker5121ce52009-01-03 21:22:43 +0000440/*
441 * output = SHA-512( input buffer )
442 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100443int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100444 size_t ilen,
445 unsigned char output[64],
446 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000447{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100448 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Hanno Beckerca6f4582018-12-18 15:37:22 +0000451 MBEDTLS_SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000452 MBEDTLS_SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
453 MBEDTLS_SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100456
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100457 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100458 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100459
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100460 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100461 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100462
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100463 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100464 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100465
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100466exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100468
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100469 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470}
471
Jaeden Amero041039f2018-02-19 15:28:08 +0000472#if !defined(MBEDTLS_DEPRECATED_REMOVED)
473void mbedtls_sha512( const unsigned char *input,
474 size_t ilen,
475 unsigned char output[64],
476 int is384 )
477{
478 mbedtls_sha512_ret( input, ilen, output, is384 );
479}
480#endif
481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484/*
485 * FIPS-180-2 test vectors
486 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000487static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000488{
489 { "abc" },
490 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
491 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
492 { "" }
493};
494
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100495static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000496{
497 3, 112, 1000
498};
499
Paul Bakker9e36f042013-06-30 14:34:05 +0200500static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000501{
502 /*
503 * SHA-384 test vectors
504 */
505 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
506 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
507 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
508 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
509 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
510 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
511 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
512 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
513 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
514 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
515 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
516 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
517 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
518 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
519 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
520 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
521 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
522 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
523
524 /*
525 * SHA-512 test vectors
526 */
527 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
528 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
529 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
530 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
531 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
532 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
533 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
534 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
535 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
536 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
537 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
538 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
539 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
540 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
541 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
542 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
543 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
544 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
545 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
546 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
547 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
548 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
549 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
550 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
551};
552
553/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000554 * Checkup routine
555 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000557{
Paul Bakker5b4af392014-06-26 12:09:34 +0200558 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500559 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200560 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
Russ Butlerbb83b422016-10-12 17:36:50 -0500563 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
564 if( NULL == buf )
565 {
566 if( verbose != 0 )
567 mbedtls_printf( "Buffer allocation failed\n" );
568
569 return( 1 );
570 }
571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200573
Paul Bakker5121ce52009-01-03 21:22:43 +0000574 for( i = 0; i < 6; i++ )
575 {
576 j = i % 3;
577 k = i < 3;
578
579 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100582 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100583 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 if( j == 2 )
586 {
587 memset( buf, 'a', buflen = 1000 );
588
589 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100590 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100591 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100592 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100593 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100594 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 }
596 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100597 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100598 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100599 sha512_test_buflen[j] );
600 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100601 goto fail;
602 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100604 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100605 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Paul Bakker9e36f042013-06-30 14:34:05 +0200607 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100608 {
609 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100610 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100611 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 }
616
617 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100620 goto exit;
621
622fail:
623 if( verbose != 0 )
624 mbedtls_printf( "failed\n" );
625
Paul Bakker5b4af392014-06-26 12:09:34 +0200626exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500628 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200629
630 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000631}
632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635#endif /* MBEDTLS_SHA512_C */