blob: 2e2b79787233ccb6a40e8adfd3efa33fb215140e [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é-Gonnard7f071952019-07-17 12:46:56 +020095#if defined(MBEDTLS_SHA512_SMALLER)
96static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
97{
98 PUT_UINT64_BE(n, b, i);
99}
100#else
101#define sha512_put_uint64_be PUT_UINT64_BE
102#endif /* MBEDTLS_SHA512_SMALLER */
103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200105{
Hanno Becker38e15d42018-12-18 17:54:00 +0000106 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200109}
110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200112{
113 if( ctx == NULL )
114 return;
115
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500116 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200117}
118
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200119void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
120 const mbedtls_sha512_context *src )
121{
Hanno Becker38e15d42018-12-18 17:54:00 +0000122 SHA512_VALIDATE( dst != NULL );
123 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000124
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200125 *dst = *src;
126}
127
Paul Bakker5121ce52009-01-03 21:22:43 +0000128/*
129 * SHA-512 context setup
130 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100131int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000132{
Hanno Becker38e15d42018-12-18 17:54:00 +0000133 SHA512_VALIDATE_RET( ctx != NULL );
134 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000135
Paul Bakker5121ce52009-01-03 21:22:43 +0000136 ctx->total[0] = 0;
137 ctx->total[1] = 0;
138
139 if( is384 == 0 )
140 {
141 /* SHA-512 */
142 ctx->state[0] = UL64(0x6A09E667F3BCC908);
143 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
144 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
145 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
146 ctx->state[4] = UL64(0x510E527FADE682D1);
147 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
148 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
149 ctx->state[7] = UL64(0x5BE0CD19137E2179);
150 }
151 else
152 {
153 /* SHA-384 */
154 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
155 ctx->state[1] = UL64(0x629A292A367CD507);
156 ctx->state[2] = UL64(0x9159015A3070DD17);
157 ctx->state[3] = UL64(0x152FECD8F70E5939);
158 ctx->state[4] = UL64(0x67332667FFC00B31);
159 ctx->state[5] = UL64(0x8EB44A8768581511);
160 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
161 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
162 }
163
164 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100165
166 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000167}
168
Jaeden Amero041039f2018-02-19 15:28:08 +0000169#if !defined(MBEDTLS_DEPRECATED_REMOVED)
170void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
171 int is384 )
172{
173 mbedtls_sha512_starts_ret( ctx, is384 );
174}
175#endif
176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200178
179/*
180 * Round constants
181 */
182static const uint64_t K[80] =
183{
184 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
185 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
186 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
187 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
188 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
189 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
190 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
191 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
192 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
193 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
194 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
195 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
196 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
197 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
198 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
199 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
200 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
201 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
202 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
203 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
204 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
205 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
206 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
207 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
208 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
209 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
210 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
211 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
212 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
213 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
214 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
215 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
216 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
217 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
218 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
219 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
220 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
221 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
222 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
223 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
224};
225
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100226int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
227 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000228{
229 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000230 uint64_t temp1, temp2, W[80];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200231 uint64_t A[8];
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
Hanno Becker38e15d42018-12-18 17:54:00 +0000233 SHA512_VALIDATE_RET( ctx != NULL );
234 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000235
Hanno Becker1eeca412018-10-15 12:01:35 +0100236#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000237#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
240#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
241
242#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
243#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
244
Hanno Becker1eeca412018-10-15 12:01:35 +0100245#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
246#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000247
Hanno Becker26d02e12018-10-30 09:29:25 +0000248#define P(a,b,c,d,e,f,g,h,x,K) \
249 do \
250 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100251 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
252 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker26d02e12018-10-30 09:29:25 +0000253 (d) += temp1; (h) = temp1 + temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100254 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200256 for( i = 0; i < 8; i++ )
257 A[i] = ctx->state[i];
258
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200259#if defined(MBEDTLS_SHA512_SMALLER)
260 for( i = 0; i < 80; i++ )
261 {
262 if( i < 16 )
263 {
264 GET_UINT64_BE( W[i], data, i << 3 );
265 }
266 else
267 {
268 W[i] = S1(W[i - 2]) + W[i - 7] +
269 S0(W[i - 15]) + W[i - 16];
270 }
271
272 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
273
274 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
275 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
276 }
277#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 for( i = 0; i < 16; i++ )
279 {
280 GET_UINT64_BE( W[i], data, i << 3 );
281 }
282
283 for( ; i < 80; i++ )
284 {
285 W[i] = S1(W[i - 2]) + W[i - 7] +
286 S0(W[i - 15]) + W[i - 16];
287 }
288
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 do
291 {
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200292 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
293 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
294 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
295 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
296 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
297 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
298 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
299 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i], K[i] ); i++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000300 }
301 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200302#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200304 for( i = 0; i < 8; i++ )
305 ctx->state[i] += A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100306
307 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308}
Jaeden Amero041039f2018-02-19 15:28:08 +0000309
310#if !defined(MBEDTLS_DEPRECATED_REMOVED)
311void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
312 const unsigned char data[128] )
313{
314 mbedtls_internal_sha512_process( ctx, data );
315}
316#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319/*
320 * SHA-512 process buffer
321 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100322int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100323 const unsigned char *input,
324 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100326 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000327 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000328 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
Hanno Becker38e15d42018-12-18 17:54:00 +0000330 SHA512_VALIDATE_RET( ctx != NULL );
331 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000332
Brian White12895d12014-04-11 11:29:42 -0400333 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100334 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Paul Bakkerb8213a12011-07-11 08:16:18 +0000336 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000337 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
Paul Bakker5c2364c2012-10-01 14:41:15 +0000339 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
Paul Bakker5c2364c2012-10-01 14:41:15 +0000341 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 ctx->total[1]++;
343
344 if( left && ilen >= fill )
345 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200346 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100347
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100348 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100349 return( ret );
350
Paul Bakker5121ce52009-01-03 21:22:43 +0000351 input += fill;
352 ilen -= fill;
353 left = 0;
354 }
355
356 while( ilen >= 128 )
357 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100358 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100359 return( ret );
360
Paul Bakker5121ce52009-01-03 21:22:43 +0000361 input += 128;
362 ilen -= 128;
363 }
364
365 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200366 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100367
368 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000369}
370
Jaeden Amero041039f2018-02-19 15:28:08 +0000371#if !defined(MBEDTLS_DEPRECATED_REMOVED)
372void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
373 const unsigned char *input,
374 size_t ilen )
375{
376 mbedtls_sha512_update_ret( ctx, input, ilen );
377}
378#endif
379
Paul Bakker5121ce52009-01-03 21:22:43 +0000380/*
381 * SHA-512 final digest
382 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100383int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100384 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000385{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100386 int ret;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200387 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000388 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
Hanno Becker38e15d42018-12-18 17:54:00 +0000390 SHA512_VALIDATE_RET( ctx != NULL );
391 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000392
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200393 /*
394 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
395 */
396 used = ctx->total[0] & 0x7F;
397
398 ctx->buffer[used++] = 0x80;
399
400 if( used <= 112 )
401 {
402 /* Enough room for padding + length in current block */
403 memset( ctx->buffer + used, 0, 112 - used );
404 }
405 else
406 {
407 /* We'll need an extra block */
408 memset( ctx->buffer + used, 0, 128 - used );
409
410 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
411 return( ret );
412
413 memset( ctx->buffer, 0, 112 );
414 }
415
416 /*
417 * Add message length
418 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 high = ( ctx->total[0] >> 61 )
420 | ( ctx->total[1] << 3 );
421 low = ( ctx->total[0] << 3 );
422
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200423 sha512_put_uint64_be( high, ctx->buffer, 112 );
424 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200426 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
427 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200429 /*
430 * Output final state
431 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200432 sha512_put_uint64_be( ctx->state[0], output, 0 );
433 sha512_put_uint64_be( ctx->state[1], output, 8 );
434 sha512_put_uint64_be( ctx->state[2], output, 16 );
435 sha512_put_uint64_be( ctx->state[3], output, 24 );
436 sha512_put_uint64_be( ctx->state[4], output, 32 );
437 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
439 if( ctx->is384 == 0 )
440 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200441 sha512_put_uint64_be( ctx->state[6], output, 48 );
442 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100444
445 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446}
447
Jaeden Amero041039f2018-02-19 15:28:08 +0000448#if !defined(MBEDTLS_DEPRECATED_REMOVED)
449void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
450 unsigned char output[64] )
451{
452 mbedtls_sha512_finish_ret( ctx, output );
453}
454#endif
455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200457
Paul Bakker5121ce52009-01-03 21:22:43 +0000458/*
459 * output = SHA-512( input buffer )
460 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100461int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100462 size_t ilen,
463 unsigned char output[64],
464 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100466 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Hanno Becker38e15d42018-12-18 17:54:00 +0000469 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
470 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
471 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100474
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100475 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100476 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100477
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100478 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100479 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100480
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100481 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100482 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100483
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100484exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100486
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100487 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
489
Jaeden Amero041039f2018-02-19 15:28:08 +0000490#if !defined(MBEDTLS_DEPRECATED_REMOVED)
491void mbedtls_sha512( const unsigned char *input,
492 size_t ilen,
493 unsigned char output[64],
494 int is384 )
495{
496 mbedtls_sha512_ret( input, ilen, output, is384 );
497}
498#endif
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
502/*
503 * FIPS-180-2 test vectors
504 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000505static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000506{
507 { "abc" },
508 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
509 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
510 { "" }
511};
512
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100513static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
515 3, 112, 1000
516};
517
Paul Bakker9e36f042013-06-30 14:34:05 +0200518static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000519{
520 /*
521 * SHA-384 test vectors
522 */
523 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
524 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
525 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
526 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
527 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
528 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
529 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
530 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
531 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
532 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
533 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
534 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
535 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
536 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
537 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
538 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
539 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
540 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
541
542 /*
543 * SHA-512 test vectors
544 */
545 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
546 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
547 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
548 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
549 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
550 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
551 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
552 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
553 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
554 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
555 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
556 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
557 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
558 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
559 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
560 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
561 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
562 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
563 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
564 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
565 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
566 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
567 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
568 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
569};
570
571/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 * Checkup routine
573 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000575{
Paul Bakker5b4af392014-06-26 12:09:34 +0200576 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500577 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200578 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Russ Butlerbb83b422016-10-12 17:36:50 -0500581 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
582 if( NULL == buf )
583 {
584 if( verbose != 0 )
585 mbedtls_printf( "Buffer allocation failed\n" );
586
587 return( 1 );
588 }
589
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200591
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 for( i = 0; i < 6; i++ )
593 {
594 j = i % 3;
595 k = i < 3;
596
597 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100600 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100601 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
603 if( j == 2 )
604 {
605 memset( buf, 'a', buflen = 1000 );
606
607 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100608 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100609 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100610 if( ret != 0 )
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 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100615 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100616 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100617 sha512_test_buflen[j] );
618 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100619 goto fail;
620 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100622 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100623 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
Paul Bakker9e36f042013-06-30 14:34:05 +0200625 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100626 {
627 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100628 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
635 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100638 goto exit;
639
640fail:
641 if( verbose != 0 )
642 mbedtls_printf( "failed\n" );
643
Paul Bakker5b4af392014-06-26 12:09:34 +0200644exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500646 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200647
648 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649}
650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#endif /* MBEDTLS_SHA512_C */