sha2: Write final hash directly to output buffer
[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, u_char *buf, size_t len)
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 datap = buf;
259 j = 0;
260 do {
261 i = ctx->sha_H[j];
262 datap[0] = i >> 24;
263 datap[1] = i >> 16;
264 datap[2] = i >> 8;
265 datap[3] = i;
266 datap += 4;
267 } while(++j < len / 4);
268 }
269
270 /* update macros for SHA512 */
271 #undef S
272 #undef uSig0
273 #undef uSig1
274 #undef lSig0
275 #undef lSig1
276 #define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
277 #define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
278 #define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
279 #define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
280 #define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
281
282 /**
283 * Single block SHA384/SHA512 transformation
284 */
285 static void sha512_transform(private_sha512_hasher_t *ctx,
286 const unsigned char *datap)
287 {
288 register int j;
289 uint64_t a, b, c, d, e, f, g, h;
290 uint64_t T1, T2, W[80], Wm2, Wm15;
291
292 /* read the data, big endian byte order */
293 j = 0;
294 do {
295 W[j] = (((uint64_t)(datap[0]))<<56) | (((uint64_t)(datap[1]))<<48) |
296 (((uint64_t)(datap[2]))<<40) | (((uint64_t)(datap[3]))<<32) |
297 (((uint64_t)(datap[4]))<<24) | (((uint64_t)(datap[5]))<<16) |
298 (((uint64_t)(datap[6]))<<8 ) | ((uint64_t)(datap[7]));
299 datap += 8;
300 } while(++j < 16);
301
302 /* initialize variables a...h */
303 a = ctx->sha_H[0];
304 b = ctx->sha_H[1];
305 c = ctx->sha_H[2];
306 d = ctx->sha_H[3];
307 e = ctx->sha_H[4];
308 f = ctx->sha_H[5];
309 g = ctx->sha_H[6];
310 h = ctx->sha_H[7];
311
312 /* apply compression function */
313 j = 0;
314 do {
315 if(j >= 16) {
316 Wm2 = W[j - 2];
317 Wm15 = W[j - 15];
318 W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
319 }
320 T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
321 T2 = uSig0(a) + Maj(a,b,c);
322 h = g; g = f; f = e;
323 e = d + T1;
324 d = c; c = b; b = a;
325 a = T1 + T2;
326 } while(++j < 80);
327
328 /* compute intermediate hash value */
329 ctx->sha_H[0] += a;
330 ctx->sha_H[1] += b;
331 ctx->sha_H[2] += c;
332 ctx->sha_H[3] += d;
333 ctx->sha_H[4] += e;
334 ctx->sha_H[5] += f;
335 ctx->sha_H[6] += g;
336 ctx->sha_H[7] += h;
337
338 ctx->sha_blocks++;
339 if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
340 }
341
342 /**
343 * Update a SHA384/SHA512 hash
344 */
345 static void sha512_write(private_sha512_hasher_t *ctx,
346 const unsigned char *datap, int length)
347 {
348 while(length > 0)
349 {
350 if(!ctx->sha_bufCnt)
351 {
352 while(length >= sizeof(ctx->sha_out))
353 {
354 sha512_transform(ctx, datap);
355 datap += sizeof(ctx->sha_out);
356 length -= sizeof(ctx->sha_out);
357 }
358 if(!length) return;
359 }
360 ctx->sha_out[ctx->sha_bufCnt] = *datap++;
361 length--;
362 if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
363 {
364 sha512_transform(ctx, &ctx->sha_out[0]);
365 ctx->sha_bufCnt = 0;
366 }
367 }
368 }
369
370 /**
371 * Finalize a SHA384/SHA512 hash
372 */
373 static void sha512_final(private_sha512_hasher_t *ctx, u_char *buf, size_t len)
374 {
375 register int j;
376 uint64_t bitLength, bitLengthMSB;
377 uint64_t i;
378 unsigned char padByte, *datap;
379
380 bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
381 bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
382 padByte = 0x80;
383 sha512_write(ctx, &padByte, 1);
384
385 /* pad extra space with zeroes */
386 padByte = 0;
387 while(ctx->sha_bufCnt != 112)
388 {
389 sha512_write(ctx, &padByte, 1);
390 }
391
392 /* write bit length, big endian byte order */
393 ctx->sha_out[112] = bitLengthMSB >> 56;
394 ctx->sha_out[113] = bitLengthMSB >> 48;
395 ctx->sha_out[114] = bitLengthMSB >> 40;
396 ctx->sha_out[115] = bitLengthMSB >> 32;
397 ctx->sha_out[116] = bitLengthMSB >> 24;
398 ctx->sha_out[117] = bitLengthMSB >> 16;
399 ctx->sha_out[118] = bitLengthMSB >> 8;
400 ctx->sha_out[119] = bitLengthMSB;
401 ctx->sha_out[120] = bitLength >> 56;
402 ctx->sha_out[121] = bitLength >> 48;
403 ctx->sha_out[122] = bitLength >> 40;
404 ctx->sha_out[123] = bitLength >> 32;
405 ctx->sha_out[124] = bitLength >> 24;
406 ctx->sha_out[125] = bitLength >> 16;
407 ctx->sha_out[126] = bitLength >> 8;
408 ctx->sha_out[127] = bitLength;
409 sha512_transform(ctx, &ctx->sha_out[0]);
410
411 datap = buf;
412 j = 0;
413 do {
414 i = ctx->sha_H[j];
415 datap[0] = i >> 56;
416 datap[1] = i >> 48;
417 datap[2] = i >> 40;
418 datap[3] = i >> 32;
419 datap[4] = i >> 24;
420 datap[5] = i >> 16;
421 datap[6] = i >> 8;
422 datap[7] = i;
423 datap += 8;
424 } while(++j < len / 8);
425 }
426
427 METHOD(hasher_t, reset224, bool,
428 private_sha256_hasher_t *this)
429 {
430 memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H));
431 this->sha_blocks = 0;
432 this->sha_bufCnt = 0;
433 return TRUE;
434 }
435
436 METHOD(hasher_t, reset256, bool,
437 private_sha256_hasher_t *this)
438 {
439 memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H));
440 this->sha_blocks = 0;
441 this->sha_bufCnt = 0;
442 return TRUE;
443 }
444
445 METHOD(hasher_t, reset384, bool,
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 return TRUE;
453 }
454
455 METHOD(hasher_t, reset512, bool,
456 private_sha512_hasher_t *this)
457 {
458 memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H));
459 this->sha_blocks = 0;
460 this->sha_blocksMSB = 0;
461 this->sha_bufCnt = 0;
462 return TRUE;
463 }
464
465 METHOD(hasher_t, get_hash224, bool,
466 private_sha256_hasher_t *this, chunk_t chunk, uint8_t *buffer)
467 {
468 sha256_write(this, chunk.ptr, chunk.len);
469 if (buffer != NULL)
470 {
471 sha256_final(this, buffer, HASH_SIZE_SHA224);
472 reset224(this);
473 }
474 return TRUE;
475 }
476
477 METHOD(hasher_t, get_hash256, bool,
478 private_sha256_hasher_t *this, chunk_t chunk, uint8_t *buffer)
479 {
480 sha256_write(this, chunk.ptr, chunk.len);
481 if (buffer != NULL)
482 {
483 sha256_final(this, buffer, 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, uint8_t *buffer)
491 {
492 sha512_write(this, chunk.ptr, chunk.len);
493 if (buffer != NULL)
494 {
495 sha512_final(this, buffer, HASH_SIZE_SHA384);
496 reset384(this);
497 }
498 return TRUE;
499 }
500
501 METHOD(hasher_t, get_hash512, bool,
502 private_sha512_hasher_t *this, chunk_t chunk, uint8_t *buffer)
503 {
504 sha512_write(this, chunk.ptr, chunk.len);
505 if (buffer != NULL)
506 {
507 sha512_final(this, buffer, HASH_SIZE_SHA512);
508 reset512(this);
509 }
510 return TRUE;
511 }
512
513 METHOD(hasher_t, allocate_hash224, bool,
514 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
515 {
516 chunk_t allocated_hash = chunk_empty;
517
518 if (hash)
519 {
520 *hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
521 }
522 return get_hash224(this, chunk, allocated_hash.ptr);
523 }
524
525 METHOD(hasher_t, allocate_hash256, bool,
526 private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
527 {
528 chunk_t allocated_hash = chunk_empty;
529
530 if (hash)
531 {
532 *hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
533 }
534 return get_hash256(this, chunk, allocated_hash.ptr);
535 }
536
537 METHOD(hasher_t, allocate_hash384, bool,
538 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
539 {
540 chunk_t allocated_hash = chunk_empty;
541
542 if (hash)
543 {
544 *hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
545 }
546 return get_hash384(this, chunk, allocated_hash.ptr);
547 }
548
549 METHOD(hasher_t, allocate_hash512, bool,
550 private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
551 {
552 chunk_t allocated_hash = chunk_empty;
553
554 if (hash)
555 {
556 *hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
557 }
558 return get_hash512(this, chunk, allocated_hash.ptr);
559 }
560
561 METHOD(hasher_t, get_hash_size224, size_t,
562 private_sha256_hasher_t *this)
563 {
564 return HASH_SIZE_SHA224;
565 }
566
567 METHOD(hasher_t, get_hash_size256, size_t,
568 private_sha256_hasher_t *this)
569 {
570 return HASH_SIZE_SHA256;
571 }
572
573 METHOD(hasher_t, get_hash_size384, size_t,
574 private_sha512_hasher_t *this)
575 {
576 return HASH_SIZE_SHA384;
577 }
578
579 METHOD(hasher_t, get_hash_size512, size_t,
580 private_sha512_hasher_t *this)
581 {
582 return HASH_SIZE_SHA512;
583 }
584
585 METHOD(hasher_t, destroy, void,
586 sha2_hasher_t *this)
587 {
588 free(this);
589 }
590
591 /*
592 * Described in header.
593 */
594 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
595 {
596 switch (algorithm)
597 {
598 case HASH_SHA224:
599 {
600 private_sha256_hasher_t *this;
601
602 INIT(this,
603 .public = {
604 .hasher_interface = {
605 .reset = _reset224,
606 .get_hash_size = _get_hash_size224,
607 .get_hash = _get_hash224,
608 .allocate_hash = _allocate_hash224,
609 .destroy = _destroy,
610 },
611 },
612 );
613 reset224(this);
614 return &this->public;
615 }
616 case HASH_SHA256:
617 {
618 private_sha256_hasher_t *this;
619
620 INIT(this,
621 .public = {
622 .hasher_interface = {
623 .reset = _reset256,
624 .get_hash_size = _get_hash_size256,
625 .get_hash = _get_hash256,
626 .allocate_hash = _allocate_hash256,
627 .destroy = _destroy,
628 },
629 },
630 );
631 reset256(this);
632 return &this->public;
633 }
634 case HASH_SHA384:
635 {
636 private_sha512_hasher_t *this;
637
638 INIT(this,
639 .public = {
640 .hasher_interface = {
641 .reset = _reset384,
642 .get_hash_size = _get_hash_size384,
643 .get_hash = _get_hash384,
644 .allocate_hash = _allocate_hash384,
645 .destroy = _destroy,
646 },
647 },
648 );
649 reset384(this);
650 return &this->public;
651 }
652 case HASH_SHA512:
653 {
654 private_sha512_hasher_t *this;
655
656 INIT(this,
657 .public = {
658 .hasher_interface = {
659 .reset = _reset512,
660 .get_hash_size = _get_hash_size512,
661 .get_hash = _get_hash512,
662 .allocate_hash = _allocate_hash512,
663 .destroy = _destroy,
664 },
665 },
666 );
667 reset512(this);
668 return &this->public;
669 }
670 default:
671 return NULL;
672 }
673 }