blob: b1947f1ea0dccd34151ef05042795fbaccb17369 [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 */
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100117int mbedtls_sha512_starts_ext( 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
Alexey Skalozub00b78a92016-01-13 17:39:58 +0200153
154/*
155 * Round constants
156 */
157static const uint64_t K[80] =
158{
159 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
160 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
161 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
162 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
163 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
164 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
165 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
166 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
167 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
168 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
169 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
170 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
171 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
172 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
173 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
174 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
175 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
176 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
177 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
178 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
179 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
180 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
181 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
182 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
183 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
184 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
185 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
186 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
187 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
188 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
189 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
190 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
191 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
192 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
193 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
194 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
195 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
196 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
197 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
198 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
199};
200
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100201int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
202 const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203{
204 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205 uint64_t temp1, temp2, W[80];
206 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
208#define SHR(x,n) (x >> n)
209#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
210
211#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
212#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
213
214#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
215#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
216
217#define F0(x,y,z) ((x & y) | (z & (x | y)))
218#define F1(x,y,z) (z ^ (x & (y ^ z)))
219
220#define P(a,b,c,d,e,f,g,h,x,K) \
221{ \
222 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
223 temp2 = S2(a) + F0(a,b,c); \
224 d += temp1; h = temp1 + temp2; \
225}
226
227 for( i = 0; i < 16; i++ )
228 {
229 GET_UINT64_BE( W[i], data, i << 3 );
230 }
231
232 for( ; i < 80; i++ )
233 {
234 W[i] = S1(W[i - 2]) + W[i - 7] +
235 S0(W[i - 15]) + W[i - 16];
236 }
237
238 A = ctx->state[0];
239 B = ctx->state[1];
240 C = ctx->state[2];
241 D = ctx->state[3];
242 E = ctx->state[4];
243 F = ctx->state[5];
244 G = ctx->state[6];
245 H = ctx->state[7];
246 i = 0;
247
248 do
249 {
250 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
251 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
252 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
253 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
254 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
255 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
256 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
257 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
258 }
259 while( i < 80 );
260
261 ctx->state[0] += A;
262 ctx->state[1] += B;
263 ctx->state[2] += C;
264 ctx->state[3] += D;
265 ctx->state[4] += E;
266 ctx->state[5] += F;
267 ctx->state[6] += G;
268 ctx->state[7] += H;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100269
270 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000271}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274/*
275 * SHA-512 process buffer
276 */
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100277int mbedtls_sha512_update_ext( mbedtls_sha512_context *ctx,
278 const unsigned char *input,
279 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100281 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000282 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000283 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Brian White12895d12014-04-11 11:29:42 -0400285 if( ilen == 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100286 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000287
Paul Bakkerb8213a12011-07-11 08:16:18 +0000288 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000289 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
Paul Bakker5c2364c2012-10-01 14:41:15 +0000293 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 ctx->total[1]++;
295
296 if( left && ilen >= fill )
297 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200298 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100299
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100300 if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100301 return( ret );
302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 input += fill;
304 ilen -= fill;
305 left = 0;
306 }
307
308 while( ilen >= 128 )
309 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100310 if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100311 return( ret );
312
Paul Bakker5121ce52009-01-03 21:22:43 +0000313 input += 128;
314 ilen -= 128;
315 }
316
317 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200318 memcpy( (void *) (ctx->buffer + left), input, ilen );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100319
320 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321}
322
Paul Bakker9e36f042013-06-30 14:34:05 +0200323static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
325 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
333};
334
335/*
336 * SHA-512 final digest
337 */
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100338int mbedtls_sha512_finish_ext( mbedtls_sha512_context *ctx,
339 unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000340{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100341 int ret;
Paul Bakker27fdf462011-06-09 13:55:13 +0000342 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000343 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000344 unsigned char msglen[16];
345
346 high = ( ctx->total[0] >> 61 )
347 | ( ctx->total[1] << 3 );
348 low = ( ctx->total[0] << 3 );
349
350 PUT_UINT64_BE( high, msglen, 0 );
351 PUT_UINT64_BE( low, msglen, 8 );
352
Paul Bakker27fdf462011-06-09 13:55:13 +0000353 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
355
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100356 if( ( ret = mbedtls_sha512_update_ext( ctx, sha512_padding, padn ) ) != 0 )
357 return( ret );
358
359 if( ( ret = mbedtls_sha512_update_ext( ctx, msglen, 16 ) ) != 0 )
360 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
362 PUT_UINT64_BE( ctx->state[0], output, 0 );
363 PUT_UINT64_BE( ctx->state[1], output, 8 );
364 PUT_UINT64_BE( ctx->state[2], output, 16 );
365 PUT_UINT64_BE( ctx->state[3], output, 24 );
366 PUT_UINT64_BE( ctx->state[4], output, 32 );
367 PUT_UINT64_BE( ctx->state[5], output, 40 );
368
369 if( ctx->is384 == 0 )
370 {
371 PUT_UINT64_BE( ctx->state[6], output, 48 );
372 PUT_UINT64_BE( ctx->state[7], output, 56 );
373 }
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100374
375 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376}
377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200379
Paul Bakker5121ce52009-01-03 21:22:43 +0000380/*
381 * output = SHA-512( input buffer )
382 */
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100383int mbedtls_sha512_ext( const unsigned char *input,
384 size_t ilen,
385 unsigned char output[64],
386 int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000387{
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100388 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_sha512_init( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100392
393 if( ( ret = mbedtls_sha512_starts_ext( &ctx, is384 ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100394 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100395
396 if( ( ret = mbedtls_sha512_update_ext( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100397 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100398
399 if( ( ret = mbedtls_sha512_finish_ext( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100400 goto exit;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100401
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100402exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_sha512_free( &ctx );
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100404
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100405 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406}
407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410/*
411 * FIPS-180-2 test vectors
412 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000413static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000414{
415 { "abc" },
416 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
417 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
418 { "" }
419};
420
Paul Bakker9e36f042013-06-30 14:34:05 +0200421static const int sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
423 3, 112, 1000
424};
425
Paul Bakker9e36f042013-06-30 14:34:05 +0200426static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000427{
428 /*
429 * SHA-384 test vectors
430 */
431 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
432 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
433 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
434 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
435 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
436 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
437 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
438 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
439 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
440 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
441 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
442 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
443 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
444 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
445 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
446 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
447 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
448 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
449
450 /*
451 * SHA-512 test vectors
452 */
453 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
454 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
455 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
456 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
457 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
458 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
459 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
460 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
461 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
462 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
463 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
464 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
465 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
466 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
467 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
468 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
469 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
470 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
471 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
472 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
473 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
474 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
475 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
476 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
477};
478
479/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000480 * Checkup routine
481 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000483{
Paul Bakker5b4af392014-06-26 12:09:34 +0200484 int i, j, k, buflen, ret = 0;
Russ Butlerbb83b422016-10-12 17:36:50 -0500485 unsigned char *buf;
Paul Bakker9e36f042013-06-30 14:34:05 +0200486 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
Russ Butlerbb83b422016-10-12 17:36:50 -0500489 buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
490 if( NULL == buf )
491 {
492 if( verbose != 0 )
493 mbedtls_printf( "Buffer allocation failed\n" );
494
495 return( 1 );
496 }
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200499
Paul Bakker5121ce52009-01-03 21:22:43 +0000500 for( i = 0; i < 6; i++ )
501 {
502 j = i % 3;
503 k = i < 3;
504
505 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000507
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100508 if( ( ret = mbedtls_sha512_starts_ext( &ctx, k ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100509 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
511 if( j == 2 )
512 {
513 memset( buf, 'a', buflen = 1000 );
514
515 for( j = 0; j < 1000; j++ )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100516 {
517 ret = mbedtls_sha512_update_ext( &ctx, buf, buflen );
518 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100519 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100520 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 }
522 else
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100523 {
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100524 ret = mbedtls_sha512_update_ext( &ctx, sha512_test_buf[j],
525 sha512_test_buflen[j] );
526 if( ret != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100527 goto fail;
528 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100530 if( ( ret = mbedtls_sha512_finish_ext( &ctx, sha512sum ) ) != 0 )
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100531 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
Paul Bakker9e36f042013-06-30 14:34:05 +0200533 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100534 {
535 ret = 1;
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100536 goto fail;
Andres Amaya Garcia6a3f3052017-07-20 14:18:54 +0100537 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
539 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000541 }
542
543 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
Andres Amaya Garcia614c6892017-05-02 12:07:26 +0100546 goto exit;
547
548fail:
549 if( verbose != 0 )
550 mbedtls_printf( "failed\n" );
551
Paul Bakker5b4af392014-06-26 12:09:34 +0200552exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 mbedtls_sha512_free( &ctx );
Russ Butlerbb83b422016-10-12 17:36:50 -0500554 mbedtls_free( buf );
Paul Bakker5b4af392014-06-26 12:09:34 +0200555
556 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557}
558
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561#endif /* MBEDTLS_SHA512_C */