blob: 9e9f07359247a22b0e96b87b4bbd0ff45ac36e9e [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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"
Paul Bakker5121ce52009-01-03 21:22:43 +000061
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000062#if defined(_MSC_VER) || defined(__WATCOMC__)
63 #define UL64(x) x##ui64
64#else
65 #define UL64(x) x##ULL
66#endif
67
Rich Evans00ab4702015-02-06 13:43:58 +000068#include <string.h>
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#if defined(MBEDTLS_SELF_TEST)
71#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000072#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010073#else
Rich Evans00ab4702015-02-06 13:43:58 +000074#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050075#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050077#define mbedtls_calloc calloc
78#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079#endif /* MBEDTLS_PLATFORM_C */
80#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010081
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020082#if !defined(MBEDTLS_SHA512_ALT)
83
Paul Bakker34617722014-06-13 17:20:13 +020084/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020086 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
87}
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{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200123}
124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200126{
127 if( ctx == NULL )
128 return;
129
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200130 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200131}
132
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200133void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
134 const mbedtls_sha512_context *src )
135{
136 *dst = *src;
137}
138
Paul Bakker5121ce52009-01-03 21:22:43 +0000139/*
140 * SHA-512 context setup
141 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100142int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000143{
144 ctx->total[0] = 0;
145 ctx->total[1] = 0;
146
147 if( is384 == 0 )
148 {
149 /* SHA-512 */
150 ctx->state[0] = UL64(0x6A09E667F3BCC908);
151 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
152 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
153 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
154 ctx->state[4] = UL64(0x510E527FADE682D1);
155 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
156 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
157 ctx->state[7] = UL64(0x5BE0CD19137E2179);
158 }
159 else
160 {
161 /* SHA-384 */
162 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
163 ctx->state[1] = UL64(0x629A292A367CD507);
164 ctx->state[2] = UL64(0x9159015A3070DD17);
165 ctx->state[3] = UL64(0x152FECD8F70E5939);
166 ctx->state[4] = UL64(0x67332667FFC00B31);
167 ctx->state[5] = UL64(0x8EB44A8768581511);
168 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
169 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
170 }
171
172 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100173
174 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000175}
176
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000177#if !defined(MBEDTLS_DEPRECATED_REMOVED)
178void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
179 int is384 )
180{
181 mbedtls_sha512_starts_ret( ctx, is384 );
182}
183#endif
184
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200186
187/*
188 * Round constants
189 */
190static const uint64_t K[80] =
191{
192 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
193 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
194 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
195 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
196 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
197 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
198 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
199 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
200 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
201 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
202 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
203 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
204 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
205 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
206 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
207 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
208 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
209 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
210 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
211 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
212 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
213 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
214 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
215 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
216 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
217 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
218 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
219 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
220 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
221 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
222 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
223 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
224 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
225 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
226 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
227 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
228 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
229 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
230 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
231 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
232};
233
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100234int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
235 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000236{
237 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000238 uint64_t temp1, temp2, W[80];
239 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
241#define SHR(x,n) (x >> n)
242#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
243
244#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
245#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
246
247#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
248#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
249
250#define F0(x,y,z) ((x & y) | (z & (x | y)))
251#define F1(x,y,z) (z ^ (x & (y ^ z)))
252
253#define P(a,b,c,d,e,f,g,h,x,K) \
254{ \
255 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
256 temp2 = S2(a) + F0(a,b,c); \
257 d += temp1; h = temp1 + temp2; \
258}
259
260 for( i = 0; i < 16; i++ )
261 {
262 GET_UINT64_BE( W[i], data, i << 3 );
263 }
264
265 for( ; i < 80; i++ )
266 {
267 W[i] = S1(W[i - 2]) + W[i - 7] +
268 S0(W[i - 15]) + W[i - 16];
269 }
270
271 A = ctx->state[0];
272 B = ctx->state[1];
273 C = ctx->state[2];
274 D = ctx->state[3];
275 E = ctx->state[4];
276 F = ctx->state[5];
277 G = ctx->state[6];
278 H = ctx->state[7];
279 i = 0;
280
281 do
282 {
283 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
284 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
285 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
286 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
287 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
288 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
289 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
290 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
291 }
292 while( i < 80 );
293
294 ctx->state[0] += A;
295 ctx->state[1] += B;
296 ctx->state[2] += C;
297 ctx->state[3] += D;
298 ctx->state[4] += E;
299 ctx->state[5] += F;
300 ctx->state[6] += G;
301 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100302
gabor-mezei-arm461c5a82020-07-30 16:41:25 +0200303 /* Zeroise buffers and variables to clear sensitive data from memory. */
304 mbedtls_zeroize( &A, sizeof( A ) );
305 mbedtls_zeroize( &B, sizeof( B ) );
306 mbedtls_zeroize( &C, sizeof( C ) );
307 mbedtls_zeroize( &D, sizeof( D ) );
308 mbedtls_zeroize( &E, sizeof( E ) );
309 mbedtls_zeroize( &F, sizeof( F ) );
310 mbedtls_zeroize( &G, sizeof( G ) );
311 mbedtls_zeroize( &H, sizeof( H ) );
312 mbedtls_zeroize( &W, sizeof( W ) );
313 mbedtls_zeroize( &temp1, sizeof( temp1 ) );
314 mbedtls_zeroize( &temp2, sizeof( temp2 ) );
315
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100316 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000318
319#if !defined(MBEDTLS_DEPRECATED_REMOVED)
320void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
321 const unsigned char data[128] )
322{
323 mbedtls_internal_sha512_process( ctx, data );
324}
325#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
328/*
329 * SHA-512 process buffer
330 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100331int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100332 const unsigned char *input,
333 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000334{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100335 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000336 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000337 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
Brian White12895d12014-04-11 11:29:42 -0400339 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100340 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
Paul Bakkerb8213a12011-07-11 08:16:18 +0000342 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000343 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 ctx->total[1]++;
349
350 if( left && ilen >= fill )
351 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200352 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100353
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100354 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100355 return( ret );
356
Paul Bakker5121ce52009-01-03 21:22:43 +0000357 input += fill;
358 ilen -= fill;
359 left = 0;
360 }
361
362 while( ilen >= 128 )
363 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100364 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100365 return( ret );
366
Paul Bakker5121ce52009-01-03 21:22:43 +0000367 input += 128;
368 ilen -= 128;
369 }
370
371 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200372 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100373
374 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375}
376
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000377#if !defined(MBEDTLS_DEPRECATED_REMOVED)
378void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
379 const unsigned char *input,
380 size_t ilen )
381{
382 mbedtls_sha512_update_ret( ctx, input, ilen );
383}
384#endif
385
Paul Bakker5121ce52009-01-03 21:22:43 +0000386/*
387 * SHA-512 final digest
388 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100389int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100390 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000391{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100392 int ret;
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200393 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000394 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200396 /*
397 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
398 */
399 used = ctx->total[0] & 0x7F;
400
401 ctx->buffer[used++] = 0x80;
402
403 if( used <= 112 )
404 {
405 /* Enough room for padding + length in current block */
406 memset( ctx->buffer + used, 0, 112 - used );
407 }
408 else
409 {
410 /* We'll need an extra block */
411 memset( ctx->buffer + used, 0, 128 - used );
412
413 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
414 return( ret );
415
416 memset( ctx->buffer, 0, 112 );
417 }
418
419 /*
420 * Add message length
421 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 high = ( ctx->total[0] >> 61 )
423 | ( ctx->total[1] << 3 );
424 low = ( ctx->total[0] << 3 );
425
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200426 PUT_UINT64_BE( high, ctx->buffer, 112 );
427 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200429 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
430 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200432 /*
433 * Output final state
434 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 PUT_UINT64_BE( ctx->state[0], output, 0 );
436 PUT_UINT64_BE( ctx->state[1], output, 8 );
437 PUT_UINT64_BE( ctx->state[2], output, 16 );
438 PUT_UINT64_BE( ctx->state[3], output, 24 );
439 PUT_UINT64_BE( ctx->state[4], output, 32 );
440 PUT_UINT64_BE( ctx->state[5], output, 40 );
441
442 if( ctx->is384 == 0 )
443 {
444 PUT_UINT64_BE( ctx->state[6], output, 48 );
445 PUT_UINT64_BE( ctx->state[7], output, 56 );
446 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100447
448 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449}
450
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000451#if !defined(MBEDTLS_DEPRECATED_REMOVED)
452void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
453 unsigned char output[64] )
454{
455 mbedtls_sha512_finish_ret( ctx, output );
456}
457#endif
458
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200460
Paul Bakker5121ce52009-01-03 21:22:43 +0000461/*
462 * output = SHA-512( input buffer )
463 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100464int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100465 size_t ilen,
466 unsigned char output[64],
467 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000468{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100469 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100473
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100474 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100475 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100476
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100477 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100478 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100479
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100480 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100481 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100482
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100483exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100485
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100486 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487}
488
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000489#if !defined(MBEDTLS_DEPRECATED_REMOVED)
490void mbedtls_sha512( const unsigned char *input,
491 size_t ilen,
492 unsigned char output[64],
493 int is384 )
494{
495 mbedtls_sha512_ret( input, ilen, output, is384 );
496}
497#endif
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
501/*
502 * FIPS-180-2 test vectors
503 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000504static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
506 { "abc" },
507 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
508 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
509 { "" }
510};
511
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100512static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000513{
514 3, 112, 1000
515};
516
Paul Bakker9e36f042013-06-30 14:34:05 +0200517static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000518{
519 /*
520 * SHA-384 test vectors
521 */
522 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
523 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
524 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
525 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
526 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
527 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
528 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
529 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
530 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
531 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
532 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
533 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
534 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
535 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
536 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
537 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
538 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
539 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
540
541 /*
542 * SHA-512 test vectors
543 */
544 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
545 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
546 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
547 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
548 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
549 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
550 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
551 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
552 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
553 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
554 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
555 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
556 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
557 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
558 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
559 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
560 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
561 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
562 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
563 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
564 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
565 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
566 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
567 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
568};
569
570/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 * Checkup routine
572 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000574{
Paul Bakker5b4af392014-06-26 12:09:34 +0200575 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500576 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200577 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Russ Butlerbb83b422016-10-12 17:36:50 -0500580 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
581 if( NULL == buf )
582 {
583 if( verbose != 0 )
584 mbedtls_printf( "Buffer allocation failed\n" );
585
586 return( 1 );
587 }
588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 for( i = 0; i < 6; i++ )
592 {
593 j = i % 3;
594 k = i < 3;
595
596 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100599 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100600 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
602 if( j == 2 )
603 {
604 memset( buf, 'a', buflen = 1000 );
605
606 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100607 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100608 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100609 if( ret != 0 )
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 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100614 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100615 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100616 sha512_test_buflen[j] );
617 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100618 goto fail;
619 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100621 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100622 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Paul Bakker9e36f042013-06-30 14:34:05 +0200624 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100625 {
626 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100627 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100628 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
630 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 }
633
634 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100637 goto exit;
638
639fail:
640 if( verbose != 0 )
641 mbedtls_printf( "failed\n" );
642
Paul Bakker5b4af392014-06-26 12:09:34 +0200643exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500645 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200646
647 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000648}
649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#endif /* MBEDTLS_SHA512_C */