blob: a2f2ebf61de483bb7e57a286ae160b3fab6529f2 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Hanno Beckerc7560492018-12-20 10:23:39 +000045#define SHA512_VALIDATE_RET(cond) \
46 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
47#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
48
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020049#if !defined(MBEDTLS_SHA512_ALT)
50
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020051#if defined(MBEDTLS_SHA512_SMALLER)
52static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
53{
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +010054 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020055}
56#else
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +010057#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020058#endif /* MBEDTLS_SHA512_SMALLER */
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020061{
Hanno Becker38e15d42018-12-18 17:54:00 +000062 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020065}
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020068{
69 if( ctx == NULL )
70 return;
71
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050072 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020073}
74
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020075void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
76 const mbedtls_sha512_context *src )
77{
Hanno Becker38e15d42018-12-18 17:54:00 +000078 SHA512_VALIDATE( dst != NULL );
79 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000080
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020081 *dst = *src;
82}
83
Paul Bakker5121ce52009-01-03 21:22:43 +000084/*
85 * SHA-512 context setup
86 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010087int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
Hanno Becker38e15d42018-12-18 17:54:00 +000089 SHA512_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +010090#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +000091 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +010092#else
93 SHA512_VALIDATE_RET( is384 == 0 );
94#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000095
Paul Bakker5121ce52009-01-03 21:22:43 +000096 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
99 if( is384 == 0 )
100 {
101 /* SHA-512 */
102 ctx->state[0] = UL64(0x6A09E667F3BCC908);
103 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
104 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
105 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
106 ctx->state[4] = UL64(0x510E527FADE682D1);
107 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
108 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
109 ctx->state[7] = UL64(0x5BE0CD19137E2179);
110 }
111 else
112 {
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200113#if defined(MBEDTLS_SHA512_NO_SHA384)
114 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
115#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000116 /* SHA-384 */
117 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
118 ctx->state[1] = UL64(0x629A292A367CD507);
119 ctx->state[2] = UL64(0x9159015A3070DD17);
120 ctx->state[3] = UL64(0x152FECD8F70E5939);
121 ctx->state[4] = UL64(0x67332667FFC00B31);
122 ctx->state[5] = UL64(0x8EB44A8768581511);
123 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
124 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200125#endif /* MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000126 }
127
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200128#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000129 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200130#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100131
132 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000133}
134
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200135#if !defined(MBEDTLS_DEPRECATED_REMOVED)
136void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
137 int is384 )
138{
139 mbedtls_sha512_starts_ret( ctx, is384 );
140}
141#endif
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 Subbiani1bd5d7d2021-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 Subbiani1bd5d7d2021-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é-Gonnard93c08472021-04-15 12:23:55 +0200294#if !defined(MBEDTLS_DEPRECATED_REMOVED)
295void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
296 const unsigned char data[128] )
297{
298 mbedtls_internal_sha512_process( ctx, data );
299}
300#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
303/*
304 * SHA-512 process buffer
305 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100306int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100307 const unsigned char *input,
308 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000309{
Janos Follath24eed8d2019-11-22 13:21:35 +0000310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000311 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000312 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Hanno Becker38e15d42018-12-18 17:54:00 +0000314 SHA512_VALIDATE_RET( ctx != NULL );
315 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000316
Brian White12895d12014-04-11 11:29:42 -0400317 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100318 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
Paul Bakkerb8213a12011-07-11 08:16:18 +0000320 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000321 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
Paul Bakker5c2364c2012-10-01 14:41:15 +0000325 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 ctx->total[1]++;
327
328 if( left && ilen >= fill )
329 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200330 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100331
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100332 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100333 return( ret );
334
Paul Bakker5121ce52009-01-03 21:22:43 +0000335 input += fill;
336 ilen -= fill;
337 left = 0;
338 }
339
340 while( ilen >= 128 )
341 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100342 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100343 return( ret );
344
Paul Bakker5121ce52009-01-03 21:22:43 +0000345 input += 128;
346 ilen -= 128;
347 }
348
349 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200350 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100351
352 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353}
354
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200355#if !defined(MBEDTLS_DEPRECATED_REMOVED)
356void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
357 const unsigned char *input,
358 size_t ilen )
359{
360 mbedtls_sha512_update_ret( ctx, input, ilen );
361}
362#endif
363
Paul Bakker5121ce52009-01-03 21:22:43 +0000364/*
365 * SHA-512 final digest
366 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100367int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100368 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000369{
Janos Follath24eed8d2019-11-22 13:21:35 +0000370 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200371 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000372 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Hanno Becker38e15d42018-12-18 17:54:00 +0000374 SHA512_VALIDATE_RET( ctx != NULL );
375 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000376
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200377 /*
378 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
379 */
380 used = ctx->total[0] & 0x7F;
381
382 ctx->buffer[used++] = 0x80;
383
384 if( used <= 112 )
385 {
386 /* Enough room for padding + length in current block */
387 memset( ctx->buffer + used, 0, 112 - used );
388 }
389 else
390 {
391 /* We'll need an extra block */
392 memset( ctx->buffer + used, 0, 128 - used );
393
394 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
395 return( ret );
396
397 memset( ctx->buffer, 0, 112 );
398 }
399
400 /*
401 * Add message length
402 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 high = ( ctx->total[0] >> 61 )
404 | ( ctx->total[1] << 3 );
405 low = ( ctx->total[0] << 3 );
406
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200407 sha512_put_uint64_be( high, ctx->buffer, 112 );
408 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200410 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
411 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200413 /*
414 * Output final state
415 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200416 sha512_put_uint64_be( ctx->state[0], output, 0 );
417 sha512_put_uint64_be( ctx->state[1], output, 8 );
418 sha512_put_uint64_be( ctx->state[2], output, 16 );
419 sha512_put_uint64_be( ctx->state[3], output, 24 );
420 sha512_put_uint64_be( ctx->state[4], output, 32 );
421 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200423#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200425#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200427 sha512_put_uint64_be( ctx->state[6], output, 48 );
428 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100430
431 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432}
433
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200434#if !defined(MBEDTLS_DEPRECATED_REMOVED)
435void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
436 unsigned char output[64] )
437{
438 mbedtls_sha512_finish_ret( ctx, output );
439}
440#endif
441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200443
Paul Bakker5121ce52009-01-03 21:22:43 +0000444/*
445 * output = SHA-512( input buffer )
446 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100447int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100448 size_t ilen,
449 unsigned char output[64],
450 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000451{
Janos Follath24eed8d2019-11-22 13:21:35 +0000452 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100455#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +0000456 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100457#else
458 SHA512_VALIDATE_RET( is384 == 0 );
459#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000460 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
461 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100464
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100465 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100466 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100467
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100468 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100469 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100470
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100471 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100472 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100473
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100474exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100476
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100477 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000478}
479
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200480#if !defined(MBEDTLS_DEPRECATED_REMOVED)
481void mbedtls_sha512( const unsigned char *input,
482 size_t ilen,
483 unsigned char output[64],
484 int is384 )
485{
486 mbedtls_sha512_ret( input, ilen, output, is384 );
487}
488#endif
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492/*
493 * FIPS-180-2 test vectors
494 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000495static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000496{
497 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200498 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 { "" }
500};
501
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100502static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000503{
504 3, 112, 1000
505};
506
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200507static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000508{
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200509#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 /*
511 * SHA-384 test vectors
512 */
513 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
514 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
515 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
516 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
517 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
518 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
519 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
520 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
521 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
522 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
523 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
524 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
525 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
526 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
527 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
528 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
529 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
530 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200531#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
533 /*
534 * SHA-512 test vectors
535 */
536 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
537 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
538 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
539 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
540 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
541 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
542 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
543 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
544 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
545 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
546 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
547 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
548 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
549 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
550 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
551 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
552 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
553 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
554 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
555 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
556 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
557 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
558 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
559 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
560};
561
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100562#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200563
Paul Bakker5121ce52009-01-03 21:22:43 +0000564/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000565 * Checkup routine
566 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000568{
Paul Bakker5b4af392014-06-26 12:09:34 +0200569 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500570 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200571 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
Russ Butlerbb83b422016-10-12 17:36:50 -0500574 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
575 if( NULL == buf )
576 {
577 if( verbose != 0 )
578 mbedtls_printf( "Buffer allocation failed\n" );
579
580 return( 1 );
581 }
582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200584
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100585 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 {
587 j = i % 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200588#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200590#else
591 k = 0;
592#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100597 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100598 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600 if( j == 2 )
601 {
602 memset( buf, 'a', buflen = 1000 );
603
604 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100605 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100606 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100607 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100608 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100609 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 }
611 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100612 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100613 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100614 sha512_test_buflen[j] );
615 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100616 goto fail;
617 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100619 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100620 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Paul Bakker9e36f042013-06-30 14:34:05 +0200622 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100623 {
624 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100625 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100626 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
628 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 }
631
632 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100635 goto exit;
636
637fail:
638 if( verbose != 0 )
639 mbedtls_printf( "failed\n" );
640
Paul Bakker5b4af392014-06-26 12:09:34 +0200641exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500643 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200644
645 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646}
647
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100648#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#endif /* MBEDTLS_SHA512_C */