blob: fdcf360d3fc9d044d8ec1f258028f0763e1da697 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000047 */
48/*
49 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
50 *
51 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
52 */
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020058#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000061
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050063#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000065#if defined(_MSC_VER) || defined(__WATCOMC__)
66 #define UL64(x) x##ui64
67#else
68 #define UL64(x) x##ULL
69#endif
70
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <string.h>
72
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if defined(MBEDTLS_SELF_TEST)
74#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000075#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010076#else
Rich Evans00ab4702015-02-06 13:43:58 +000077#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050078#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050080#define mbedtls_calloc calloc
81#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082#endif /* MBEDTLS_PLATFORM_C */
83#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010084
Hanno Beckerc7560492018-12-20 10:23:39 +000085#define SHA512_VALIDATE_RET(cond) \
86 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
87#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
88
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020089#if !defined(MBEDTLS_SHA512_ALT)
90
Paul Bakker5121ce52009-01-03 21:22:43 +000091/*
92 * 64-bit integer manipulation macros (big endian)
93 */
94#ifndef GET_UINT64_BE
95#define GET_UINT64_BE(n,b,i) \
96{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000097 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
98 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
99 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
100 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
101 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
102 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
103 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
104 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000105}
Paul Bakker9af723c2014-05-01 13:03:14 +0200106#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108#ifndef PUT_UINT64_BE
109#define PUT_UINT64_BE(n,b,i) \
110{ \
111 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
112 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
113 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
114 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
115 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
116 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
117 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
118 (b)[(i) + 7] = (unsigned char) ( (n) ); \
119}
Paul Bakker9af723c2014-05-01 13:03:14 +0200120#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200123{
Hanno Becker38e15d42018-12-18 17:54:00 +0000124 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200127}
128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200130{
131 if( ctx == NULL )
132 return;
133
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500134 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200135}
136
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200137void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
138 const mbedtls_sha512_context *src )
139{
Hanno Becker38e15d42018-12-18 17:54:00 +0000140 SHA512_VALIDATE( dst != NULL );
141 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000142
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200143 *dst = *src;
144}
145
Paul Bakker5121ce52009-01-03 21:22:43 +0000146/*
147 * SHA-512 context setup
148 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100149int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
Hanno Becker38e15d42018-12-18 17:54:00 +0000151 SHA512_VALIDATE_RET( ctx != NULL );
152 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000153
Paul Bakker5121ce52009-01-03 21:22:43 +0000154 ctx->total[0] = 0;
155 ctx->total[1] = 0;
156
157 if( is384 == 0 )
158 {
159 /* SHA-512 */
160 ctx->state[0] = UL64(0x6A09E667F3BCC908);
161 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
162 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
163 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
164 ctx->state[4] = UL64(0x510E527FADE682D1);
165 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
166 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
167 ctx->state[7] = UL64(0x5BE0CD19137E2179);
168 }
169 else
170 {
171 /* SHA-384 */
172 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
173 ctx->state[1] = UL64(0x629A292A367CD507);
174 ctx->state[2] = UL64(0x9159015A3070DD17);
175 ctx->state[3] = UL64(0x152FECD8F70E5939);
176 ctx->state[4] = UL64(0x67332667FFC00B31);
177 ctx->state[5] = UL64(0x8EB44A8768581511);
178 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
179 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
180 }
181
182 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100183
184 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000185}
186
Jaeden Amero041039f2018-02-19 15:28:08 +0000187#if !defined(MBEDTLS_DEPRECATED_REMOVED)
188void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
189 int is384 )
190{
191 mbedtls_sha512_starts_ret( ctx, is384 );
192}
193#endif
194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200196
197/*
198 * Round constants
199 */
200static const uint64_t K[80] =
201{
202 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
203 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
204 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
205 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
206 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
207 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
208 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
209 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
210 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
211 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
212 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
213 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
214 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
215 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
216 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
217 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
218 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
219 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
220 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
221 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
222 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
223 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
224 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
225 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
226 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
227 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
228 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
229 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
230 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
231 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
232 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
233 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
234 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
235 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
236 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
237 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
238 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
239 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
240 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
241 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
242};
243
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100244int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
245 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000246{
247 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000248 uint64_t temp1, temp2, W[80];
249 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
Hanno Becker38e15d42018-12-18 17:54:00 +0000251 SHA512_VALIDATE_RET( ctx != NULL );
252 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000253
Hanno Beckerd6028a12018-10-15 12:01:35 +0100254#define SHR(x,n) ((x) >> (n))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000255#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
257#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
258#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
259
260#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
261#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
262
Hanno Beckerd6028a12018-10-15 12:01:35 +0100263#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
264#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
Hanno Becker9306f1c2018-10-30 09:29:25 +0000266#define P(a,b,c,d,e,f,g,h,x,K) \
267 do \
268 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100269 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
270 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker9306f1c2018-10-30 09:29:25 +0000271 (d) += temp1; (h) = temp1 + temp2; \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100272 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274 for( i = 0; i < 16; i++ )
275 {
276 GET_UINT64_BE( W[i], data, i << 3 );
277 }
278
279 for( ; i < 80; i++ )
280 {
281 W[i] = S1(W[i - 2]) + W[i - 7] +
282 S0(W[i - 15]) + W[i - 16];
283 }
284
285 A = ctx->state[0];
286 B = ctx->state[1];
287 C = ctx->state[2];
288 D = ctx->state[3];
289 E = ctx->state[4];
290 F = ctx->state[5];
291 G = ctx->state[6];
292 H = ctx->state[7];
293 i = 0;
294
295 do
296 {
297 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
298 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
299 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
300 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
301 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
302 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
303 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
304 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
305 }
306 while( i < 80 );
307
308 ctx->state[0] += A;
309 ctx->state[1] += B;
310 ctx->state[2] += C;
311 ctx->state[3] += D;
312 ctx->state[4] += E;
313 ctx->state[5] += F;
314 ctx->state[6] += G;
315 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100316
317 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318}
Jaeden Amero041039f2018-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
Hanno Becker38e15d42018-12-18 17:54:00 +0000340 SHA512_VALIDATE_RET( ctx != NULL );
341 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000342
Brian White12895d12014-04-11 11:29:42 -0400343 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100344 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Paul Bakkerb8213a12011-07-11 08:16:18 +0000346 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000347 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Paul Bakker5c2364c2012-10-01 14:41:15 +0000349 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000352 ctx->total[1]++;
353
354 if( left && ilen >= fill )
355 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200356 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100357
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100358 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100359 return( ret );
360
Paul Bakker5121ce52009-01-03 21:22:43 +0000361 input += fill;
362 ilen -= fill;
363 left = 0;
364 }
365
366 while( ilen >= 128 )
367 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100368 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100369 return( ret );
370
Paul Bakker5121ce52009-01-03 21:22:43 +0000371 input += 128;
372 ilen -= 128;
373 }
374
375 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200376 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100377
378 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379}
380
Jaeden Amero041039f2018-02-19 15:28:08 +0000381#if !defined(MBEDTLS_DEPRECATED_REMOVED)
382void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
383 const unsigned char *input,
384 size_t ilen )
385{
386 mbedtls_sha512_update_ret( ctx, input, ilen );
387}
388#endif
389
Paul Bakker5121ce52009-01-03 21:22:43 +0000390/*
391 * SHA-512 final digest
392 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100393int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100394 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100396 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200397 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Hanno Becker38e15d42018-12-18 17:54:00 +0000400 SHA512_VALIDATE_RET( ctx != NULL );
401 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000402
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200403 /*
404 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
405 */
406 used = ctx->total[0] & 0x7F;
407
408 ctx->buffer[used++] = 0x80;
409
410 if( used <= 112 )
411 {
412 /* Enough room for padding + length in current block */
413 memset( ctx->buffer + used, 0, 112 - used );
414 }
415 else
416 {
417 /* We'll need an extra block */
418 memset( ctx->buffer + used, 0, 128 - used );
419
420 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
421 return( ret );
422
423 memset( ctx->buffer, 0, 112 );
424 }
425
426 /*
427 * Add message length
428 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 high = ( ctx->total[0] >> 61 )
430 | ( ctx->total[1] << 3 );
431 low = ( ctx->total[0] << 3 );
432
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200433 PUT_UINT64_BE( high, ctx->buffer, 112 );
434 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200436 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
437 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200439 /*
440 * Output final state
441 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 PUT_UINT64_BE( ctx->state[0], output, 0 );
443 PUT_UINT64_BE( ctx->state[1], output, 8 );
444 PUT_UINT64_BE( ctx->state[2], output, 16 );
445 PUT_UINT64_BE( ctx->state[3], output, 24 );
446 PUT_UINT64_BE( ctx->state[4], output, 32 );
447 PUT_UINT64_BE( ctx->state[5], output, 40 );
448
449 if( ctx->is384 == 0 )
450 {
451 PUT_UINT64_BE( ctx->state[6], output, 48 );
452 PUT_UINT64_BE( ctx->state[7], output, 56 );
453 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100454
455 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456}
457
Jaeden Amero041039f2018-02-19 15:28:08 +0000458#if !defined(MBEDTLS_DEPRECATED_REMOVED)
459void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
460 unsigned char output[64] )
461{
462 mbedtls_sha512_finish_ret( ctx, output );
463}
464#endif
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200467
Paul Bakker5121ce52009-01-03 21:22:43 +0000468/*
469 * output = SHA-512( input buffer )
470 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100471int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100472 size_t ilen,
473 unsigned char output[64],
474 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000475{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100476 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Hanno Becker38e15d42018-12-18 17:54:00 +0000479 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
480 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
481 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100484
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100485 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100486 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100487
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100488 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100489 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100490
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100491 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100492 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100493
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100494exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100496
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100497 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498}
499
Jaeden Amero041039f2018-02-19 15:28:08 +0000500#if !defined(MBEDTLS_DEPRECATED_REMOVED)
501void mbedtls_sha512( const unsigned char *input,
502 size_t ilen,
503 unsigned char output[64],
504 int is384 )
505{
506 mbedtls_sha512_ret( input, ilen, output, is384 );
507}
508#endif
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
512/*
513 * FIPS-180-2 test vectors
514 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000515static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000516{
517 { "abc" },
518 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
519 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
520 { "" }
521};
522
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100523static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000524{
525 3, 112, 1000
526};
527
Paul Bakker9e36f042013-06-30 14:34:05 +0200528static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000529{
530 /*
531 * SHA-384 test vectors
532 */
533 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
534 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
535 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
536 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
537 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
538 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
539 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
540 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
541 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
542 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
543 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
544 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
545 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
546 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
547 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
548 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
549 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
550 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
551
552 /*
553 * SHA-512 test vectors
554 */
555 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
556 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
557 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
558 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
559 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
560 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
561 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
562 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
563 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
564 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
565 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
566 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
567 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
568 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
569 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
570 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
571 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
572 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
573 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
574 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
575 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
576 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
577 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
578 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
579};
580
581/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 * Checkup routine
583 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000585{
Paul Bakker5b4af392014-06-26 12:09:34 +0200586 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500587 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200588 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
Russ Butlerbb83b422016-10-12 17:36:50 -0500591 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
592 if( NULL == buf )
593 {
594 if( verbose != 0 )
595 mbedtls_printf( "Buffer allocation failed\n" );
596
597 return( 1 );
598 }
599
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200601
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 for( i = 0; i < 6; i++ )
603 {
604 j = i % 3;
605 k = i < 3;
606
607 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100610 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100611 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 if( j == 2 )
614 {
615 memset( buf, 'a', buflen = 1000 );
616
617 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100618 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100619 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100620 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100621 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100622 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 }
624 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100625 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100626 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100627 sha512_test_buflen[j] );
628 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100629 goto fail;
630 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100632 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100633 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
Paul Bakker9e36f042013-06-30 14:34:05 +0200635 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100636 {
637 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100638 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100639 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000643 }
644
645 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100648 goto exit;
649
650fail:
651 if( verbose != 0 )
652 mbedtls_printf( "failed\n" );
653
Paul Bakker5b4af392014-06-26 12:09:34 +0200654exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500656 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200657
658 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000659}
660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663#endif /* MBEDTLS_SHA512_C */