blob: 37a01dd7bd4d809aca45111da1059032eab7f632 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker5121ce52009-01-03 21:22:43 +000045 */
46/*
47 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
48 *
49 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
50 */
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000053#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020054#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000060#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050061#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000063#if defined(_MSC_VER) || defined(__WATCOMC__)
64 #define UL64(x) x##ui64
65#else
66 #define UL64(x) x##ULL
67#endif
68
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <string.h>
70
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#if defined(MBEDTLS_SELF_TEST)
72#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010074#else
Rich Evans00ab4702015-02-06 13:43:58 +000075#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050076#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050078#define mbedtls_calloc calloc
79#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080#endif /* MBEDTLS_PLATFORM_C */
81#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010082
Hanno Beckerc7560492018-12-20 10:23:39 +000083#define SHA512_VALIDATE_RET(cond) \
84 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
85#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
86
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020087#if !defined(MBEDTLS_SHA512_ALT)
88
Paul Bakker5121ce52009-01-03 21:22:43 +000089/*
90 * 64-bit integer manipulation macros (big endian)
91 */
92#ifndef GET_UINT64_BE
93#define GET_UINT64_BE(n,b,i) \
94{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000095 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
96 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
97 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
98 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
99 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
100 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
101 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
102 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000103}
Paul Bakker9af723c2014-05-01 13:03:14 +0200104#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000105
106#ifndef PUT_UINT64_BE
107#define PUT_UINT64_BE(n,b,i) \
108{ \
109 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
110 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
111 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
112 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
113 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
114 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
115 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
116 (b)[(i) + 7] = (unsigned char) ( (n) ); \
117}
Paul Bakker9af723c2014-05-01 13:03:14 +0200118#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200121{
Hanno Becker38e15d42018-12-18 17:54:00 +0000122 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200125}
126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200128{
129 if( ctx == NULL )
130 return;
131
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500132 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200133}
134
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200135void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
136 const mbedtls_sha512_context *src )
137{
Hanno Becker38e15d42018-12-18 17:54:00 +0000138 SHA512_VALIDATE( dst != NULL );
139 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000140
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200141 *dst = *src;
142}
143
Paul Bakker5121ce52009-01-03 21:22:43 +0000144/*
145 * SHA-512 context setup
146 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100147int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000148{
Hanno Becker38e15d42018-12-18 17:54:00 +0000149 SHA512_VALIDATE_RET( ctx != NULL );
150 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000151
Paul Bakker5121ce52009-01-03 21:22:43 +0000152 ctx->total[0] = 0;
153 ctx->total[1] = 0;
154
155 if( is384 == 0 )
156 {
157 /* SHA-512 */
158 ctx->state[0] = UL64(0x6A09E667F3BCC908);
159 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
160 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
161 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
162 ctx->state[4] = UL64(0x510E527FADE682D1);
163 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
164 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
165 ctx->state[7] = UL64(0x5BE0CD19137E2179);
166 }
167 else
168 {
169 /* SHA-384 */
170 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
171 ctx->state[1] = UL64(0x629A292A367CD507);
172 ctx->state[2] = UL64(0x9159015A3070DD17);
173 ctx->state[3] = UL64(0x152FECD8F70E5939);
174 ctx->state[4] = UL64(0x67332667FFC00B31);
175 ctx->state[5] = UL64(0x8EB44A8768581511);
176 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
177 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
178 }
179
180 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100181
182 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000183}
184
Jaeden Amero041039f2018-02-19 15:28:08 +0000185#if !defined(MBEDTLS_DEPRECATED_REMOVED)
186void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
187 int is384 )
188{
189 mbedtls_sha512_starts_ret( ctx, is384 );
190}
191#endif
192
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200194
195/*
196 * Round constants
197 */
198static const uint64_t K[80] =
199{
200 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
201 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
202 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
203 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
204 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
205 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
206 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
207 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
208 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
209 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
210 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
211 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
212 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
213 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
214 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
215 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
216 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
217 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
218 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
219 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
220 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
221 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
222 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
223 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
224 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
225 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
226 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
227 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
228 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
229 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
230 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
231 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
232 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
233 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
234 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
235 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
236 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
237 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
238 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
239 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
240};
241
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100242int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
243 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000244{
245 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000246 uint64_t temp1, temp2, W[80];
247 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
Hanno Becker38e15d42018-12-18 17:54:00 +0000249 SHA512_VALIDATE_RET( ctx != NULL );
250 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000251
Hanno Beckerd6028a12018-10-15 12:01:35 +0100252#define SHR(x,n) ((x) >> (n))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000253#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
256#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
257
258#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
259#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
260
Hanno Beckerd6028a12018-10-15 12:01:35 +0100261#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
262#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
Hanno Becker9306f1c2018-10-30 09:29:25 +0000264#define P(a,b,c,d,e,f,g,h,x,K) \
265 do \
266 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100267 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
268 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker9306f1c2018-10-30 09:29:25 +0000269 (d) += temp1; (h) = temp1 + temp2; \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100270 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
272 for( i = 0; i < 16; i++ )
273 {
274 GET_UINT64_BE( W[i], data, i << 3 );
275 }
276
277 for( ; i < 80; i++ )
278 {
279 W[i] = S1(W[i - 2]) + W[i - 7] +
280 S0(W[i - 15]) + W[i - 16];
281 }
282
283 A = ctx->state[0];
284 B = ctx->state[1];
285 C = ctx->state[2];
286 D = ctx->state[3];
287 E = ctx->state[4];
288 F = ctx->state[5];
289 G = ctx->state[6];
290 H = ctx->state[7];
291 i = 0;
292
293 do
294 {
295 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
296 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
297 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
298 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
299 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
300 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
301 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
302 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
303 }
304 while( i < 80 );
305
306 ctx->state[0] += A;
307 ctx->state[1] += B;
308 ctx->state[2] += C;
309 ctx->state[3] += D;
310 ctx->state[4] += E;
311 ctx->state[5] += F;
312 ctx->state[6] += G;
313 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100314
gabor-mezei-armd5253bb2020-07-30 16:41:25 +0200315 /* Zeroise buffers and variables to clear sensitive data from memory. */
316 mbedtls_platform_zeroize( &A, sizeof( A ) );
317 mbedtls_platform_zeroize( &B, sizeof( B ) );
318 mbedtls_platform_zeroize( &C, sizeof( C ) );
319 mbedtls_platform_zeroize( &D, sizeof( D ) );
320 mbedtls_platform_zeroize( &E, sizeof( E ) );
321 mbedtls_platform_zeroize( &F, sizeof( F ) );
322 mbedtls_platform_zeroize( &G, sizeof( G ) );
323 mbedtls_platform_zeroize( &H, sizeof( H ) );
324 mbedtls_platform_zeroize( &W, sizeof( W ) );
325 mbedtls_platform_zeroize( &temp1, sizeof( temp1 ) );
326 mbedtls_platform_zeroize( &temp2, sizeof( temp2 ) );
327
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100328 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329}
Jaeden Amero041039f2018-02-19 15:28:08 +0000330
331#if !defined(MBEDTLS_DEPRECATED_REMOVED)
332void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
333 const unsigned char data[128] )
334{
335 mbedtls_internal_sha512_process( ctx, data );
336}
337#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340/*
341 * SHA-512 process buffer
342 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100343int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100344 const unsigned char *input,
345 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000346{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100347 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000348 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000349 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
Hanno Becker38e15d42018-12-18 17:54:00 +0000351 SHA512_VALIDATE_RET( ctx != NULL );
352 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000353
Brian White12895d12014-04-11 11:29:42 -0400354 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100355 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
Paul Bakkerb8213a12011-07-11 08:16:18 +0000357 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000358 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
Paul Bakker5c2364c2012-10-01 14:41:15 +0000360 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Paul Bakker5c2364c2012-10-01 14:41:15 +0000362 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 ctx->total[1]++;
364
365 if( left && ilen >= fill )
366 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200367 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100368
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100369 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100370 return( ret );
371
Paul Bakker5121ce52009-01-03 21:22:43 +0000372 input += fill;
373 ilen -= fill;
374 left = 0;
375 }
376
377 while( ilen >= 128 )
378 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100379 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100380 return( ret );
381
Paul Bakker5121ce52009-01-03 21:22:43 +0000382 input += 128;
383 ilen -= 128;
384 }
385
386 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200387 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100388
389 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390}
391
Jaeden Amero041039f2018-02-19 15:28:08 +0000392#if !defined(MBEDTLS_DEPRECATED_REMOVED)
393void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
394 const unsigned char *input,
395 size_t ilen )
396{
397 mbedtls_sha512_update_ret( ctx, input, ilen );
398}
399#endif
400
Paul Bakker5121ce52009-01-03 21:22:43 +0000401/*
402 * SHA-512 final digest
403 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100404int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100405 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100407 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200408 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000409 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Hanno Becker38e15d42018-12-18 17:54:00 +0000411 SHA512_VALIDATE_RET( ctx != NULL );
412 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000413
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200414 /*
415 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
416 */
417 used = ctx->total[0] & 0x7F;
418
419 ctx->buffer[used++] = 0x80;
420
421 if( used <= 112 )
422 {
423 /* Enough room for padding + length in current block */
424 memset( ctx->buffer + used, 0, 112 - used );
425 }
426 else
427 {
428 /* We'll need an extra block */
429 memset( ctx->buffer + used, 0, 128 - used );
430
431 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
432 return( ret );
433
434 memset( ctx->buffer, 0, 112 );
435 }
436
437 /*
438 * Add message length
439 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 high = ( ctx->total[0] >> 61 )
441 | ( ctx->total[1] << 3 );
442 low = ( ctx->total[0] << 3 );
443
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200444 PUT_UINT64_BE( high, ctx->buffer, 112 );
445 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200447 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
448 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200450 /*
451 * Output final state
452 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 PUT_UINT64_BE( ctx->state[0], output, 0 );
454 PUT_UINT64_BE( ctx->state[1], output, 8 );
455 PUT_UINT64_BE( ctx->state[2], output, 16 );
456 PUT_UINT64_BE( ctx->state[3], output, 24 );
457 PUT_UINT64_BE( ctx->state[4], output, 32 );
458 PUT_UINT64_BE( ctx->state[5], output, 40 );
459
460 if( ctx->is384 == 0 )
461 {
462 PUT_UINT64_BE( ctx->state[6], output, 48 );
463 PUT_UINT64_BE( ctx->state[7], output, 56 );
464 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100465
466 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467}
468
Jaeden Amero041039f2018-02-19 15:28:08 +0000469#if !defined(MBEDTLS_DEPRECATED_REMOVED)
470void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
471 unsigned char output[64] )
472{
473 mbedtls_sha512_finish_ret( ctx, output );
474}
475#endif
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200478
Paul Bakker5121ce52009-01-03 21:22:43 +0000479/*
480 * output = SHA-512( input buffer )
481 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100482int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100483 size_t ilen,
484 unsigned char output[64],
485 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000486{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100487 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
Hanno Becker38e15d42018-12-18 17:54:00 +0000490 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
491 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
492 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100495
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100496 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100497 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100498
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100499 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100500 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100501
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100502 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100503 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100504
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100505exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100507
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100508 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509}
510
Jaeden Amero041039f2018-02-19 15:28:08 +0000511#if !defined(MBEDTLS_DEPRECATED_REMOVED)
512void mbedtls_sha512( const unsigned char *input,
513 size_t ilen,
514 unsigned char output[64],
515 int is384 )
516{
517 mbedtls_sha512_ret( input, ilen, output, is384 );
518}
519#endif
520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
523/*
524 * FIPS-180-2 test vectors
525 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000526static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000527{
528 { "abc" },
529 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
530 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
531 { "" }
532};
533
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100534static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000535{
536 3, 112, 1000
537};
538
Paul Bakker9e36f042013-06-30 14:34:05 +0200539static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000540{
541 /*
542 * SHA-384 test vectors
543 */
544 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
545 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
546 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
547 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
548 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
549 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
550 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
551 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
552 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
553 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
554 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
555 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
556 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
557 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
558 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
559 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
560 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
561 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
562
563 /*
564 * SHA-512 test vectors
565 */
566 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
567 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
568 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
569 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
570 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
571 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
572 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
573 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
574 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
575 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
576 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
577 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
578 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
579 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
580 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
581 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
582 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
583 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
584 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
585 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
586 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
587 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
588 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
589 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
590};
591
592/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 * Checkup routine
594 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000596{
Paul Bakker5b4af392014-06-26 12:09:34 +0200597 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500598 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200599 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Russ Butlerbb83b422016-10-12 17:36:50 -0500602 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
603 if( NULL == buf )
604 {
605 if( verbose != 0 )
606 mbedtls_printf( "Buffer allocation failed\n" );
607
608 return( 1 );
609 }
610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200612
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 for( i = 0; i < 6; i++ )
614 {
615 j = i % 3;
616 k = i < 3;
617
618 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100621 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100622 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
624 if( j == 2 )
625 {
626 memset( buf, 'a', buflen = 1000 );
627
628 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100630 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100631 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100632 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100633 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100636 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100637 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100638 sha512_test_buflen[j] );
639 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100640 goto fail;
641 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100643 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100644 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
Paul Bakker9e36f042013-06-30 14:34:05 +0200646 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100647 {
648 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100649 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100650 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 }
655
656 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100659 goto exit;
660
661fail:
662 if( verbose != 0 )
663 mbedtls_printf( "failed\n" );
664
Paul Bakker5b4af392014-06-26 12:09:34 +0200665exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500667 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200668
669 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000670}
671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#endif /* MBEDTLS_SHA512_C */