blob: fa4025653ddbf84532e03303364c2130920f2657 [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 {
154 /* SHA-384 */
155 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
156 ctx->state[1] = UL64(0x629A292A367CD507);
157 ctx->state[2] = UL64(0x9159015A3070DD17);
158 ctx->state[3] = UL64(0x152FECD8F70E5939);
159 ctx->state[4] = UL64(0x67332667FFC00B31);
160 ctx->state[5] = UL64(0x8EB44A8768581511);
161 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
162 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
163 }
164
165 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100166
167 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168}
169
Jaeden Amero041039f2018-02-19 15:28:08 +0000170#if !defined(MBEDTLS_DEPRECATED_REMOVED)
171void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
172 int is384 )
173{
174 mbedtls_sha512_starts_ret( ctx, is384 );
175}
176#endif
177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200179
180/*
181 * Round constants
182 */
183static const uint64_t K[80] =
184{
185 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
186 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
187 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
188 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
189 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
190 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
191 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
192 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
193 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
194 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
195 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
196 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
197 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
198 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
199 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
200 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
201 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
202 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
203 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
204 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
205 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
206 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
207 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
208 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
209 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
210 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
211 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
212 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
213 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
214 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
215 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
216 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
217 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
218 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
219 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
220 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
221 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
222 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
223 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
224 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
225};
226
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100227int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
228 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000229{
230 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000231 uint64_t temp1, temp2, W[80];
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200232 uint64_t A[8];
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
Hanno Becker38e15d42018-12-18 17:54:00 +0000234 SHA512_VALIDATE_RET( ctx != NULL );
235 SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000236
Hanno Becker1eeca412018-10-15 12:01:35 +0100237#define SHR(x,n) ((x) >> (n))
Hanno Becker26d02e12018-10-30 09:29:25 +0000238#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
240#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
241#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
242
243#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
244#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
245
Hanno Becker1eeca412018-10-15 12:01:35 +0100246#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
247#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
Hanno Becker26d02e12018-10-30 09:29:25 +0000249#define P(a,b,c,d,e,f,g,h,x,K) \
250 do \
251 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100252 temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \
253 temp2 = S2(a) + F0((a),(b),(c)); \
Hanno Becker26d02e12018-10-30 09:29:25 +0000254 (d) += temp1; (h) = temp1 + temp2; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100255 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200257 for( i = 0; i < 8; i++ )
258 A[i] = ctx->state[i];
259
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200260#if defined(MBEDTLS_SHA512_SMALLER)
261 for( i = 0; i < 80; i++ )
262 {
263 if( i < 16 )
264 {
265 GET_UINT64_BE( W[i], data, i << 3 );
266 }
267 else
268 {
269 W[i] = S1(W[i - 2]) + W[i - 7] +
270 S0(W[i - 15]) + W[i - 16];
271 }
272
273 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
274
275 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
276 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
277 }
278#else /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 for( i = 0; i < 16; i++ )
280 {
281 GET_UINT64_BE( W[i], data, i << 3 );
282 }
283
284 for( ; i < 80; i++ )
285 {
286 W[i] = S1(W[i - 2]) + W[i - 7] +
287 S0(W[i - 15]) + W[i - 16];
288 }
289
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 i = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 do
292 {
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200293 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); i++;
294 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i], K[i] ); i++;
295 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i], K[i] ); i++;
296 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i], K[i] ); i++;
297 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i], K[i] ); i++;
298 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i], K[i] ); i++;
299 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i], K[i] ); i++;
300 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 +0000301 }
302 while( i < 80 );
Manuel Pégourié-Gonnard49d65ba2019-07-17 13:16:54 +0200303#endif /* MBEDTLS_SHA512_SMALLER */
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
Manuel Pégourié-Gonnard0270ed92019-07-17 13:01:56 +0200305 for( i = 0; i < 8; i++ )
306 ctx->state[i] += A[i];
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100307
308 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309}
Jaeden Amero041039f2018-02-19 15:28:08 +0000310
311#if !defined(MBEDTLS_DEPRECATED_REMOVED)
312void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
313 const unsigned char data[128] )
314{
315 mbedtls_internal_sha512_process( ctx, data );
316}
317#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
320/*
321 * SHA-512 process buffer
322 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100323int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100324 const unsigned char *input,
325 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000326{
Janos Follath24eed8d2019-11-22 13:21:35 +0000327 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000328 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000329 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Hanno Becker38e15d42018-12-18 17:54:00 +0000331 SHA512_VALIDATE_RET( ctx != NULL );
332 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
Hanno Beckerca6f4582018-12-18 15:37:22 +0000333
Brian White12895d12014-04-11 11:29:42 -0400334 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100335 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
Paul Bakkerb8213a12011-07-11 08:16:18 +0000337 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000338 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 ctx->total[1]++;
344
345 if( left && ilen >= fill )
346 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200347 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100348
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100349 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100350 return( ret );
351
Paul Bakker5121ce52009-01-03 21:22:43 +0000352 input += fill;
353 ilen -= fill;
354 left = 0;
355 }
356
357 while( ilen >= 128 )
358 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100359 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100360 return( ret );
361
Paul Bakker5121ce52009-01-03 21:22:43 +0000362 input += 128;
363 ilen -= 128;
364 }
365
366 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200367 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100368
369 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000370}
371
Jaeden Amero041039f2018-02-19 15:28:08 +0000372#if !defined(MBEDTLS_DEPRECATED_REMOVED)
373void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
374 const unsigned char *input,
375 size_t ilen )
376{
377 mbedtls_sha512_update_ret( ctx, input, ilen );
378}
379#endif
380
Paul Bakker5121ce52009-01-03 21:22:43 +0000381/*
382 * SHA-512 final digest
383 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100384int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100385 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000386{
Janos Follath24eed8d2019-11-22 13:21:35 +0000387 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200388 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000389 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Hanno Becker38e15d42018-12-18 17:54:00 +0000391 SHA512_VALIDATE_RET( ctx != NULL );
392 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000393
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200394 /*
395 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
396 */
397 used = ctx->total[0] & 0x7F;
398
399 ctx->buffer[used++] = 0x80;
400
401 if( used <= 112 )
402 {
403 /* Enough room for padding + length in current block */
404 memset( ctx->buffer + used, 0, 112 - used );
405 }
406 else
407 {
408 /* We'll need an extra block */
409 memset( ctx->buffer + used, 0, 128 - used );
410
411 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
412 return( ret );
413
414 memset( ctx->buffer, 0, 112 );
415 }
416
417 /*
418 * Add message length
419 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 high = ( ctx->total[0] >> 61 )
421 | ( ctx->total[1] << 3 );
422 low = ( ctx->total[0] << 3 );
423
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200424 sha512_put_uint64_be( high, ctx->buffer, 112 );
425 sha512_put_uint64_be( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200427 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
428 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Manuel Pégourié-Gonnard1cc1fb02018-06-28 12:10:27 +0200430 /*
431 * Output final state
432 */
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200433 sha512_put_uint64_be( ctx->state[0], output, 0 );
434 sha512_put_uint64_be( ctx->state[1], output, 8 );
435 sha512_put_uint64_be( ctx->state[2], output, 16 );
436 sha512_put_uint64_be( ctx->state[3], output, 24 );
437 sha512_put_uint64_be( ctx->state[4], output, 32 );
438 sha512_put_uint64_be( ctx->state[5], output, 40 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
440 if( ctx->is384 == 0 )
441 {
Manuel Pégourié-Gonnard7f071952019-07-17 12:46:56 +0200442 sha512_put_uint64_be( ctx->state[6], output, 48 );
443 sha512_put_uint64_be( ctx->state[7], output, 56 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100445
446 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447}
448
Jaeden Amero041039f2018-02-19 15:28:08 +0000449#if !defined(MBEDTLS_DEPRECATED_REMOVED)
450void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
451 unsigned char output[64] )
452{
453 mbedtls_sha512_finish_ret( ctx, output );
454}
455#endif
456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200458
Paul Bakker5121ce52009-01-03 21:22:43 +0000459/*
460 * output = SHA-512( input buffer )
461 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100462int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100463 size_t ilen,
464 unsigned char output[64],
465 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000466{
Janos Follath24eed8d2019-11-22 13:21:35 +0000467 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Hanno Becker38e15d42018-12-18 17:54:00 +0000470 SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
471 SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
472 SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
Andres Amaya Garciaba519b92018-12-09 20:58:36 +0000473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100475
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100476 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100477 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100478
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100479 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100480 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100481
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100482 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100483 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100484
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100485exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100487
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100488 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489}
490
Jaeden Amero041039f2018-02-19 15:28:08 +0000491#if !defined(MBEDTLS_DEPRECATED_REMOVED)
492void mbedtls_sha512( const unsigned char *input,
493 size_t ilen,
494 unsigned char output[64],
495 int is384 )
496{
497 mbedtls_sha512_ret( input, ilen, output, is384 );
498}
499#endif
500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000502
503/*
504 * FIPS-180-2 test vectors
505 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000506static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000507{
508 { "abc" },
509 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
510 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
511 { "" }
512};
513
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100514static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000515{
516 3, 112, 1000
517};
518
Paul Bakker9e36f042013-06-30 14:34:05 +0200519static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000520{
521 /*
522 * SHA-384 test vectors
523 */
524 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
525 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
526 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
527 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
528 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
529 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
530 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
531 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
532 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
533 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
534 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
535 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
536 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
537 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
538 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
539 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
540 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
541 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
542
543 /*
544 * SHA-512 test vectors
545 */
546 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
547 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
548 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
549 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
550 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
551 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
552 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
553 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
554 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
555 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
556 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
557 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
558 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
559 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
560 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
561 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
562 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
563 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
564 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
565 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
566 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
567 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
568 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
569 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
570};
571
572/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000573 * Checkup routine
574 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000576{
Paul Bakker5b4af392014-06-26 12:09:34 +0200577 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500578 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200579 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
Russ Butlerbb83b422016-10-12 17:36:50 -0500582 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200592
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 for( i = 0; i < 6; i++ )
594 {
595 j = i % 3;
596 k = i < 3;
597
598 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100601 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100602 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
604 if( j == 2 )
605 {
606 memset( buf, 'a', buflen = 1000 );
607
608 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100609 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100610 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100611 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100612 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100613 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 }
615 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100616 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100617 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100618 sha512_test_buflen[j] );
619 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100620 goto fail;
621 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100623 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100624 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Paul Bakker9e36f042013-06-30 14:34:05 +0200626 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100627 {
628 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100629 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100630 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
632 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
636 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100639 goto exit;
640
641fail:
642 if( verbose != 0 )
643 mbedtls_printf( "failed\n" );
644
Paul Bakker5b4af392014-06-26 12:09:34 +0200645exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500647 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200648
649 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000650}
651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#endif /* MBEDTLS_SHA512_C */