blob: 2b4cc547e40dc0658e73660659a4450f6ca0a8f0 [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
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020059#if defined(MBEDTLS_SHA512_SMALLER)
60static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
61{
Joe Subbiani99edd6c2021-07-16 12:29:49 +010062 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020063}
64#else
Joe Subbiani99edd6c2021-07-16 12:29:49 +010065#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020066#endif /* MBEDTLS_SHA512_SMALLER */
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020069{
Hanno Becker38e15d42018-12-18 17:54:00 +000070 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020073}
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020076{
77 if( ctx == NULL )
78 return;
79
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050080 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020083void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
84 const mbedtls_sha512_context *src )
85{
Hanno Becker38e15d42018-12-18 17:54:00 +000086 SHA512_VALIDATE( dst != NULL );
87 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000088
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020089 *dst = *src;
90}
91
Paul Bakker5121ce52009-01-03 21:22:43 +000092/*
93 * SHA-512 context setup
94 */
TRodziewicz26371e42021-06-08 16:45:41 +020095int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +000096{
Hanno Becker38e15d42018-12-18 17:54:00 +000097 SHA512_VALIDATE_RET( ctx != NULL );
Mateusz Starzyk3352a532021-04-06 14:28:22 +020098#if defined(MBEDTLS_SHA384_C)
Hanno Becker38e15d42018-12-18 17:54:00 +000099 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100100#else
101 SHA512_VALIDATE_RET( is384 == 0 );
102#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000103
Paul Bakker5121ce52009-01-03 21:22:43 +0000104 ctx->total[0] = 0;
105 ctx->total[1] = 0;
106
107 if( is384 == 0 )
108 {
109 /* SHA-512 */
110 ctx->state[0] = UL64(0x6A09E667F3BCC908);
111 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
112 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
113 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
114 ctx->state[4] = UL64(0x510E527FADE682D1);
115 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
116 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
117 ctx->state[7] = UL64(0x5BE0CD19137E2179);
118 }
119 else
120 {
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200121#if !defined(MBEDTLS_SHA384_C)
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200122 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
123#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000124 /* SHA-384 */
125 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
126 ctx->state[1] = UL64(0x629A292A367CD507);
127 ctx->state[2] = UL64(0x9159015A3070DD17);
128 ctx->state[3] = UL64(0x152FECD8F70E5939);
129 ctx->state[4] = UL64(0x67332667FFC00B31);
130 ctx->state[5] = UL64(0x8EB44A8768581511);
131 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
132 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200133#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000134 }
135
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200136#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000137 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200138#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100139
140 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000141}
142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200144
145/*
146 * Round constants
147 */
148static const uint64_t K[80] =
149{
150 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
151 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
152 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
153 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
154 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
155 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
156 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
157 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
158 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
159 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
160 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
161 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
162 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
163 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
164 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
165 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
166 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
167 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
168 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
169 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
170 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
171 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
172 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
173 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
174 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
175 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
176 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
177 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
178 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
179 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
180 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
181 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
182 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
183 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
184 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
185 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
186 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
187 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
188 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
189 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
190};
191
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100192int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
193 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000194{
195 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200196 struct
197 {
198 uint64_t temp1, temp2, W[80];
199 uint64_t A[8];
200 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000201
Hanno Becker38e15d42018-12-18 17:54:00 +0000202 SHA512_VALIDATE_RET( ctx != NULL );
203 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000204
Hanno Becker1eeca412018-10-15 12:01:35 +0100205#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000206#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
208#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
209#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
210
211#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
212#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
213
Hanno Becker1eeca412018-10-15 12:01:35 +0100214#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
215#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000216
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200217#define P(a,b,c,d,e,f,g,h,x,K) \
218 do \
219 { \
220 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
221 local.temp2 = S2(a) + F0((a),(b),(c)); \
222 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100223 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200225 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200226 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200227
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200228#if defined(MBEDTLS_SHA512_SMALLER)
229 for( i = 0; i < 80; i++ )
230 {
231 if( i < 16 )
232 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100233 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200234 }
235 else
236 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200237 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
238 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200239 }
240
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200241 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
242 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200243
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200244 local.temp1 = local.A[7]; local.A[7] = local.A[6];
245 local.A[6] = local.A[5]; local.A[5] = local.A[4];
246 local.A[4] = local.A[3]; local.A[3] = local.A[2];
247 local.A[2] = local.A[1]; local.A[1] = local.A[0];
248 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200249 }
250#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 for( i = 0; i < 16; i++ )
252 {
Joe Subbiani99edd6c2021-07-16 12:29:49 +0100253 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254 }
255
256 for( ; i < 80; i++ )
257 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200258 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
259 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 }
261
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000263 do
264 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200265 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
266 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
267 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
268 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
269 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
270 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
271 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
272 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
273 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
274 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
275 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
276 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
277 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
278 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
279 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
280 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 }
282 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200283#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200285 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200286 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100287
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200288 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200289 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100290
291 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292}
Jaeden Amero041039f2018-02-19 15:28:08 +0000293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
296/*
297 * SHA-512 process buffer
298 */
TRodziewicz26371e42021-06-08 16:45:41 +0200299int mbedtls_sha512_update( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100300 const unsigned char *input,
301 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000302{
Janos Follath24eed8d2019-11-22 13:21:35 +0000303 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000304 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000305 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Hanno Becker38e15d42018-12-18 17:54:00 +0000307 SHA512_VALIDATE_RET( ctx != NULL );
308 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000309
Brian White12895d12014-04-11 11:29:42 -0400310 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100311 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
Paul Bakkerb8213a12011-07-11 08:16:18 +0000313 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000314 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 ctx->total[1]++;
320
321 if( left && ilen >= fill )
322 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200323 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100324
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100325 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100326 return( ret );
327
Paul Bakker5121ce52009-01-03 21:22:43 +0000328 input += fill;
329 ilen -= fill;
330 left = 0;
331 }
332
333 while( ilen >= 128 )
334 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100335 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100336 return( ret );
337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 input += 128;
339 ilen -= 128;
340 }
341
342 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200343 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100344
345 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346}
347
Paul Bakker5121ce52009-01-03 21:22:43 +0000348/*
349 * SHA-512 final digest
350 */
TRodziewicz26371e42021-06-08 16:45:41 +0200351int mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200352 unsigned char *output )
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
Janos Follath24eed8d2019-11-22 13:21:35 +0000354 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200355 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000356 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Hanno Becker38e15d42018-12-18 17:54:00 +0000358 SHA512_VALIDATE_RET( ctx != NULL );
359 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000360
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200361 /*
362 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
363 */
364 used = ctx->total[0] & 0x7F;
365
366 ctx->buffer[used++] = 0x80;
367
368 if( used <= 112 )
369 {
370 /* Enough room for padding + length in current block */
371 memset( ctx->buffer + used, 0, 112 - used );
372 }
373 else
374 {
375 /* We'll need an extra block */
376 memset( ctx->buffer + used, 0, 128 - used );
377
378 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
379 return( ret );
380
381 memset( ctx->buffer, 0, 112 );
382 }
383
384 /*
385 * Add message length
386 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 high = ( ctx->total[0] >> 61 )
388 | ( ctx->total[1] << 3 );
389 low = ( ctx->total[0] << 3 );
390
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200391 sha512_put_uint64_be( high, ctx->buffer, 112 );
392 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200394 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
395 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200397 /*
398 * Output final state
399 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200400 sha512_put_uint64_be( ctx->state[0], output, 0 );
401 sha512_put_uint64_be( ctx->state[1], output, 8 );
402 sha512_put_uint64_be( ctx->state[2], output, 16 );
403 sha512_put_uint64_be( ctx->state[3], output, 24 );
404 sha512_put_uint64_be( ctx->state[4], output, 32 );
405 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200407#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200409#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200411 sha512_put_uint64_be( ctx->state[6], output, 48 );
412 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100414
415 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000416}
417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200419
Paul Bakker5121ce52009-01-03 21:22:43 +0000420/*
421 * output = SHA-512( input buffer )
422 */
TRodziewicz26371e42021-06-08 16:45:41 +0200423int mbedtls_sha512( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100424 size_t ilen,
Gilles Peskinee02e02f2021-05-13 00:22:35 +0200425 unsigned char *output,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100426 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000427{
Janos Follath24eed8d2019-11-22 13:21:35 +0000428 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200431#if defined(MBEDTLS_SHA384_C)
Hanno Becker38e15d42018-12-18 17:54:00 +0000432 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100433#else
434 SHA512_VALIDATE_RET( is384 == 0 );
435#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000436 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
437 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100440
TRodziewicz26371e42021-06-08 16:45:41 +0200441 if( ( ret = mbedtls_sha512_starts( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100442 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100443
TRodziewicz26371e42021-06-08 16:45:41 +0200444 if( ( ret = mbedtls_sha512_update( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100445 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100446
TRodziewicz26371e42021-06-08 16:45:41 +0200447 if( ( ret = mbedtls_sha512_finish( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100448 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100449
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100450exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100452
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100453 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000454}
455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458/*
459 * FIPS-180-2 test vectors
460 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000461static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
463 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200464 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000465 { "" }
466};
467
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100468static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000469{
470 3, 112, 1000
471};
472
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200473static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000474{
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200475#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000476 /*
477 * SHA-384 test vectors
478 */
479 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
480 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
481 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
482 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
483 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
484 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
485 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
486 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
487 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
488 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
489 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
490 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
491 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
492 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
493 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
494 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
495 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
496 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200497#endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
499 /*
500 * SHA-512 test vectors
501 */
502 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
503 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
504 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
505 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
506 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
507 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
508 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
509 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
510 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
511 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
512 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
513 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
514 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
515 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
516 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
517 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
518 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
519 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
520 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
521 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
522 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
523 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
524 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
525 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
526};
527
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100528#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200529
Paul Bakker5121ce52009-01-03 21:22:43 +0000530/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 * Checkup routine
532 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000534{
Paul Bakker5b4af392014-06-26 12:09:34 +0200535 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500536 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200537 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000539
Russ Butlerbb83b422016-10-12 17:36:50 -0500540 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
541 if( NULL == buf )
542 {
543 if( verbose != 0 )
544 mbedtls_printf( "Buffer allocation failed\n" );
545
546 return( 1 );
547 }
548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200550
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100551 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 {
553 j = i % 3;
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200554#if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200556#else
557 k = 0;
558#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000559
560 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
TRodziewicz26371e42021-06-08 16:45:41 +0200563 if( ( ret = mbedtls_sha512_starts( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100564 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 if( j == 2 )
567 {
568 memset( buf, 'a', buflen = 1000 );
569
570 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100571 {
TRodziewicz26371e42021-06-08 16:45:41 +0200572 ret = mbedtls_sha512_update( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100573 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100574 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100575 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 }
577 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100578 {
TRodziewicz26371e42021-06-08 16:45:41 +0200579 ret = mbedtls_sha512_update( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100580 sha512_test_buflen[j] );
581 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100582 goto fail;
583 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
TRodziewicz26371e42021-06-08 16:45:41 +0200585 if( ( ret = mbedtls_sha512_finish( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100586 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
Paul Bakker9e36f042013-06-30 14:34:05 +0200588 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100589 {
590 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100591 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100592 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 }
597
598 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100601 goto exit;
602
603fail:
604 if( verbose != 0 )
605 mbedtls_printf( "failed\n" );
606
Paul Bakker5b4af392014-06-26 12:09:34 +0200607exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500609 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200610
611 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000612}
613
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100614#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618#endif /* MBEDTLS_SHA512_C */