support of SHA224-based certificate signatures
[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 /**
430 * Implementation of hasher_t.get_hash for SHA224.
431 */
432 static void get_hash224(private_sha256_hasher_t *this,
433 chunk_t chunk, u_int8_t *buffer)
434 {
435 sha256_write(this, chunk.ptr, chunk.len);
436 if (buffer != NULL)
437 {
438 sha256_final(this);
439 memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
440 this->public.hasher_interface.reset(&(this->public.hasher_interface));
441 }
442 }
443
444 /**
445 * Implementation of hasher_t.get_hash for SHA256.
446 */
447 static void get_hash256(private_sha256_hasher_t *this,
448 chunk_t chunk, u_int8_t *buffer)
449 {
450 sha256_write(this, chunk.ptr, chunk.len);
451 if (buffer != NULL)
452 {
453 sha256_final(this);
454 memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
455 this->public.hasher_interface.reset(&(this->public.hasher_interface));
456 }
457 }
458
459 /**
460 * Implementation of hasher_t.get_hash for SHA384.
461 */
462 static void get_hash384(private_sha512_hasher_t *this,
463 chunk_t chunk, u_int8_t *buffer)
464 {
465 sha512_write(this, chunk.ptr, chunk.len);
466 if (buffer != NULL)
467 {
468 sha512_final(this);
469 memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
470 this->public.hasher_interface.reset(&(this->public.hasher_interface));
471 }
472 }
473
474 /**
475 * Implementation of hasher_t.get_hash for SHA512.
476 */
477 static void get_hash512(private_sha512_hasher_t *this,
478 chunk_t chunk, u_int8_t *buffer)
479 {
480 sha512_write(this, chunk.ptr, chunk.len);
481 if (buffer != NULL)
482 {
483 sha512_final(this);
484 memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
485 this->public.hasher_interface.reset(&(this->public.hasher_interface));
486 }
487 }
488
489 /**
490 * Implementation of hasher_t.allocate_hash for SHA224.
491 */
492 static void allocate_hash224(private_sha256_hasher_t *this,
493 chunk_t chunk, chunk_t *hash)
494 {
495 chunk_t allocated_hash;
496
497 sha256_write(this, chunk.ptr, chunk.len);
498 if (hash != NULL)
499 {
500 sha256_final(this);
501 allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
502 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
503 this->public.hasher_interface.reset(&(this->public.hasher_interface));
504 *hash = allocated_hash;
505 }
506 }
507
508 /**
509 * Implementation of hasher_t.allocate_hash for SHA256.
510 */
511 static void allocate_hash256(private_sha256_hasher_t *this,
512 chunk_t chunk, chunk_t *hash)
513 {
514 chunk_t allocated_hash;
515
516 sha256_write(this, chunk.ptr, chunk.len);
517 if (hash != NULL)
518 {
519 sha256_final(this);
520 allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
521 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
522 this->public.hasher_interface.reset(&(this->public.hasher_interface));
523 *hash = allocated_hash;
524 }
525 }
526
527 /**
528 * Implementation of hasher_t.allocate_hash for SHA384.
529 */
530 static void allocate_hash384(private_sha512_hasher_t *this,
531 chunk_t chunk, chunk_t *hash)
532 {
533 chunk_t allocated_hash;
534
535 sha512_write(this, chunk.ptr, chunk.len);
536 if (hash != NULL)
537 {
538 sha512_final(this);
539 allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
540 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
541 this->public.hasher_interface.reset(&(this->public.hasher_interface));
542 *hash = allocated_hash;
543 }
544 }
545
546 /**
547 * Implementation of hasher_t.allocate_hash for SHA512.
548 */
549 static void allocate_hash512(private_sha512_hasher_t *this,
550 chunk_t chunk, chunk_t *hash)
551 {
552 chunk_t allocated_hash;
553
554 sha512_write(this, chunk.ptr, chunk.len);
555 if (hash != NULL)
556 {
557 sha512_final(this);
558 allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
559 memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
560 this->public.hasher_interface.reset(&(this->public.hasher_interface));
561 *hash = allocated_hash;
562 }
563 }
564
565 /**
566 * Implementation of hasher_t.get_hash_size for SHA224.
567 */
568 static size_t get_hash_size224(private_sha256_hasher_t *this)
569 {
570 return HASH_SIZE_SHA224;
571 }
572
573 /**
574 * Implementation of hasher_t.get_hash_size for SHA256.
575 */
576 static size_t get_hash_size256(private_sha256_hasher_t *this)
577 {
578 return HASH_SIZE_SHA256;
579 }
580
581 /**
582 * Implementation of hasher_t.get_hash_size for SHA384.
583 */
584 static size_t get_hash_size384(private_sha512_hasher_t *this)
585 {
586 return HASH_SIZE_SHA384;
587 }
588
589 /**
590 * Implementation of hasher_t.get_hash_size for SHA512.
591 */
592 static size_t get_hash_size512(private_sha512_hasher_t *this)
593 {
594 return HASH_SIZE_SHA512;
595 }
596
597 /**
598 * Implementation of hasher_t.reset for SHA224
599 */
600 static void reset224(private_sha256_hasher_t *ctx)
601 {
602 memcpy(&ctx->sha_H[0], &sha224_hashInit[0], sizeof(ctx->sha_H));
603 ctx->sha_blocks = 0;
604 ctx->sha_bufCnt = 0;
605 }
606
607 /**
608 * Implementation of hasher_t.reset for SHA256
609 */
610 static void reset256(private_sha256_hasher_t *ctx)
611 {
612 memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
613 ctx->sha_blocks = 0;
614 ctx->sha_bufCnt = 0;
615 }
616
617 /**
618 * Implementation of hasher_t.reset for SHA384
619 */
620 static void reset384(private_sha512_hasher_t *ctx)
621 {
622 memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
623 ctx->sha_blocks = 0;
624 ctx->sha_blocksMSB = 0;
625 ctx->sha_bufCnt = 0;
626 }
627
628 /**
629 * Implementation of hasher_t.reset for SHA512
630 */
631 static void reset512(private_sha512_hasher_t *ctx)
632 {
633 memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
634 ctx->sha_blocks = 0;
635 ctx->sha_blocksMSB = 0;
636 ctx->sha_bufCnt = 0;
637 }
638
639 /**
640 * Implementation of hasher_t.destroy.
641 */
642 static void destroy(sha2_hasher_t *this)
643 {
644 free(this);
645 }
646
647 /*
648 * Described in header.
649 */
650 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
651 {
652 sha2_hasher_t *this;
653
654 switch (algorithm)
655 {
656 case HASH_SHA224:
657 this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
658 this->hasher_interface.reset = (void(*)(hasher_t*))reset224;
659 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size224;
660 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash224;
661 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash224;
662 break;
663 case HASH_SHA256:
664 this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
665 this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
666 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
667 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
668 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
669 break;
670 case HASH_SHA384:
671 /* uses SHA512 data structure */
672 this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
673 this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
674 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
675 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
676 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
677 break;
678 case HASH_SHA512:
679 this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
680 this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
681 this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
682 this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
683 this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
684 break;
685 default:
686 return NULL;
687 }
688 this->hasher_interface.destroy = (void(*)(hasher_t*))destroy;
689
690 /* initialize */
691 this->hasher_interface.reset(&this->hasher_interface);
692
693 return this;
694 }