Add a return value to hasher_t.get_hash()
[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 u_int64_t sha_H[8];
37 u_int64_t sha_blocks;
38 u_int64_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 u_int32_t sha_H[8];
56 u_int64_t sha_blocks;
57 int sha_bufCnt;
58 };
59
60
61 static const u_int32_t sha224_hashInit[8] = {
62 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511,
63 0x64f98fa7, 0xbefa4fa4
64 };
65
66 static const u_int32_t sha256_hashInit[8] = {
67 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
68 0x1f83d9ab, 0x5be0cd19
69 };
70
71 static const u_int32_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 u_int64_t sha512_hashInit[8] = {
86 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
87 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
88 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
89 };
90
91 static const u_int64_t sha384_hashInit[8] = {
92 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
93 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
94 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
95 };
96
97 static const u_int64_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 u_int32_t a, b, c, d, e, f, g, h;
147 u_int32_t T1, T2, W[64], Wm2, Wm15;
148
149 /* read the data, big endian byte order */
150 j = 0;
151 do {
152 W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
153 (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_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 u_int64_t bitLength;
233 u_int32_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 u_int64_t a, b, c, d, e, f, g, h;
291 u_int64_t T1, T2, W[80], Wm2, Wm15;
292
293 /* read the data, big endian byte order */
294 j = 0;
295 do {
296 W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
297 (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
298 (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
299 (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_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 u_int64_t bitLength, bitLengthMSB;
378 u_int64_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, void,
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
437 METHOD(hasher_t, reset256, void,
438 private_sha256_hasher_t *this)
439 {
440 memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H));
441 this->sha_blocks = 0;
442 this->sha_bufCnt = 0;
443 }
444
445 METHOD(hasher_t, reset384, void,
446 private_sha512_hasher_t *this)
447 {
448 memcpy(&this->sha_H[0], &sha384_hashInit[0], sizeof(this->sha_H));
449 this->sha_blocks = 0;
450 this->sha_blocksMSB = 0;
451 this->sha_bufCnt = 0;
452 }
453
454 METHOD(hasher_t, reset512, void,
455 private_sha512_hasher_t *this)
456 {
457 memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H));
458 this->sha_blocks = 0;
459 this->sha_blocksMSB = 0;
460 this->sha_bufCnt = 0;
461 }
462
463 METHOD(hasher_t, get_hash224, bool,
464 private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
465 {
466 sha256_write(this, chunk.ptr, chunk.len);
467 if (buffer != NULL)
468 {
469 sha256_final(this);
470 memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
471 reset224(this);
472 }
473 return TRUE;
474 }
475
476 METHOD(hasher_t, get_hash256, bool,
477 private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
478 {
479 sha256_write(this, chunk.ptr, chunk.len);
480 if (buffer != NULL)
481 {
482 sha256_final(this);
483 memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
484 reset256(this);
485 }
486 return TRUE;
487 }
488
489 METHOD(hasher_t, get_hash384, bool,
490 private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
491 {
492 sha512_write(this, chunk.ptr, chunk.len);
493 if (buffer != NULL)
494 {
495 sha512_final(this);
496 memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
497 reset384(this);
498 }
499 return TRUE;
500 }
501
502 METHOD(hasher_t, get_hash512, bool,
503 private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
504 {
505 sha512_write(this, chunk.ptr, chunk.len);
506 if (buffer != NULL)
507 {
508 sha512_final(this);
509 memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
510 reset512(this);
511 }
512 return TRUE;
513 }
514
515 METHOD(hasher_t, allocate_hash224, void,
516 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
517 {
518 chunk_t allocated_hash;
519
520 sha256_write(this, chunk.ptr, chunk.len);
521 if (hash != NULL)
522 {
523 sha256_final(this);
524 allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
525 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
526 reset224(this);
527 *hash = allocated_hash;
528 }
529 }
530
531 METHOD(hasher_t, allocate_hash256, void,
532 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
533 {
534 chunk_t allocated_hash;
535
536 sha256_write(this, chunk.ptr, chunk.len);
537 if (hash != NULL)
538 {
539 sha256_final(this);
540 allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
541 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
542 reset256(this);
543 *hash = allocated_hash;
544 }
545 }
546
547 METHOD(hasher_t, allocate_hash384, void,
548 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
549 {
550 chunk_t allocated_hash;
551
552 sha512_write(this, chunk.ptr, chunk.len);
553 if (hash != NULL)
554 {
555 sha512_final(this);
556 allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
557 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
558 reset384(this);
559 *hash = allocated_hash;
560 }
561 }
562
563 METHOD(hasher_t, allocate_hash512, void,
564 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
565 {
566 chunk_t allocated_hash;
567
568 sha512_write(this, chunk.ptr, chunk.len);
569 if (hash != NULL)
570 {
571 sha512_final(this);
572 allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
573 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
574 reset512(this);
575 *hash = allocated_hash;
576 }
577 }
578
579 METHOD(hasher_t, get_hash_size224, size_t,
580 private_sha256_hasher_t *this)
581 {
582 return HASH_SIZE_SHA224;
583 }
584
585 METHOD(hasher_t, get_hash_size256, size_t,
586 private_sha256_hasher_t *this)
587 {
588 return HASH_SIZE_SHA256;
589 }
590
591 METHOD(hasher_t, get_hash_size384, size_t,
592 private_sha512_hasher_t *this)
593 {
594 return HASH_SIZE_SHA384;
595 }
596
597 METHOD(hasher_t, get_hash_size512, size_t,
598 private_sha512_hasher_t *this)
599 {
600 return HASH_SIZE_SHA512;
601 }
602
603 METHOD(hasher_t, destroy, void,
604 sha2_hasher_t *this)
605 {
606 free(this);
607 }
608
609 /*
610 * Described in header.
611 */
612 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
613 {
614 switch (algorithm)
615 {
616 case HASH_SHA224:
617 {
618 private_sha256_hasher_t *this;
619
620 INIT(this,
621 .public = {
622 .hasher_interface = {
623 .reset = _reset224,
624 .get_hash_size = _get_hash_size224,
625 .get_hash = _get_hash224,
626 .allocate_hash = _allocate_hash224,
627 .destroy = _destroy,
628 },
629 },
630 );
631 reset224(this);
632 return &this->public;
633 }
634 case HASH_SHA256:
635 {
636 private_sha256_hasher_t *this;
637
638 INIT(this,
639 .public = {
640 .hasher_interface = {
641 .reset = _reset256,
642 .get_hash_size = _get_hash_size256,
643 .get_hash = _get_hash256,
644 .allocate_hash = _allocate_hash256,
645 .destroy = _destroy,
646 },
647 },
648 );
649 reset256(this);
650 return &this->public;
651 }
652 case HASH_SHA384:
653 {
654 private_sha512_hasher_t *this;
655
656 INIT(this,
657 .public = {
658 .hasher_interface = {
659 .reset = _reset384,
660 .get_hash_size = _get_hash_size384,
661 .get_hash = _get_hash384,
662 .allocate_hash = _allocate_hash384,
663 .destroy = _destroy,
664 },
665 },
666 );
667 reset384(this);
668 return &this->public;
669 }
670 case HASH_SHA512:
671 {
672 private_sha512_hasher_t *this;
673
674 INIT(this,
675 .public = {
676 .hasher_interface = {
677 .reset = _reset512,
678 .get_hash_size = _get_hash_size512,
679 .get_hash = _get_hash512,
680 .allocate_hash = _allocate_hash512,
681 .destroy = _destroy,
682 },
683 },
684 );
685 reset512(this);
686 return &this->public;
687 }
688 default:
689 return NULL;
690 }
691 }