89e7675e333f776ab3706044291e1034bbb2d48e
[strongswan.git] / src / libstrongswan / plugins / sha2 / sha2_hasher.c
1 /*
2 * Copyright (C) 2006 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2001 Jari Ruusu.
5 *
6 * Ported from strongSwans implementation written by Jari Ruusu.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include <string.h>
20
21 #include "sha2_hasher.h"
22
23
24 typedef struct private_sha512_hasher_t private_sha512_hasher_t;
25
26 /**
27 * Private data structure with hasing context for SHA384 and SHA512
28 */
29 struct private_sha512_hasher_t {
30 /**
31 * Public interface for this hasher.
32 */
33 sha2_hasher_t public;
34
35 unsigned char sha_out[128]; /* results are here, bytes 0..47/0..63 */
36 uint64_t sha_H[8];
37 uint64_t sha_blocks;
38 uint64_t sha_blocksMSB;
39 int sha_bufCnt;
40 };
41
42
43 typedef struct private_sha256_hasher_t private_sha256_hasher_t;
44
45 /**
46 * Private data structure with hasing context for SHA256
47 */
48 struct private_sha256_hasher_t {
49 /**
50 * Public interface for this hasher.
51 */
52 sha2_hasher_t public;
53
54 unsigned char sha_out[64]; /* results are here, bytes 0...31 */
55 uint32_t sha_H[8];
56 uint64_t sha_blocks;
57 int sha_bufCnt;
58 };
59
60
61 static const uint32_t sha224_hashInit[8] = {
62 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511,
63 0x64f98fa7, 0xbefa4fa4
64 };
65
66 static const uint32_t sha256_hashInit[8] = {
67 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
68 0x1f83d9ab, 0x5be0cd19
69 };
70
71 static const uint32_t sha256_K[64] = {
72 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
73 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
74 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
75 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
76 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
77 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
78 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
79 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
80 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
81 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
82 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
83 };
84
85 static const uint64_t sha512_hashInit[8] = {
86 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
87 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
88 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
89 };
90
91 static const uint64_t sha384_hashInit[8] = {
92 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
93 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
94 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
95 };
96
97 static const uint64_t sha512_K[80] = {
98 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
99 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
100 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
101 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
102 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
103 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
104 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
105 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
106 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
107 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
108 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
109 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
110 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
111 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
112 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
113 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
114 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
115 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
116 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
117 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
118 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
119 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
120 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
121 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
122 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
123 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
124 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
125 };
126
127
128 /* set macros for SHA256 */
129 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
130 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
131 #define R(x,y) ((y) >> (x))
132
133 #define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
134 #define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
135 #define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
136 #define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
137 #define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
138
139 /**
140 * Single block SHA256 transformation
141 */
142 static void sha256_transform(private_sha256_hasher_t *ctx,
143 const unsigned char *datap)
144 {
145 register int j;
146 uint32_t a, b, c, d, e, f, g, h;
147 uint32_t T1, T2, W[64], Wm2, Wm15;
148
149 /* read the data, big endian byte order */
150 j = 0;
151 do {
152 W[j] = (((uint32_t)(datap[0]))<<24) | (((uint32_t)(datap[1]))<<16) |
153 (((uint32_t)(datap[2]))<<8 ) | ((uint32_t)(datap[3]));
154 datap += 4;
155 } while(++j < 16);
156
157 /* initialize variables a...h */
158 a = ctx->sha_H[0];
159 b = ctx->sha_H[1];
160 c = ctx->sha_H[2];
161 d = ctx->sha_H[3];
162 e = ctx->sha_H[4];
163 f = ctx->sha_H[5];
164 g = ctx->sha_H[6];
165 h = ctx->sha_H[7];
166
167 /* apply compression function */
168 j = 0;
169 do
170 {
171 if(j >= 16)
172 {
173 Wm2 = W[j - 2];
174 Wm15 = W[j - 15];
175 W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
176 }
177 T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
178 T2 = uSig0(a) + Maj(a,b,c);
179 h = g; g = f; f = e;
180 e = d + T1;
181 d = c; c = b; b = a;
182 a = T1 + T2;
183 } while(++j < 64);
184
185 /* compute intermediate hash value */
186 ctx->sha_H[0] += a;
187 ctx->sha_H[1] += b;
188 ctx->sha_H[2] += c;
189 ctx->sha_H[3] += d;
190 ctx->sha_H[4] += e;
191 ctx->sha_H[5] += f;
192 ctx->sha_H[6] += g;
193 ctx->sha_H[7] += h;
194
195 ctx->sha_blocks++;
196 }
197
198 /**
199 * Update SHA256 hash
200 */
201 static void sha256_write(private_sha256_hasher_t *ctx,
202 const unsigned char *datap, int length)
203 {
204 while(length > 0)
205 {
206 if(!ctx->sha_bufCnt)
207 {
208 while(length >= sizeof(ctx->sha_out))
209 {
210 sha256_transform(ctx, datap);
211 datap += sizeof(ctx->sha_out);
212 length -= sizeof(ctx->sha_out);
213 }
214 if(!length) return;
215 }
216 ctx->sha_out[ctx->sha_bufCnt] = *datap++;
217 length--;
218 if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
219 {
220 sha256_transform(ctx, &ctx->sha_out[0]);
221 ctx->sha_bufCnt = 0;
222 }
223 }
224 }
225
226 /**
227 * finalize SHA256 hash
228 */
229 static void sha256_final(private_sha256_hasher_t *ctx)
230 {
231 register int j;
232 uint64_t bitLength;
233 uint32_t i;
234 unsigned char padByte, *datap;
235
236 bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
237 padByte = 0x80;
238 sha256_write(ctx, &padByte, 1);
239
240 /* pad extra space with zeroes */
241 padByte = 0;
242 while(ctx->sha_bufCnt != 56)
243 {
244 sha256_write(ctx, &padByte, 1);
245 }
246
247 /* write bit length, big endian byte order */
248 ctx->sha_out[56] = bitLength >> 56;
249 ctx->sha_out[57] = bitLength >> 48;
250 ctx->sha_out[58] = bitLength >> 40;
251 ctx->sha_out[59] = bitLength >> 32;
252 ctx->sha_out[60] = bitLength >> 24;
253 ctx->sha_out[61] = bitLength >> 16;
254 ctx->sha_out[62] = bitLength >> 8;
255 ctx->sha_out[63] = bitLength;
256 sha256_transform(ctx, &ctx->sha_out[0]);
257
258 /* return results in ctx->sha_out[0...31] */
259 datap = &ctx->sha_out[0];
260 j = 0;
261 do {
262 i = ctx->sha_H[j];
263 datap[0] = i >> 24;
264 datap[1] = i >> 16;
265 datap[2] = i >> 8;
266 datap[3] = i;
267 datap += 4;
268 } while(++j < 8);
269 }
270
271 /* update macros for SHA512 */
272 #undef S
273 #undef uSig0
274 #undef uSig1
275 #undef lSig0
276 #undef lSig1
277 #define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
278 #define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
279 #define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
280 #define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
281 #define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
282
283 /**
284 * Single block SHA384/SHA512 transformation
285 */
286 static void sha512_transform(private_sha512_hasher_t *ctx,
287 const unsigned char *datap)
288 {
289 register int j;
290 uint64_t a, b, c, d, e, f, g, h;
291 uint64_t T1, T2, W[80], Wm2, Wm15;
292
293 /* read the data, big endian byte order */
294 j = 0;
295 do {
296 W[j] = (((uint64_t)(datap[0]))<<56) | (((uint64_t)(datap[1]))<<48) |
297 (((uint64_t)(datap[2]))<<40) | (((uint64_t)(datap[3]))<<32) |
298 (((uint64_t)(datap[4]))<<24) | (((uint64_t)(datap[5]))<<16) |
299 (((uint64_t)(datap[6]))<<8 ) | ((uint64_t)(datap[7]));
300 datap += 8;
301 } while(++j < 16);
302
303 /* initialize variables a...h */
304 a = ctx->sha_H[0];
305 b = ctx->sha_H[1];
306 c = ctx->sha_H[2];
307 d = ctx->sha_H[3];
308 e = ctx->sha_H[4];
309 f = ctx->sha_H[5];
310 g = ctx->sha_H[6];
311 h = ctx->sha_H[7];
312
313 /* apply compression function */
314 j = 0;
315 do {
316 if(j >= 16) {
317 Wm2 = W[j - 2];
318 Wm15 = W[j - 15];
319 W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
320 }
321 T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
322 T2 = uSig0(a) + Maj(a,b,c);
323 h = g; g = f; f = e;
324 e = d + T1;
325 d = c; c = b; b = a;
326 a = T1 + T2;
327 } while(++j < 80);
328
329 /* compute intermediate hash value */
330 ctx->sha_H[0] += a;
331 ctx->sha_H[1] += b;
332 ctx->sha_H[2] += c;
333 ctx->sha_H[3] += d;
334 ctx->sha_H[4] += e;
335 ctx->sha_H[5] += f;
336 ctx->sha_H[6] += g;
337 ctx->sha_H[7] += h;
338
339 ctx->sha_blocks++;
340 if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
341 }
342
343 /**
344 * Update a SHA384/SHA512 hash
345 */
346 static void sha512_write(private_sha512_hasher_t *ctx,
347 const unsigned char *datap, int length)
348 {
349 while(length > 0)
350 {
351 if(!ctx->sha_bufCnt)
352 {
353 while(length >= sizeof(ctx->sha_out))
354 {
355 sha512_transform(ctx, datap);
356 datap += sizeof(ctx->sha_out);
357 length -= sizeof(ctx->sha_out);
358 }
359 if(!length) return;
360 }
361 ctx->sha_out[ctx->sha_bufCnt] = *datap++;
362 length--;
363 if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
364 {
365 sha512_transform(ctx, &ctx->sha_out[0]);
366 ctx->sha_bufCnt = 0;
367 }
368 }
369 }
370
371 /**
372 * Finalize a SHA384/SHA512 hash
373 */
374 static void sha512_final(private_sha512_hasher_t *ctx)
375 {
376 register int j;
377 uint64_t bitLength, bitLengthMSB;
378 uint64_t i;
379 unsigned char padByte, *datap;
380
381 bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
382 bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
383 padByte = 0x80;
384 sha512_write(ctx, &padByte, 1);
385
386 /* pad extra space with zeroes */
387 padByte = 0;
388 while(ctx->sha_bufCnt != 112)
389 {
390 sha512_write(ctx, &padByte, 1);
391 }
392
393 /* write bit length, big endian byte order */
394 ctx->sha_out[112] = bitLengthMSB >> 56;
395 ctx->sha_out[113] = bitLengthMSB >> 48;
396 ctx->sha_out[114] = bitLengthMSB >> 40;
397 ctx->sha_out[115] = bitLengthMSB >> 32;
398 ctx->sha_out[116] = bitLengthMSB >> 24;
399 ctx->sha_out[117] = bitLengthMSB >> 16;
400 ctx->sha_out[118] = bitLengthMSB >> 8;
401 ctx->sha_out[119] = bitLengthMSB;
402 ctx->sha_out[120] = bitLength >> 56;
403 ctx->sha_out[121] = bitLength >> 48;
404 ctx->sha_out[122] = bitLength >> 40;
405 ctx->sha_out[123] = bitLength >> 32;
406 ctx->sha_out[124] = bitLength >> 24;
407 ctx->sha_out[125] = bitLength >> 16;
408 ctx->sha_out[126] = bitLength >> 8;
409 ctx->sha_out[127] = bitLength;
410 sha512_transform(ctx, &ctx->sha_out[0]);
411
412 /* return results in ctx->sha_out[0...63] */
413 datap = &ctx->sha_out[0];
414 j = 0;
415 do {
416 i = ctx->sha_H[j];
417 datap[0] = i >> 56;
418 datap[1] = i >> 48;
419 datap[2] = i >> 40;
420 datap[3] = i >> 32;
421 datap[4] = i >> 24;
422 datap[5] = i >> 16;
423 datap[6] = i >> 8;
424 datap[7] = i;
425 datap += 8;
426 } while(++j < 8);
427 }
428
429 METHOD(hasher_t, reset224, bool,
430 private_sha256_hasher_t *this)
431 {
432 memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H));
433 this->sha_blocks = 0;
434 this->sha_bufCnt = 0;
435
436 return TRUE;
437 }
438
439 METHOD(hasher_t, reset256, bool,
440 private_sha256_hasher_t *this)
441 {
442 memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H));
443 this->sha_blocks = 0;
444 this->sha_bufCnt = 0;
445
446 return TRUE;
447 }
448
449 METHOD(hasher_t, reset384, bool,
450 private_sha512_hasher_t *this)
451 {
452 memcpy(&this->sha_H[0], &sha384_hashInit[0], sizeof(this->sha_H));
453 this->sha_blocks = 0;
454 this->sha_blocksMSB = 0;
455 this->sha_bufCnt = 0;
456
457 return TRUE;
458 }
459
460 METHOD(hasher_t, reset512, bool,
461 private_sha512_hasher_t *this)
462 {
463 memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H));
464 this->sha_blocks = 0;
465 this->sha_blocksMSB = 0;
466 this->sha_bufCnt = 0;
467
468 return TRUE;
469 }
470
471 METHOD(hasher_t, get_hash224, bool,
472 private_sha256_hasher_t *this, chunk_t chunk, uint8_t *buffer)
473 {
474 sha256_write(this, chunk.ptr, chunk.len);
475 if (buffer != NULL)
476 {
477 sha256_final(this);
478 memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
479 reset224(this);
480 }
481 return TRUE;
482 }
483
484 METHOD(hasher_t, get_hash256, bool,
485 private_sha256_hasher_t *this, chunk_t chunk, uint8_t *buffer)
486 {
487 sha256_write(this, chunk.ptr, chunk.len);
488 if (buffer != NULL)
489 {
490 sha256_final(this);
491 memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
492 reset256(this);
493 }
494 return TRUE;
495 }
496
497 METHOD(hasher_t, get_hash384, bool,
498 private_sha512_hasher_t *this, chunk_t chunk, uint8_t *buffer)
499 {
500 sha512_write(this, chunk.ptr, chunk.len);
501 if (buffer != NULL)
502 {
503 sha512_final(this);
504 memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
505 reset384(this);
506 }
507 return TRUE;
508 }
509
510 METHOD(hasher_t, get_hash512, bool,
511 private_sha512_hasher_t *this, chunk_t chunk, uint8_t *buffer)
512 {
513 sha512_write(this, chunk.ptr, chunk.len);
514 if (buffer != NULL)
515 {
516 sha512_final(this);
517 memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
518 reset512(this);
519 }
520 return TRUE;
521 }
522
523 METHOD(hasher_t, allocate_hash224, bool,
524 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
525 {
526 chunk_t allocated_hash;
527
528 sha256_write(this, chunk.ptr, chunk.len);
529 if (hash != NULL)
530 {
531 sha256_final(this);
532 allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
533 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
534 reset224(this);
535 *hash = allocated_hash;
536 }
537 return TRUE;
538 }
539
540 METHOD(hasher_t, allocate_hash256, bool,
541 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
542 {
543 chunk_t allocated_hash;
544
545 sha256_write(this, chunk.ptr, chunk.len);
546 if (hash != NULL)
547 {
548 sha256_final(this);
549 allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
550 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
551 reset256(this);
552 *hash = allocated_hash;
553 }
554 return TRUE;
555 }
556
557 METHOD(hasher_t, allocate_hash384, bool,
558 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
559 {
560 chunk_t allocated_hash;
561
562 sha512_write(this, chunk.ptr, chunk.len);
563 if (hash != NULL)
564 {
565 sha512_final(this);
566 allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
567 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
568 reset384(this);
569 *hash = allocated_hash;
570 }
571 return TRUE;
572 }
573
574 METHOD(hasher_t, allocate_hash512, bool,
575 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
576 {
577 chunk_t allocated_hash;
578
579 sha512_write(this, chunk.ptr, chunk.len);
580 if (hash != NULL)
581 {
582 sha512_final(this);
583 allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
584 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
585 reset512(this);
586 *hash = allocated_hash;
587 }
588 return TRUE;
589 }
590
591 METHOD(hasher_t, get_hash_size224, size_t,
592 private_sha256_hasher_t *this)
593 {
594 return HASH_SIZE_SHA224;
595 }
596
597 METHOD(hasher_t, get_hash_size256, size_t,
598 private_sha256_hasher_t *this)
599 {
600 return HASH_SIZE_SHA256;
601 }
602
603 METHOD(hasher_t, get_hash_size384, size_t,
604 private_sha512_hasher_t *this)
605 {
606 return HASH_SIZE_SHA384;
607 }
608
609 METHOD(hasher_t, get_hash_size512, size_t,
610 private_sha512_hasher_t *this)
611 {
612 return HASH_SIZE_SHA512;
613 }
614
615 METHOD(hasher_t, destroy, void,
616 sha2_hasher_t *this)
617 {
618 free(this);
619 }
620
621 /*
622 * Described in header.
623 */
624 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
625 {
626 switch (algorithm)
627 {
628 case HASH_SHA224:
629 {
630 private_sha256_hasher_t *this;
631
632 INIT(this,
633 .public = {
634 .hasher_interface = {
635 .reset = _reset224,
636 .get_hash_size = _get_hash_size224,
637 .get_hash = _get_hash224,
638 .allocate_hash = _allocate_hash224,
639 .destroy = _destroy,
640 },
641 },
642 );
643 reset224(this);
644 return &this->public;
645 }
646 case HASH_SHA256:
647 {
648 private_sha256_hasher_t *this;
649
650 INIT(this,
651 .public = {
652 .hasher_interface = {
653 .reset = _reset256,
654 .get_hash_size = _get_hash_size256,
655 .get_hash = _get_hash256,
656 .allocate_hash = _allocate_hash256,
657 .destroy = _destroy,
658 },
659 },
660 );
661 reset256(this);
662 return &this->public;
663 }
664 case HASH_SHA384:
665 {
666 private_sha512_hasher_t *this;
667
668 INIT(this,
669 .public = {
670 .hasher_interface = {
671 .reset = _reset384,
672 .get_hash_size = _get_hash_size384,
673 .get_hash = _get_hash384,
674 .allocate_hash = _allocate_hash384,
675 .destroy = _destroy,
676 },
677 },
678 );
679 reset384(this);
680 return &this->public;
681 }
682 case HASH_SHA512:
683 {
684 private_sha512_hasher_t *this;
685
686 INIT(this,
687 .public = {
688 .hasher_interface = {
689 .reset = _reset512,
690 .get_hash_size = _get_hash_size512,
691 .get_hash = _get_hash512,
692 .allocate_hash = _allocate_hash512,
693 .destroy = _destroy,
694 },
695 },
696 );
697 reset512(this);
698 return &this->public;
699 }
700 default:
701 return NULL;
702 }
703 }