blob: fc21331e9e390104ba365691d718f111ec1ca454 [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"
Janos Follath24eed8d2019-11-22 13:21:35 +000037#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000039#if defined(_MSC_VER) || defined(__WATCOMC__)
40 #define UL64(x) x##ui64
41#else
42 #define UL64(x) x##ULL
43#endif
44
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <string.h>
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if defined(MBEDTLS_SELF_TEST)
48#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000049#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#else
Rich Evans00ab4702015-02-06 13:43:58 +000051#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050052#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050054#define mbedtls_calloc calloc
55#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#endif /* MBEDTLS_PLATFORM_C */
57#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
Hanno Beckerc7560492018-12-20 10:23:39 +000059#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 )
62
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020063#if !defined(MBEDTLS_SHA512_ALT)
64
Paul Bakker5121ce52009-01-03 21:22:43 +000065/*
66 * 64-bit integer manipulation macros (big endian)
67 */
68#ifndef GET_UINT64_BE
69#define GET_UINT64_BE(n,b,i) \
70{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000071 (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] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000079}
Paul Bakker9af723c2014-05-01 13:03:14 +020080#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000081
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}
Paul Bakker9af723c2014-05-01 13:03:14 +020094#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000095
Manuel Pégourié-Gonnard7f071952019-07-17 12:46: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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200106{
Hanno Becker38e15d42018-12-18 17:54:00 +0000107 SHA512_VALIDATE( ctx != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200110}
111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200113{
114 if( ctx == NULL )
115 return;
116
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500117 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200118}
119
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200120void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
121 const mbedtls_sha512_context *src )
122{
Hanno Becker38e15d42018-12-18 17:54:00 +0000123 SHA512_VALIDATE( dst != NULL );
124 SHA512_VALIDATE( src != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000125
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200126 *dst = *src;
127}
128
Paul Bakker5121ce52009-01-03 21:22:43 +0000129/*
130 * SHA-512 context setup
131 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100132int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000133{
Hanno Becker38e15d42018-12-18 17:54:00 +0000134 SHA512_VALIDATE_RET( ctx != NULL );
135 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000136
Paul Bakker5121ce52009-01-03 21:22:43 +0000137 ctx->total[0] = 0;
138 ctx->total[1] = 0;
139
140 if( is384 == 0 )
141 {
142 /* SHA-512 */
143 ctx->state[0] = UL64(0x6A09E667F3BCC908);
144 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
145 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
146 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
147 ctx->state[4] = UL64(0x510E527FADE682D1);
148 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
149 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
150 ctx->state[7] = UL64(0x5BE0CD19137E2179);
151 }
152 else
153 {
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200154#if defined(MBEDTLS_SHA512_NO_SHA384)
155 return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
156#else
Paul Bakker5121ce52009-01-03 21:22:43 +0000157 /* SHA-384 */
158 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
159 ctx->state[1] = UL64(0x629A292A367CD507);
160 ctx->state[2] = UL64(0x9159015A3070DD17);
161 ctx->state[3] = UL64(0x152FECD8F70E5939);
162 ctx->state[4] = UL64(0x67332667FFC00B31);
163 ctx->state[5] = UL64(0x8EB44A8768581511);
164 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
165 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200166#endif /* MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 }
168
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200169#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000170 ctx->is384 = is384;
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200171#endif
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100172
173 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000174}
175
Jaeden Amero041039f2018-02-19 15:28:08 +0000176#if !defined(MBEDTLS_DEPRECATED_REMOVED)
177void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
178 int is384 )
179{
180 mbedtls_sha512_starts_ret( ctx, is384 );
181}
182#endif
183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200185
186/*
187 * Round constants
188 */
189static const uint64_t K[80] =
190{
191 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
192 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
193 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
194 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
195 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
196 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
197 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
198 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
199 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
200 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
201 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
202 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
203 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
204 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
205 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
206 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
207 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
208 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
209 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
210 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
211 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
212 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
213 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
214 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
215 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
216 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
217 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
218 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
219 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
220 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
221 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
222 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
223 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
224 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
225 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
226 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
227 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
228 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
229 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
230 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
231};
232
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100233int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
234 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000235{
236 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000237 uint64_t temp1, temp2, W[80];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200238 uint64_t A[8];
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
Hanno Becker38e15d42018-12-18 17:54:00 +0000240 SHA512_VALIDATE_RET( ctx != NULL );
241 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000242
Hanno Becker1eeca412018-10-15 12:01:35 +0100243#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000244#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
246#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
247#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
248
249#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
250#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
251
Hanno Becker1eeca412018-10-15 12:01:35 +0100252#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
253#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
Hanno Becker26d02e12018-10-30 09:29:25 +0000255#define P(a,b,c,d,e,f,g,h,x,K) \
256 do \
257 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100258 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
259 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker26d02e12018-10-30 09:29:25 +0000260 (d) += temp1; (h) = temp1 + temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100261 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200263 for( i = 0; i < 8; i++ )
264 A[i] = ctx->state[i];
265
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200266#if defined(MBEDTLS_SHA512_SMALLER)
267 for( i = 0; i < 80; i++ )
268 {
269 if( i < 16 )
270 {
271 GET_UINT64_BE( W[i], data, i << 3 );
272 }
273 else
274 {
275 W[i] = S1(W[i - 2]) + W[i - 7] +
276 S0(W[i - 15]) + W[i - 16];
277 }
278
279 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
280
281 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
282 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
283 }
284#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 for( i = 0; i < 16; i++ )
286 {
287 GET_UINT64_BE( W[i], data, i << 3 );
288 }
289
290 for( ; i < 80; i++ )
291 {
292 W[i] = S1(W[i - 2]) + W[i - 7] +
293 S0(W[i - 15]) + W[i - 16];
294 }
295
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 do
298 {
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200299 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
300 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
301 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
302 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
303 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
304 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
305 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
306 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 +0000307 }
308 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200309#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200311 for( i = 0; i < 8; i++ )
312 ctx->state[i] += A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100313
314 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000315}
Jaeden Amero041039f2018-02-19 15:28:08 +0000316
317#if !defined(MBEDTLS_DEPRECATED_REMOVED)
318void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
319 const unsigned char data[128] )
320{
321 mbedtls_internal_sha512_process( ctx, data );
322}
323#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
326/*
327 * SHA-512 process buffer
328 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100329int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100330 const unsigned char *input,
331 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
Janos Follath24eed8d2019-11-22 13:21:35 +0000333 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000334 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000335 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
Hanno Becker38e15d42018-12-18 17:54:00 +0000337 SHA512_VALIDATE_RET( ctx != NULL );
338 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000339
Brian White12895d12014-04-11 11:29:42 -0400340 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100341 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Paul Bakkerb8213a12011-07-11 08:16:18 +0000343 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000344 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 ctx->total[1]++;
350
351 if( left && ilen >= fill )
352 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200353 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100354
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100355 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100356 return( ret );
357
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 input += fill;
359 ilen -= fill;
360 left = 0;
361 }
362
363 while( ilen >= 128 )
364 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100365 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100366 return( ret );
367
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 input += 128;
369 ilen -= 128;
370 }
371
372 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200373 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100374
375 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376}
377
Jaeden Amero041039f2018-02-19 15:28:08 +0000378#if !defined(MBEDTLS_DEPRECATED_REMOVED)
379void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
380 const unsigned char *input,
381 size_t ilen )
382{
383 mbedtls_sha512_update_ret( ctx, input, ilen );
384}
385#endif
386
Paul Bakker5121ce52009-01-03 21:22:43 +0000387/*
388 * SHA-512 final digest
389 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100390int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100391 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000392{
Janos Follath24eed8d2019-11-22 13:21:35 +0000393 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200394 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Hanno Becker38e15d42018-12-18 17:54:00 +0000397 SHA512_VALIDATE_RET( ctx != NULL );
398 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000399
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200400 /*
401 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
402 */
403 used = ctx->total[0] & 0x7F;
404
405 ctx->buffer[used++] = 0x80;
406
407 if( used <= 112 )
408 {
409 /* Enough room for padding + length in current block */
410 memset( ctx->buffer + used, 0, 112 - used );
411 }
412 else
413 {
414 /* We'll need an extra block */
415 memset( ctx->buffer + used, 0, 128 - used );
416
417 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
418 return( ret );
419
420 memset( ctx->buffer, 0, 112 );
421 }
422
423 /*
424 * Add message length
425 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 high = ( ctx->total[0] >> 61 )
427 | ( ctx->total[1] << 3 );
428 low = ( ctx->total[0] << 3 );
429
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200430 sha512_put_uint64_be( high, ctx->buffer, 112 );
431 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200433 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
434 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200436 /*
437 * Output final state
438 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200439 sha512_put_uint64_be( ctx->state[0], output, 0 );
440 sha512_put_uint64_be( ctx->state[1], output, 8 );
441 sha512_put_uint64_be( ctx->state[2], output, 16 );
442 sha512_put_uint64_be( ctx->state[3], output, 24 );
443 sha512_put_uint64_be( ctx->state[4], output, 32 );
444 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200446#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 if( ctx->is384 == 0 )
Manuel Pégourié-Gonnard3df4e602019-07-17 15:16:14 +0200448#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200450 sha512_put_uint64_be( ctx->state[6], output, 48 );
451 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100453
454 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455}
456
Jaeden Amero041039f2018-02-19 15:28:08 +0000457#if !defined(MBEDTLS_DEPRECATED_REMOVED)
458void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
459 unsigned char output[64] )
460{
461 mbedtls_sha512_finish_ret( ctx, output );
462}
463#endif
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200466
Paul Bakker5121ce52009-01-03 21:22:43 +0000467/*
468 * output = SHA-512( input buffer )
469 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100470int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100471 size_t ilen,
472 unsigned char output[64],
473 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000474{
Janos Follath24eed8d2019-11-22 13:21:35 +0000475 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Hanno Becker38e15d42018-12-18 17:54:00 +0000478 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
479 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
480 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100483
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100484 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100485 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100486
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100487 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100488 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100489
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100490 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100491 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100492
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100493exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100495
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100496 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497}
498
Jaeden Amero041039f2018-02-19 15:28:08 +0000499#if !defined(MBEDTLS_DEPRECATED_REMOVED)
500void mbedtls_sha512( const unsigned char *input,
501 size_t ilen,
502 unsigned char output[64],
503 int is384 )
504{
505 mbedtls_sha512_ret( input, ilen, output, is384 );
506}
507#endif
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
511/*
512 * FIPS-180-2 test vectors
513 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000514static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000515{
516 { "abc" },
517 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
518 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
519 { "" }
520};
521
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100522static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000523{
524 3, 112, 1000
525};
526
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200527static const unsigned char sha512_test_sum[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000528{
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200529#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000530 /*
531 * SHA-384 test vectors
532 */
533 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
534 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
535 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
536 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
537 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
538 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
539 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
540 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
541 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
542 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
543 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
544 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
545 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
546 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
547 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
548 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
549 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
550 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200551#endif /* !MBEDTLS_SHA512_NO_SHA384 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
553 /*
554 * SHA-512 test vectors
555 */
556 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
557 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
558 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
559 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
560 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
561 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
562 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
563 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
564 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
565 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
566 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
567 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
568 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
569 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
570 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
571 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
572 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
573 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
574 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
575 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
576 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
577 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
578 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
579 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
580};
581
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200582#define SHA512_TEST_SUM_N \
583 ( sizeof( sha512_test_sum ) / sizeof( sha512_test_sum[0] ) )
584
585
Paul Bakker5121ce52009-01-03 21:22:43 +0000586/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 * Checkup routine
588 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000590{
Paul Bakker5b4af392014-06-26 12:09:34 +0200591 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500592 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200593 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Russ Butlerbb83b422016-10-12 17:36:50 -0500596 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
597 if( NULL == buf )
598 {
599 if( verbose != 0 )
600 mbedtls_printf( "Buffer allocation failed\n" );
601
602 return( 1 );
603 }
604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200606
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200607 for( i = 0; i < (int) SHA512_TEST_SUM_N; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 {
609 j = i % 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200610#if !defined(MBEDTLS_SHA512_NO_SHA384)
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 k = i < 3;
Manuel Pégourié-Gonnard39ea19a2019-07-17 15:36:23 +0200612#else
613 k = 0;
614#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100619 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100620 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 if( j == 2 )
623 {
624 memset( buf, 'a', buflen = 1000 );
625
626 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100627 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100628 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100629 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100630 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100631 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 }
633 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100634 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100635 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100636 sha512_test_buflen[j] );
637 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100638 goto fail;
639 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100641 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100642 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Paul Bakker9e36f042013-06-30 14:34:05 +0200644 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100645 {
646 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100647 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100648 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 }
653
654 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100657 goto exit;
658
659fail:
660 if( verbose != 0 )
661 mbedtls_printf( "failed\n" );
662
Paul Bakker5b4af392014-06-26 12:09:34 +0200663exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500665 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200666
667 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668}
669
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672#endif /* MBEDTLS_SHA512_C */