blob: fb872a151a13ae6b278c963b8a6c9e1eaaf74643 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
24 *
25 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_SHA512_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/sha512.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_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +000047#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000048#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_SELF_TEST)
51#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000052#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010053#else
Rich Evans00ab4702015-02-06 13:43:58 +000054#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#define mbedtls_printf printf
56#endif /* MBEDTLS_PLATFORM_C */
57#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010058
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064#if !defined(MBEDTLS_SHA512_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020065
Paul Bakker5121ce52009-01-03 21:22:43 +000066/*
67 * 64-bit integer manipulation macros (big endian)
68 */
69#ifndef GET_UINT64_BE
70#define GET_UINT64_BE(n,b,i) \
71{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000072 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
73 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
74 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
75 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
76 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
77 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
78 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
79 | ( (uint64_t) (b)[(i) + 7] ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000080}
Paul Bakker9af723c2014-05-01 13:03:14 +020081#endif /* GET_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000082
83#ifndef PUT_UINT64_BE
84#define PUT_UINT64_BE(n,b,i) \
85{ \
86 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
87 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
88 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
89 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
90 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
91 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
92 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
93 (b)[(i) + 7] = (unsigned char) ( (n) ); \
94}
Paul Bakker9af723c2014-05-01 13:03:14 +020095#endif /* PUT_UINT64_BE */
Paul Bakker5121ce52009-01-03 21:22:43 +000096
97/*
98 * Round constants
99 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000100static const uint64_t K[80] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000101{
102 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
103 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
104 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
105 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
106 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
107 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
108 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
109 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
110 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
111 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
112 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
113 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
114 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
115 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
116 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
117 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
118 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
119 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
120 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
121 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
122 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
123 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
124 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
125 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
126 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
127 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
128 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
129 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
130 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
131 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
132 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
133 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
134 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
135 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
136 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
137 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
138 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
139 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
140 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
141 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
142};
143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200145{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200147}
148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200150{
151 if( ctx == NULL )
152 return;
153
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200155}
156
Paul Bakker5121ce52009-01-03 21:22:43 +0000157/*
158 * SHA-512 context setup
159 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000161{
162 ctx->total[0] = 0;
163 ctx->total[1] = 0;
164
165 if( is384 == 0 )
166 {
167 /* SHA-512 */
168 ctx->state[0] = UL64(0x6A09E667F3BCC908);
169 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
170 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
171 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
172 ctx->state[4] = UL64(0x510E527FADE682D1);
173 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
174 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
175 ctx->state[7] = UL64(0x5BE0CD19137E2179);
176 }
177 else
178 {
179 /* SHA-384 */
180 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
181 ctx->state[1] = UL64(0x629A292A367CD507);
182 ctx->state[2] = UL64(0x9159015A3070DD17);
183 ctx->state[3] = UL64(0x152FECD8F70E5939);
184 ctx->state[4] = UL64(0x67332667FFC00B31);
185 ctx->state[5] = UL64(0x8EB44A8768581511);
186 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
187 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
188 }
189
190 ctx->is384 = is384;
191}
192
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
194void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
196 int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197 uint64_t temp1, temp2, W[80];
198 uint64_t A, B, C, D, E, F, G, H;
Paul Bakker5121ce52009-01-03 21:22:43 +0000199
200#define SHR(x,n) (x >> n)
201#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
202
203#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
204#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
205
206#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
207#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
208
209#define F0(x,y,z) ((x & y) | (z & (x | y)))
210#define F1(x,y,z) (z ^ (x & (y ^ z)))
211
212#define P(a,b,c,d,e,f,g,h,x,K) \
213{ \
214 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
215 temp2 = S2(a) + F0(a,b,c); \
216 d += temp1; h = temp1 + temp2; \
217}
218
219 for( i = 0; i < 16; i++ )
220 {
221 GET_UINT64_BE( W[i], data, i << 3 );
222 }
223
224 for( ; i < 80; i++ )
225 {
226 W[i] = S1(W[i - 2]) + W[i - 7] +
227 S0(W[i - 15]) + W[i - 16];
228 }
229
230 A = ctx->state[0];
231 B = ctx->state[1];
232 C = ctx->state[2];
233 D = ctx->state[3];
234 E = ctx->state[4];
235 F = ctx->state[5];
236 G = ctx->state[6];
237 H = ctx->state[7];
238 i = 0;
239
240 do
241 {
242 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
243 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
244 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
245 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
246 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
247 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
248 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
249 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
250 }
251 while( i < 80 );
252
253 ctx->state[0] += A;
254 ctx->state[1] += B;
255 ctx->state[2] += C;
256 ctx->state[3] += D;
257 ctx->state[4] += E;
258 ctx->state[5] += F;
259 ctx->state[6] += G;
260 ctx->state[7] += H;
261}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * SHA-512 process buffer
266 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200268 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000269{
Paul Bakker23986e52011-04-24 08:57:21 +0000270 size_t fill;
Paul Bakkerb8213a12011-07-11 08:16:18 +0000271 unsigned int left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000272
Brian White12895d12014-04-11 11:29:42 -0400273 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 return;
275
Paul Bakkerb8213a12011-07-11 08:16:18 +0000276 left = (unsigned int) (ctx->total[0] & 0x7F);
Paul Bakker27fdf462011-06-09 13:55:13 +0000277 fill = 128 - left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 ctx->total[0] += (uint64_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
Paul Bakker5c2364c2012-10-01 14:41:15 +0000281 if( ctx->total[0] < (uint64_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 ctx->total[1]++;
283
284 if( left && ilen >= fill )
285 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200286 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 mbedtls_sha512_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 input += fill;
289 ilen -= fill;
290 left = 0;
291 }
292
293 while( ilen >= 128 )
294 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295 mbedtls_sha512_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 input += 128;
297 ilen -= 128;
298 }
299
300 if( ilen > 0 )
Paul Bakker3c2122f2013-06-24 19:03:14 +0200301 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302}
303
Paul Bakker9e36f042013-06-30 14:34:05 +0200304static const unsigned char sha512_padding[128] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000305{
306 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
314};
315
316/*
317 * SHA-512 final digest
318 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000320{
Paul Bakker27fdf462011-06-09 13:55:13 +0000321 size_t last, padn;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322 uint64_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000323 unsigned char msglen[16];
324
325 high = ( ctx->total[0] >> 61 )
326 | ( ctx->total[1] << 3 );
327 low = ( ctx->total[0] << 3 );
328
329 PUT_UINT64_BE( high, msglen, 0 );
330 PUT_UINT64_BE( low, msglen, 8 );
331
Paul Bakker27fdf462011-06-09 13:55:13 +0000332 last = (size_t)( ctx->total[0] & 0x7F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 mbedtls_sha512_update( ctx, sha512_padding, padn );
336 mbedtls_sha512_update( ctx, msglen, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338 PUT_UINT64_BE( ctx->state[0], output, 0 );
339 PUT_UINT64_BE( ctx->state[1], output, 8 );
340 PUT_UINT64_BE( ctx->state[2], output, 16 );
341 PUT_UINT64_BE( ctx->state[3], output, 24 );
342 PUT_UINT64_BE( ctx->state[4], output, 32 );
343 PUT_UINT64_BE( ctx->state[5], output, 40 );
344
345 if( ctx->is384 == 0 )
346 {
347 PUT_UINT64_BE( ctx->state[6], output, 48 );
348 PUT_UINT64_BE( ctx->state[7], output, 56 );
349 }
350}
351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352#endif /* !MBEDTLS_SHA512_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200353
Paul Bakker5121ce52009-01-03 21:22:43 +0000354/*
355 * output = SHA-512( input buffer )
356 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357void mbedtls_sha512( const unsigned char *input, size_t ilen,
Paul Bakker9e36f042013-06-30 14:34:05 +0200358 unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000359{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_sha512_init( &ctx );
363 mbedtls_sha512_starts( &ctx, is384 );
364 mbedtls_sha512_update( &ctx, input, ilen );
365 mbedtls_sha512_finish( &ctx, output );
366 mbedtls_sha512_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000367}
368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369#if defined(MBEDTLS_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370/*
371 * output = SHA-512( file contents )
372 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373int mbedtls_sha512_file( const char *path, unsigned char output[64], int is384 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000374{
375 FILE *f;
376 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 unsigned char buf[1024];
379
380 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 return( MBEDTLS_ERR_SHA512_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_sha512_init( &ctx );
384 mbedtls_sha512_starts( &ctx, is384 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
386 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 mbedtls_sha512_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_sha512_finish( &ctx, output );
390 mbedtls_sha512_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392 if( ferror( f ) != 0 )
393 {
394 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 return( MBEDTLS_ERR_SHA512_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 }
397
398 fclose( f );
399 return( 0 );
400}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401#endif /* MBEDTLS_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
405/*
406 * FIPS-180-2 test vectors
407 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000408static const unsigned char sha512_test_buf[3][113] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000409{
410 { "abc" },
411 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
412 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
413 { "" }
414};
415
Paul Bakker9e36f042013-06-30 14:34:05 +0200416static const int sha512_test_buflen[3] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000417{
418 3, 112, 1000
419};
420
Paul Bakker9e36f042013-06-30 14:34:05 +0200421static const unsigned char sha512_test_sum[6][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
423 /*
424 * SHA-384 test vectors
425 */
426 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
427 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
428 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
429 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
430 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
431 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
432 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
433 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
434 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
435 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
436 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
437 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
438 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
439 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
440 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
441 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
442 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
443 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
444
445 /*
446 * SHA-512 test vectors
447 */
448 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
449 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
450 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
451 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
452 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
453 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
454 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
455 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
456 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
457 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
458 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
459 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
460 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
461 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
462 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
463 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
464 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
465 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
466 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
467 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
468 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
469 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
470 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
471 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
472};
473
474/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000475 * Checkup routine
476 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477int mbedtls_sha512_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000478{
Paul Bakker5b4af392014-06-26 12:09:34 +0200479 int i, j, k, buflen, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000480 unsigned char buf[1024];
Paul Bakker9e36f042013-06-30 14:34:05 +0200481 unsigned char sha512sum[64];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 mbedtls_sha512_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_sha512_init( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200485
Paul Bakker5121ce52009-01-03 21:22:43 +0000486 for( i = 0; i < 6; i++ )
487 {
488 j = i % 3;
489 k = i < 3;
490
491 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_sha512_starts( &ctx, k );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496 if( j == 2 )
497 {
498 memset( buf, 'a', buflen = 1000 );
499
500 for( j = 0; j < 1000; j++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_sha512_update( &ctx, buf, buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000502 }
503 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 mbedtls_sha512_update( &ctx, sha512_test_buf[j],
Paul Bakker9e36f042013-06-30 14:34:05 +0200505 sha512_test_buflen[j] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 mbedtls_sha512_finish( &ctx, sha512sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Paul Bakker9e36f042013-06-30 14:34:05 +0200509 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 {
511 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
Paul Bakker5b4af392014-06-26 12:09:34 +0200514 ret = 1;
515 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 }
517
518 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 }
521
522 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
Paul Bakker5b4af392014-06-26 12:09:34 +0200525exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_sha512_free( &ctx );
Paul Bakker5b4af392014-06-26 12:09:34 +0200527
528 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529}
530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#endif /* MBEDTLS_SHA512_C */