blob: 4d43487a98d506f72bb124a3d901138bc7184970 [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"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000037#if defined(_MSC_VER) || defined(__WATCOMC__)
38 #define UL64(x) x##ui64
39#else
40 #define UL64(x) x##ULL
41#endif
42
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <string.h>
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050050#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050052#define mbedtls_calloc calloc
53#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#endif /* MBEDTLS_PLATFORM_C */
55#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010056
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020057#if !defined(MBEDTLS_SHA512_ALT)
58
Paul Bakker34617722014-06-13 17:20:13 +020059/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020061 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
62}
63
Paul Bakker5121ce52009-01-03 21:22:43 +000064/*
65 * 64-bit integer manipulation macros (big endian)
66 */
67#ifndef GET_UINT64_BE
68#define GET_UINT64_BE(n,b,i) \
69{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000070 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
71 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
72 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
73 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
74 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
75 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
76 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
77 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000078}
Paul Bakker9af723c2014-05-01 13:03:14 +020079#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000080
81#ifndef PUT_UINT64_BE
82#define PUT_UINT64_BE(n,b,i) \
83{ \
84 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
85 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
86 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
87 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
88 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
89 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
90 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
91 (b)[(i) + 7] = (unsigned char) ( (n) ); \
92}
Paul Bakker9af723c2014-05-01 13:03:14 +020093#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020096{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020098}
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200101{
102 if( ctx == NULL )
103 return;
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200106}
107
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200108void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
109 const mbedtls_sha512_context *src )
110{
111 *dst = *src;
112}
113
Paul Bakker5121ce52009-01-03 21:22:43 +0000114/*
115 * SHA-512 context setup
116 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100117int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000118{
119 ctx->total[0] = 0;
120 ctx->total[1] = 0;
121
122 if( is384 == 0 )
123 {
124 /* SHA-512 */
125 ctx->state[0] = UL64(0x6A09E667F3BCC908);
126 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
127 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
128 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
129 ctx->state[4] = UL64(0x510E527FADE682D1);
130 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
131 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
132 ctx->state[7] = UL64(0x5BE0CD19137E2179);
133 }
134 else
135 {
136 /* SHA-384 */
137 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
138 ctx->state[1] = UL64(0x629A292A367CD507);
139 ctx->state[2] = UL64(0x9159015A3070DD17);
140 ctx->state[3] = UL64(0x152FECD8F70E5939);
141 ctx->state[4] = UL64(0x67332667FFC00B31);
142 ctx->state[5] = UL64(0x8EB44A8768581511);
143 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
144 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
145 }
146
147 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100148
149 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000150}
151
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000152#if !defined(MBEDTLS_DEPRECATED_REMOVED)
153void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
154 int is384 )
155{
156 mbedtls_sha512_starts_ret( ctx, is384 );
157}
158#endif
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200161
162/*
163 * Round constants
164 */
165static const uint64_t K[80] =
166{
167 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
168 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
169 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
170 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
171 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
172 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
173 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
174 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
175 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
176 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
177 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
178 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
179 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
180 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
181 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
182 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
183 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
184 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
185 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
186 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
187 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
188 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
189 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
190 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
191 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
192 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
193 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
194 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
195 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
196 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
197 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
198 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
199 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
200 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
201 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
202 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
203 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
204 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
205 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
206 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
207};
208
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100209int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
210 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000211{
212 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213 uint64_t temp1, temp2, W[80];
214 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000215
216#define SHR(x,n) (x >> n)
217#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
218
219#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
220#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
221
222#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
223#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
224
225#define F0(x,y,z) ((x & y) | (z & (x | y)))
226#define F1(x,y,z) (z ^ (x & (y ^ z)))
227
228#define P(a,b,c,d,e,f,g,h,x,K) \
229{ \
230 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
231 temp2 = S2(a) + F0(a,b,c); \
232 d += temp1; h = temp1 + temp2; \
233}
234
235 for( i = 0; i < 16; i++ )
236 {
237 GET_UINT64_BE( W[i], data, i << 3 );
238 }
239
240 for( ; i < 80; i++ )
241 {
242 W[i] = S1(W[i - 2]) + W[i - 7] +
243 S0(W[i - 15]) + W[i - 16];
244 }
245
246 A = ctx->state[0];
247 B = ctx->state[1];
248 C = ctx->state[2];
249 D = ctx->state[3];
250 E = ctx->state[4];
251 F = ctx->state[5];
252 G = ctx->state[6];
253 H = ctx->state[7];
254 i = 0;
255
256 do
257 {
258 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
259 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
260 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
261 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
262 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
263 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
264 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
265 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
266 }
267 while( i < 80 );
268
269 ctx->state[0] += A;
270 ctx->state[1] += B;
271 ctx->state[2] += C;
272 ctx->state[3] += D;
273 ctx->state[4] += E;
274 ctx->state[5] += F;
275 ctx->state[6] += G;
276 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100277
278 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000279}
Mohammad Azim Khan233a4212018-02-23 16:20:21 +0000280#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000281
282#if !defined(MBEDTLS_DEPRECATED_REMOVED)
283void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
284 const unsigned char data[128] )
285{
286 mbedtls_internal_sha512_process( ctx, data );
287}
288#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000289
290/*
291 * SHA-512 process buffer
292 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100293int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100294 const unsigned char *input,
295 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100297 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000298 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000299 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
Brian White12895d12014-04-11 11:29:42 -0400301 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100302 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Paul Bakkerb8213a12011-07-11 08:16:18 +0000304 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000305 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
Paul Bakker5c2364c2012-10-01 14:41:15 +0000309 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 ctx->total[1]++;
311
312 if( left && ilen >= fill )
313 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200314 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100315
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100316 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100317 return( ret );
318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 input += fill;
320 ilen -= fill;
321 left = 0;
322 }
323
324 while( ilen >= 128 )
325 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100326 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100327 return( ret );
328
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 input += 128;
330 ilen -= 128;
331 }
332
333 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200334 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100335
336 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337}
338
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000339#if !defined(MBEDTLS_DEPRECATED_REMOVED)
340void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
341 const unsigned char *input,
342 size_t ilen )
343{
344 mbedtls_sha512_update_ret( ctx, input, ilen );
345}
346#endif
347
Paul Bakker9e36f042013-06-30 14:34:05 +0200348static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000349{
350 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
358};
359
360/*
361 * SHA-512 final digest
362 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100363int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100364 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100366 int ret;
Paul Bakker27fdf462011-06-09 13:55:13 +0000367 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000368 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 unsigned char msglen[16];
370
371 high = ( ctx->total[0] >> 61 )
372 | ( ctx->total[1] << 3 );
373 low = ( ctx->total[0] << 3 );
374
375 PUT_UINT64_BE( high, msglen, 0 );
376 PUT_UINT64_BE( low, msglen, 8 );
377
Paul Bakker27fdf462011-06-09 13:55:13 +0000378 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
380
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100381 if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100382 return( ret );
383
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100384 if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100385 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000386
387 PUT_UINT64_BE( ctx->state[0], output, 0 );
388 PUT_UINT64_BE( ctx->state[1], output, 8 );
389 PUT_UINT64_BE( ctx->state[2], output, 16 );
390 PUT_UINT64_BE( ctx->state[3], output, 24 );
391 PUT_UINT64_BE( ctx->state[4], output, 32 );
392 PUT_UINT64_BE( ctx->state[5], output, 40 );
393
394 if( ctx->is384 == 0 )
395 {
396 PUT_UINT64_BE( ctx->state[6], output, 48 );
397 PUT_UINT64_BE( ctx->state[7], output, 56 );
398 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100399
400 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401}
402
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000403#if !defined(MBEDTLS_DEPRECATED_REMOVED)
404void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
405 unsigned char output[64] )
406{
407 mbedtls_sha512_finish_ret( ctx, output );
408}
409#endif
410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200412
Paul Bakker5121ce52009-01-03 21:22:43 +0000413/*
414 * output = SHA-512( input buffer )
415 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100416int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100417 size_t ilen,
418 unsigned char output[64],
419 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000420{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100421 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100425
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100426 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100427 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100428
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100429 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100430 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100431
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100432 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100433 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100434
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100435exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100437
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100438 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000439}
440
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000441#if !defined(MBEDTLS_DEPRECATED_REMOVED)
442void mbedtls_sha512( const unsigned char *input,
443 size_t ilen,
444 unsigned char output[64],
445 int is384 )
446{
447 mbedtls_sha512_ret( input, ilen, output, is384 );
448}
449#endif
450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453/*
454 * FIPS-180-2 test vectors
455 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000456static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000457{
458 { "abc" },
459 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
460 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
461 { "" }
462};
463
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100464static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
466 3, 112, 1000
467};
468
Paul Bakker9e36f042013-06-30 14:34:05 +0200469static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000470{
471 /*
472 * SHA-384 test vectors
473 */
474 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
475 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
476 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
477 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
478 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
479 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
480 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
481 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
482 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
483 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
484 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
485 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
486 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
487 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
488 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
489 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
490 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
491 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
492
493 /*
494 * SHA-512 test vectors
495 */
496 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
497 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
498 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
499 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
500 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
501 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
502 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
503 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
504 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
505 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
506 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
507 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
508 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
509 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
510 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
511 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
512 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
513 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
514 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
515 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
516 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
517 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
518 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
519 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
520};
521
522/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 * Checkup routine
524 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000526{
Paul Bakker5b4af392014-06-26 12:09:34 +0200527 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500528 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200529 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Russ Butlerbb83b422016-10-12 17:36:50 -0500532 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
533 if( NULL == buf )
534 {
535 if( verbose != 0 )
536 mbedtls_printf( "Buffer allocation failed\n" );
537
538 return( 1 );
539 }
540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200542
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 for( i = 0; i < 6; i++ )
544 {
545 j = i % 3;
546 k = i < 3;
547
548 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100551 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100552 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554 if( j == 2 )
555 {
556 memset( buf, 'a', buflen = 1000 );
557
558 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100559 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100560 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100561 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100562 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100563 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 }
565 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100566 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100567 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100568 sha512_test_buflen[j] );
569 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100570 goto fail;
571 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000572
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100573 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100574 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
Paul Bakker9e36f042013-06-30 14:34:05 +0200576 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100577 {
578 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100579 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100580 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 }
585
586 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100589 goto exit;
590
591fail:
592 if( verbose != 0 )
593 mbedtls_printf( "failed\n" );
594
Paul Bakker5b4af392014-06-26 12:09:34 +0200595exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500597 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200598
599 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600}
601
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604#endif /* MBEDTLS_SHA512_C */