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