blob: a3a28525c3d9c828b26e37e3007d975865ff7950 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
21 *
22 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000033#if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35#else
36 #define UL64(x) x##ULL
37#endif
38
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050046#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050048#define mbedtls_calloc calloc
49#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Hanno Beckerc7560492018-12-20 10:23:39 +000053#define SHA512_VALIDATE_RET(cond) \
54 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
55#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
56
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020057#if !defined(MBEDTLS_SHA512_ALT)
58
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * 64-bit integer manipulation macros (big endian)
61 */
62#ifndef GET_UINT64_BE
63#define GET_UINT64_BE(n,b,i) \
64{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000065 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
66 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
67 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
68 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
69 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
70 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
71 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
72 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000073}
Paul Bakker9af723c2014-05-01 13:03:14 +020074#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000075
76#ifndef PUT_UINT64_BE
77#define PUT_UINT64_BE(n,b,i) \
78{ \
79 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
80 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
81 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
82 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
83 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
84 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
85 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
86 (b)[(i) + 7] = (unsigned char) ( (n) ); \
87}
Paul Bakker9af723c2014-05-01 13:03:14 +020088#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000089
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020090#if defined(MBEDTLS_SHA512_SMALLER)
91static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
92{
93 PUT_UINT64_BE(n, b, i);
94}
95#else
96#define sha512_put_uint64_be PUT_UINT64_BE
97#endif /* MBEDTLS_SHA512_SMALLER */
98
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200100{
Hanno Becker38e15d42018-12-18 17:54:00 +0000101 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200104}
105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200107{
108 if( ctx == NULL )
109 return;
110
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500111 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200112}
113
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200114void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
115 const mbedtls_sha512_context *src )
116{
Hanno Becker38e15d42018-12-18 17:54:00 +0000117 SHA512_VALIDATE( dst != NULL );
118 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000119
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200120 *dst = *src;
121}
122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123/*
124 * SHA-512 context setup
125 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100126int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000127{
Hanno Becker38e15d42018-12-18 17:54:00 +0000128 SHA512_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100129#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +0000130 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100131#else
132 SHA512_VALIDATE_RET( is384 == 0 );
133#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000134
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 ctx->total[0] = 0;
136 ctx->total[1] = 0;
137
138 if( is384 == 0 )
139 {
140 /* SHA-512 */
141 ctx->state[0] = UL64(0x6A09E667F3BCC908);
142 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
143 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
144 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
145 ctx->state[4] = UL64(0x510E527FADE682D1);
146 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
147 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
148 ctx->state[7] = UL64(0x5BE0CD19137E2179);
149 }
150 else
151 {
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200152#if defined(MBEDTLS_SHA512_NO_SHA384)
153 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
154#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 /* SHA-384 */
156 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
157 ctx->state[1] = UL64(0x629A292A367CD507);
158 ctx->state[2] = UL64(0x9159015A3070DD17);
159 ctx->state[3] = UL64(0x152FECD8F70E5939);
160 ctx->state[4] = UL64(0x67332667FFC00B31);
161 ctx->state[5] = UL64(0x8EB44A8768581511);
162 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
163 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200164#endif /* MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000165 }
166
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200167#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000168 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200169#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100170
171 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000172}
173
Jaeden Amero041039f2018-02-19 15:28:08 +0000174#if !defined(MBEDTLS_DEPRECATED_REMOVED)
175void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
176 int is384 )
177{
178 mbedtls_sha512_starts_ret( ctx, is384 );
179}
180#endif
181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200183
184/*
185 * Round constants
186 */
187static const uint64_t K[80] =
188{
189 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
190 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
191 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
192 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
193 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
194 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
195 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
196 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
197 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
198 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
199 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
200 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
201 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
202 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
203 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
204 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
205 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
206 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
207 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
208 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
209 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
210 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
211 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
212 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
213 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
214 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
215 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
216 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
217 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
218 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
219 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
220 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
221 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
222 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
223 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
224 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
225 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
226 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
227 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
228 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
229};
230
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100231int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
232 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000233{
234 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000235 uint64_t temp1, temp2, W[80];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200236 uint64_t A[8];
Paul Bakker5121ce52009-01-03 21:22:43 +0000237
Hanno Becker38e15d42018-12-18 17:54:00 +0000238 SHA512_VALIDATE_RET( ctx != NULL );
239 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000240
Hanno Becker1eeca412018-10-15 12:01:35 +0100241#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000242#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
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
Hanno Becker1eeca412018-10-15 12:01:35 +0100250#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
251#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000252
Hanno Becker26d02e12018-10-30 09:29:25 +0000253#define P(a,b,c,d,e,f,g,h,x,K) \
254 do \
255 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100256 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
257 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker26d02e12018-10-30 09:29:25 +0000258 (d) += temp1; (h) = temp1 + temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100259 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200261 for( i = 0; i < 8; i++ )
262 A[i] = ctx->state[i];
263
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200264#if defined(MBEDTLS_SHA512_SMALLER)
265 for( i = 0; i < 80; i++ )
266 {
267 if( i < 16 )
268 {
269 GET_UINT64_BE( W[i], data, i << 3 );
270 }
271 else
272 {
273 W[i] = S1(W[i - 2]) + W[i - 7] +
274 S0(W[i - 15]) + W[i - 16];
275 }
276
277 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
278
279 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
280 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
281 }
282#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 for( i = 0; i < 16; i++ )
284 {
285 GET_UINT64_BE( W[i], data, i << 3 );
286 }
287
288 for( ; i < 80; i++ )
289 {
290 W[i] = S1(W[i - 2]) + W[i - 7] +
291 S0(W[i - 15]) + W[i - 16];
292 }
293
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 do
296 {
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200297 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
298 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
299 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
300 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
301 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
302 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
303 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
304 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 }
306 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200307#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200309 for( i = 0; i < 8; i++ )
310 ctx->state[i] += A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100311
312 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313}
Jaeden Amero041039f2018-02-19 15:28:08 +0000314
315#if !defined(MBEDTLS_DEPRECATED_REMOVED)
316void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
317 const unsigned char data[128] )
318{
319 mbedtls_internal_sha512_process( ctx, data );
320}
321#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324/*
325 * SHA-512 process buffer
326 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100327int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100328 const unsigned char *input,
329 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
Janos Follath24eed8d2019-11-22 13:21:35 +0000331 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000332 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000333 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
Hanno Becker38e15d42018-12-18 17:54:00 +0000335 SHA512_VALIDATE_RET( ctx != NULL );
336 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000337
Brian White12895d12014-04-11 11:29:42 -0400338 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100339 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
Paul Bakkerb8213a12011-07-11 08:16:18 +0000341 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000342 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000347 ctx->total[1]++;
348
349 if( left && ilen >= fill )
350 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200351 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100352
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100353 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100354 return( ret );
355
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 input += fill;
357 ilen -= fill;
358 left = 0;
359 }
360
361 while( ilen >= 128 )
362 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100363 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100364 return( ret );
365
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 input += 128;
367 ilen -= 128;
368 }
369
370 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200371 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100372
373 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000374}
375
Jaeden Amero041039f2018-02-19 15:28:08 +0000376#if !defined(MBEDTLS_DEPRECATED_REMOVED)
377void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
378 const unsigned char *input,
379 size_t ilen )
380{
381 mbedtls_sha512_update_ret( ctx, input, ilen );
382}
383#endif
384
Paul Bakker5121ce52009-01-03 21:22:43 +0000385/*
386 * SHA-512 final digest
387 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100388int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100389 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000390{
Janos Follath24eed8d2019-11-22 13:21:35 +0000391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200392 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000393 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
Hanno Becker38e15d42018-12-18 17:54:00 +0000395 SHA512_VALIDATE_RET( ctx != NULL );
396 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000397
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200398 /*
399 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
400 */
401 used = ctx->total[0] & 0x7F;
402
403 ctx->buffer[used++] = 0x80;
404
405 if( used <= 112 )
406 {
407 /* Enough room for padding + length in current block */
408 memset( ctx->buffer + used, 0, 112 - used );
409 }
410 else
411 {
412 /* We'll need an extra block */
413 memset( ctx->buffer + used, 0, 128 - used );
414
415 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
416 return( ret );
417
418 memset( ctx->buffer, 0, 112 );
419 }
420
421 /*
422 * Add message length
423 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 high = ( ctx->total[0] >> 61 )
425 | ( ctx->total[1] << 3 );
426 low = ( ctx->total[0] << 3 );
427
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200428 sha512_put_uint64_be( high, ctx->buffer, 112 );
429 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200431 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
432 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200434 /*
435 * Output final state
436 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200437 sha512_put_uint64_be( ctx->state[0], output, 0 );
438 sha512_put_uint64_be( ctx->state[1], output, 8 );
439 sha512_put_uint64_be( ctx->state[2], output, 16 );
440 sha512_put_uint64_be( ctx->state[3], output, 24 );
441 sha512_put_uint64_be( ctx->state[4], output, 32 );
442 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200444#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200446#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200448 sha512_put_uint64_be( ctx->state[6], output, 48 );
449 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100451
452 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000453}
454
Jaeden Amero041039f2018-02-19 15:28:08 +0000455#if !defined(MBEDTLS_DEPRECATED_REMOVED)
456void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
457 unsigned char output[64] )
458{
459 mbedtls_sha512_finish_ret( ctx, output );
460}
461#endif
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200464
Paul Bakker5121ce52009-01-03 21:22:43 +0000465/*
466 * output = SHA-512( input buffer )
467 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100468int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100469 size_t ilen,
470 unsigned char output[64],
471 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000472{
Janos Follath24eed8d2019-11-22 13:21:35 +0000473 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100476#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +0000477 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100478#else
479 SHA512_VALIDATE_RET( is384 == 0 );
480#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000481 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
482 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100485
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100486 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100487 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100488
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100489 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100490 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100491
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100492 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100493 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100494
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100495exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100497
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100498 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499}
500
Jaeden Amero041039f2018-02-19 15:28:08 +0000501#if !defined(MBEDTLS_DEPRECATED_REMOVED)
502void mbedtls_sha512( const unsigned char *input,
503 size_t ilen,
504 unsigned char output[64],
505 int is384 )
506{
507 mbedtls_sha512_ret( input, ilen, output, is384 );
508}
509#endif
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
513/*
514 * FIPS-180-2 test vectors
515 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000516static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000517{
518 { "abc" },
Guido Vranken027fe002020-08-21 10:05:52 +0200519 { ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
520 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") },
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 { "" }
522};
523
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100524static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000525{
526 3, 112, 1000
527};
528
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200529static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000530{
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200531#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 /*
533 * SHA-384 test vectors
534 */
535 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
536 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
537 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
538 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
539 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
540 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
541 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
542 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
543 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
544 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
545 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
546 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
547 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
548 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
549 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
550 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
551 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
552 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200553#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
555 /*
556 * SHA-512 test vectors
557 */
558 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
559 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
560 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
561 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
562 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
563 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
564 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
565 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
566 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
567 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
568 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
569 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
570 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
571 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
572 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
573 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
574 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
575 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
576 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
577 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
578 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
579 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
580 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
581 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
582};
583
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100584#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200585
Paul Bakker5121ce52009-01-03 21:22:43 +0000586/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 * Checkup routine
588 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000590{
Paul Bakker5b4af392014-06-26 12:09:34 +0200591 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500592 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200593 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Russ Butlerbb83b422016-10-12 17:36:50 -0500596 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
597 if( NULL == buf )
598 {
599 if( verbose != 0 )
600 mbedtls_printf( "Buffer allocation failed\n" );
601
602 return( 1 );
603 }
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200606
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100607 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 {
609 j = i % 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200610#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200612#else
613 k = 0;
614#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100619 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100620 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 if( j == 2 )
623 {
624 memset( buf, 'a', buflen = 1000 );
625
626 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100627 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100628 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100630 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100631 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 }
633 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100634 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100635 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100636 sha512_test_buflen[j] );
637 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100638 goto fail;
639 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100641 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100642 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Paul Bakker9e36f042013-06-30 14:34:05 +0200644 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100645 {
646 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100647 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100648 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 }
653
654 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100657 goto exit;
658
659fail:
660 if( verbose != 0 )
661 mbedtls_printf( "failed\n" );
662
Paul Bakker5b4af392014-06-26 12:09:34 +0200663exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500665 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200666
667 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668}
669
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100670#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674#endif /* MBEDTLS_SHA512_C */