blob: 2a0cbe6100fe1140a8cfd347a5a6f61d0eee7683 [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é-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Hanno Beckerc7560492018-12-20 10:23:39 +000043#define SHA512_VALIDATE_RET(cond) \
44 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
45#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
46
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020047#if !defined(MBEDTLS_SHA512_ALT)
48
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020049#if defined(MBEDTLS_SHA512_SMALLER)
50static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
51{
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +010052 MBEDTLS_PUT_UINT64_BE(n, b, i);
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020053}
54#else
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +010055#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020056#endif /* MBEDTLS_SHA512_SMALLER */
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020059{
Hanno Becker38e15d42018-12-18 17:54:00 +000060 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020063}
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020066{
67 if( ctx == NULL )
68 return;
69
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050070 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020071}
72
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020073void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
74 const mbedtls_sha512_context *src )
75{
Hanno Becker38e15d42018-12-18 17:54:00 +000076 SHA512_VALIDATE( dst != NULL );
77 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000078
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020079 *dst = *src;
80}
81
Paul Bakker5121ce52009-01-03 21:22:43 +000082/*
83 * SHA-512 context setup
84 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010085int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +000086{
Hanno Becker38e15d42018-12-18 17:54:00 +000087 SHA512_VALIDATE_RET( ctx != NULL );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +010088#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +000089 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +010090#else
91 SHA512_VALIDATE_RET( is384 == 0 );
92#endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000093
Paul Bakker5121ce52009-01-03 21:22:43 +000094 ctx->total[0] = 0;
95 ctx->total[1] = 0;
96
97 if( is384 == 0 )
98 {
99 /* SHA-512 */
100 ctx->state[0] = UL64(0x6A09E667F3BCC908);
101 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
102 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
103 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
104 ctx->state[4] = UL64(0x510E527FADE682D1);
105 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
106 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
107 ctx->state[7] = UL64(0x5BE0CD19137E2179);
108 }
109 else
110 {
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200111#if defined(MBEDTLS_SHA512_NO_SHA384)
112 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
113#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000114 /* SHA-384 */
115 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
116 ctx->state[1] = UL64(0x629A292A367CD507);
117 ctx->state[2] = UL64(0x9159015A3070DD17);
118 ctx->state[3] = UL64(0x152FECD8F70E5939);
119 ctx->state[4] = UL64(0x67332667FFC00B31);
120 ctx->state[5] = UL64(0x8EB44A8768581511);
121 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
122 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200123#endif /* MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000124 }
125
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200126#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200128#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100129
130 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000131}
132
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200133#if !defined(MBEDTLS_DEPRECATED_REMOVED)
134void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
135 int is384 )
136{
137 mbedtls_sha512_starts_ret( ctx, is384 );
138}
139#endif
140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200142
143/*
144 * Round constants
145 */
146static const uint64_t K[80] =
147{
148 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
149 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
150 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
151 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
152 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
153 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
154 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
155 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
156 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
157 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
158 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
159 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
160 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
161 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
162 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
163 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
164 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
165 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
166 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
167 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
168 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
169 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
170 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
171 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
172 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
173 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
174 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
175 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
176 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
177 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
178 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
179 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
180 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
181 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
182 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
183 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
184 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
185 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
186 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
187 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
188};
189
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100190int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
191 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000192{
193 int i;
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200194 struct
195 {
196 uint64_t temp1, temp2, W[80];
197 uint64_t A[8];
198 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000199
Hanno Becker38e15d42018-12-18 17:54:00 +0000200 SHA512_VALIDATE_RET( ctx != NULL );
201 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000202
Hanno Becker1eeca412018-10-15 12:01:35 +0100203#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000204#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000205
206#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
207#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
208
209#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
210#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
211
Hanno Becker1eeca412018-10-15 12:01:35 +0100212#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
213#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200215#define P(a,b,c,d,e,f,g,h,x,K) \
216 do \
217 { \
218 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
219 local.temp2 = S2(a) + F0((a),(b),(c)); \
220 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100221 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200223 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200224 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200225
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200226#if defined(MBEDTLS_SHA512_SMALLER)
227 for( i = 0; i < 80; i++ )
228 {
229 if( i < 16 )
230 {
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100231 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200232 }
233 else
234 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200235 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
236 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200237 }
238
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200239 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
240 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200241
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200242 local.temp1 = local.A[7]; local.A[7] = local.A[6];
243 local.A[6] = local.A[5]; local.A[5] = local.A[4];
244 local.A[4] = local.A[3]; local.A[3] = local.A[2];
245 local.A[2] = local.A[1]; local.A[1] = local.A[0];
246 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200247 }
248#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 for( i = 0; i < 16; i++ )
250 {
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +0100251 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 }
253
254 for( ; i < 80; i++ )
255 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200256 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
257 S0(local.W[i - 15]) + local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 }
259
Paul Bakker5121ce52009-01-03 21:22:43 +0000260 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 do
262 {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200263 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
264 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
265 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
266 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
267 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
268 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
269 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
270 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
271 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
272 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
273 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
274 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
275 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
276 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
277 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
278 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 }
280 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200281#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200283 for( i = 0; i < 8; i++ )
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200284 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100285
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200286 /* Zeroise buffers and variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200287 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100288
289 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000290}
Jaeden Amero041039f2018-02-19 15:28:08 +0000291
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200292#if !defined(MBEDTLS_DEPRECATED_REMOVED)
293void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
294 const unsigned char data[128] )
295{
296 mbedtls_internal_sha512_process( ctx, data );
297}
298#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301/*
302 * SHA-512 process buffer
303 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100304int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100305 const unsigned char *input,
306 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000307{
Janos Follath24eed8d2019-11-22 13:21:35 +0000308 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000309 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000310 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
Hanno Becker38e15d42018-12-18 17:54:00 +0000312 SHA512_VALIDATE_RET( ctx != NULL );
313 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000314
Brian White12895d12014-04-11 11:29:42 -0400315 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100316 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
Paul Bakkerb8213a12011-07-11 08:16:18 +0000318 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000319 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 ctx->total[1]++;
325
326 if( left && ilen >= fill )
327 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200328 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100329
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100330 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100331 return( ret );
332
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 input += fill;
334 ilen -= fill;
335 left = 0;
336 }
337
338 while( ilen >= 128 )
339 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100340 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100341 return( ret );
342
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 input += 128;
344 ilen -= 128;
345 }
346
347 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200348 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100349
350 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351}
352
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200353#if !defined(MBEDTLS_DEPRECATED_REMOVED)
354void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
355 const unsigned char *input,
356 size_t ilen )
357{
358 mbedtls_sha512_update_ret( ctx, input, ilen );
359}
360#endif
361
Paul Bakker5121ce52009-01-03 21:22:43 +0000362/*
363 * SHA-512 final digest
364 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100365int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100366 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
Janos Follath24eed8d2019-11-22 13:21:35 +0000368 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200369 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000370 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Hanno Becker38e15d42018-12-18 17:54:00 +0000372 SHA512_VALIDATE_RET( ctx != NULL );
373 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000374
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200375 /*
376 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
377 */
378 used = ctx->total[0] & 0x7F;
379
380 ctx->buffer[used++] = 0x80;
381
382 if( used <= 112 )
383 {
384 /* Enough room for padding + length in current block */
385 memset( ctx->buffer + used, 0, 112 - used );
386 }
387 else
388 {
389 /* We'll need an extra block */
390 memset( ctx->buffer + used, 0, 128 - used );
391
392 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
393 return( ret );
394
395 memset( ctx->buffer, 0, 112 );
396 }
397
398 /*
399 * Add message length
400 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 high = ( ctx->total[0] >> 61 )
402 | ( ctx->total[1] << 3 );
403 low = ( ctx->total[0] << 3 );
404
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200405 sha512_put_uint64_be( high, ctx->buffer, 112 );
406 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200408 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
409 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200411 /*
412 * Output final state
413 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200414 sha512_put_uint64_be( ctx->state[0], output, 0 );
415 sha512_put_uint64_be( ctx->state[1], output, 8 );
416 sha512_put_uint64_be( ctx->state[2], output, 16 );
417 sha512_put_uint64_be( ctx->state[3], output, 24 );
418 sha512_put_uint64_be( ctx->state[4], output, 32 );
419 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200421#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200423#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200425 sha512_put_uint64_be( ctx->state[6], output, 48 );
426 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100428
429 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430}
431
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200432#if !defined(MBEDTLS_DEPRECATED_REMOVED)
433void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
434 unsigned char output[64] )
435{
436 mbedtls_sha512_finish_ret( ctx, output );
437}
438#endif
439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200441
Paul Bakker5121ce52009-01-03 21:22:43 +0000442/*
443 * output = SHA-512( input buffer )
444 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100445int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100446 size_t ilen,
447 unsigned char output[64],
448 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000449{
Janos Follath24eed8d2019-11-22 13:21:35 +0000450 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100453#if !defined(MBEDTLS_SHA512_NO_SHA384)
Hanno Becker38e15d42018-12-18 17:54:00 +0000454 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Manuel Pégourié-Gonnard0b9db442020-01-07 10:14:54 +0100455#else
456 SHA512_VALIDATE_RET( is384 == 0 );
457#endif
Hanno Becker38e15d42018-12-18 17:54:00 +0000458 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
459 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100462
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100463 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100464 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100465
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100466 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100467 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100468
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100469 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100470 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100471
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100472exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100474
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100475 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476}
477
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200478#if !defined(MBEDTLS_DEPRECATED_REMOVED)
479void mbedtls_sha512( const unsigned char *input,
480 size_t ilen,
481 unsigned char output[64],
482 int is384 )
483{
484 mbedtls_sha512_ret( input, ilen, output, is384 );
485}
486#endif
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490/*
491 * FIPS-180-2 test vectors
492 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000493static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000494{
495 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200496 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 { "" }
498};
499
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100500static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000501{
502 3, 112, 1000
503};
504
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200505static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000506{
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200507#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000508 /*
509 * SHA-384 test vectors
510 */
511 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
512 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
513 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
514 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
515 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
516 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
517 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
518 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
519 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
520 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
521 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
522 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
523 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
524 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
525 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
526 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
527 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
528 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200529#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
531 /*
532 * SHA-512 test vectors
533 */
534 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
535 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
536 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
537 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
538 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
539 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
540 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
541 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
542 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
543 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
544 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
545 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
546 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
547 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
548 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
549 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
550 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
551 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
552 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
553 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
554 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
555 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
556 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
557 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
558};
559
Manuel Pégourié-Gonnard74ca84a2020-01-29 09:46:49 +0100560#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200561
Paul Bakker5121ce52009-01-03 21:22:43 +0000562/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000563 * Checkup routine
564 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000566{
Paul Bakker5b4af392014-06-26 12:09:34 +0200567 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500568 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200569 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Russ Butlerbb83b422016-10-12 17:36:50 -0500572 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
573 if( NULL == buf )
574 {
575 if( verbose != 0 )
576 mbedtls_printf( "Buffer allocation failed\n" );
577
578 return( 1 );
579 }
580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200582
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100583 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 {
585 j = i % 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200586#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200588#else
589 k = 0;
590#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100595 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100596 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 if( j == 2 )
599 {
600 memset( buf, 'a', buflen = 1000 );
601
602 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100603 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100604 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100605 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100606 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100607 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100610 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100611 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100612 sha512_test_buflen[j] );
613 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100614 goto fail;
615 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100617 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100618 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Paul Bakker9e36f042013-06-30 14:34:05 +0200620 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100621 {
622 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100623 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100624 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
626 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 }
629
630 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100633 goto exit;
634
635fail:
636 if( verbose != 0 )
637 mbedtls_printf( "failed\n" );
638
Paul Bakker5b4af392014-06-26 12:09:34 +0200639exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500641 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200642
643 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000644}
645
Manuel Pégourié-Gonnard2b9b7802020-01-24 11:01:02 +0100646#undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_SHA512_C */