blob: 02a135ca926569bcf7eb6f5b700056046f2e7f64 [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
Jerome Forissier11fa71b2020-04-20 17:17:56 +020059#if defined(MBEDTLS_SHA512_SMALLER)
60static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
61{
Jerome Forissier039e02d2022-08-09 17:10:15 +020062 MBEDTLS_PUT_UINT64_BE(n, b, i);
Jerome Forissier11fa71b2020-04-20 17:17:56 +020063}
64#else
Jerome Forissier039e02d2022-08-09 17:10:15 +020065#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
Jerome Forissier11fa71b2020-04-20 17:17:56 +020066#endif /* MBEDTLS_SHA512_SMALLER */
67
Jens Wiklander817466c2018-05-22 13:49:31 +020068void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
69{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010070 SHA512_VALIDATE( ctx != NULL );
71
Jens Wiklander817466c2018-05-22 13:49:31 +020072 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
73}
74
75void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
76{
77 if( ctx == NULL )
78 return;
79
Jens Wiklander3d3b0592019-03-20 15:30:29 +010080 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +020081}
82
83void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
84 const mbedtls_sha512_context *src )
85{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010086 SHA512_VALIDATE( dst != NULL );
87 SHA512_VALIDATE( src != NULL );
88
Jens Wiklander817466c2018-05-22 13:49:31 +020089 *dst = *src;
90}
91
92/*
93 * SHA-512 context setup
94 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +010095int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +020096{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010097 SHA512_VALIDATE_RET( ctx != NULL );
Jerome Forissier11fa71b2020-04-20 17:17:56 +020098#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010099 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200100#else
101 SHA512_VALIDATE_RET( is384 == 0 );
102#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100103
Jens Wiklander817466c2018-05-22 13:49:31 +0200104 ctx->total[0] = 0;
105 ctx->total[1] = 0;
106
107 if( is384 == 0 )
108 {
109 /* SHA-512 */
110 ctx->state[0] = UL64(0x6A09E667F3BCC908);
111 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
112 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
113 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
114 ctx->state[4] = UL64(0x510E527FADE682D1);
115 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
116 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
117 ctx->state[7] = UL64(0x5BE0CD19137E2179);
118 }
119 else
120 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200121#if defined(MBEDTLS_SHA512_NO_SHA384)
122 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
123#else
Jens Wiklander817466c2018-05-22 13:49:31 +0200124 /* SHA-384 */
125 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
126 ctx->state[1] = UL64(0x629A292A367CD507);
127 ctx->state[2] = UL64(0x9159015A3070DD17);
128 ctx->state[3] = UL64(0x152FECD8F70E5939);
129 ctx->state[4] = UL64(0x67332667FFC00B31);
130 ctx->state[5] = UL64(0x8EB44A8768581511);
131 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
132 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200133#endif /* MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200134 }
135
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200136#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200137 ctx->is384 = is384;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200138#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100139
140 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200141}
142
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100143#if !defined(MBEDTLS_DEPRECATED_REMOVED)
144void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
145 int is384 )
146{
147 mbedtls_sha512_starts_ret( ctx, is384 );
148}
149#endif
150
Jens Wiklander817466c2018-05-22 13:49:31 +0200151#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
152
153/*
154 * Round constants
155 */
156static const uint64_t K[80] =
157{
158 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
159 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
160 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
161 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
162 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
163 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
164 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
165 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
166 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
167 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
168 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
169 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
170 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
171 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
172 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
173 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
174 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
175 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
176 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
177 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
178 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
179 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
180 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
181 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
182 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
183 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
184 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
185 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
186 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
187 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
188 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
189 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
190 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
191 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
192 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
193 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
194 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
195 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
196 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
197 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
198};
199
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100200int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
201 const unsigned char data[128] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200202{
203 int i;
Jerome Forissier79013242021-07-28 10:24:04 +0200204 struct
205 {
206 uint64_t temp1, temp2, W[80];
207 uint64_t A[8];
208 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +0200209
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100210 SHA512_VALIDATE_RET( ctx != NULL );
211 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
212
Jerome Forissier5b25c762020-04-07 11:18:49 +0200213#define SHR(x,n) ((x) >> (n))
214#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200215
216#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
217#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
218
219#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
220#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
221
Jerome Forissier5b25c762020-04-07 11:18:49 +0200222#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
223#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200224
Jerome Forissier79013242021-07-28 10:24:04 +0200225#define P(a,b,c,d,e,f,g,h,x,K) \
226 do \
227 { \
228 local.temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
229 local.temp2 = S2(a) + F0((a),(b),(c)); \
230 (d) += local.temp1; (h) = local.temp1 + local.temp2; \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200231 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200232
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200233 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200234 local.A[i] = ctx->state[i];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200235
236#if defined(MBEDTLS_SHA512_SMALLER)
237 for( i = 0; i < 80; i++ )
238 {
239 if( i < 16 )
240 {
Jerome Forissier039e02d2022-08-09 17:10:15 +0200241 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200242 }
243 else
244 {
Jerome Forissier79013242021-07-28 10:24:04 +0200245 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
246 S0(local.W[i - 15]) + local.W[i - 16];
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200247 }
248
Jerome Forissier79013242021-07-28 10:24:04 +0200249 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
250 local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200251
Jerome Forissier79013242021-07-28 10:24:04 +0200252 local.temp1 = local.A[7]; local.A[7] = local.A[6];
253 local.A[6] = local.A[5]; local.A[5] = local.A[4];
254 local.A[4] = local.A[3]; local.A[3] = local.A[2];
255 local.A[2] = local.A[1]; local.A[1] = local.A[0];
256 local.A[0] = local.temp1;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200257 }
258#else /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200259 for( i = 0; i < 16; i++ )
260 {
Jerome Forissier039e02d2022-08-09 17:10:15 +0200261 local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200262 }
263
264 for( ; i < 80; i++ )
265 {
Jerome Forissier79013242021-07-28 10:24:04 +0200266 local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
267 S0(local.W[i - 15]) + local.W[i - 16];
Jens Wiklander817466c2018-05-22 13:49:31 +0200268 }
269
Jens Wiklander817466c2018-05-22 13:49:31 +0200270 i = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200271 do
272 {
Jerome Forissier79013242021-07-28 10:24:04 +0200273 P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
274 local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
275 P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
276 local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
277 P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
278 local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
279 P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
280 local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
281 P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
282 local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
283 P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
284 local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
285 P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
286 local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
287 P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
288 local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
Jens Wiklander817466c2018-05-22 13:49:31 +0200289 }
290 while( i < 80 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200291#endif /* MBEDTLS_SHA512_SMALLER */
Jens Wiklander817466c2018-05-22 13:49:31 +0200292
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200293 for( i = 0; i < 8; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +0200294 ctx->state[i] += local.A[i];
295
296 /* Zeroise buffers and variables to clear sensitive data from memory. */
297 mbedtls_platform_zeroize( &local, sizeof( local ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100298
299 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200300}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100301
302#if !defined(MBEDTLS_DEPRECATED_REMOVED)
303void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
304 const unsigned char data[128] )
305{
306 mbedtls_internal_sha512_process( ctx, data );
307}
308#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200309#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
310
311/*
312 * SHA-512 process buffer
313 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100314int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
315 const unsigned char *input,
316 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200317{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200318 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200319 size_t fill;
320 unsigned int left;
321
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100322 SHA512_VALIDATE_RET( ctx != NULL );
323 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
324
Jens Wiklander817466c2018-05-22 13:49:31 +0200325 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100326 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200327
328 left = (unsigned int) (ctx->total[0] & 0x7F);
329 fill = 128 - left;
330
331 ctx->total[0] += (uint64_t) ilen;
332
333 if( ctx->total[0] < (uint64_t) ilen )
334 ctx->total[1]++;
335
336 if( left && ilen >= fill )
337 {
338 memcpy( (void *) (ctx->buffer + left), input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100339
340 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
341 return( ret );
342
Jens Wiklander817466c2018-05-22 13:49:31 +0200343 input += fill;
344 ilen -= fill;
345 left = 0;
346 }
347
348 while( ilen >= 128 )
349 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100350 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
351 return( ret );
352
Jens Wiklander817466c2018-05-22 13:49:31 +0200353 input += 128;
354 ilen -= 128;
355 }
356
357 if( ilen > 0 )
358 memcpy( (void *) (ctx->buffer + left), input, ilen );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100359
360 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200361}
362
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100363#if !defined(MBEDTLS_DEPRECATED_REMOVED)
364void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
365 const unsigned char *input,
366 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200367{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100368 mbedtls_sha512_update_ret( ctx, input, ilen );
369}
370#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200371
372/*
373 * SHA-512 final digest
374 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100375int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
376 unsigned char output[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200377{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200378 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100379 unsigned used;
Jens Wiklander817466c2018-05-22 13:49:31 +0200380 uint64_t high, low;
Jens Wiklander817466c2018-05-22 13:49:31 +0200381
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100382 SHA512_VALIDATE_RET( ctx != NULL );
383 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
384
385 /*
386 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
387 */
388 used = ctx->total[0] & 0x7F;
389
390 ctx->buffer[used++] = 0x80;
391
392 if( used <= 112 )
393 {
394 /* Enough room for padding + length in current block */
395 memset( ctx->buffer + used, 0, 112 - used );
396 }
397 else
398 {
399 /* We'll need an extra block */
400 memset( ctx->buffer + used, 0, 128 - used );
401
402 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
403 return( ret );
404
405 memset( ctx->buffer, 0, 112 );
406 }
407
408 /*
409 * Add message length
410 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200411 high = ( ctx->total[0] >> 61 )
412 | ( ctx->total[1] << 3 );
413 low = ( ctx->total[0] << 3 );
414
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200415 sha512_put_uint64_be( high, ctx->buffer, 112 );
416 sha512_put_uint64_be( low, ctx->buffer, 120 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200417
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100418 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
419 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200420
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100421 /*
422 * Output final state
423 */
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200424 sha512_put_uint64_be( ctx->state[0], output, 0 );
425 sha512_put_uint64_be( ctx->state[1], output, 8 );
426 sha512_put_uint64_be( ctx->state[2], output, 16 );
427 sha512_put_uint64_be( ctx->state[3], output, 24 );
428 sha512_put_uint64_be( ctx->state[4], output, 32 );
429 sha512_put_uint64_be( ctx->state[5], output, 40 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200430
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200431#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200432 if( ctx->is384 == 0 )
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200433#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200434 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200435 sha512_put_uint64_be( ctx->state[6], output, 48 );
436 sha512_put_uint64_be( ctx->state[7], output, 56 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200437 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100438
439 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200440}
441
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100442#if !defined(MBEDTLS_DEPRECATED_REMOVED)
443void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
444 unsigned char output[64] )
445{
446 mbedtls_sha512_finish_ret( ctx, output );
447}
448#endif
449
Jens Wiklander817466c2018-05-22 13:49:31 +0200450#endif /* !MBEDTLS_SHA512_ALT */
451
452/*
453 * output = SHA-512( input buffer )
454 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100455int mbedtls_sha512_ret( const unsigned char *input,
456 size_t ilen,
457 unsigned char output[64],
458 int is384 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200459{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200460 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200461 mbedtls_sha512_context ctx;
462
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200463#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100464 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200465#else
466 SHA512_VALIDATE_RET( is384 == 0 );
467#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100468 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
469 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
470
Jens Wiklander817466c2018-05-22 13:49:31 +0200471 mbedtls_sha512_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100472
473 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
474 goto exit;
475
476 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
477 goto exit;
478
479 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
480 goto exit;
481
482exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200483 mbedtls_sha512_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100484
485 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200486}
487
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100488#if !defined(MBEDTLS_DEPRECATED_REMOVED)
489void mbedtls_sha512( const unsigned char *input,
490 size_t ilen,
491 unsigned char output[64],
492 int is384 )
493{
494 mbedtls_sha512_ret( input, ilen, output, is384 );
495}
496#endif
497
Jens Wiklander817466c2018-05-22 13:49:31 +0200498#if defined(MBEDTLS_SELF_TEST)
499
500/*
501 * FIPS-180-2 test vectors
502 */
503static const unsigned char sha512_test_buf[3][113] =
504{
505 { "abc" },
Guido Vranken36905f92021-04-22 14:47:51 +0200506 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
Jens Wiklander817466c2018-05-22 13:49:31 +0200507 { "" }
508};
509
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100510static const size_t sha512_test_buflen[3] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200511{
512 3, 112, 1000
513};
514
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200515static const unsigned char sha512_test_sum[][64] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200516{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200517#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200518 /*
519 * SHA-384 test vectors
520 */
521 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
522 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
523 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
524 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
525 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
526 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
527 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
528 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
529 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
530 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
531 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
532 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
533 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
534 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
535 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
536 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
537 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
538 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200539#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Jens Wiklander817466c2018-05-22 13:49:31 +0200540
541 /*
542 * SHA-512 test vectors
543 */
544 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
545 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
546 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
547 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
548 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
549 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
550 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
551 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
552 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
553 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
554 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
555 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
556 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
557 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
558 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
559 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
560 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
561 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
562 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
563 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
564 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
565 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
566 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
567 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
568};
569
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200570#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
571
Jens Wiklander817466c2018-05-22 13:49:31 +0200572/*
573 * Checkup routine
574 */
575int mbedtls_sha512_self_test( int verbose )
576{
577 int i, j, k, buflen, ret = 0;
578 unsigned char *buf;
579 unsigned char sha512sum[64];
580 mbedtls_sha512_context ctx;
581
582 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
583 if( NULL == buf )
584 {
585 if( verbose != 0 )
586 mbedtls_printf( "Buffer allocation failed\n" );
587
588 return( 1 );
589 }
590
591 mbedtls_sha512_init( &ctx );
592
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200593 for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +0200594 {
595 j = i % 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200596#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200597 k = i < 3;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200598#else
599 k = 0;
600#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200601
602 if( verbose != 0 )
603 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
604
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100605 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
606 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200607
608 if( j == 2 )
609 {
610 memset( buf, 'a', buflen = 1000 );
611
612 for( j = 0; j < 1000; j++ )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100613 {
614 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
615 if( ret != 0 )
616 goto fail;
617 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200618 }
619 else
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100620 {
621 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
622 sha512_test_buflen[j] );
623 if( ret != 0 )
624 goto fail;
625 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200626
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100627 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
628 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200629
630 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
631 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200632 ret = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100633 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200634 }
635
636 if( verbose != 0 )
637 mbedtls_printf( "passed\n" );
638 }
639
640 if( verbose != 0 )
641 mbedtls_printf( "\n" );
642
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100643 goto exit;
644
645fail:
646 if( verbose != 0 )
647 mbedtls_printf( "failed\n" );
648
Jens Wiklander817466c2018-05-22 13:49:31 +0200649exit:
650 mbedtls_sha512_free( &ctx );
651 mbedtls_free( buf );
652
653 return( ret );
654}
655
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200656#undef ARRAY_LENGTH
657
Jens Wiklander817466c2018-05-22 13:49:31 +0200658#endif /* MBEDTLS_SELF_TEST */
659
660#endif /* MBEDTLS_SHA512_C */