blob: 986037ab7c95853e20b54ad8dca691b6ce24d837 [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;
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200246 struct
247 {
248 uint64_t temp1, temp2, W[80];
249 uint64_t A, B, C, D, E, F, G, H;
250 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
Hanno Becker38e15d42018-12-18 17:54:00 +0000252 SHA512_VALIDATE_RET( ctx != NULL );
253 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000254
Hanno Beckerd6028a12018-10-15 12:01:35 +0100255#define SHR(x,n) ((x) >> (n))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000256#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
259#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
260
261#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
262#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
263
Hanno Beckerd6028a12018-10-15 12:01:35 +0100264#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
265#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200267#define P(a,b,c,d,e,f,g,h,x,K) \
268 do \
269 { \
270 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
271 local.temp2 = S2(a) + F0((a),(b),(c)); \
272 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100273 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000274
275 for( i = 0; i < 16; i++ )
276 {
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200277 GET_UINT64_BE( local.W[i], data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 }
279
280 for( ; i < 80; i++ )
281 {
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200282 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
283 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 }
285
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200286 local.A = ctx->state[0];
287 local.B = ctx->state[1];
288 local.C = ctx->state[2];
289 local.D = ctx->state[3];
290 local.E = ctx->state[4];
291 local.F = ctx->state[5];
292 local.G = ctx->state[6];
293 local.H = ctx->state[7];
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 i = 0;
295
296 do
297 {
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200298 P( local.A, local.B, local.C, local.D, local.E,
299 local.F, local.G, local.H, local.W[i], K[i] ); i++;
300 P( local.H, local.A, local.B, local.C, local.D,
301 local.E, local.F, local.G, local.W[i], K[i] ); i++;
302 P( local.G, local.H, local.A, local.B, local.C,
303 local.D, local.E, local.F, local.W[i], K[i] ); i++;
304 P( local.F, local.G, local.H, local.A, local.B,
305 local.C, local.D, local.E, local.W[i], K[i] ); i++;
306 P( local.E, local.F, local.G, local.H, local.A,
307 local.B, local.C, local.D, local.W[i], K[i] ); i++;
308 P( local.D, local.E, local.F, local.G, local.H,
309 local.A, local.B, local.C, local.W[i], K[i] ); i++;
310 P( local.C, local.D, local.E, local.F, local.G,
311 local.H, local.A, local.B, local.W[i], K[i] ); i++;
312 P( local.B, local.C, local.D, local.E, local.F,
313 local.G, local.H, local.A, local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000314 }
315 while( i < 80 );
316
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200317 ctx->state[0] += local.A;
318 ctx->state[1] += local.B;
319 ctx->state[2] += local.C;
320 ctx->state[3] += local.D;
321 ctx->state[4] += local.E;
322 ctx->state[5] += local.F;
323 ctx->state[6] += local.G;
324 ctx->state[7] += local.H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100325
gabor-mezei-armd5253bb2020-07-30 16:41:25 +0200326 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm70f7f672020-08-25 19:12:01 +0200327 mbedtls_platform_zeroize( &local, sizeof( local ) );
gabor-mezei-armd5253bb2020-07-30 16:41:25 +0200328
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100329 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330}
Jaeden Amero041039f2018-02-19 15:28:08 +0000331
332#if !defined(MBEDTLS_DEPRECATED_REMOVED)
333void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
334 const unsigned char data[128] )
335{
336 mbedtls_internal_sha512_process( ctx, data );
337}
338#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * SHA-512 process buffer
343 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100344int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100345 const unsigned char *input,
346 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000347{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100348 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000349 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000350 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
Hanno Becker38e15d42018-12-18 17:54:00 +0000352 SHA512_VALIDATE_RET( ctx != NULL );
353 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000354
Brian White12895d12014-04-11 11:29:42 -0400355 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100356 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Paul Bakkerb8213a12011-07-11 08:16:18 +0000358 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000359 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
Paul Bakker5c2364c2012-10-01 14:41:15 +0000361 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Paul Bakker5c2364c2012-10-01 14:41:15 +0000363 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000364 ctx->total[1]++;
365
366 if( left && ilen >= fill )
367 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200368 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100369
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100370 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100371 return( ret );
372
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 input += fill;
374 ilen -= fill;
375 left = 0;
376 }
377
378 while( ilen >= 128 )
379 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100380 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100381 return( ret );
382
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 input += 128;
384 ilen -= 128;
385 }
386
387 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200388 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100389
390 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391}
392
Jaeden Amero041039f2018-02-19 15:28:08 +0000393#if !defined(MBEDTLS_DEPRECATED_REMOVED)
394void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
395 const unsigned char *input,
396 size_t ilen )
397{
398 mbedtls_sha512_update_ret( ctx, input, ilen );
399}
400#endif
401
Paul Bakker5121ce52009-01-03 21:22:43 +0000402/*
403 * SHA-512 final digest
404 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100405int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100406 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000407{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100408 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200409 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000410 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Hanno Becker38e15d42018-12-18 17:54:00 +0000412 SHA512_VALIDATE_RET( ctx != NULL );
413 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000414
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200415 /*
416 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
417 */
418 used = ctx->total[0] & 0x7F;
419
420 ctx->buffer[used++] = 0x80;
421
422 if( used <= 112 )
423 {
424 /* Enough room for padding + length in current block */
425 memset( ctx->buffer + used, 0, 112 - used );
426 }
427 else
428 {
429 /* We'll need an extra block */
430 memset( ctx->buffer + used, 0, 128 - used );
431
432 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
433 return( ret );
434
435 memset( ctx->buffer, 0, 112 );
436 }
437
438 /*
439 * Add message length
440 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 high = ( ctx->total[0] >> 61 )
442 | ( ctx->total[1] << 3 );
443 low = ( ctx->total[0] << 3 );
444
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200445 PUT_UINT64_BE( high, ctx->buffer, 112 );
446 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200448 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
449 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200451 /*
452 * Output final state
453 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 PUT_UINT64_BE( ctx->state[0], output, 0 );
455 PUT_UINT64_BE( ctx->state[1], output, 8 );
456 PUT_UINT64_BE( ctx->state[2], output, 16 );
457 PUT_UINT64_BE( ctx->state[3], output, 24 );
458 PUT_UINT64_BE( ctx->state[4], output, 32 );
459 PUT_UINT64_BE( ctx->state[5], output, 40 );
460
461 if( ctx->is384 == 0 )
462 {
463 PUT_UINT64_BE( ctx->state[6], output, 48 );
464 PUT_UINT64_BE( ctx->state[7], output, 56 );
465 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466
467 return( 0 );
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_finish( mbedtls_sha512_context *ctx,
472 unsigned char output[64] )
473{
474 mbedtls_sha512_finish_ret( ctx, output );
475}
476#endif
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200479
Paul Bakker5121ce52009-01-03 21:22:43 +0000480/*
481 * output = SHA-512( input buffer )
482 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100483int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100484 size_t ilen,
485 unsigned char output[64],
486 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100488 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
Hanno Becker38e15d42018-12-18 17:54:00 +0000491 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
492 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
493 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100496
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100497 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100498 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100499
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100500 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100501 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100502
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100503 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100504 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100505
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100506exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100508
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100509 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000510}
511
Jaeden Amero041039f2018-02-19 15:28:08 +0000512#if !defined(MBEDTLS_DEPRECATED_REMOVED)
513void mbedtls_sha512( const unsigned char *input,
514 size_t ilen,
515 unsigned char output[64],
516 int is384 )
517{
518 mbedtls_sha512_ret( input, ilen, output, is384 );
519}
520#endif
521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524/*
525 * FIPS-180-2 test vectors
526 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000527static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000528{
529 { "abc" },
530 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
531 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
532 { "" }
533};
534
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100535static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000536{
537 3, 112, 1000
538};
539
Paul Bakker9e36f042013-06-30 14:34:05 +0200540static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000541{
542 /*
543 * SHA-384 test vectors
544 */
545 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
546 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
547 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
548 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
549 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
550 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
551 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
552 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
553 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
554 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
555 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
556 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
557 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
558 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
559 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
560 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
561 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
562 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
563
564 /*
565 * SHA-512 test vectors
566 */
567 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
568 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
569 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
570 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
571 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
572 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
573 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
574 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
575 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
576 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
577 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
578 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
579 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
580 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
581 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
582 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
583 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
584 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
585 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
586 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
587 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
588 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
589 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
590 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
591};
592
593/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000594 * Checkup routine
595 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker5b4af392014-06-26 12:09:34 +0200598 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500599 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200600 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
Russ Butlerbb83b422016-10-12 17:36:50 -0500603 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
604 if( NULL == buf )
605 {
606 if( verbose != 0 )
607 mbedtls_printf( "Buffer allocation failed\n" );
608
609 return( 1 );
610 }
611
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200613
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 for( i = 0; i < 6; i++ )
615 {
616 j = i % 3;
617 k = i < 3;
618
619 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100622 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100623 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625 if( j == 2 )
626 {
627 memset( buf, 'a', buflen = 1000 );
628
629 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100630 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100631 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100632 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100633 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100634 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100637 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100638 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100639 sha512_test_buflen[j] );
640 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100641 goto fail;
642 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100644 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100645 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Paul Bakker9e36f042013-06-30 14:34:05 +0200647 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100648 {
649 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100650 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100651 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
653 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 }
656
657 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100660 goto exit;
661
662fail:
663 if( verbose != 0 )
664 mbedtls_printf( "failed\n" );
665
Paul Bakker5b4af392014-06-26 12:09:34 +0200666exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500668 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200669
670 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671}
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675#endif /* MBEDTLS_SHA512_C */