blob: 265923674a83d1ba7247b2216d66c75fab70ed21 [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
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000047 */
48/*
49 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
50 *
51 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
52 */
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020056#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020058#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000061
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/sha512.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000063
Manuel Pégourié-Gonnard1dd16742015-03-05 16:13:04 +000064#if defined(_MSC_VER) || defined(__WATCOMC__)
65 #define UL64(x) x##ui64
66#else
67 #define UL64(x) x##ULL
68#endif
69
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <string.h>
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if defined(MBEDTLS_SELF_TEST)
73#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000074#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010075#else
Rich Evans00ab4702015-02-06 13:43:58 +000076#include <stdio.h>
Russ Butlerbb83b422016-10-12 17:36:50 -050077#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#define mbedtls_printf printf
Russ Butlerbb83b422016-10-12 17:36:50 -050079#define mbedtls_calloc calloc
80#define mbedtls_free free
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081#endif /* MBEDTLS_PLATFORM_C */
82#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010083
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020084#if !defined(MBEDTLS_SHA512_ALT)
85
Paul Bakker34617722014-06-13 17:20:13 +020086/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020088 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
89}
90
Paul Bakker5121ce52009-01-03 21:22:43 +000091/*
92 * 64-bit integer manipulation macros (big endian)
93 */
94#ifndef GET_UINT64_BE
95#define GET_UINT64_BE(n,b,i) \
96{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000097 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
98 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
99 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
100 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
101 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
102 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
103 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
104 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000105}
Paul Bakker9af723c2014-05-01 13:03:14 +0200106#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108#ifndef PUT_UINT64_BE
109#define PUT_UINT64_BE(n,b,i) \
110{ \
111 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
112 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
113 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
114 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
115 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
116 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
117 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
118 (b)[(i) + 7] = (unsigned char) ( (n) ); \
119}
Paul Bakker9af723c2014-05-01 13:03:14 +0200120#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200123{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200125}
126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200128{
129 if( ctx == NULL )
130 return;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200133}
134
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200135void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
136 const mbedtls_sha512_context *src )
137{
138 *dst = *src;
139}
140
Paul Bakker5121ce52009-01-03 21:22:43 +0000141/*
142 * SHA-512 context setup
143 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100144int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000145{
146 ctx->total[0] = 0;
147 ctx->total[1] = 0;
148
149 if( is384 == 0 )
150 {
151 /* SHA-512 */
152 ctx->state[0] = UL64(0x6A09E667F3BCC908);
153 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
154 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
155 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
156 ctx->state[4] = UL64(0x510E527FADE682D1);
157 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
158 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
159 ctx->state[7] = UL64(0x5BE0CD19137E2179);
160 }
161 else
162 {
163 /* SHA-384 */
164 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
165 ctx->state[1] = UL64(0x629A292A367CD507);
166 ctx->state[2] = UL64(0x9159015A3070DD17);
167 ctx->state[3] = UL64(0x152FECD8F70E5939);
168 ctx->state[4] = UL64(0x67332667FFC00B31);
169 ctx->state[5] = UL64(0x8EB44A8768581511);
170 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
171 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
172 }
173
174 ctx->is384 = is384;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100175
176 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000177}
178
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000179#if !defined(MBEDTLS_DEPRECATED_REMOVED)
180void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
181 int is384 )
182{
183 mbedtls_sha512_starts_ret( ctx, is384 );
184}
185#endif
186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200188
189/*
190 * Round constants
191 */
192static const uint64_t K[80] =
193{
194 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
195 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
196 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
197 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
198 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
199 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
200 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
201 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
202 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
203 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
204 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
205 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
206 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
207 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
208 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
209 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
210 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
211 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
212 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
213 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
214 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
215 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
216 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
217 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
218 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
219 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
220 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
221 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
222 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
223 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
224 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
225 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
226 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
227 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
228 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
229 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
230 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
231 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
232 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
233 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
234};
235
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100236int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
237 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000238{
239 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000240 uint64_t temp1, temp2, W[80];
241 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
243#define SHR(x,n) (x >> n)
244#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
245
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
252#define F0(x,y,z) ((x & y) | (z & (x | y)))
253#define F1(x,y,z) (z ^ (x & (y ^ z)))
254
255#define P(a,b,c,d,e,f,g,h,x,K) \
256{ \
257 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
258 temp2 = S2(a) + F0(a,b,c); \
259 d += temp1; h = temp1 + temp2; \
260}
261
262 for( i = 0; i < 16; i++ )
263 {
264 GET_UINT64_BE( W[i], data, i << 3 );
265 }
266
267 for( ; i < 80; i++ )
268 {
269 W[i] = S1(W[i - 2]) + W[i - 7] +
270 S0(W[i - 15]) + W[i - 16];
271 }
272
273 A = ctx->state[0];
274 B = ctx->state[1];
275 C = ctx->state[2];
276 D = ctx->state[3];
277 E = ctx->state[4];
278 F = ctx->state[5];
279 G = ctx->state[6];
280 H = ctx->state[7];
281 i = 0;
282
283 do
284 {
285 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
286 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
287 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
288 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
289 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
290 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
291 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
292 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
293 }
294 while( i < 80 );
295
296 ctx->state[0] += A;
297 ctx->state[1] += B;
298 ctx->state[2] += C;
299 ctx->state[3] += D;
300 ctx->state[4] += E;
301 ctx->state[5] += F;
302 ctx->state[6] += G;
303 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100304
305 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000307
308#if !defined(MBEDTLS_DEPRECATED_REMOVED)
309void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
310 const unsigned char data[128] )
311{
312 mbedtls_internal_sha512_process( ctx, data );
313}
314#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317/*
318 * SHA-512 process buffer
319 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100320int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100321 const unsigned char *input,
322 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000323{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100324 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000325 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000326 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
Brian White12895d12014-04-11 11:29:42 -0400328 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100329 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Paul Bakkerb8213a12011-07-11 08:16:18 +0000331 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000332 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 ctx->total[1]++;
338
339 if( left && ilen >= fill )
340 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200341 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100342
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100343 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100344 return( ret );
345
Paul Bakker5121ce52009-01-03 21:22:43 +0000346 input += fill;
347 ilen -= fill;
348 left = 0;
349 }
350
351 while( ilen >= 128 )
352 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100353 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100354 return( ret );
355
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 input += 128;
357 ilen -= 128;
358 }
359
360 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200361 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100362
363 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364}
365
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000366#if !defined(MBEDTLS_DEPRECATED_REMOVED)
367void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
368 const unsigned char *input,
369 size_t ilen )
370{
371 mbedtls_sha512_update_ret( ctx, input, ilen );
372}
373#endif
374
Paul Bakker5121ce52009-01-03 21:22:43 +0000375/*
376 * SHA-512 final digest
377 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100378int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100379 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100381 int ret;
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200382 unsigned used;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000383 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200385 /*
386 * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
387 */
388 used = ctx->total[0] & 0x7F;
389
390 ctx->buffer[used++] = 0x80;
391
392 if( used <= 112 )
393 {
394 /* Enough room for padding + length in current block */
395 memset( ctx->buffer + used, 0, 112 - used );
396 }
397 else
398 {
399 /* We'll need an extra block */
400 memset( ctx->buffer + used, 0, 128 - used );
401
402 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
403 return( ret );
404
405 memset( ctx->buffer, 0, 112 );
406 }
407
408 /*
409 * Add message length
410 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 high = ( ctx->total[0] >> 61 )
412 | ( ctx->total[1] << 3 );
413 low = ( ctx->total[0] << 3 );
414
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200415 PUT_UINT64_BE( high, ctx->buffer, 112 );
416 PUT_UINT64_BE( low, ctx->buffer, 120 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200418 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
419 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Manuel Pégourié-Gonnard5fcfd032018-06-28 12:10:27 +0200421 /*
422 * Output final state
423 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 PUT_UINT64_BE( ctx->state[0], output, 0 );
425 PUT_UINT64_BE( ctx->state[1], output, 8 );
426 PUT_UINT64_BE( ctx->state[2], output, 16 );
427 PUT_UINT64_BE( ctx->state[3], output, 24 );
428 PUT_UINT64_BE( ctx->state[4], output, 32 );
429 PUT_UINT64_BE( ctx->state[5], output, 40 );
430
431 if( ctx->is384 == 0 )
432 {
433 PUT_UINT64_BE( ctx->state[6], output, 48 );
434 PUT_UINT64_BE( ctx->state[7], output, 56 );
435 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100436
437 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438}
439
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000440#if !defined(MBEDTLS_DEPRECATED_REMOVED)
441void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
442 unsigned char output[64] )
443{
444 mbedtls_sha512_finish_ret( ctx, output );
445}
446#endif
447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200449
Paul Bakker5121ce52009-01-03 21:22:43 +0000450/*
451 * output = SHA-512( input buffer )
452 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100453int mbedtls_sha512_ret( const unsigned char *input,
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100454 size_t ilen,
455 unsigned char output[64],
456 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000457{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100458 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100462
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100463 if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100464 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100465
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100466 if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100467 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100468
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100469 if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100470 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100471
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100472exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100474
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100475 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000476}
477
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000478#if !defined(MBEDTLS_DEPRECATED_REMOVED)
479void mbedtls_sha512( const unsigned char *input,
480 size_t ilen,
481 unsigned char output[64],
482 int is384 )
483{
484 mbedtls_sha512_ret( input, ilen, output, is384 );
485}
486#endif
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490/*
491 * FIPS-180-2 test vectors
492 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000493static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000494{
495 { "abc" },
496 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
497 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
498 { "" }
499};
500
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100501static const size_t sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000502{
503 3, 112, 1000
504};
505
Paul Bakker9e36f042013-06-30 14:34:05 +0200506static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000507{
508 /*
509 * SHA-384 test vectors
510 */
511 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
512 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
513 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
514 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
515 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
516 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
517 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
518 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
519 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
520 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
521 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
522 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
523 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
524 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
525 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
526 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
527 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
528 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
529
530 /*
531 * SHA-512 test vectors
532 */
533 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
534 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
535 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
536 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
537 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
538 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
539 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
540 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
541 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
542 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
543 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
544 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
545 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
546 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
547 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
548 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
549 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
550 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
551 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
552 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
553 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
554 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
555 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
556 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
557};
558
559/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 * Checkup routine
561 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000563{
Paul Bakker5b4af392014-06-26 12:09:34 +0200564 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500565 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200566 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Russ Butlerbb83b422016-10-12 17:36:50 -0500569 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
570 if( NULL == buf )
571 {
572 if( verbose != 0 )
573 mbedtls_printf( "Buffer allocation failed\n" );
574
575 return( 1 );
576 }
577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200579
Paul Bakker5121ce52009-01-03 21:22:43 +0000580 for( i = 0; i < 6; i++ )
581 {
582 j = i % 3;
583 k = i < 3;
584
585 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100588 if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100589 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
591 if( j == 2 )
592 {
593 memset( buf, 'a', buflen = 1000 );
594
595 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100596 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100597 ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100598 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100599 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100600 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 }
602 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100603 {
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100604 ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100605 sha512_test_buflen[j] );
606 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100607 goto fail;
608 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100610 if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100611 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Paul Bakker9e36f042013-06-30 14:34:05 +0200613 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100614 {
615 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100616 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100617 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 }
622
623 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100626 goto exit;
627
628fail:
629 if( verbose != 0 )
630 mbedtls_printf( "failed\n" );
631
Paul Bakker5b4af392014-06-26 12:09:34 +0200632exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500634 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200635
636 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637}
638
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641#endif /* MBEDTLS_SHA512_C */