blob: 31608d675310bec52121926db43cbb32dda7fd07 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "mbedtls/sha512.h"
30# include "mbedtls/platform_util.h"
31# include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020033# if defined(_MSC_VER) || defined(__WATCOMC__)
34# define UL64(x) x##ui64
35# else
36# define UL64(x) x##ULL
37# endif
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000038
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020039# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000040
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020041# if defined(MBEDTLS_SELF_TEST)
42# if defined(MBEDTLS_PLATFORM_C)
43# include "mbedtls/platform.h"
44# else
45# include <stdio.h>
46# include <stdlib.h>
47# define mbedtls_printf printf
48# define mbedtls_calloc calloc
49# define mbedtls_free free
50# endif /* MBEDTLS_PLATFORM_C */
51# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020053# 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)
Hanno Beckerc7560492018-12-20 10:23:39 +000056
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020057# if !defined(MBEDTLS_SHA512_ALT)
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020058
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * 64-bit integer manipulation macros (big endian)
61 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020062# ifndef GET_UINT64_BE
63# define GET_UINT64_BE(n, b, i) \
64 { \
65 (n) = ((uint64_t)(b)[(i)] << 56) | \
66 ((uint64_t)(b)[(i) + 1] << 48) | \
67 ((uint64_t)(b)[(i) + 2] << 40) | \
68 ((uint64_t)(b)[(i) + 3] << 32) | \
69 ((uint64_t)(b)[(i) + 4] << 24) | \
70 ((uint64_t)(b)[(i) + 5] << 16) | \
71 ((uint64_t)(b)[(i) + 6] << 8) | \
72 ((uint64_t)(b)[(i) + 7]); \
73 }
74# endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076# ifndef PUT_UINT64_BE
77# define PUT_UINT64_BE(n, b, i) \
78 { \
79 (b)[(i)] = (unsigned char)((n) >> 56); \
80 (b)[(i) + 1] = (unsigned char)((n) >> 48); \
81 (b)[(i) + 2] = (unsigned char)((n) >> 40); \
82 (b)[(i) + 3] = (unsigned char)((n) >> 32); \
83 (b)[(i) + 4] = (unsigned char)((n) >> 24); \
84 (b)[(i) + 5] = (unsigned char)((n) >> 16); \
85 (b)[(i) + 6] = (unsigned char)((n) >> 8); \
86 (b)[(i) + 7] = (unsigned char)((n)); \
87 }
88# endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000089
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090# if defined(MBEDTLS_SHA512_SMALLER)
91static void sha512_put_uint64_be(uint64_t n, unsigned char *b, uint8_t i)
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020092{
93 PUT_UINT64_BE(n, b, i);
94}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020095# else
96# define sha512_put_uint64_be PUT_UINT64_BE
97# endif /* MBEDTLS_SHA512_SMALLER */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +020098
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020099void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200100{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200101 SHA512_VALIDATE(ctx != NULL);
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000102
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103 memset(ctx, 0, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200104}
105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
Paul Bakker5b4af392014-06-26 12:09:34 +0200107{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108 if (ctx == NULL)
Paul Bakker5b4af392014-06-26 12:09:34 +0200109 return;
110
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200111 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha512_context));
Paul Bakker5b4af392014-06-26 12:09:34 +0200112}
113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200114void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
115 const mbedtls_sha512_context *src)
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200116{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117 SHA512_VALIDATE(dst != NULL);
118 SHA512_VALIDATE(src != NULL);
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000119
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200120 *dst = *src;
121}
122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123/*
124 * SHA-512 context setup
125 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000127{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128 SHA512_VALIDATE_RET(ctx != NULL);
129# if defined(MBEDTLS_SHA384_C)
130 SHA512_VALIDATE_RET(is384 == 0 || is384 == 1);
131# else
132 SHA512_VALIDATE_RET(is384 == 0);
133# endif
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000134
Paul Bakker5121ce52009-01-03 21:22:43 +0000135 ctx->total[0] = 0;
136 ctx->total[1] = 0;
137
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200138 if (is384 == 0) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 /* SHA-512 */
140 ctx->state[0] = UL64(0x6A09E667F3BCC908);
141 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
142 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
143 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
144 ctx->state[4] = UL64(0x510E527FADE682D1);
145 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
146 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
147 ctx->state[7] = UL64(0x5BE0CD19137E2179);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200148 } else {
149# if !defined(MBEDTLS_SHA384_C)
150 return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
151# else
Paul Bakker5121ce52009-01-03 21:22:43 +0000152 /* SHA-384 */
153 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
154 ctx->state[1] = UL64(0x629A292A367CD507);
155 ctx->state[2] = UL64(0x9159015A3070DD17);
156 ctx->state[3] = UL64(0x152FECD8F70E5939);
157 ctx->state[4] = UL64(0x67332667FFC00B31);
158 ctx->state[5] = UL64(0x8EB44A8768581511);
159 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
160 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161# endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000162 }
163
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200164# if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000165 ctx->is384 = is384;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200166# endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100167
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000169}
170
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200171# if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200172
173/*
174 * Round constants
175 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176static const uint64_t K[80] = {
177 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
178 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
179 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
180 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
181 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
182 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
183 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
184 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
185 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
186 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
187 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
188 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
189 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
190 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
191 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
192 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
193 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
194 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
195 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
196 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
197 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
198 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
199 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
200 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
201 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
202 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
203 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
204 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
205 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
206 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
207 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
208 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
209 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
210 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
211 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
212 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
213 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
214 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
215 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
216 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200217};
218
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx,
220 const unsigned char data[128])
Paul Bakker5121ce52009-01-03 21:22:43 +0000221{
222 int i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200223 struct {
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200224 uint64_t temp1, temp2, W[80];
225 uint64_t A[8];
226 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000227
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200228 SHA512_VALIDATE_RET(ctx != NULL);
229 SHA512_VALIDATE_RET((const unsigned char *)data != NULL);
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000230
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200231# define SHR(x, n) ((x) >> (n))
232# define ROTR(x, n) (SHR((x), (n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200234# define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
235# define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200237# define S2(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
238# define S3(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200240# define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
241# define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200243# define P(a, b, c, d, e, f, g, h, x, K) \
244 do { \
245 local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \
246 local.temp2 = S2(a) + F0((a), (b), (c)); \
247 (d) += local.temp1; \
248 (h) = local.temp1 + local.temp2; \
249 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200251 for (i = 0; i < 8; i++)
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200252 local.A[i] = ctx->state[i];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200253
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200254# if defined(MBEDTLS_SHA512_SMALLER)
255 for (i = 0; i < 80; i++) {
256 if (i < 16) {
257 GET_UINT64_BE(local.W[i], data, i << 3);
258 } else {
259 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
260 S0(local.W[i - 15]) + local.W[i - 16];
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200261 }
262
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +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]);
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 local.temp1 = local.A[7];
267 local.A[7] = local.A[6];
268 local.A[6] = local.A[5];
269 local.A[5] = local.A[4];
270 local.A[4] = local.A[3];
271 local.A[3] = local.A[2];
272 local.A[2] = local.A[1];
273 local.A[1] = local.A[0];
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200274 local.A[0] = local.temp1;
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200275 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200276# else /* MBEDTLS_SHA512_SMALLER */
277 for (i = 0; i < 16; i++) {
278 GET_UINT64_BE(local.W[i], data, i << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 }
280
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281 for (; i < 80; i++) {
282 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] + S0(local.W[i - 15]) +
283 local.W[i - 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 }
285
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 i = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200287 do {
288 P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
289 local.A[5], local.A[6], local.A[7], local.W[i], K[i]);
290 i++;
291 P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
292 local.A[4], local.A[5], local.A[6], local.W[i], K[i]);
293 i++;
294 P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
295 local.A[3], local.A[4], local.A[5], local.W[i], K[i]);
296 i++;
297 P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
298 local.A[2], local.A[3], local.A[4], local.W[i], K[i]);
299 i++;
300 P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
301 local.A[1], local.A[2], local.A[3], local.W[i], K[i]);
302 i++;
303 P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
304 local.A[0], local.A[1], local.A[2], local.W[i], K[i]);
305 i++;
306 P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
307 local.A[7], local.A[0], local.A[1], local.W[i], K[i]);
308 i++;
309 P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
310 local.A[6], local.A[7], local.A[0], local.W[i], K[i]);
311 i++;
312 } while (i < 80);
313# endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200315 for (i = 0; i < 8; i++)
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200316 ctx->state[i] += local.A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100317
gabor-mezei-arm76749ae2020-07-30 16:41:25 +0200318 /* Zeroise buffers and variables to clear sensitive data from memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200319 mbedtls_platform_zeroize(&local, sizeof(local));
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200321 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322}
Jaeden Amero041039f2018-02-19 15:28:08 +0000323
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200324# endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
326/*
327 * SHA-512 process buffer
328 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200329int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
330 const unsigned char *input,
331 size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
Janos Follath24eed8d2019-11-22 13:21:35 +0000333 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000334 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000335 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200337 SHA512_VALIDATE_RET(ctx != NULL);
338 SHA512_VALIDATE_RET(ilen == 0 || input != NULL);
Hanno Beckerca6f4582018-12-18 15:37:22 +0000339
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 if (ilen == 0)
341 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200343 left = (unsigned int)(ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000344 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200346 ctx->total[0] += (uint64_t)ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 if (ctx->total[0] < (uint64_t)ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 ctx->total[1]++;
350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351 if (left && ilen >= fill) {
352 memcpy((void *)(ctx->buffer + left), input, fill);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100353
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200354 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0)
355 return ret;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100356
Paul Bakker5121ce52009-01-03 21:22:43 +0000357 input += fill;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200358 ilen -= fill;
Paul Bakker5121ce52009-01-03 21:22:43 +0000359 left = 0;
360 }
361
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 while (ilen >= 128) {
363 if ((ret = mbedtls_internal_sha512_process(ctx, input)) != 0)
364 return ret;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100365
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 input += 128;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 ilen -= 128;
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 }
369
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200370 if (ilen > 0)
371 memcpy((void *)(ctx->buffer + left), input, ilen);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100372
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200373 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000374}
375
Paul Bakker5121ce52009-01-03 21:22:43 +0000376/*
377 * SHA-512 final digest
378 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200379int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
Janos Follath24eed8d2019-11-22 13:21:35 +0000381 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200382 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000383 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385 SHA512_VALIDATE_RET(ctx != NULL);
386 SHA512_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000387
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200388 /*
389 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
390 */
391 used = ctx->total[0] & 0x7F;
392
393 ctx->buffer[used++] = 0x80;
394
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200395 if (used <= 112) {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200396 /* Enough room for padding + length in current block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200397 memset(ctx->buffer + used, 0, 112 - used);
398 } else {
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200399 /* We'll need an extra block */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400 memset(ctx->buffer + used, 0, 128 - used);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200401
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200402 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0)
403 return ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200404
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405 memset(ctx->buffer, 0, 112);
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200406 }
407
408 /*
409 * Add message length
410 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200411 high = (ctx->total[0] >> 61) | (ctx->total[1] << 3);
412 low = (ctx->total[0] << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200414 sha512_put_uint64_be(high, ctx->buffer, 112);
415 sha512_put_uint64_be(low, ctx->buffer, 120);
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200417 if ((ret = mbedtls_internal_sha512_process(ctx, ctx->buffer)) != 0)
418 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200420 /*
421 * Output final state
422 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200423 sha512_put_uint64_be(ctx->state[0], output, 0);
424 sha512_put_uint64_be(ctx->state[1], output, 8);
425 sha512_put_uint64_be(ctx->state[2], output, 16);
426 sha512_put_uint64_be(ctx->state[3], output, 24);
427 sha512_put_uint64_be(ctx->state[4], output, 32);
428 sha512_put_uint64_be(ctx->state[5], output, 40);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430# if defined(MBEDTLS_SHA384_C)
431 if (ctx->is384 == 0)
432# endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200434 sha512_put_uint64_be(ctx->state[6], output, 48);
435 sha512_put_uint64_be(ctx->state[7], output, 56);
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000439}
440
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200441# endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200442
Paul Bakker5121ce52009-01-03 21:22:43 +0000443/*
444 * output = SHA-512( input buffer )
445 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200446int mbedtls_sha512(const unsigned char *input,
447 size_t ilen,
448 unsigned char *output,
449 int is384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000450{
Janos Follath24eed8d2019-11-22 13:21:35 +0000451 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200454# if defined(MBEDTLS_SHA384_C)
455 SHA512_VALIDATE_RET(is384 == 0 || is384 == 1);
456# else
457 SHA512_VALIDATE_RET(is384 == 0);
458# endif
459 SHA512_VALIDATE_RET(ilen == 0 || input != NULL);
460 SHA512_VALIDATE_RET((unsigned char *)output != NULL);
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000461
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200462 mbedtls_sha512_init(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100463
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200464 if ((ret = mbedtls_sha512_starts(&ctx, is384)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100465 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200467 if ((ret = mbedtls_sha512_update(&ctx, input, ilen)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100468 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100469
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470 if ((ret = mbedtls_sha512_finish(&ctx, output)) != 0)
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100471 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100472
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100473exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200474 mbedtls_sha512_free(&ctx);
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100475
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200476 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000477}
478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200479# if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481/*
482 * FIPS-180-2 test vectors
483 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200484static const unsigned char sha512_test_buf[3][113] = {
Paul Bakker5121ce52009-01-03 21:22:43 +0000485 { "abc" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200486 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 { "" }
488};
489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200490static const size_t sha512_test_buflen[3] = { 3, 112, 1000 };
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492static const unsigned char sha512_test_sum[][64] = {
493# if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 /*
495 * SHA-384 test vectors
496 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200497 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 0xB5, 0xA0, 0x3D, 0x69,
498 0x9A, 0xC6, 0x50, 0x07, 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
499 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 0x80, 0x86, 0x07, 0x2B,
500 0xA1, 0xE7, 0xCC, 0x23, 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
501 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, 0x3D, 0x19, 0x2F, 0xC7,
502 0x82, 0xCD, 0x1B, 0x47, 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
503 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, 0xFC, 0xC7, 0xC7, 0x1A,
504 0x55, 0x7E, 0x2D, 0xB9, 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
505 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, 0x08, 0x6E, 0x83, 0x4E,
506 0x31, 0x0A, 0x4A, 0x1C, 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
507 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, 0x07, 0xB8, 0xB3, 0xDC,
508 0x38, 0xEC, 0xC4, 0xEB, 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
509# endif /* MBEDTLS_SHA384_C */
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
511 /*
512 * SHA-512 test vectors
513 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200514 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 0xCC, 0x41, 0x73,
515 0x49, 0xAE, 0x20, 0x41, 0x31, 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9,
516 0x7E, 0xA2, 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 0x21,
517 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 0x36, 0xBA, 0x3C, 0x23,
518 0xA3, 0xFE, 0xEB, 0xBD, 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8,
519 0x0E, 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
520 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 0x8C, 0xF4, 0xF7,
521 0x28, 0x14, 0xFC, 0x14, 0x3F, 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F,
522 0x7F, 0xA1, 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 0x50,
523 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 0x33, 0x1B, 0x99, 0xDE,
524 0xC4, 0xB5, 0x43, 0x3A, 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26,
525 0x54, 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
526 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, 0x4E, 0x2E, 0x42,
527 0xC7, 0xBC, 0x15, 0xB4, 0x63, 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20,
528 0x44, 0x28, 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, 0xDE,
529 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, 0x4C, 0xB0, 0x43, 0x2C,
530 0xE5, 0x77, 0xC3, 0x1B, 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA,
531 0x2E, 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
Paul Bakker5121ce52009-01-03 21:22:43 +0000532};
533
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200534# define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200535
Paul Bakker5121ce52009-01-03 21:22:43 +0000536/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 * Checkup routine
538 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200539int mbedtls_sha512_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000540{
Paul Bakker5b4af392014-06-26 12:09:34 +0200541 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500542 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200543 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200546 buf = mbedtls_calloc(1024, sizeof(unsigned char));
547 if (NULL == buf) {
548 if (verbose != 0)
549 mbedtls_printf("Buffer allocation failed\n");
Russ Butlerbb83b422016-10-12 17:36:50 -0500550
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200551 return 1;
Russ Butlerbb83b422016-10-12 17:36:50 -0500552 }
553
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200554 mbedtls_sha512_init(&ctx);
Paul Bakker5b4af392014-06-26 12:09:34 +0200555
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200556 for (i = 0; i < (int)ARRAY_LENGTH(sha512_test_sum); i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000557 j = i % 3;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200558# if defined(MBEDTLS_SHA384_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 k = i < 3;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200560# else
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200561 k = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562# endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200564 if (verbose != 0)
565 mbedtls_printf(" SHA-%d test #%d: ", 512 - k * 128, j + 1);
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200567 if ((ret = mbedtls_sha512_starts(&ctx, k)) != 0)
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100568 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200570 if (j == 2) {
571 memset(buf, 'a', buflen = 1000);
Paul Bakker5121ce52009-01-03 21:22:43 +0000572
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200573 for (j = 0; j < 1000; j++) {
574 ret = mbedtls_sha512_update(&ctx, buf, buflen);
575 if (ret != 0)
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100576 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100577 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200578 } else {
579 ret = mbedtls_sha512_update(&ctx, sha512_test_buf[j],
580 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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200588 if (memcmp(sha512sum, sha512_test_sum[i], 64 - k * 16) != 0) {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100589 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100590 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100591 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200593 if (verbose != 0)
594 mbedtls_printf("passed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 }
596
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200597 if (verbose != 0)
598 mbedtls_printf("\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100600 goto exit;
601
602fail:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200603 if (verbose != 0)
604 mbedtls_printf("failed\n");
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100605
Paul Bakker5b4af392014-06-26 12:09:34 +0200606exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200607 mbedtls_sha512_free(&ctx);
608 mbedtls_free(buf);
Paul Bakker5b4af392014-06-26 12:09:34 +0200609
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200610 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611}
612
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200613# undef ARRAY_LENGTH
Manuel Pégourié-Gonnard2d885492020-01-07 10:17:35 +0100614
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200615# endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617#endif /* MBEDTLS_SHA512_C */