0e8811ccac7522caede3159894c76d42de661c96
[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 sha256_hashInit[8] = {
62 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
63 0x1f83d9ab, 0x5be0cd19
64 };
65
66 static const u_int32_t sha256_K[64] = {
67 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
68 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
69 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
70 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
71 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
72 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
73 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
74 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
75 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
76 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
77 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
78 };
79
80 static const u_int64_t sha512_hashInit[8] = {
81 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
82 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
83 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
84 };
85
86 static const u_int64_t sha384_hashInit[8] = {
87 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
88 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
89 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
90 };
91
92 static const u_int64_t sha512_K[80] = {
93 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
94 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
95 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
96 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
97 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
98 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
99 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
100 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
101 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
102 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
103 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
104 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
105 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
106 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
107 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
108 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
109 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
110 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
111 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
112 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
113 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
114 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
115 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
116 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
117 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
118 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
119 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
120 };
121
122
123 /* set macros for SHA256 */
124 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
125 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
126 #define R(x,y) ((y) >> (x))
127
128 #define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
129 #define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
130 #define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
131 #define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
132 #define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
133
134 /**
135 * Single block SHA256 transformation
136 */
137 static void sha256_transform(private_sha256_hasher_t *ctx,
138 const unsigned char *datap)
139 {
140 register int j;
141 u_int32_t a, b, c, d, e, f, g, h;
142 u_int32_t T1, T2, W[64], Wm2, Wm15;
143
144 /* read the data, big endian byte order */
145 j = 0;
146 do {
147 W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
148 (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
149 datap += 4;
150 } while(++j < 16);
151
152 /* initialize variables a...h */
153 a = ctx->sha_H[0];
154 b = ctx->sha_H[1];
155 c = ctx->sha_H[2];
156 d = ctx->sha_H[3];
157 e = ctx->sha_H[4];
158 f = ctx->sha_H[5];
159 g = ctx->sha_H[6];
160 h = ctx->sha_H[7];
161
162 /* apply compression function */
163 j = 0;
164 do
165 {
166 if(j >= 16)
167 {
168 Wm2 = W[j - 2];
169 Wm15 = W[j - 15];
170 W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
171 }
172 T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
173 T2 = uSig0(a) + Maj(a,b,c);
174 h = g; g = f; f = e;
175 e = d + T1;
176 d = c; c = b; b = a;
177 a = T1 + T2;
178 } while(++j < 64);
179
180 /* compute intermediate hash value */
181 ctx->sha_H[0] += a;
182 ctx->sha_H[1] += b;
183 ctx->sha_H[2] += c;
184 ctx->sha_H[3] += d;
185 ctx->sha_H[4] += e;
186 ctx->sha_H[5] += f;
187 ctx->sha_H[6] += g;
188 ctx->sha_H[7] += h;
189
190 ctx->sha_blocks++;
191 }
192
193 /**
194 * Update SHA256 hash
195 */
196 static void sha256_write(private_sha256_hasher_t *ctx,
197 const unsigned char *datap, int length)
198 {
199 while(length > 0)
200 {
201 if(!ctx->sha_bufCnt)
202 {
203 while(length >= sizeof(ctx->sha_out))
204 {
205 sha256_transform(ctx, datap);
206 datap += sizeof(ctx->sha_out);
207 length -= sizeof(ctx->sha_out);
208 }
209 if(!length) return;
210 }
211 ctx->sha_out[ctx->sha_bufCnt] = *datap++;
212 length--;
213 if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
214 {
215 sha256_transform(ctx, &ctx->sha_out[0]);
216 ctx->sha_bufCnt = 0;
217 }
218 }
219 }
220
221 /**
222 * finalize SHA256 hash
223 */
224 static void sha256_final(private_sha256_hasher_t *ctx)
225 {
226 register int j;
227 u_int64_t bitLength;
228 u_int32_t i;
229 unsigned char padByte, *datap;
230
231 bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
232 padByte = 0x80;
233 sha256_write(ctx, &padByte, 1);
234
235 /* pad extra space with zeroes */
236 padByte = 0;
237 while(ctx->sha_bufCnt != 56)
238 {
239 sha256_write(ctx, &padByte, 1);
240 }
241
242 /* write bit length, big endian byte order */
243 ctx->sha_out[56] = bitLength >> 56;
244 ctx->sha_out[57] = bitLength >> 48;
245 ctx->sha_out[58] = bitLength >> 40;
246 ctx->sha_out[59] = bitLength >> 32;
247 ctx->sha_out[60] = bitLength >> 24;
248 ctx->sha_out[61] = bitLength >> 16;
249 ctx->sha_out[62] = bitLength >> 8;
250 ctx->sha_out[63] = bitLength;
251 sha256_transform(ctx, &ctx->sha_out[0]);
252
253 /* return results in ctx->sha_out[0...31] */
254 datap = &ctx->sha_out[0];
255 j = 0;
256 do {
257 i = ctx->sha_H[j];
258 datap[0] = i >> 24;
259 datap[1] = i >> 16;
260 datap[2] = i >> 8;
261 datap[3] = i;
262 datap += 4;
263 } while(++j < 8);
264 }
265
266 /* update macros for SHA512 */
267 #undef S
268 #undef uSig0
269 #undef uSig1
270 #undef lSig0
271 #undef lSig1
272 #define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
273 #define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
274 #define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
275 #define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
276 #define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
277
278 /**
279 * Single block SHA384/SHA512 transformation
280 */
281 static void sha512_transform(private_sha512_hasher_t *ctx,
282 const unsigned char *datap)
283 {
284 register int j;
285 u_int64_t a, b, c, d, e, f, g, h;
286 u_int64_t T1, T2, W[80], Wm2, Wm15;
287
288 /* read the data, big endian byte order */
289 j = 0;
290 do {
291 W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
292 (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
293 (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
294 (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
295 datap += 8;
296 } while(++j < 16);
297
298 /* initialize variables a...h */
299 a = ctx->sha_H[0];
300 b = ctx->sha_H[1];
301 c = ctx->sha_H[2];
302 d = ctx->sha_H[3];
303 e = ctx->sha_H[4];
304 f = ctx->sha_H[5];
305 g = ctx->sha_H[6];
306 h = ctx->sha_H[7];
307
308 /* apply compression function */
309 j = 0;
310 do {
311 if(j >= 16) {
312 Wm2 = W[j - 2];
313 Wm15 = W[j - 15];
314 W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
315 }
316 T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
317 T2 = uSig0(a) + Maj(a,b,c);
318 h = g; g = f; f = e;
319 e = d + T1;
320 d = c; c = b; b = a;
321 a = T1 + T2;
322 } while(++j < 80);
323
324 /* compute intermediate hash value */
325 ctx->sha_H[0] += a;
326 ctx->sha_H[1] += b;
327 ctx->sha_H[2] += c;
328 ctx->sha_H[3] += d;
329 ctx->sha_H[4] += e;
330 ctx->sha_H[5] += f;
331 ctx->sha_H[6] += g;
332 ctx->sha_H[7] += h;
333
334 ctx->sha_blocks++;
335 if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
336 }
337
338 /**
339 * Update a SHA384/SHA512 hash
340 */
341 static void sha512_write(private_sha512_hasher_t *ctx,
342 const unsigned char *datap, int length)
343 {
344 while(length > 0)
345 {
346 if(!ctx->sha_bufCnt)
347 {
348 while(length >= sizeof(ctx->sha_out))
349 {
350 sha512_transform(ctx, datap);
351 datap += sizeof(ctx->sha_out);
352 length -= sizeof(ctx->sha_out);
353 }
354 if(!length) return;
355 }
356 ctx->sha_out[ctx->sha_bufCnt] = *datap++;
357 length--;
358 if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
359 {
360 sha512_transform(ctx, &ctx->sha_out[0]);
361 ctx->sha_bufCnt = 0;
362 }
363 }
364 }
365
366 /**
367 * Finalize a SHA384/SHA512 hash
368 */
369 static void sha512_final(private_sha512_hasher_t *ctx)
370 {
371 register int j;
372 u_int64_t bitLength, bitLengthMSB;
373 u_int64_t i;
374 unsigned char padByte, *datap;
375
376 bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
377 bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
378 padByte = 0x80;
379 sha512_write(ctx, &padByte, 1);
380
381 /* pad extra space with zeroes */
382 padByte = 0;
383 while(ctx->sha_bufCnt != 112)
384 {
385 sha512_write(ctx, &padByte, 1);
386 }
387
388 /* write bit length, big endian byte order */
389 ctx->sha_out[112] = bitLengthMSB >> 56;
390 ctx->sha_out[113] = bitLengthMSB >> 48;
391 ctx->sha_out[114] = bitLengthMSB >> 40;
392 ctx->sha_out[115] = bitLengthMSB >> 32;
393 ctx->sha_out[116] = bitLengthMSB >> 24;
394 ctx->sha_out[117] = bitLengthMSB >> 16;
395 ctx->sha_out[118] = bitLengthMSB >> 8;
396 ctx->sha_out[119] = bitLengthMSB;
397 ctx->sha_out[120] = bitLength >> 56;
398 ctx->sha_out[121] = bitLength >> 48;
399 ctx->sha_out[122] = bitLength >> 40;
400 ctx->sha_out[123] = bitLength >> 32;
401 ctx->sha_out[124] = bitLength >> 24;
402 ctx->sha_out[125] = bitLength >> 16;
403 ctx->sha_out[126] = bitLength >> 8;
404 ctx->sha_out[127] = bitLength;
405 sha512_transform(ctx, &ctx->sha_out[0]);
406
407 /* return results in ctx->sha_out[0...63] */
408 datap = &ctx->sha_out[0];
409 j = 0;
410 do {
411 i = ctx->sha_H[j];
412 datap[0] = i >> 56;
413 datap[1] = i >> 48;
414 datap[2] = i >> 40;
415 datap[3] = i >> 32;
416 datap[4] = i >> 24;
417 datap[5] = i >> 16;
418 datap[6] = i >> 8;
419 datap[7] = i;
420 datap += 8;
421 } while(++j < 8);
422 }
423
424 /**
425 * Implementation of hasher_t.get_hash for SHA256.
426 */
427 static void get_hash256(private_sha256_hasher_t *this,
428 chunk_t chunk, u_int8_t *buffer)
429 {
430 sha256_write(this, chunk.ptr, chunk.len);
431 if (buffer != NULL)
432 {
433 sha256_final(this);
434 memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
435 this->public.hasher_interface.reset(&(this->public.hasher_interface));
436 }
437 }
438
439 /**
440 * Implementation of hasher_t.get_hash for SHA384.
441 */
442 static void get_hash384(private_sha512_hasher_t *this,
443 chunk_t chunk, u_int8_t *buffer)
444 {
445 sha512_write(this, chunk.ptr, chunk.len);
446 if (buffer != NULL)
447 {
448 sha512_final(this);
449 memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
450 this->public.hasher_interface.reset(&(this->public.hasher_interface));
451 }
452 }
453
454 /**
455 * Implementation of hasher_t.get_hash for SHA512.
456 */
457 static void get_hash512(private_sha512_hasher_t *this,
458 chunk_t chunk, u_int8_t *buffer)
459 {
460 sha512_write(this, chunk.ptr, chunk.len);
461 if (buffer != NULL)
462 {
463 sha512_final(this);
464 memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
465 this->public.hasher_interface.reset(&(this->public.hasher_interface));
466 }
467 }
468
469 /**
470 * Implementation of hasher_t.allocate_hash for SHA256.
471 */
472 static void allocate_hash256(private_sha256_hasher_t *this,
473 chunk_t chunk, chunk_t *hash)
474 {
475 chunk_t allocated_hash;
476
477 sha256_write(this, chunk.ptr, chunk.len);
478 if (hash != NULL)
479 {
480 sha256_final(this);
481 allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
482 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
483 this->public.hasher_interface.reset(&(this->public.hasher_interface));
484 *hash = allocated_hash;
485 }
486 }
487
488 /**
489 * Implementation of hasher_t.allocate_hash for SHA384.
490 */
491 static void allocate_hash384(private_sha512_hasher_t *this,
492 chunk_t chunk, chunk_t *hash)
493 {
494 chunk_t allocated_hash;
495
496 sha512_write(this, chunk.ptr, chunk.len);
497 if (hash != NULL)
498 {
499 sha512_final(this);
500 allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
501 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
502 this->public.hasher_interface.reset(&(this->public.hasher_interface));
503 *hash = allocated_hash;
504 }
505 }
506
507 /**
508 * Implementation of hasher_t.allocate_hash for SHA512.
509 */
510 static void allocate_hash512(private_sha512_hasher_t *this,
511 chunk_t chunk, chunk_t *hash)
512 {
513 chunk_t allocated_hash;
514
515 sha512_write(this, chunk.ptr, chunk.len);
516 if (hash != NULL)
517 {
518 sha512_final(this);
519 allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
520 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
521 this->public.hasher_interface.reset(&(this->public.hasher_interface));
522 *hash = allocated_hash;
523 }
524 }
525
526 /**
527 * Implementation of hasher_t.get_hash_size for SHA256.
528 */
529 static size_t get_hash_size256(private_sha256_hasher_t *this)
530 {
531 return HASH_SIZE_SHA256;
532 }
533
534 /**
535 * Implementation of hasher_t.get_hash_size for SHA384.
536 */
537 static size_t get_hash_size384(private_sha512_hasher_t *this)
538 {
539 return HASH_SIZE_SHA384;
540 }
541
542 /**
543 * Implementation of hasher_t.get_hash_size for SHA512.
544 */
545 static size_t get_hash_size512(private_sha512_hasher_t *this)
546 {
547 return HASH_SIZE_SHA512;
548 }
549
550 /**
551 * Implementation of hasher_t.reset for SHA256
552 */
553 static void reset256(private_sha256_hasher_t *ctx)
554 {
555 memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
556 ctx->sha_blocks = 0;
557 ctx->sha_bufCnt = 0;
558 }
559
560 /**
561 * Implementation of hasher_t.reset for SHA384
562 */
563 static void reset384(private_sha512_hasher_t *ctx)
564 {
565 memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
566 ctx->sha_blocks = 0;
567 ctx->sha_blocksMSB = 0;
568 ctx->sha_bufCnt = 0;
569 }
570
571 /**
572 * Implementation of hasher_t.reset for SHA512
573 */
574 static void reset512(private_sha512_hasher_t *ctx)
575 {
576 memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
577 ctx->sha_blocks = 0;
578 ctx->sha_blocksMSB = 0;
579 ctx->sha_bufCnt = 0;
580 }
581
582 /**
583 * Implementation of hasher_t.destroy.
584 */
585 static void destroy(sha2_hasher_t *this)
586 {
587 free(this);
588 }
589
590 /*
591 * Described in header.
592 */
593 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
594 {
595 sha2_hasher_t *this;
596
597 switch (algorithm)
598 {
599 case HASH_SHA256:
600 this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
601 this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
602 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
603 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
604 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
605 break;
606 case HASH_SHA384:
607 /* uses SHA512 data structure */
608 this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
609 this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
610 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
611 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
612 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
613 break;
614 case HASH_SHA512:
615 this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
616 this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
617 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
618 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
619 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
620 break;
621 default:
622 return NULL;
623 }
624 this->hasher_interface.destroy = (void(*)(hasher_t*))destroy;
625
626 /* initialize */
627 this->hasher_interface.reset(&this->hasher_interface);
628
629 return this;
630 }