blob: 6de94e99b43cc6ed817c26388be0f3ae30e4aa8b [file] [log] [blame] [raw]
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 Bakker90995b52013-06-24 19:20:35 +020057
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020058#if !defined(MBEDTLS_SHA512_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000059
60/*
61 * 64-bit integer manipulation macros (big endian)
62 */
63#ifndef GET_UINT64_BE
64#define GET_UINT64_BE(n,b,i) \
65{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000066 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
67 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
68 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
69 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
70 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
71 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
72 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
73 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000074}
Paul Bakker9af723c2014-05-01 13:03:14 +020075#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77#ifndef PUT_UINT64_BE
78#define PUT_UINT64_BE(n,b,i) \
79{ \
80 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
81 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
82 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
83 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
84 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
85 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
86 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
87 (b)[(i) + 7] = (unsigned char) ( (n) ); \
88}
Paul Bakker9af723c2014-05-01 13:03:14 +020089#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020091void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020092{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020094}
95
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020097{
98 if( ctx == NULL )
99 return;
100
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500101 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200102}
103
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200104void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
105 const mbedtls_sha512_context *src )
106{
107 *dst = *src;
108}
109
Paul Bakker5121ce52009-01-03 21:22:43 +0000110/*
111 * SHA-512 context setup
112 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100113int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000114{
115 ctx->total[0] = 0;
116 ctx->total[1] = 0;
117
118 if( is384 == 0 )
119 {
120 /* SHA-512 */
121 ctx->state[0] = UL64(0x6A09E667F3BCC908);
122 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
123 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
124 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
125 ctx->state[4] = UL64(0x510E527FADE682D1);
126 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
127 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
128 ctx->state[7] = UL64(0x5BE0CD19137E2179);
129 }
130 else
131 {
132 /* SHA-384 */
133 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
134 ctx->state[1] = UL64(0x629A292A367CD507);
135 ctx->state[2] = UL64(0x9159015A3070DD17);
136 ctx->state[3] = UL64(0x152FECD8F70E5939);
137 ctx->state[4] = UL64(0x67332667FFC00B31);
138 ctx->state[5] = UL64(0x8EB44A8768581511);
139 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
140 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
141 }
142
143 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100144
145 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000146}
147
Jaeden Amero041039f2018-02-19 15:28:08 +0000148#if !defined(MBEDTLS_DEPRECATED_REMOVED)
149void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
150 int is384 )
151{
152 mbedtls_sha512_starts_ret( ctx, is384 );
153}
154#endif
155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200157
158/*
159 * Round constants
160 */
161static const uint64_t K[80] =
162{
163 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
164 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
165 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
166 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
167 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
168 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
169 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
170 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
171 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
172 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
173 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
174 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
175 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
176 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
177 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
178 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
179 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
180 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
181 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
182 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
183 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
184 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
185 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
186 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
187 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
188 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
189 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
190 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
191 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
192 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
193 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
194 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
195 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
196 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
197 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
198 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
199 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
200 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
201 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
202 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
203};
204
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100205int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
206 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000207{
208 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000209 uint64_t temp1, temp2, W[80];
210 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000211
212#define SHR(x,n) (x >> n)
213#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
214
215#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
216#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
217
218#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
219#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
220
221#define F0(x,y,z) ((x & y) | (z & (x | y)))
222#define F1(x,y,z) (z ^ (x & (y ^ z)))
223
224#define P(a,b,c,d,e,f,g,h,x,K) \
225{ \
226 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
227 temp2 = S2(a) + F0(a,b,c); \
228 d += temp1; h = temp1 + temp2; \
229}
230
231 for( i = 0; i < 16; i++ )
232 {
233 GET_UINT64_BE( W[i], data, i << 3 );
234 }
235
236 for( ; i < 80; i++ )
237 {
238 W[i] = S1(W[i - 2]) + W[i - 7] +
239 S0(W[i - 15]) + W[i - 16];
240 }
241
242 A = ctx->state[0];
243 B = ctx->state[1];
244 C = ctx->state[2];
245 D = ctx->state[3];
246 E = ctx->state[4];
247 F = ctx->state[5];
248 G = ctx->state[6];
249 H = ctx->state[7];
250 i = 0;
251
252 do
253 {
254 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
255 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
256 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
257 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
258 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
259 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
260 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
261 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
262 }
263 while( i < 80 );
264
265 ctx->state[0] += A;
266 ctx->state[1] += B;
267 ctx->state[2] += C;
268 ctx->state[3] += D;
269 ctx->state[4] += E;
270 ctx->state[5] += F;
271 ctx->state[6] += G;
272 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100273
274 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000275}
Jaeden Amero041039f2018-02-19 15:28:08 +0000276
277#if !defined(MBEDTLS_DEPRECATED_REMOVED)
278void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
279 const unsigned char data[128] )
280{
281 mbedtls_internal_sha512_process( ctx, data );
282}
283#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000285
286/*
287 * SHA-512 process buffer
288 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100289int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100290 const unsigned char *input,
291 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100293 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000294 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000295 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
Brian White12895d12014-04-11 11:29:42 -0400297 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100298 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
Paul Bakkerb8213a12011-07-11 08:16:18 +0000300 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000301 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 ctx->total[1]++;
307
308 if( left && ilen >= fill )
309 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200310 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100311
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100312 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100313 return( ret );
314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 input += fill;
316 ilen -= fill;
317 left = 0;
318 }
319
320 while( ilen >= 128 )
321 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100322 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100323 return( ret );
324
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 input += 128;
326 ilen -= 128;
327 }
328
329 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200330 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100331
332 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333}
Jaeden Amero041039f2018-02-19 15:28:08 +0000334
335#if !defined(MBEDTLS_DEPRECATED_REMOVED)
336void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
337 const unsigned char *input,
338 size_t ilen )
339{
340 mbedtls_sha512_update_ret( ctx, input, ilen );
341}
342#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
Paul Bakker9e36f042013-06-30 14:34:05 +0200344static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000345{
346 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
348 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
352 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
354};
355
356/*
357 * SHA-512 final digest
358 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100359int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100360 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000361{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100362 int ret;
Paul Bakker27fdf462011-06-09 13:55:13 +0000363 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 unsigned char msglen[16];
366
367 high = ( ctx->total[0] >> 61 )
368 | ( ctx->total[1] << 3 );
369 low = ( ctx->total[0] << 3 );
370
371 PUT_UINT64_BE( high, msglen, 0 );
372 PUT_UINT64_BE( low, msglen, 8 );
373
Paul Bakker27fdf462011-06-09 13:55:13 +0000374 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
376
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100377 if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100378 return( ret );
379
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100380 if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100381 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
383 PUT_UINT64_BE( ctx->state[0], output, 0 );
384 PUT_UINT64_BE( ctx->state[1], output, 8 );
385 PUT_UINT64_BE( ctx->state[2], output, 16 );
386 PUT_UINT64_BE( ctx->state[3], output, 24 );
387 PUT_UINT64_BE( ctx->state[4], output, 32 );
388 PUT_UINT64_BE( ctx->state[5], output, 40 );
389
390 if( ctx->is384 == 0 )
391 {
392 PUT_UINT64_BE( ctx->state[6], output, 48 );
393 PUT_UINT64_BE( ctx->state[7], output, 56 );
394 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100395
396 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397}
398
Jaeden Amero041039f2018-02-19 15:28:08 +0000399#if !defined(MBEDTLS_DEPRECATED_REMOVED)
400void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
401 unsigned char output[64] )
402{
403 mbedtls_sha512_finish_ret( ctx, output );
404}
405#endif
406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200408
Paul Bakker5121ce52009-01-03 21:22:43 +0000409/*
410 * output = SHA-512( input buffer )
411 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100412int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100413 size_t ilen,
414 unsigned char output[64],
415 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000416{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100417 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100421
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100422 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100423 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100424
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100425 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100426 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100427
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100428 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100429 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100430
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100431exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100433
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100434 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000435}
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Jaeden Amero041039f2018-02-19 15:28:08 +0000437#if !defined(MBEDTLS_DEPRECATED_REMOVED)
438void mbedtls_sha512( const unsigned char *input,
439 size_t ilen,
440 unsigned char output[64],
441 int is384 )
442{
443 mbedtls_sha512_ret( input, ilen, output, is384 );
444}
445#endif
446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449/*
450 * FIPS-180-2 test vectors
451 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000452static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000453{
454 { "abc" },
455 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
456 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
457 { "" }
458};
459
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100460static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000461{
462 3, 112, 1000
463};
464
Paul Bakker9e36f042013-06-30 14:34:05 +0200465static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000466{
467 /*
468 * SHA-384 test vectors
469 */
470 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
471 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
472 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
473 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
474 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
475 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
476 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
477 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
478 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
479 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
480 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
481 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
482 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
483 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
484 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
485 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
486 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
487 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
488
489 /*
490 * SHA-512 test vectors
491 */
492 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
493 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
494 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
495 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
496 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
497 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
498 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
499 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
500 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
501 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
502 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
503 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
504 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
505 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
506 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
507 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
508 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
509 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
510 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
511 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
512 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
513 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
514 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
515 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
516};
517
518/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 * Checkup routine
520 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000522{
Paul Bakker5b4af392014-06-26 12:09:34 +0200523 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500524 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200525 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_sha512_context ctx;
Russ Butlerbb83b422016-10-12 17:36:50 -0500527
528 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
529 if( NULL == buf )
530 {
531 if( verbose != 0 )
532 mbedtls_printf( "Buffer allocation failed\n" );
533
534 return( 1 );
535 }
Paul Bakker5b4af392014-06-26 12:09:34 +0200536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537 mbedtls_sha512_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
539 for( i = 0; i < 6; i++ )
540 {
541 j = i % 3;
542 k = i < 3;
543
544 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100547 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100548 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 if( j == 2 )
551 {
552 memset( buf, 'a', buflen = 1000 );
553
554 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100555 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100556 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100557 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100558 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100559 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 }
561 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100562 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100563 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100564 sha512_test_buflen[j] );
565 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100566 goto fail;
567 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100569 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100570 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
Paul Bakker9e36f042013-06-30 14:34:05 +0200572 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100573 {
574 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100575 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100576 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580 }
581
582 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100585 goto exit;
586
587fail:
588 if( verbose != 0 )
589 mbedtls_printf( "failed\n" );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100590
Paul Bakker5b4af392014-06-26 12:09:34 +0200591exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500593 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200594
595 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596}
597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600#endif /* MBEDTLS_SHA512_C */