blob: 06a628aedce6e8e21dad87101ea8b9d9ac348f29 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jerome Forissier79013242021-07-28 10:24:04 +020025#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020026
27#if defined(MBEDTLS_SHA512_C)
28
29#include "mbedtls/sha512.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010030#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020031#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020032
33#if defined(_MSC_VER) || defined(__WATCOMC__)
34 #define UL64(x) x##ui64
35#else
36 #define UL64(x) x##ULL
37#endif
38
39#include <string.h>
40
41#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 */
52
Jens Wiklander3d3b0592019-03-20 15:30:29 +010053#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 )
Jens Wiklander817466c2018-05-22 13:49:31 +020056
Jens Wiklander3d3b0592019-03-20 15:30:29 +010057#if !defined(MBEDTLS_SHA512_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +020058
59/*
60 * 64-bit integer manipulation macros (big endian)
61 */
62#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 */
75
76#ifndef PUT_UINT64_BE
77#define PUT_UINT64_BE(n,b,i) \
78{ \
79 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
80 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
81 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
82 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
83 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
84 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
85 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
86 (b)[(i) + 7] = (unsigned char) ( (n) ); \
87}
88#endif /* PUT_UINT64_BE */
89
Jerome Forissier11fa71b2020-04-20 17:17:56 +020090#if defined(MBEDTLS_SHA512_SMALLER)
91static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
92{
93 PUT_UINT64_BE(n, b, i);
94}
95#else
96#define sha512_put_uint64_be PUT_UINT64_BE
97#endif /* MBEDTLS_SHA512_SMALLER */
98
Jens Wiklander817466c2018-05-22 13:49:31 +020099void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
100{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100101 SHA512_VALIDATE( ctx != NULL );
102
Jens Wiklander817466c2018-05-22 13:49:31 +0200103 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
104}
105
106void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
107{
108 if( ctx == NULL )
109 return;
110
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100111 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200112}
113
114void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
115 const mbedtls_sha512_context *src )
116{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100117 SHA512_VALIDATE( dst != NULL );
118 SHA512_VALIDATE( src != NULL );
119
Jens Wiklander817466c2018-05-22 13:49:31 +0200120 *dst = *src;
121}
122
123/*
124 * SHA-512 context setup
125 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100126int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200127{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100128 SHA512_VALIDATE_RET( ctx != NULL );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200129#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100130 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200131#else
132 SHA512_VALIDATE_RET( is384 == 0 );
133#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100134
Jens Wiklander817466c2018-05-22 13:49:31 +0200135 ctx->total[0] = 0;
136 ctx->total[1] = 0;
137
138 if( is384 == 0 )
139 {
140 /* SHA-512 */
141 ctx->state[0] = UL64(0x6A09E667F3BCC908);
142 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
143 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
144 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
145 ctx->state[4] = UL64(0x510E527FADE682D1);
146 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
147 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
148 ctx->state[7] = UL64(0x5BE0CD19137E2179);
149 }
150 else
151 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200152#if defined(MBEDTLS_SHA512_NO_SHA384)
153 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
154#else
Jens Wiklander817466c2018-05-22 13:49:31 +0200155 /* SHA-384 */
156 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
157 ctx->state[1] = UL64(0x629A292A367CD507);
158 ctx->state[2] = UL64(0x9159015A3070DD17);
159 ctx->state[3] = UL64(0x152FECD8F70E5939);
160 ctx->state[4] = UL64(0x67332667FFC00B31);
161 ctx->state[5] = UL64(0x8EB44A8768581511);
162 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
163 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200164#endif /* MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200165 }
166
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200167#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200168 ctx->is384 = is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200169#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100170
171 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200172}
173
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100174#if !defined(MBEDTLS_DEPRECATED_REMOVED)
175void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
176 int is384 )
177{
178 mbedtls_sha512_starts_ret( ctx, is384 );
179}
180#endif
181
Jens Wiklander817466c2018-05-22 13:49:31 +0200182#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
183
184/*
185 * Round constants
186 */
187static const uint64_t K[80] =
188{
189 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
190 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
191 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
192 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
193 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
194 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
195 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
196 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
197 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
198 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
199 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
200 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
201 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
202 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
203 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
204 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
205 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
206 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
207 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
208 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
209 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
210 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
211 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
212 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
213 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
214 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
215 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
216 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
217 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
218 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
219 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
220 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
221 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
222 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
223 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
224 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
225 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
226 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
227 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
228 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
229};
230
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100231int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
232 const unsigned char data[128] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200233{
234 int i;
Jerome Forissier79013242021-07-28 10:24:04 +0200235 struct
236 {
237 uint64_t temp1, temp2, W[80];
238 uint64_t A[8];
239 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +0200240
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100241 SHA512_VALIDATE_RET( ctx != NULL );
242 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
243
Jerome Forissier5b25c762020-04-07 11:18:49 +0200244#define SHR(x,n) ((x) >> (n))
245#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200246
247#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
248#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
249
250#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
251#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
252
Jerome Forissier5b25c762020-04-07 11:18:49 +0200253#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
254#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200255
Jerome Forissier79013242021-07-28 10:24:04 +0200256#define P(a,b,c,d,e,f,g,h,x,K) \
257 do \
258 { \
259 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
260 local.temp2 = S2(a) + F0((a),(b),(c)); \
261 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200262 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200263
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200264 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200265 local.A[i] = ctx->state[i];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200266
267#if defined(MBEDTLS_SHA512_SMALLER)
268 for( i = 0; i < 80; i++ )
269 {
270 if( i < 16 )
271 {
Jerome Forissier79013242021-07-28 10:24:04 +0200272 GET_UINT64_BE( local.W[i], data, i << 3 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200273 }
274 else
275 {
Jerome Forissier79013242021-07-28 10:24:04 +0200276 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
277 S0(local.W[i - 15]) + local.W[i - 16];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200278 }
279
Jerome Forissier79013242021-07-28 10:24:04 +0200280 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
281 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200282
Jerome Forissier79013242021-07-28 10:24:04 +0200283 local.temp1 = local.A[7]; local.A[7] = local.A[6];
284 local.A[6] = local.A[5]; local.A[5] = local.A[4];
285 local.A[4] = local.A[3]; local.A[3] = local.A[2];
286 local.A[2] = local.A[1]; local.A[1] = local.A[0];
287 local.A[0] = local.temp1;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200288 }
289#else /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200290 for( i = 0; i < 16; i++ )
291 {
Jerome Forissier79013242021-07-28 10:24:04 +0200292 GET_UINT64_BE( local.W[i], data, i << 3 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200293 }
294
295 for( ; i < 80; i++ )
296 {
Jerome Forissier79013242021-07-28 10:24:04 +0200297 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
298 S0(local.W[i - 15]) + local.W[i - 16];
Jens Wiklander817466c2018-05-22 13:49:31 +0200299 }
300
Jens Wiklander817466c2018-05-22 13:49:31 +0200301 i = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200302 do
303 {
Jerome Forissier79013242021-07-28 10:24:04 +0200304 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
305 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
306 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
307 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
308 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
309 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
310 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
311 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
312 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
313 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
314 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
315 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
316 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
317 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
318 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
319 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Jens Wiklander817466c2018-05-22 13:49:31 +0200320 }
321 while( i < 80 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200322#endif /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200323
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200324 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200325 ctx->state[i] += local.A[i];
326
327 /* Zeroise buffers and variables to clear sensitive data from memory. */
328 mbedtls_platform_zeroize( &local, sizeof( local ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100329
330 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200331}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100332
333#if !defined(MBEDTLS_DEPRECATED_REMOVED)
334void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
335 const unsigned char data[128] )
336{
337 mbedtls_internal_sha512_process( ctx, data );
338}
339#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200340#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
341
342/*
343 * SHA-512 process buffer
344 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100345int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
346 const unsigned char *input,
347 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200348{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200349 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200350 size_t fill;
351 unsigned int left;
352
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100353 SHA512_VALIDATE_RET( ctx != NULL );
354 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
355
Jens Wiklander817466c2018-05-22 13:49:31 +0200356 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100357 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200358
359 left = (unsigned int) (ctx->total[0] & 0x7F);
360 fill = 128 - left;
361
362 ctx->total[0] += (uint64_t) ilen;
363
364 if( ctx->total[0] < (uint64_t) ilen )
365 ctx->total[1]++;
366
367 if( left && ilen >= fill )
368 {
369 memcpy( (void *) (ctx->buffer + left), input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100370
371 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
372 return( ret );
373
Jens Wiklander817466c2018-05-22 13:49:31 +0200374 input += fill;
375 ilen -= fill;
376 left = 0;
377 }
378
379 while( ilen >= 128 )
380 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100381 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
382 return( ret );
383
Jens Wiklander817466c2018-05-22 13:49:31 +0200384 input += 128;
385 ilen -= 128;
386 }
387
388 if( ilen > 0 )
389 memcpy( (void *) (ctx->buffer + left), input, ilen );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100390
391 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200392}
393
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100394#if !defined(MBEDTLS_DEPRECATED_REMOVED)
395void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
396 const unsigned char *input,
397 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200398{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100399 mbedtls_sha512_update_ret( ctx, input, ilen );
400}
401#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200402
403/*
404 * SHA-512 final digest
405 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100406int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
407 unsigned char output[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200408{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200409 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100410 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200411 uint64_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200412
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100413 SHA512_VALIDATE_RET( ctx != NULL );
414 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
415
416 /*
417 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
418 */
419 used = ctx->total[0] & 0x7F;
420
421 ctx->buffer[used++] = 0x80;
422
423 if( used <= 112 )
424 {
425 /* Enough room for padding + length in current block */
426 memset( ctx->buffer + used, 0, 112 - used );
427 }
428 else
429 {
430 /* We'll need an extra block */
431 memset( ctx->buffer + used, 0, 128 - used );
432
433 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
434 return( ret );
435
436 memset( ctx->buffer, 0, 112 );
437 }
438
439 /*
440 * Add message length
441 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200442 high = ( ctx->total[0] >> 61 )
443 | ( ctx->total[1] << 3 );
444 low = ( ctx->total[0] << 3 );
445
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200446 sha512_put_uint64_be( high, ctx->buffer, 112 );
447 sha512_put_uint64_be( low, ctx->buffer, 120 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200448
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100449 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
450 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200451
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100452 /*
453 * Output final state
454 */
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200455 sha512_put_uint64_be( ctx->state[0], output, 0 );
456 sha512_put_uint64_be( ctx->state[1], output, 8 );
457 sha512_put_uint64_be( ctx->state[2], output, 16 );
458 sha512_put_uint64_be( ctx->state[3], output, 24 );
459 sha512_put_uint64_be( ctx->state[4], output, 32 );
460 sha512_put_uint64_be( ctx->state[5], output, 40 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200461
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200462#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200463 if( ctx->is384 == 0 )
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200464#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200465 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200466 sha512_put_uint64_be( ctx->state[6], output, 48 );
467 sha512_put_uint64_be( ctx->state[7], output, 56 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200468 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100469
470 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200471}
472
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100473#if !defined(MBEDTLS_DEPRECATED_REMOVED)
474void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
475 unsigned char output[64] )
476{
477 mbedtls_sha512_finish_ret( ctx, output );
478}
479#endif
480
Jens Wiklander817466c2018-05-22 13:49:31 +0200481#endif /* !MBEDTLS_SHA512_ALT */
482
483/*
484 * output = SHA-512( input buffer )
485 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100486int mbedtls_sha512_ret( const unsigned char *input,
487 size_t ilen,
488 unsigned char output[64],
489 int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200490{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200491 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200492 mbedtls_sha512_context ctx;
493
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200494#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100495 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200496#else
497 SHA512_VALIDATE_RET( is384 == 0 );
498#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100499 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
500 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
501
Jens Wiklander817466c2018-05-22 13:49:31 +0200502 mbedtls_sha512_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100503
504 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
505 goto exit;
506
507 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
508 goto exit;
509
510 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
511 goto exit;
512
513exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200514 mbedtls_sha512_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100515
516 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200517}
518
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100519#if !defined(MBEDTLS_DEPRECATED_REMOVED)
520void mbedtls_sha512( const unsigned char *input,
521 size_t ilen,
522 unsigned char output[64],
523 int is384 )
524{
525 mbedtls_sha512_ret( input, ilen, output, is384 );
526}
527#endif
528
Jens Wiklander817466c2018-05-22 13:49:31 +0200529#if defined(MBEDTLS_SELF_TEST)
530
531/*
532 * FIPS-180-2 test vectors
533 */
534static const unsigned char sha512_test_buf[3][113] =
535{
536 { "abc" },
Guido Vranken36905f92021-04-22 14:47:51 +0200537 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Jens Wiklander817466c2018-05-22 13:49:31 +0200538 { "" }
539};
540
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100541static const size_t sha512_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200542{
543 3, 112, 1000
544};
545
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200546static const unsigned char sha512_test_sum[][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200547{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200548#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200549 /*
550 * SHA-384 test vectors
551 */
552 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
553 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
554 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
555 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
556 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
557 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
558 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
559 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
560 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
561 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
562 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
563 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
564 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
565 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
566 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
567 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
568 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
569 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200570#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200571
572 /*
573 * SHA-512 test vectors
574 */
575 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
576 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
577 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
578 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
579 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
580 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
581 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
582 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
583 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
584 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
585 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
586 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
587 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
588 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
589 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
590 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
591 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
592 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
593 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
594 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
595 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
596 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
597 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
598 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
599};
600
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200601#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
602
Jens Wiklander817466c2018-05-22 13:49:31 +0200603/*
604 * Checkup routine
605 */
606int mbedtls_sha512_self_test( int verbose )
607{
608 int i, j, k, buflen, ret = 0;
609 unsigned char *buf;
610 unsigned char sha512sum[64];
611 mbedtls_sha512_context ctx;
612
613 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
614 if( NULL == buf )
615 {
616 if( verbose != 0 )
617 mbedtls_printf( "Buffer allocation failed\n" );
618
619 return( 1 );
620 }
621
622 mbedtls_sha512_init( &ctx );
623
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200624 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +0200625 {
626 j = i % 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200627#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200628 k = i < 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200629#else
630 k = 0;
631#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200632
633 if( verbose != 0 )
634 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
635
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100636 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
637 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200638
639 if( j == 2 )
640 {
641 memset( buf, 'a', buflen = 1000 );
642
643 for( j = 0; j < 1000; j++ )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100644 {
645 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
646 if( ret != 0 )
647 goto fail;
648 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200649 }
650 else
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100651 {
652 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
653 sha512_test_buflen[j] );
654 if( ret != 0 )
655 goto fail;
656 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200657
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100658 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
659 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200660
661 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
662 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200663 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100664 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200665 }
666
667 if( verbose != 0 )
668 mbedtls_printf( "passed\n" );
669 }
670
671 if( verbose != 0 )
672 mbedtls_printf( "\n" );
673
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100674 goto exit;
675
676fail:
677 if( verbose != 0 )
678 mbedtls_printf( "failed\n" );
679
Jens Wiklander817466c2018-05-22 13:49:31 +0200680exit:
681 mbedtls_sha512_free( &ctx );
682 mbedtls_free( buf );
683
684 return( ret );
685}
686
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200687#undef ARRAY_LENGTH
688
Jens Wiklander817466c2018-05-22 13:49:31 +0200689#endif /* MBEDTLS_SELF_TEST */
690
691#endif /* MBEDTLS_SHA512_C */