blob: 5b7bb0fd6fb0727dc3f06653a3063d417c490a58 [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 );
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200129#if defined(MBEDTLS_SHA384_C)
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 {
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200152#if !defined(MBEDTLS_SHA384_C)
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200153 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);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200164#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000165 }
166
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200167#if defined(MBEDTLS_SHA384_C)
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200175
176/*
177 * Round constants
178 */
179static const uint64_t K[80] =
180{
181 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
182 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
183 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
184 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
185 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
186 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
187 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
188 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
189 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
190 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
191 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
192 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
193 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
194 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
195 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
196 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
197 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
198 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
199 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
200 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
201 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
202 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
203 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
204 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
205 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
206 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
207 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
208 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
209 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
210 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
211 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
212 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
213 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
214 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
215 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
216 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
217 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
218 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
219 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
220 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
221};
222
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100223int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
224 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000225{
226 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200227 struct
228 {
229 uint64_t temp1, temp2, W[80];
230 uint64_t A[8];
231 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
Hanno Becker38e15d42018-12-18 17:54:00 +0000233 SHA512_VALIDATE_RET( ctx != NULL );
234 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000235
Hanno Becker1eeca412018-10-15 12:01:35 +0100236#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000237#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
240#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
241
242#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
243#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
244
Hanno Becker1eeca412018-10-15 12:01:35 +0100245#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
246#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000247
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200248#define P(a,b,c,d,e,f,g,h,x,K) \
249 do \
250 { \
251 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
252 local.temp2 = S2(a) + F0((a),(b),(c)); \
253 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100254 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200256 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200257 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200258
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200259#if defined(MBEDTLS_SHA512_SMALLER)
260 for( i = 0; i < 80; i++ )
261 {
262 if( i < 16 )
263 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200264 GET_UINT64_BE( local.W[i], data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200265 }
266 else
267 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200268 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
269 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200270 }
271
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200272 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
273 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200274
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200275 local.temp1 = local.A[7]; local.A[7] = local.A[6];
276 local.A[6] = local.A[5]; local.A[5] = local.A[4];
277 local.A[4] = local.A[3]; local.A[3] = local.A[2];
278 local.A[2] = local.A[1]; local.A[1] = local.A[0];
279 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200280 }
281#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 for( i = 0; i < 16; i++ )
283 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200284 GET_UINT64_BE( local.W[i], data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 }
286
287 for( ; i < 80; i++ )
288 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200289 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
290 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 }
292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 do
295 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200296 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
297 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
298 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
299 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
300 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
301 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
302 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
303 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
304 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
305 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
306 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
307 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
308 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
309 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
310 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
311 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 }
313 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200314#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200316 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200317 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100318
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200319 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200320 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100321
322 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323}
Jaeden Amero041039f2018-02-19 15:28:08 +0000324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327/*
328 * SHA-512 process buffer
329 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100330int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100331 const unsigned char *input,
332 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000333{
Janos Follath24eed8d2019-11-22 13:21:35 +0000334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000335 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000336 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
Hanno Becker38e15d42018-12-18 17:54:00 +0000338 SHA512_VALIDATE_RET( ctx != NULL );
339 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000340
Brian White12895d12014-04-11 11:29:42 -0400341 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100342 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
Paul Bakkerb8213a12011-07-11 08:16:18 +0000344 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000345 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Paul Bakker5c2364c2012-10-01 14:41:15 +0000349 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000350 ctx->total[1]++;
351
352 if( left && ilen >= fill )
353 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200354 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100355
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100356 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100357 return( ret );
358
Paul Bakker5121ce52009-01-03 21:22:43 +0000359 input += fill;
360 ilen -= fill;
361 left = 0;
362 }
363
364 while( ilen >= 128 )
365 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100366 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100367 return( ret );
368
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 input += 128;
370 ilen -= 128;
371 }
372
373 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200374 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100375
376 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000377}
378
Paul Bakker5121ce52009-01-03 21:22:43 +0000379/*
380 * SHA-512 final digest
381 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100382int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100383 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000384{
Janos Follath24eed8d2019-11-22 13:21:35 +0000385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200386 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000387 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
Hanno Becker38e15d42018-12-18 17:54:00 +0000389 SHA512_VALIDATE_RET( ctx != NULL );
390 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000391
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200392 /*
393 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
394 */
395 used = ctx->total[0] & 0x7F;
396
397 ctx->buffer[used++] = 0x80;
398
399 if( used <= 112 )
400 {
401 /* Enough room for padding + length in current block */
402 memset( ctx->buffer + used, 0, 112 - used );
403 }
404 else
405 {
406 /* We'll need an extra block */
407 memset( ctx->buffer + used, 0, 128 - used );
408
409 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
410 return( ret );
411
412 memset( ctx->buffer, 0, 112 );
413 }
414
415 /*
416 * Add message length
417 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 high = ( ctx->total[0] >> 61 )
419 | ( ctx->total[1] << 3 );
420 low = ( ctx->total[0] << 3 );
421
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200422 sha512_put_uint64_be( high, ctx->buffer, 112 );
423 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200425 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
426 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200428 /*
429 * Output final state
430 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200431 sha512_put_uint64_be( ctx->state[0], output, 0 );
432 sha512_put_uint64_be( ctx->state[1], output, 8 );
433 sha512_put_uint64_be( ctx->state[2], output, 16 );
434 sha512_put_uint64_be( ctx->state[3], output, 24 );
435 sha512_put_uint64_be( ctx->state[4], output, 32 );
436 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200438#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200440#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200442 sha512_put_uint64_be( ctx->state[6], output, 48 );
443 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100445
446 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447}
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200450
Paul Bakker5121ce52009-01-03 21:22:43 +0000451/*
452 * output = SHA-512( input buffer )
453 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100454int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100455 size_t ilen,
456 unsigned char output[64],
457 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000458{
Janos Follath24eed8d2019-11-22 13:21:35 +0000459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200462#if defined(MBEDTLS_SHA384_C)
Hanno Becker38e15d42018-12-18 17:54:00 +0000463 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100464#else
465 SHA512_VALIDATE_RET( is384 == 0 );
466#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000467 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
468 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100471
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100472 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100473 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100474
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100475 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 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_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100479 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100480
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100481exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100483
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100484 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485}
486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489/*
490 * FIPS-180-2 test vectors
491 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000492static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000493{
494 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200495 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 { "" }
497};
498
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100499static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000500{
501 3, 112, 1000
502};
503
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200504static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200506#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 /*
508 * SHA-384 test vectors
509 */
510 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
511 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
512 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
513 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
514 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
515 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
516 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
517 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
518 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
519 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
520 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
521 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
522 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
523 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
524 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
525 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
526 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
527 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200528#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
530 /*
531 * SHA-512 test vectors
532 */
533 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
534 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
535 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
536 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
537 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
538 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
539 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
540 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
541 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
542 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
543 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
544 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
545 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
546 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
547 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
548 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
549 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
550 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
551 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
552 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
553 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
554 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
555 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
556 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
557};
558
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100559#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200560
Paul Bakker5121ce52009-01-03 21:22:43 +0000561/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000562 * Checkup routine
563 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000565{
Paul Bakker5b4af392014-06-26 12:09:34 +0200566 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500567 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200568 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Russ Butlerbb83b422016-10-12 17:36:50 -0500571 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
572 if( NULL == buf )
573 {
574 if( verbose != 0 )
575 mbedtls_printf( "Buffer allocation failed\n" );
576
577 return( 1 );
578 }
579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200581
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100582 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000583 {
584 j = i % 3;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200585#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200587#else
588 k = 0;
589#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
591 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100594 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100595 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 if( j == 2 )
598 {
599 memset( buf, 'a', buflen = 1000 );
600
601 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100602 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100603 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100604 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100605 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100606 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 }
608 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100609 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100610 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100611 sha512_test_buflen[j] );
612 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100613 goto fail;
614 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100616 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100617 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Paul Bakker9e36f042013-06-30 14:34:05 +0200619 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100620 {
621 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100622 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100623 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
628
629 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100632 goto exit;
633
634fail:
635 if( verbose != 0 )
636 mbedtls_printf( "failed\n" );
637
Paul Bakker5b4af392014-06-26 12:09:34 +0200638exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500640 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200641
642 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000643}
644
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100645#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649#endif /* MBEDTLS_SHA512_C */