blob: fdd4ec9d78f6041d242d35129696b6b84e27bff0 [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;
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200238 struct
239 {
240 uint64_t temp1, temp2, W[80];
241 uint64_t A, B, C, D, E, F, G, H;
242 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
244#define SHR(x,n) (x >> n)
245#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
246
247#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
248#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
249
250#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
251#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
252
253#define F0(x,y,z) ((x & y) | (z & (x | y)))
254#define F1(x,y,z) (z ^ (x & (y ^ z)))
255
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200256#define P(a,b,c,d,e,f,g,h,x,K) \
257{ \
258 local.temp1 = h + S3(e) + F1(e,f,g) + K + x; \
259 local.temp2 = S2(a) + F0(a,b,c); \
260 d += local.temp1; h = local.temp1 + local.temp2; \
Paul Bakker5121ce52009-01-03 21:22:43 +0000261}
262
263 for( i = 0; i < 16; i++ )
264 {
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200265 GET_UINT64_BE( local.W[i], data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000266 }
267
268 for( ; i < 80; i++ )
269 {
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200270 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
271 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 }
273
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200274 local.A = ctx->state[0];
275 local.B = ctx->state[1];
276 local.C = ctx->state[2];
277 local.D = ctx->state[3];
278 local.E = ctx->state[4];
279 local.F = ctx->state[5];
280 local.G = ctx->state[6];
281 local.H = ctx->state[7];
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 i = 0;
283
284 do
285 {
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200286 P( local.A, local.B, local.C, local.D, local.E,
287 local.F, local.G, local.H, local.W[i], K[i] ); i++;
288 P( local.H, local.A, local.B, local.C, local.D,
289 local.E, local.F, local.G, local.W[i], K[i] ); i++;
290 P( local.G, local.H, local.A, local.B, local.C,
291 local.D, local.E, local.F, local.W[i], K[i] ); i++;
292 P( local.F, local.G, local.H, local.A, local.B,
293 local.C, local.D, local.E, local.W[i], K[i] ); i++;
294 P( local.E, local.F, local.G, local.H, local.A,
295 local.B, local.C, local.D, local.W[i], K[i] ); i++;
296 P( local.D, local.E, local.F, local.G, local.H,
297 local.A, local.B, local.C, local.W[i], K[i] ); i++;
298 P( local.C, local.D, local.E, local.F, local.G,
299 local.H, local.A, local.B, local.W[i], K[i] ); i++;
300 P( local.B, local.C, local.D, local.E, local.F,
301 local.G, local.H, local.A, local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 }
303 while( i < 80 );
304
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200305 ctx->state[0] += local.A;
306 ctx->state[1] += local.B;
307 ctx->state[2] += local.C;
308 ctx->state[3] += local.D;
309 ctx->state[4] += local.E;
310 ctx->state[5] += local.F;
311 ctx->state[6] += local.G;
312 ctx->state[7] += local.H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100313
gabor-mezei-arm461c5a82020-07-30 16:41:25 +0200314 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-armbfdbd432020-08-25 19:12:01 +0200315 mbedtls_zeroize( &local, sizeof( local ) );
gabor-mezei-arm461c5a82020-07-30 16:41:25 +0200316
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100317 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000319
320#if !defined(MBEDTLS_DEPRECATED_REMOVED)
321void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
322 const unsigned char data[128] )
323{
324 mbedtls_internal_sha512_process( ctx, data );
325}
326#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329/*
330 * SHA-512 process buffer
331 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100332int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100333 const unsigned char *input,
334 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000335{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100336 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000337 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000338 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Brian White12895d12014-04-11 11:29:42 -0400340 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100341 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Paul Bakkerb8213a12011-07-11 08:16:18 +0000343 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000344 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 ctx->total[1]++;
350
351 if( left && ilen >= fill )
352 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200353 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100354
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100355 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100356 return( ret );
357
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 input += fill;
359 ilen -= fill;
360 left = 0;
361 }
362
363 while( ilen >= 128 )
364 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100365 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100366 return( ret );
367
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 input += 128;
369 ilen -= 128;
370 }
371
372 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200373 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100374
375 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376}
377
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000378#if !defined(MBEDTLS_DEPRECATED_REMOVED)
379void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
380 const unsigned char *input,
381 size_t ilen )
382{
383 mbedtls_sha512_update_ret( ctx, input, ilen );
384}
385#endif
386
Paul Bakker5121ce52009-01-03 21:22:43 +0000387/*
388 * SHA-512 final digest
389 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100390int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100391 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000392{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100393 int ret;
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200394 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200397 /*
398 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
399 */
400 used = ctx->total[0] & 0x7F;
401
402 ctx->buffer[used++] = 0x80;
403
404 if( used <= 112 )
405 {
406 /* Enough room for padding + length in current block */
407 memset( ctx->buffer + used, 0, 112 - used );
408 }
409 else
410 {
411 /* We'll need an extra block */
412 memset( ctx->buffer + used, 0, 128 - used );
413
414 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
415 return( ret );
416
417 memset( ctx->buffer, 0, 112 );
418 }
419
420 /*
421 * Add message length
422 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 high = ( ctx->total[0] >> 61 )
424 | ( ctx->total[1] << 3 );
425 low = ( ctx->total[0] << 3 );
426
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200427 PUT_UINT64_BE( high, ctx->buffer, 112 );
428 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200430 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
431 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200433 /*
434 * Output final state
435 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 PUT_UINT64_BE( ctx->state[0], output, 0 );
437 PUT_UINT64_BE( ctx->state[1], output, 8 );
438 PUT_UINT64_BE( ctx->state[2], output, 16 );
439 PUT_UINT64_BE( ctx->state[3], output, 24 );
440 PUT_UINT64_BE( ctx->state[4], output, 32 );
441 PUT_UINT64_BE( ctx->state[5], output, 40 );
442
443 if( ctx->is384 == 0 )
444 {
445 PUT_UINT64_BE( ctx->state[6], output, 48 );
446 PUT_UINT64_BE( ctx->state[7], output, 56 );
447 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100448
449 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450}
451
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000452#if !defined(MBEDTLS_DEPRECATED_REMOVED)
453void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
454 unsigned char output[64] )
455{
456 mbedtls_sha512_finish_ret( ctx, output );
457}
458#endif
459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200461
Paul Bakker5121ce52009-01-03 21:22:43 +0000462/*
463 * output = SHA-512( input buffer )
464 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100465int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466 size_t ilen,
467 unsigned char output[64],
468 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000469{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100470 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100474
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100475 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100476 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100477
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100478 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100479 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100480
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100481 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100482 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100483
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100484exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100486
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100487 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
489
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000490#if !defined(MBEDTLS_DEPRECATED_REMOVED)
491void mbedtls_sha512( const unsigned char *input,
492 size_t ilen,
493 unsigned char output[64],
494 int is384 )
495{
496 mbedtls_sha512_ret( input, ilen, output, is384 );
497}
498#endif
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
502/*
503 * FIPS-180-2 test vectors
504 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000505static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000506{
507 { "abc" },
508 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
509 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
510 { "" }
511};
512
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100513static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
515 3, 112, 1000
516};
517
Paul Bakker9e36f042013-06-30 14:34:05 +0200518static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000519{
520 /*
521 * SHA-384 test vectors
522 */
523 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
524 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
525 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
526 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
527 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
528 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
529 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
530 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
531 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
532 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
533 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
534 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
535 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
536 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
537 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
538 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
539 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
540 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
541
542 /*
543 * SHA-512 test vectors
544 */
545 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
546 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
547 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
548 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
549 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
550 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
551 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
552 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
553 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
554 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
555 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
556 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
557 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
558 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
559 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
560 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
561 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
562 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
563 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
564 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
565 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
566 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
567 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
568 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
569};
570
571/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 * Checkup routine
573 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000575{
Paul Bakker5b4af392014-06-26 12:09:34 +0200576 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500577 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200578 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Russ Butlerbb83b422016-10-12 17:36:50 -0500581 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
582 if( NULL == buf )
583 {
584 if( verbose != 0 )
585 mbedtls_printf( "Buffer allocation failed\n" );
586
587 return( 1 );
588 }
589
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200591
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 for( i = 0; i < 6; i++ )
593 {
594 j = i % 3;
595 k = i < 3;
596
597 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100600 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100601 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
603 if( j == 2 )
604 {
605 memset( buf, 'a', buflen = 1000 );
606
607 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100608 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100609 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100610 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100611 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100612 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 }
614 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100615 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100616 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100617 sha512_test_buflen[j] );
618 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100619 goto fail;
620 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100622 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100623 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Paul Bakker9e36f042013-06-30 14:34:05 +0200625 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100626 {
627 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100628 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
635 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100638 goto exit;
639
640fail:
641 if( verbose != 0 )
642 mbedtls_printf( "failed\n" );
643
Paul Bakker5b4af392014-06-26 12:09:34 +0200644exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500646 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200647
648 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649}
650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#endif /* MBEDTLS_SHA512_C */