049f6b600e28c8b93d1ae14fc58eef43c4192edc
[reactos.git] / reactos / dll / 3rdparty / mbedtls / sha512.c
1 /*
2 * FIPS-180-2 compliant SHA-384/512 implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23 /*
24 * The SHA-512 Secure Hash Standard was published by NIST in 2002.
25 *
26 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
27 */
28
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
31 #else
32 #include MBEDTLS_CONFIG_FILE
33 #endif
34
35 #if defined(MBEDTLS_SHA512_C)
36
37 #include "mbedtls/sha512.h"
38
39 #if defined(_MSC_VER) || defined(__WATCOMC__)
40 #define UL64(x) x##ui64
41 #else
42 #define UL64(x) x##ULL
43 #endif
44
45 #include <string.h>
46
47 #if defined(MBEDTLS_SELF_TEST)
48 #if defined(MBEDTLS_PLATFORM_C)
49 #include "mbedtls/platform.h"
50 #else
51 #include <stdio.h>
52 #define mbedtls_printf printf
53 #endif /* MBEDTLS_PLATFORM_C */
54 #endif /* MBEDTLS_SELF_TEST */
55
56 #if !defined(MBEDTLS_SHA512_ALT)
57
58 /* Implementation that should never be optimized out by the compiler */
59 static void mbedtls_zeroize( void *v, size_t n ) {
60 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
61 }
62
63 /*
64 * 64-bit integer manipulation macros (big endian)
65 */
66 #ifndef GET_UINT64_BE
67 #define GET_UINT64_BE(n,b,i) \
68 { \
69 (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
70 | ( (uint64_t) (b)[(i) + 1] << 48 ) \
71 | ( (uint64_t) (b)[(i) + 2] << 40 ) \
72 | ( (uint64_t) (b)[(i) + 3] << 32 ) \
73 | ( (uint64_t) (b)[(i) + 4] << 24 ) \
74 | ( (uint64_t) (b)[(i) + 5] << 16 ) \
75 | ( (uint64_t) (b)[(i) + 6] << 8 ) \
76 | ( (uint64_t) (b)[(i) + 7] ); \
77 }
78 #endif /* GET_UINT64_BE */
79
80 #ifndef PUT_UINT64_BE
81 #define PUT_UINT64_BE(n,b,i) \
82 { \
83 (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
84 (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
85 (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
86 (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
87 (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
88 (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
89 (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
90 (b)[(i) + 7] = (unsigned char) ( (n) ); \
91 }
92 #endif /* PUT_UINT64_BE */
93
94 void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
95 {
96 memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
97 }
98
99 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
100 {
101 if( ctx == NULL )
102 return;
103
104 mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
105 }
106
107 void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
108 const mbedtls_sha512_context *src )
109 {
110 *dst = *src;
111 }
112
113 /*
114 * SHA-512 context setup
115 */
116 void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
117 {
118 ctx->total[0] = 0;
119 ctx->total[1] = 0;
120
121 if( is384 == 0 )
122 {
123 /* SHA-512 */
124 ctx->state[0] = UL64(0x6A09E667F3BCC908);
125 ctx->state[1] = UL64(0xBB67AE8584CAA73B);
126 ctx->state[2] = UL64(0x3C6EF372FE94F82B);
127 ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
128 ctx->state[4] = UL64(0x510E527FADE682D1);
129 ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
130 ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
131 ctx->state[7] = UL64(0x5BE0CD19137E2179);
132 }
133 else
134 {
135 /* SHA-384 */
136 ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
137 ctx->state[1] = UL64(0x629A292A367CD507);
138 ctx->state[2] = UL64(0x9159015A3070DD17);
139 ctx->state[3] = UL64(0x152FECD8F70E5939);
140 ctx->state[4] = UL64(0x67332667FFC00B31);
141 ctx->state[5] = UL64(0x8EB44A8768581511);
142 ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
143 ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
144 }
145
146 ctx->is384 = is384;
147 }
148
149 #if !defined(MBEDTLS_SHA512_PROCESS_ALT)
150
151 /*
152 * Round constants
153 */
154 static const uint64_t K[80] =
155 {
156 UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
157 UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
158 UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
159 UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
160 UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
161 UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
162 UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
163 UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
164 UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
165 UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
166 UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
167 UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
168 UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
169 UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
170 UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
171 UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
172 UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
173 UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
174 UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
175 UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
176 UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
177 UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
178 UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
179 UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
180 UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
181 UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
182 UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
183 UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
184 UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
185 UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
186 UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
187 UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
188 UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
189 UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
190 UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
191 UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
192 UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
193 UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
194 UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
195 UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
196 };
197
198 void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
199 {
200 int i;
201 uint64_t temp1, temp2, W[80];
202 uint64_t A, B, C, D, E, F, G, H;
203
204 #define SHR(x,n) (x >> n)
205 #define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
206
207 #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
208 #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
209
210 #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
211 #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
212
213 #define F0(x,y,z) ((x & y) | (z & (x | y)))
214 #define F1(x,y,z) (z ^ (x & (y ^ z)))
215
216 #define P(a,b,c,d,e,f,g,h,x,K) \
217 { \
218 temp1 = h + S3(e) + F1(e,f,g) + K + x; \
219 temp2 = S2(a) + F0(a,b,c); \
220 d += temp1; h = temp1 + temp2; \
221 }
222
223 for( i = 0; i < 16; i++ )
224 {
225 GET_UINT64_BE( W[i], data, i << 3 );
226 }
227
228 for( ; i < 80; i++ )
229 {
230 W[i] = S1(W[i - 2]) + W[i - 7] +
231 S0(W[i - 15]) + W[i - 16];
232 }
233
234 A = ctx->state[0];
235 B = ctx->state[1];
236 C = ctx->state[2];
237 D = ctx->state[3];
238 E = ctx->state[4];
239 F = ctx->state[5];
240 G = ctx->state[6];
241 H = ctx->state[7];
242 i = 0;
243
244 do
245 {
246 P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
247 P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
248 P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
249 P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
250 P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
251 P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
252 P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
253 P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
254 }
255 while( i < 80 );
256
257 ctx->state[0] += A;
258 ctx->state[1] += B;
259 ctx->state[2] += C;
260 ctx->state[3] += D;
261 ctx->state[4] += E;
262 ctx->state[5] += F;
263 ctx->state[6] += G;
264 ctx->state[7] += H;
265 }
266 #endif /* !MBEDTLS_SHA512_PROCESS_ALT */
267
268 /*
269 * SHA-512 process buffer
270 */
271 void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
272 size_t ilen )
273 {
274 size_t fill;
275 unsigned int left;
276
277 if( ilen == 0 )
278 return;
279
280 left = (unsigned int) (ctx->total[0] & 0x7F);
281 fill = 128 - left;
282
283 ctx->total[0] += (uint64_t) ilen;
284
285 if( ctx->total[0] < (uint64_t) ilen )
286 ctx->total[1]++;
287
288 if( left && ilen >= fill )
289 {
290 memcpy( (void *) (ctx->buffer + left), input, fill );
291 mbedtls_sha512_process( ctx, ctx->buffer );
292 input += fill;
293 ilen -= fill;
294 left = 0;
295 }
296
297 while( ilen >= 128 )
298 {
299 mbedtls_sha512_process( ctx, input );
300 input += 128;
301 ilen -= 128;
302 }
303
304 if( ilen > 0 )
305 memcpy( (void *) (ctx->buffer + left), input, ilen );
306 }
307
308 static const unsigned char sha512_padding[128] =
309 {
310 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
318 };
319
320 /*
321 * SHA-512 final digest
322 */
323 void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
324 {
325 size_t last, padn;
326 uint64_t high, low;
327 unsigned char msglen[16];
328
329 high = ( ctx->total[0] >> 61 )
330 | ( ctx->total[1] << 3 );
331 low = ( ctx->total[0] << 3 );
332
333 PUT_UINT64_BE( high, msglen, 0 );
334 PUT_UINT64_BE( low, msglen, 8 );
335
336 last = (size_t)( ctx->total[0] & 0x7F );
337 padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
338
339 mbedtls_sha512_update( ctx, sha512_padding, padn );
340 mbedtls_sha512_update( ctx, msglen, 16 );
341
342 PUT_UINT64_BE( ctx->state[0], output, 0 );
343 PUT_UINT64_BE( ctx->state[1], output, 8 );
344 PUT_UINT64_BE( ctx->state[2], output, 16 );
345 PUT_UINT64_BE( ctx->state[3], output, 24 );
346 PUT_UINT64_BE( ctx->state[4], output, 32 );
347 PUT_UINT64_BE( ctx->state[5], output, 40 );
348
349 if( ctx->is384 == 0 )
350 {
351 PUT_UINT64_BE( ctx->state[6], output, 48 );
352 PUT_UINT64_BE( ctx->state[7], output, 56 );
353 }
354 }
355
356 #endif /* !MBEDTLS_SHA512_ALT */
357
358 /*
359 * output = SHA-512( input buffer )
360 */
361 void mbedtls_sha512( const unsigned char *input, size_t ilen,
362 unsigned char output[64], int is384 )
363 {
364 mbedtls_sha512_context ctx;
365
366 mbedtls_sha512_init( &ctx );
367 mbedtls_sha512_starts( &ctx, is384 );
368 mbedtls_sha512_update( &ctx, input, ilen );
369 mbedtls_sha512_finish( &ctx, output );
370 mbedtls_sha512_free( &ctx );
371 }
372
373 #if defined(MBEDTLS_SELF_TEST)
374
375 /*
376 * FIPS-180-2 test vectors
377 */
378 static const unsigned char sha512_test_buf[3][113] =
379 {
380 { "abc" },
381 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
382 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
383 { "" }
384 };
385
386 static const int sha512_test_buflen[3] =
387 {
388 3, 112, 1000
389 };
390
391 static const unsigned char sha512_test_sum[6][64] =
392 {
393 /*
394 * SHA-384 test vectors
395 */
396 { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
397 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
398 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
399 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
400 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
401 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
402 { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
403 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
404 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
405 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
406 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
407 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
408 { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
409 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
410 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
411 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
412 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
413 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
414
415 /*
416 * SHA-512 test vectors
417 */
418 { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
419 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
420 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
421 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
422 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
423 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
424 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
425 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
426 { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
427 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
428 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
429 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
430 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
431 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
432 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
433 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
434 { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
435 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
436 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
437 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
438 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
439 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
440 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
441 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
442 };
443
444 /*
445 * Checkup routine
446 */
447 int mbedtls_sha512_self_test( int verbose )
448 {
449 int i, j, k, buflen, ret = 0;
450 unsigned char buf[1024];
451 unsigned char sha512sum[64];
452 mbedtls_sha512_context ctx;
453
454 mbedtls_sha512_init( &ctx );
455
456 for( i = 0; i < 6; i++ )
457 {
458 j = i % 3;
459 k = i < 3;
460
461 if( verbose != 0 )
462 mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
463
464 mbedtls_sha512_starts( &ctx, k );
465
466 if( j == 2 )
467 {
468 memset( buf, 'a', buflen = 1000 );
469
470 for( j = 0; j < 1000; j++ )
471 mbedtls_sha512_update( &ctx, buf, buflen );
472 }
473 else
474 mbedtls_sha512_update( &ctx, sha512_test_buf[j],
475 sha512_test_buflen[j] );
476
477 mbedtls_sha512_finish( &ctx, sha512sum );
478
479 if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
480 {
481 if( verbose != 0 )
482 mbedtls_printf( "failed\n" );
483
484 ret = 1;
485 goto exit;
486 }
487
488 if( verbose != 0 )
489 mbedtls_printf( "passed\n" );
490 }
491
492 if( verbose != 0 )
493 mbedtls_printf( "\n" );
494
495 exit:
496 mbedtls_sha512_free( &ctx );
497
498 return( ret );
499 }
500
501 #endif /* MBEDTLS_SELF_TEST */
502
503 #endif /* MBEDTLS_SHA512_C */