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