blob: cec955b4c7f8a571826e5a84bbbfc1d4e83c8069 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/sha512.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000038#if defined(_MSC_VER) || defined(__WATCOMC__)
39 #define UL64(x) x##ui64
40#else
41 #define UL64(x) x##ULL
42#endif
43
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <string.h>
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_SELF_TEST)
47#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010049#else
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050051#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050053#define mbedtls_calloc calloc
54#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#endif /* MBEDTLS_PLATFORM_C */
56#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Hanno Beckerc7560492018-12-20 10:23:39 +000058#define SHA512_VALIDATE_RET(cond) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
60#define SHA512_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond )
61
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020062#if !defined(MBEDTLS_SHA512_ALT)
63
Paul Bakker5121ce52009-01-03 21:22:43 +000064/*
65 * 64-bit integer manipulation macros (big endian)
66 */
67#ifndef GET_UINT64_BE
68#define GET_UINT64_BE(n,b,i) \
69{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000070 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
71 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
72 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
73 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
74 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
75 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
76 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
77 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000078}
Paul Bakker9af723c2014-05-01 13:03:14 +020079#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000080
81#ifndef PUT_UINT64_BE
82#define PUT_UINT64_BE(n,b,i) \
83{ \
84 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
85 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
86 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
87 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
88 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
89 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
90 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
91 (b)[(i) + 7] = (unsigned char) ( (n) ); \
92}
Paul Bakker9af723c2014-05-01 13:03:14 +020093#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020096{
Hanno Becker38e15d42018-12-18 17:54:00 +000097 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +000098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200100}
101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200103{
104 if( ctx == NULL )
105 return;
106
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500107 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200108}
109
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200110void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
111 const mbedtls_sha512_context *src )
112{
Hanno Becker38e15d42018-12-18 17:54:00 +0000113 SHA512_VALIDATE( dst != NULL );
114 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000115
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200116 *dst = *src;
117}
118
Paul Bakker5121ce52009-01-03 21:22:43 +0000119/*
120 * SHA-512 context setup
121 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100122int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000123{
Hanno Becker38e15d42018-12-18 17:54:00 +0000124 SHA512_VALIDATE_RET( ctx != NULL );
125 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000126
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 ctx->total[0] = 0;
128 ctx->total[1] = 0;
129
130 if( is384 == 0 )
131 {
132 /* SHA-512 */
133 ctx->state[0] = UL64(0x6A09E667F3BCC908);
134 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
135 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
136 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
137 ctx->state[4] = UL64(0x510E527FADE682D1);
138 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
139 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
140 ctx->state[7] = UL64(0x5BE0CD19137E2179);
141 }
142 else
143 {
144 /* SHA-384 */
145 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
146 ctx->state[1] = UL64(0x629A292A367CD507);
147 ctx->state[2] = UL64(0x9159015A3070DD17);
148 ctx->state[3] = UL64(0x152FECD8F70E5939);
149 ctx->state[4] = UL64(0x67332667FFC00B31);
150 ctx->state[5] = UL64(0x8EB44A8768581511);
151 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
152 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
153 }
154
155 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100156
157 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000158}
159
Jaeden Amero041039f2018-02-19 15:28:08 +0000160#if !defined(MBEDTLS_DEPRECATED_REMOVED)
161void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
162 int is384 )
163{
164 mbedtls_sha512_starts_ret( ctx, is384 );
165}
166#endif
167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200169
170/*
171 * Round constants
172 */
173static const uint64_t K[80] =
174{
175 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
176 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
177 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
178 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
179 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
180 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
181 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
182 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
183 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
184 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
185 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
186 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
187 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
188 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
189 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
190 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
191 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
192 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
193 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
194 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
195 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
196 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
197 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
198 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
199 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
200 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
201 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
202 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
203 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
204 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
205 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
206 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
207 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
208 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
209 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
210 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
211 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
212 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
213 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
214 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
215};
216
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100217int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
218 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219{
220 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000221 uint64_t temp1, temp2, W[80];
222 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000223
Hanno Becker38e15d42018-12-18 17:54:00 +0000224 SHA512_VALIDATE_RET( ctx != NULL );
225 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000226
Hanno Beckerd6028a12018-10-15 12:01:35 +0100227#define SHR(x,n) ((x) >> (n))
228#define ROTR(x,n) (SHR(x,n) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000229
230#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
231#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
232
233#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
234#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
235
Hanno Beckerd6028a12018-10-15 12:01:35 +0100236#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
237#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
Hanno Beckerd6028a12018-10-15 12:01:35 +0100239#define P(a,b,c,d,e,f,g,h,x,K) \
240 do \
241 { \
242 temp1 = (h) + S3(e) + F1(e,f,g) + (K) + (x); \
243 temp2 = S2(a) + F0(a,b,c); \
244 (d) += temp1; (h) = temp1 + temp2; \
245 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
247 for( i = 0; i < 16; i++ )
248 {
249 GET_UINT64_BE( W[i], data, i << 3 );
250 }
251
252 for( ; i < 80; i++ )
253 {
254 W[i] = S1(W[i - 2]) + W[i - 7] +
255 S0(W[i - 15]) + W[i - 16];
256 }
257
258 A = ctx->state[0];
259 B = ctx->state[1];
260 C = ctx->state[2];
261 D = ctx->state[3];
262 E = ctx->state[4];
263 F = ctx->state[5];
264 G = ctx->state[6];
265 H = ctx->state[7];
266 i = 0;
267
268 do
269 {
270 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
271 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
272 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
273 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
274 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
275 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
276 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
277 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
278 }
279 while( i < 80 );
280
281 ctx->state[0] += A;
282 ctx->state[1] += B;
283 ctx->state[2] += C;
284 ctx->state[3] += D;
285 ctx->state[4] += E;
286 ctx->state[5] += F;
287 ctx->state[6] += G;
288 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100289
290 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000291}
Jaeden Amero041039f2018-02-19 15:28:08 +0000292
293#if !defined(MBEDTLS_DEPRECATED_REMOVED)
294void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
295 const unsigned char data[128] )
296{
297 mbedtls_internal_sha512_process( ctx, data );
298}
299#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
302/*
303 * SHA-512 process buffer
304 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100305int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100306 const unsigned char *input,
307 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000308{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100309 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000310 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000311 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
Hanno Becker38e15d42018-12-18 17:54:00 +0000313 SHA512_VALIDATE_RET( ctx != NULL );
314 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000315
Brian White12895d12014-04-11 11:29:42 -0400316 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100317 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
Paul Bakkerb8213a12011-07-11 08:16:18 +0000319 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000320 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 ctx->total[1]++;
326
327 if( left && ilen >= fill )
328 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200329 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100330
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100331 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100332 return( ret );
333
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 input += fill;
335 ilen -= fill;
336 left = 0;
337 }
338
339 while( ilen >= 128 )
340 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100341 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100342 return( ret );
343
Paul Bakker5121ce52009-01-03 21:22:43 +0000344 input += 128;
345 ilen -= 128;
346 }
347
348 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200349 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100350
351 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352}
353
Jaeden Amero041039f2018-02-19 15:28:08 +0000354#if !defined(MBEDTLS_DEPRECATED_REMOVED)
355void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
356 const unsigned char *input,
357 size_t ilen )
358{
359 mbedtls_sha512_update_ret( ctx, input, ilen );
360}
361#endif
362
Paul Bakker5121ce52009-01-03 21:22:43 +0000363/*
364 * SHA-512 final digest
365 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100366int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100367 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000368{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100369 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200370 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000371 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
Hanno Becker38e15d42018-12-18 17:54:00 +0000373 SHA512_VALIDATE_RET( ctx != NULL );
374 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000375
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200376 /*
377 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
378 */
379 used = ctx->total[0] & 0x7F;
380
381 ctx->buffer[used++] = 0x80;
382
383 if( used <= 112 )
384 {
385 /* Enough room for padding + length in current block */
386 memset( ctx->buffer + used, 0, 112 - used );
387 }
388 else
389 {
390 /* We'll need an extra block */
391 memset( ctx->buffer + used, 0, 128 - used );
392
393 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
394 return( ret );
395
396 memset( ctx->buffer, 0, 112 );
397 }
398
399 /*
400 * Add message length
401 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 high = ( ctx->total[0] >> 61 )
403 | ( ctx->total[1] << 3 );
404 low = ( ctx->total[0] << 3 );
405
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200406 PUT_UINT64_BE( high, ctx->buffer, 112 );
407 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200409 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
410 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200412 /*
413 * Output final state
414 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 PUT_UINT64_BE( ctx->state[0], output, 0 );
416 PUT_UINT64_BE( ctx->state[1], output, 8 );
417 PUT_UINT64_BE( ctx->state[2], output, 16 );
418 PUT_UINT64_BE( ctx->state[3], output, 24 );
419 PUT_UINT64_BE( ctx->state[4], output, 32 );
420 PUT_UINT64_BE( ctx->state[5], output, 40 );
421
422 if( ctx->is384 == 0 )
423 {
424 PUT_UINT64_BE( ctx->state[6], output, 48 );
425 PUT_UINT64_BE( ctx->state[7], output, 56 );
426 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100427
428 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429}
430
Jaeden Amero041039f2018-02-19 15:28:08 +0000431#if !defined(MBEDTLS_DEPRECATED_REMOVED)
432void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
433 unsigned char output[64] )
434{
435 mbedtls_sha512_finish_ret( ctx, output );
436}
437#endif
438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200440
Paul Bakker5121ce52009-01-03 21:22:43 +0000441/*
442 * output = SHA-512( input buffer )
443 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100444int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100445 size_t ilen,
446 unsigned char output[64],
447 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000448{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100449 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Hanno Becker38e15d42018-12-18 17:54:00 +0000452 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
453 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
454 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100457
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100458 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100459 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100460
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100461 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100462 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100463
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100464 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100465 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100467exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100469
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100470 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000471}
472
Jaeden Amero041039f2018-02-19 15:28:08 +0000473#if !defined(MBEDTLS_DEPRECATED_REMOVED)
474void mbedtls_sha512( const unsigned char *input,
475 size_t ilen,
476 unsigned char output[64],
477 int is384 )
478{
479 mbedtls_sha512_ret( input, ilen, output, is384 );
480}
481#endif
482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485/*
486 * FIPS-180-2 test vectors
487 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000488static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000489{
490 { "abc" },
491 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
492 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
493 { "" }
494};
495
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100496static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000497{
498 3, 112, 1000
499};
500
Paul Bakker9e36f042013-06-30 14:34:05 +0200501static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000502{
503 /*
504 * SHA-384 test vectors
505 */
506 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
507 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
508 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
509 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
510 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
511 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
512 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
513 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
514 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
515 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
516 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
517 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
518 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
519 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
520 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
521 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
522 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
523 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
524
525 /*
526 * SHA-512 test vectors
527 */
528 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
529 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
530 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
531 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
532 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
533 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
534 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
535 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
536 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
537 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
538 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
539 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
540 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
541 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
542 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
543 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
544 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
545 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
546 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
547 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
548 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
549 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
550 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
551 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
552};
553
554/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 * Checkup routine
556 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000558{
Paul Bakker5b4af392014-06-26 12:09:34 +0200559 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500560 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200561 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Russ Butlerbb83b422016-10-12 17:36:50 -0500564 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
565 if( NULL == buf )
566 {
567 if( verbose != 0 )
568 mbedtls_printf( "Buffer allocation failed\n" );
569
570 return( 1 );
571 }
572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200574
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 for( i = 0; i < 6; i++ )
576 {
577 j = i % 3;
578 k = i < 3;
579
580 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100583 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100584 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 if( j == 2 )
587 {
588 memset( buf, 'a', buflen = 1000 );
589
590 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100591 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100592 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100593 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100594 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100595 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 }
597 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100598 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100599 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100600 sha512_test_buflen[j] );
601 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100602 goto fail;
603 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100605 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100606 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Paul Bakker9e36f042013-06-30 14:34:05 +0200608 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100609 {
610 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100611 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100612 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 }
617
618 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100621 goto exit;
622
623fail:
624 if( verbose != 0 )
625 mbedtls_printf( "failed\n" );
626
Paul Bakker5b4af392014-06-26 12:09:34 +0200627exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500629 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200630
631 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632}
633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636#endif /* MBEDTLS_SHA512_C */