blob: d5a5b51d03dcd8073371d028c10a622ac0f11535 [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * FIPS-180-2 compliant SHA-384/512 implementation
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21/*
22 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
23 *
24 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
25 */
26
27#if !defined(MBEDTLS_CONFIG_FILE)
28#include "mbedtls/config.h"
29#else
30#include MBEDTLS_CONFIG_FILE
31#endif
32
33#if defined(MBEDTLS_SHA512_C)
34
35#include "mbedtls/sha512.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020037#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020038
39#if defined(_MSC_VER) || defined(__WATCOMC__)
40 #define UL64(x) x##ui64
41#else
42 #define UL64(x) x##ULL
43#endif
44
45#include <string.h>
46
47#if defined(MBEDTLS_SELF_TEST)
48#if defined(MBEDTLS_PLATFORM_C)
49#include "mbedtls/platform.h"
50#else
51#include <stdio.h>
52#include <stdlib.h>
53#define mbedtls_printf printf
54#define mbedtls_calloc calloc
55#define mbedtls_free free
56#endif /* MBEDTLS_PLATFORM_C */
57#endif /* MBEDTLS_SELF_TEST */
58
Jens Wiklander3d3b0592019-03-20 15:30:29 +010059#define SHA512_VALIDATE_RET(cond) \
60 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
61#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020062
Jens Wiklander3d3b0592019-03-20 15:30:29 +010063#if !defined(MBEDTLS_SHA512_ALT)
Jens Wiklander817466c2018-05-22 13:49:31 +020064
65/*
66 * 64-bit integer manipulation macros (big endian)
67 */
68#ifndef GET_UINT64_BE
69#define GET_UINT64_BE(n,b,i) \
70{ \
71 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
72 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
73 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
74 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
75 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
76 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
77 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
78 | ( (uint64_t) (b)[(i) + 7] ); \
79}
80#endif /* GET_UINT64_BE */
81
82#ifndef PUT_UINT64_BE
83#define PUT_UINT64_BE(n,b,i) \
84{ \
85 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
86 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
87 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
88 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
89 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
90 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
91 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
92 (b)[(i) + 7] = (unsigned char) ( (n) ); \
93}
94#endif /* PUT_UINT64_BE */
95
Jerome Forissier11fa71b2020-04-20 17:17:56 +020096#if defined(MBEDTLS_SHA512_SMALLER)
97static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
98{
99 PUT_UINT64_BE(n, b, i);
100}
101#else
102#define sha512_put_uint64_be PUT_UINT64_BE
103#endif /* MBEDTLS_SHA512_SMALLER */
104
Jens Wiklander817466c2018-05-22 13:49:31 +0200105void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
106{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100107 SHA512_VALIDATE( ctx != NULL );
108
Jens Wiklander817466c2018-05-22 13:49:31 +0200109 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
110}
111
112void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
113{
114 if( ctx == NULL )
115 return;
116
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100117 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200118}
119
120void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
121 const mbedtls_sha512_context *src )
122{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100123 SHA512_VALIDATE( dst != NULL );
124 SHA512_VALIDATE( src != NULL );
125
Jens Wiklander817466c2018-05-22 13:49:31 +0200126 *dst = *src;
127}
128
129/*
130 * SHA-512 context setup
131 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100132int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200133{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100134 SHA512_VALIDATE_RET( ctx != NULL );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200135#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100136 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200137#else
138 SHA512_VALIDATE_RET( is384 == 0 );
139#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100140
Jens Wiklander817466c2018-05-22 13:49:31 +0200141 ctx->total[0] = 0;
142 ctx->total[1] = 0;
143
144 if( is384 == 0 )
145 {
146 /* SHA-512 */
147 ctx->state[0] = UL64(0x6A09E667F3BCC908);
148 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
149 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
150 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
151 ctx->state[4] = UL64(0x510E527FADE682D1);
152 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
153 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
154 ctx->state[7] = UL64(0x5BE0CD19137E2179);
155 }
156 else
157 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200158#if defined(MBEDTLS_SHA512_NO_SHA384)
159 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
160#else
Jens Wiklander817466c2018-05-22 13:49:31 +0200161 /* SHA-384 */
162 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
163 ctx->state[1] = UL64(0x629A292A367CD507);
164 ctx->state[2] = UL64(0x9159015A3070DD17);
165 ctx->state[3] = UL64(0x152FECD8F70E5939);
166 ctx->state[4] = UL64(0x67332667FFC00B31);
167 ctx->state[5] = UL64(0x8EB44A8768581511);
168 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
169 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200170#endif /* MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200171 }
172
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200173#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200174 ctx->is384 = is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200175#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100176
177 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200178}
179
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100180#if !defined(MBEDTLS_DEPRECATED_REMOVED)
181void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
182 int is384 )
183{
184 mbedtls_sha512_starts_ret( ctx, is384 );
185}
186#endif
187
Jens Wiklander817466c2018-05-22 13:49:31 +0200188#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
189
190/*
191 * Round constants
192 */
193static const uint64_t K[80] =
194{
195 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
196 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
197 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
198 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
199 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
200 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
201 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
202 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
203 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
204 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
205 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
206 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
207 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
208 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
209 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
210 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
211 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
212 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
213 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
214 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
215 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
216 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
217 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
218 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
219 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
220 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
221 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
222 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
223 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
224 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
225 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
226 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
227 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
228 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
229 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
230 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
231 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
232 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
233 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
234 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
235};
236
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100237int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
238 const unsigned char data[128] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200239{
240 int i;
241 uint64_t temp1, temp2, W[80];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200242 uint64_t A[8];
Jens Wiklander817466c2018-05-22 13:49:31 +0200243
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100244 SHA512_VALIDATE_RET( ctx != NULL );
245 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
246
Jerome Forissier5b25c762020-04-07 11:18:49 +0200247#define SHR(x,n) ((x) >> (n))
248#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200249
250#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
251#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
252
253#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
254#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
255
Jerome Forissier5b25c762020-04-07 11:18:49 +0200256#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
257#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200258
Jerome Forissier5b25c762020-04-07 11:18:49 +0200259#define P(a,b,c,d,e,f,g,h,x,K) \
260 do \
261 { \
262 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
263 temp2 = S2(a) + F0((a),(b),(c)); \
264 (d) += temp1; (h) = temp1 + temp2; \
265 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200266
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200267 for( i = 0; i < 8; i++ )
268 A[i] = ctx->state[i];
269
270#if defined(MBEDTLS_SHA512_SMALLER)
271 for( i = 0; i < 80; i++ )
272 {
273 if( i < 16 )
274 {
275 GET_UINT64_BE( W[i], data, i << 3 );
276 }
277 else
278 {
279 W[i] = S1(W[i - 2]) + W[i - 7] +
280 S0(W[i - 15]) + W[i - 16];
281 }
282
283 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
284
285 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
286 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
287 }
288#else /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200289 for( i = 0; i < 16; i++ )
290 {
291 GET_UINT64_BE( W[i], data, i << 3 );
292 }
293
294 for( ; i < 80; i++ )
295 {
296 W[i] = S1(W[i - 2]) + W[i - 7] +
297 S0(W[i - 15]) + W[i - 16];
298 }
299
Jens Wiklander817466c2018-05-22 13:49:31 +0200300 i = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200301 do
302 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200303 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
304 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
305 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
306 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
307 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
308 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
309 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
310 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
Jens Wiklander817466c2018-05-22 13:49:31 +0200311 }
312 while( i < 80 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200313#endif /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200314
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200315 for( i = 0; i < 8; i++ )
316 ctx->state[i] += A[i];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100317
318 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200319}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100320
321#if !defined(MBEDTLS_DEPRECATED_REMOVED)
322void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
323 const unsigned char data[128] )
324{
325 mbedtls_internal_sha512_process( ctx, data );
326}
327#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200328#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
329
330/*
331 * SHA-512 process buffer
332 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100333int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
334 const unsigned char *input,
335 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200336{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200337 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200338 size_t fill;
339 unsigned int left;
340
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100341 SHA512_VALIDATE_RET( ctx != NULL );
342 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
343
Jens Wiklander817466c2018-05-22 13:49:31 +0200344 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100345 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200346
347 left = (unsigned int) (ctx->total[0] & 0x7F);
348 fill = 128 - left;
349
350 ctx->total[0] += (uint64_t) ilen;
351
352 if( ctx->total[0] < (uint64_t) ilen )
353 ctx->total[1]++;
354
355 if( left && ilen >= fill )
356 {
357 memcpy( (void *) (ctx->buffer + left), input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100358
359 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
360 return( ret );
361
Jens Wiklander817466c2018-05-22 13:49:31 +0200362 input += fill;
363 ilen -= fill;
364 left = 0;
365 }
366
367 while( ilen >= 128 )
368 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100369 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
370 return( ret );
371
Jens Wiklander817466c2018-05-22 13:49:31 +0200372 input += 128;
373 ilen -= 128;
374 }
375
376 if( ilen > 0 )
377 memcpy( (void *) (ctx->buffer + left), input, ilen );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100378
379 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200380}
381
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100382#if !defined(MBEDTLS_DEPRECATED_REMOVED)
383void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
384 const unsigned char *input,
385 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200386{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100387 mbedtls_sha512_update_ret( ctx, input, ilen );
388}
389#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200390
391/*
392 * SHA-512 final digest
393 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100394int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
395 unsigned char output[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200396{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200397 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100398 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200399 uint64_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200400
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100401 SHA512_VALIDATE_RET( ctx != NULL );
402 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
403
404 /*
405 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
406 */
407 used = ctx->total[0] & 0x7F;
408
409 ctx->buffer[used++] = 0x80;
410
411 if( used <= 112 )
412 {
413 /* Enough room for padding + length in current block */
414 memset( ctx->buffer + used, 0, 112 - used );
415 }
416 else
417 {
418 /* We'll need an extra block */
419 memset( ctx->buffer + used, 0, 128 - used );
420
421 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
422 return( ret );
423
424 memset( ctx->buffer, 0, 112 );
425 }
426
427 /*
428 * Add message length
429 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200430 high = ( ctx->total[0] >> 61 )
431 | ( ctx->total[1] << 3 );
432 low = ( ctx->total[0] << 3 );
433
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200434 sha512_put_uint64_be( high, ctx->buffer, 112 );
435 sha512_put_uint64_be( low, ctx->buffer, 120 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200436
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100437 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
438 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200439
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100440 /*
441 * Output final state
442 */
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200443 sha512_put_uint64_be( ctx->state[0], output, 0 );
444 sha512_put_uint64_be( ctx->state[1], output, 8 );
445 sha512_put_uint64_be( ctx->state[2], output, 16 );
446 sha512_put_uint64_be( ctx->state[3], output, 24 );
447 sha512_put_uint64_be( ctx->state[4], output, 32 );
448 sha512_put_uint64_be( ctx->state[5], output, 40 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200449
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200450#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200451 if( ctx->is384 == 0 )
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200452#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200453 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200454 sha512_put_uint64_be( ctx->state[6], output, 48 );
455 sha512_put_uint64_be( ctx->state[7], output, 56 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200456 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100457
458 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200459}
460
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100461#if !defined(MBEDTLS_DEPRECATED_REMOVED)
462void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
463 unsigned char output[64] )
464{
465 mbedtls_sha512_finish_ret( ctx, output );
466}
467#endif
468
Jens Wiklander817466c2018-05-22 13:49:31 +0200469#endif /* !MBEDTLS_SHA512_ALT */
470
471/*
472 * output = SHA-512( input buffer )
473 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100474int mbedtls_sha512_ret( const unsigned char *input,
475 size_t ilen,
476 unsigned char output[64],
477 int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200478{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200479 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200480 mbedtls_sha512_context ctx;
481
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200482#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100483 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200484#else
485 SHA512_VALIDATE_RET( is384 == 0 );
486#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100487 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
488 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
489
Jens Wiklander817466c2018-05-22 13:49:31 +0200490 mbedtls_sha512_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100491
492 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
493 goto exit;
494
495 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
496 goto exit;
497
498 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
499 goto exit;
500
501exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200502 mbedtls_sha512_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100503
504 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200505}
506
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100507#if !defined(MBEDTLS_DEPRECATED_REMOVED)
508void mbedtls_sha512( const unsigned char *input,
509 size_t ilen,
510 unsigned char output[64],
511 int is384 )
512{
513 mbedtls_sha512_ret( input, ilen, output, is384 );
514}
515#endif
516
Jens Wiklander817466c2018-05-22 13:49:31 +0200517#if defined(MBEDTLS_SELF_TEST)
518
519/*
520 * FIPS-180-2 test vectors
521 */
522static const unsigned char sha512_test_buf[3][113] =
523{
524 { "abc" },
Guido Vranken36905f92021-04-22 14:47:51 +0200525 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Jens Wiklander817466c2018-05-22 13:49:31 +0200526 { "" }
527};
528
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100529static const size_t sha512_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200530{
531 3, 112, 1000
532};
533
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200534static const unsigned char sha512_test_sum[][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200535{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200536#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200537 /*
538 * SHA-384 test vectors
539 */
540 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
541 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
542 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
543 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
544 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
545 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
546 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
547 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
548 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
549 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
550 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
551 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
552 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
553 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
554 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
555 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
556 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
557 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200558#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200559
560 /*
561 * SHA-512 test vectors
562 */
563 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
564 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
565 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
566 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
567 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
568 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
569 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
570 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
571 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
572 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
573 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
574 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
575 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
576 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
577 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
578 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
579 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
580 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
581 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
582 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
583 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
584 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
585 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
586 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
587};
588
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200589#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
590
Jens Wiklander817466c2018-05-22 13:49:31 +0200591/*
592 * Checkup routine
593 */
594int mbedtls_sha512_self_test( int verbose )
595{
596 int i, j, k, buflen, ret = 0;
597 unsigned char *buf;
598 unsigned char sha512sum[64];
599 mbedtls_sha512_context ctx;
600
601 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
602 if( NULL == buf )
603 {
604 if( verbose != 0 )
605 mbedtls_printf( "Buffer allocation failed\n" );
606
607 return( 1 );
608 }
609
610 mbedtls_sha512_init( &ctx );
611
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200612 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +0200613 {
614 j = i % 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200615#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200616 k = i < 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200617#else
618 k = 0;
619#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200620
621 if( verbose != 0 )
622 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
623
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100624 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
625 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200626
627 if( j == 2 )
628 {
629 memset( buf, 'a', buflen = 1000 );
630
631 for( j = 0; j < 1000; j++ )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100632 {
633 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
634 if( ret != 0 )
635 goto fail;
636 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200637 }
638 else
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100639 {
640 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
641 sha512_test_buflen[j] );
642 if( ret != 0 )
643 goto fail;
644 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200645
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100646 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
647 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200648
649 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
650 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200651 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100652 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200653 }
654
655 if( verbose != 0 )
656 mbedtls_printf( "passed\n" );
657 }
658
659 if( verbose != 0 )
660 mbedtls_printf( "\n" );
661
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100662 goto exit;
663
664fail:
665 if( verbose != 0 )
666 mbedtls_printf( "failed\n" );
667
Jens Wiklander817466c2018-05-22 13:49:31 +0200668exit:
669 mbedtls_sha512_free( &ctx );
670 mbedtls_free( buf );
671
672 return( ret );
673}
674
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200675#undef ARRAY_LENGTH
676
Jens Wiklander817466c2018-05-22 13:49:31 +0200677#endif /* MBEDTLS_SELF_TEST */
678
679#endif /* MBEDTLS_SHA512_C */