]> git.ipfire.org Git - thirdparty/bird.git/blame - lib/sha512.c
Minor changes to SHA hash functions
[thirdparty/bird.git] / lib / sha512.c
CommitLineData
f312a837
PT
1/*
2 * BIRD Library -- SHA-512 and SHA-384 Hash Functions,
3 * HMAC-SHA-512 and HMAC-SHA-384 Functions
4 *
5 * (c) 2015 CZ.NIC z.s.p.o.
6 *
7 * Based on the code from libgcrypt-1.6.0, which is
8 * (c) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
9 *
10 * Can be freely distributed and used under the terms of the GNU GPL.
11 */
12
f312a837
PT
13#include "lib/sha512.h"
14#include "lib/unaligned.h"
15
5126380b
OZ
16
17// #define SHA512_UNROLLED
f312a837
PT
18
19void
20sha512_init(struct sha512_context *ctx)
21{
5126380b
OZ
22 ctx->h0 = U64(0x6a09e667f3bcc908);
23 ctx->h1 = U64(0xbb67ae8584caa73b);
24 ctx->h2 = U64(0x3c6ef372fe94f82b);
25 ctx->h3 = U64(0xa54ff53a5f1d36f1);
26 ctx->h4 = U64(0x510e527fade682d1);
27 ctx->h5 = U64(0x9b05688c2b3e6c1f);
28 ctx->h6 = U64(0x1f83d9abfb41bd6b);
29 ctx->h7 = U64(0x5be0cd19137e2179);
30
31 ctx->nblocks = 0;
32 ctx->count = 0;
f312a837
PT
33}
34
35void
36sha384_init(struct sha384_context *ctx)
37{
5126380b
OZ
38 ctx->h0 = U64(0xcbbb9d5dc1059ed8);
39 ctx->h1 = U64(0x629a292a367cd507);
40 ctx->h2 = U64(0x9159015a3070dd17);
41 ctx->h3 = U64(0x152fecd8f70e5939);
42 ctx->h4 = U64(0x67332667ffc00b31);
43 ctx->h5 = U64(0x8eb44a8768581511);
44 ctx->h6 = U64(0xdb0c2e0d64f98fa7);
45 ctx->h7 = U64(0x47b5481dbefa4fa4);
46
47 ctx->nblocks = 0;
48 ctx->count = 0;
f312a837
PT
49}
50
51static inline u64
52ROTR(u64 x, u64 n)
53{
54 return ((x >> n) | (x << (64 - n)));
55}
56
57static inline u64
58Ch(u64 x, u64 y, u64 z)
59{
60 return ((x & y) ^ ( ~x & z));
61}
62
63static inline u64
64Maj(u64 x, u64 y, u64 z)
65{
66 return ((x & y) ^ (x & z) ^ (y & z));
67}
68
69static inline u64
5126380b 70sum0(u64 x)
f312a837 71{
5126380b 72 return (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39));
f312a837
PT
73}
74
75static inline u64
5126380b 76sum1(u64 x)
f312a837 77{
5126380b 78 return (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41));
f312a837
PT
79}
80
81static const u64 k[] =
82{
5126380b
OZ
83 U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
84 U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
85 U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
86 U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
87 U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
88 U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
89 U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
90 U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
91 U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
92 U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
93 U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
94 U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
95 U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
96 U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
97 U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
98 U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
99 U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
100 U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
101 U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
102 U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
103 U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
104 U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
105 U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
106 U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
107 U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
108 U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
109 U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
110 U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
111 U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
112 U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
113 U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
114 U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
115 U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
116 U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
117 U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
118 U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
119 U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
120 U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
121 U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
122 U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
f312a837
PT
123};
124
125/*
126 * Transform the message W which consists of 16 64-bit-words
127 */
128static uint
5126380b 129sha512_transform(struct sha512_context *ctx, const byte *data)
f312a837
PT
130{
131 u64 a, b, c, d, e, f, g, h;
132 u64 w[16];
5126380b 133 uint t;
f312a837
PT
134
135 /* get values from the chaining vars */
5126380b
OZ
136 a = ctx->h0;
137 b = ctx->h1;
138 c = ctx->h2;
139 d = ctx->h3;
140 e = ctx->h4;
141 f = ctx->h5;
142 g = ctx->h6;
143 h = ctx->h7;
144
145 for (t = 0; t < 16; t++)
f312a837
PT
146 w[t] = get_u64(data + t * 8);
147
148#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
149#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
150
151 for (t = 0; t < 80 - 16; )
152 {
153 u64 t1, t2;
154
155 /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
156 with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
157 initialized to 0,1,2,3...255,0,... and 1000 iterations:
158
159 Not unrolled with macros: 440ms
160 Unrolled with macros: 350ms
161 Unrolled with inline: 330ms
162 */
5126380b
OZ
163#ifndef SHA512_UNROLLED
164 t1 = h + sum1(e) + Ch(e, f, g) + k[t] + w[t%16];
165 w[t%16] += S1(w[(t - 2)%16]) + w[(t - 7)%16] + S0(w[(t - 15)%16]);
166 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
167 h = g;
168 g = f;
169 f = e;
170 e = d + t1;
171 d = c;
172 c = b;
173 b = a;
174 a = t1 + t2;
175 t++;
5126380b
OZ
176#else /* Unrolled */
177 t1 = h + sum1(e) + Ch(e, f, g) + k[t] + w[0];
178 w[0] += S1(w[14]) + w[9] + S0(w[1]);
179 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
180 d += t1;
181 h = t1 + t2;
182
5126380b
OZ
183 t1 = g + sum1(d) + Ch(d, e, f) + k[t+1] + w[1];
184 w[1] += S1(w[15]) + w[10] + S0(w[2]);
185 t2 = sum0(h) + Maj(h, a, b);
f312a837
PT
186 c += t1;
187 g = t1 + t2;
188
5126380b
OZ
189 t1 = f + sum1(c) + Ch(c, d, e) + k[t+2] + w[2];
190 w[2] += S1(w[0]) + w[11] + S0(w[3]);
191 t2 = sum0(g) + Maj(g, h, a);
f312a837
PT
192 b += t1;
193 f = t1 + t2;
194
5126380b
OZ
195 t1 = e + sum1(b) + Ch(b, c, d) + k[t+3] + w[3];
196 w[3] += S1(w[1]) + w[12] + S0(w[4]);
197 t2 = sum0(f) + Maj(f, g, h);
f312a837
PT
198 a += t1;
199 e = t1 + t2;
200
5126380b
OZ
201 t1 = d + sum1(a) + Ch(a, b, c) + k[t+4] + w[4];
202 w[4] += S1(w[2]) + w[13] + S0(w[5]);
203 t2 = sum0(e) + Maj(e, f, g);
f312a837
PT
204 h += t1;
205 d = t1 + t2;
206
5126380b
OZ
207 t1 = c + sum1(h) + Ch(h, a, b) + k[t+5] + w[5];
208 w[5] += S1(w[3]) + w[14] + S0(w[6]);
209 t2 = sum0(d) + Maj(d, e, f);
f312a837
PT
210 g += t1;
211 c = t1 + t2;
212
5126380b
OZ
213 t1 = b + sum1(g) + Ch(g, h, a) + k[t+6] + w[6];
214 w[6] += S1(w[4]) + w[15] + S0(w[7]);
215 t2 = sum0(c) + Maj(c, d, e);
f312a837
PT
216 f += t1;
217 b = t1 + t2;
218
5126380b
OZ
219 t1 = a + sum1(f) + Ch(f, g, h) + k[t+7] + w[7];
220 w[7] += S1(w[5]) + w[0] + S0(w[8]);
221 t2 = sum0(b) + Maj(b, c, d);
f312a837
PT
222 e += t1;
223 a = t1 + t2;
224
5126380b
OZ
225 t1 = h + sum1(e) + Ch(e, f, g) + k[t+8] + w[8];
226 w[8] += S1(w[6]) + w[1] + S0(w[9]);
227 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
228 d += t1;
229 h = t1 + t2;
230
5126380b
OZ
231 t1 = g + sum1(d) + Ch(d, e, f) + k[t+9] + w[9];
232 w[9] += S1(w[7]) + w[2] + S0(w[10]);
233 t2 = sum0(h) + Maj(h, a, b);
f312a837
PT
234 c += t1;
235 g = t1 + t2;
236
5126380b
OZ
237 t1 = f + sum1(c) + Ch(c, d, e) + k[t+10] + w[10];
238 w[10] += S1(w[8]) + w[3] + S0(w[11]);
239 t2 = sum0(g) + Maj(g, h, a);
f312a837
PT
240 b += t1;
241 f = t1 + t2;
242
5126380b
OZ
243 t1 = e + sum1(b) + Ch(b, c, d) + k[t+11] + w[11];
244 w[11] += S1(w[9]) + w[4] + S0(w[12]);
245 t2 = sum0(f) + Maj(f, g, h);
f312a837
PT
246 a += t1;
247 e = t1 + t2;
248
5126380b
OZ
249 t1 = d + sum1(a) + Ch(a, b, c) + k[t+12] + w[12];
250 w[12] += S1(w[10]) + w[5] + S0(w[13]);
251 t2 = sum0(e) + Maj(e, f, g);
f312a837
PT
252 h += t1;
253 d = t1 + t2;
254
5126380b
OZ
255 t1 = c + sum1(h) + Ch(h, a, b) + k[t+13] + w[13];
256 w[13] += S1(w[11]) + w[6] + S0(w[14]);
257 t2 = sum0(d) + Maj(d, e, f);
f312a837
PT
258 g += t1;
259 c = t1 + t2;
260
5126380b
OZ
261 t1 = b + sum1(g) + Ch(g, h, a) + k[t+14] + w[14];
262 w[14] += S1(w[12]) + w[7] + S0(w[15]);
263 t2 = sum0(c) + Maj(c, d, e);
f312a837
PT
264 f += t1;
265 b = t1 + t2;
266
5126380b
OZ
267 t1 = a + sum1(f) + Ch(f, g, h) + k[t+15] + w[15];
268 w[15] += S1(w[13]) + w[8] + S0(w[0]);
269 t2 = sum0(b) + Maj(b, c, d);
f312a837
PT
270 e += t1;
271 a = t1 + t2;
272
273 t += 16;
274#endif
275 }
276
277 for (; t < 80; )
278 {
279 u64 t1, t2;
280
5126380b
OZ
281#ifndef SHA512_UNROLLED
282 t1 = h + sum1(e) + Ch(e, f, g) + k[t] + w[t%16];
283 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
284 h = g;
285 g = f;
286 f = e;
287 e = d + t1;
288 d = c;
289 c = b;
290 b = a;
291 a = t1 + t2;
292 t++;
5126380b
OZ
293#else /* Unrolled */
294 t1 = h + sum1(e) + Ch(e, f, g) + k[t] + w[0];
295 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
296 d += t1;
297 h = t1 + t2;
298
5126380b
OZ
299 t1 = g + sum1(d) + Ch(d, e, f) + k[t+1] + w[1];
300 t2 = sum0(h) + Maj(h, a, b);
f312a837
PT
301 c += t1;
302 g = t1 + t2;
303
5126380b
OZ
304 t1 = f + sum1(c) + Ch(c, d, e) + k[t+2] + w[2];
305 t2 = sum0(g) + Maj(g, h, a);
f312a837
PT
306 b += t1;
307 f = t1 + t2;
308
5126380b
OZ
309 t1 = e + sum1(b) + Ch(b, c, d) + k[t+3] + w[3];
310 t2 = sum0(f) + Maj(f, g, h);
f312a837
PT
311 a += t1;
312 e = t1 + t2;
313
5126380b
OZ
314 t1 = d + sum1(a) + Ch(a, b, c) + k[t+4] + w[4];
315 t2 = sum0(e) + Maj(e, f, g);
f312a837
PT
316 h += t1;
317 d = t1 + t2;
318
5126380b
OZ
319 t1 = c + sum1(h) + Ch(h, a, b) + k[t+5] + w[5];
320 t2 = sum0(d) + Maj(d, e, f);
f312a837
PT
321 g += t1;
322 c = t1 + t2;
323
5126380b
OZ
324 t1 = b + sum1(g) + Ch(g, h, a) + k[t+6] + w[6];
325 t2 = sum0(c) + Maj(c, d, e);
f312a837
PT
326 f += t1;
327 b = t1 + t2;
328
5126380b
OZ
329 t1 = a + sum1(f) + Ch(f, g, h) + k[t+7] + w[7];
330 t2 = sum0(b) + Maj(b, c, d);
f312a837
PT
331 e += t1;
332 a = t1 + t2;
333
5126380b
OZ
334 t1 = h + sum1(e) + Ch(e, f, g) + k[t+8] + w[8];
335 t2 = sum0(a) + Maj(a, b, c);
f312a837
PT
336 d += t1;
337 h = t1 + t2;
338
5126380b
OZ
339 t1 = g + sum1(d) + Ch(d, e, f) + k[t+9] + w[9];
340 t2 = sum0(h) + Maj(h, a, b);
f312a837
PT
341 c += t1;
342 g = t1 + t2;
343
5126380b
OZ
344 t1 = f + sum1(c) + Ch(c, d, e) + k[t+10] + w[10];
345 t2 = sum0(g) + Maj(g, h, a);
f312a837
PT
346 b += t1;
347 f = t1 + t2;
348
5126380b
OZ
349 t1 = e + sum1(b) + Ch(b, c, d) + k[t+11] + w[11];
350 t2 = sum0(f) + Maj(f, g, h);
f312a837
PT
351 a += t1;
352 e = t1 + t2;
353
5126380b
OZ
354 t1 = d + sum1(a) + Ch(a, b, c) + k[t+12] + w[12];
355 t2 = sum0(e) + Maj(e, f, g);
f312a837
PT
356 h += t1;
357 d = t1 + t2;
358
5126380b
OZ
359 t1 = c + sum1(h) + Ch(h, a, b) + k[t+13] + w[13];
360 t2 = sum0(d) + Maj(d, e, f);
f312a837
PT
361 g += t1;
362 c = t1 + t2;
363
5126380b
OZ
364 t1 = b + sum1(g) + Ch(g, h, a) + k[t+14] + w[14];
365 t2 = sum0(c) + Maj(c, d, e);
f312a837
PT
366 f += t1;
367 b = t1 + t2;
368
5126380b
OZ
369 t1 = a + sum1(f) + Ch(f, g, h) + k[t+15] + w[15];
370 t2 = sum0(b) + Maj(b, c, d);
f312a837
PT
371 e += t1;
372 a = t1 + t2;
373
374 t += 16;
375#endif
376 }
377
378 /* Update chaining vars. */
5126380b
OZ
379 ctx->h0 += a;
380 ctx->h1 += b;
381 ctx->h2 += c;
382 ctx->h3 += d;
383 ctx->h4 += e;
384 ctx->h5 += f;
385 ctx->h6 += g;
386 ctx->h7 += h;
f312a837
PT
387
388 return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) + 3 * sizeof(void*);
389}
390
5126380b
OZ
391void
392sha512_update(struct sha512_context *ctx, const byte *buf, size_t len)
f312a837 393{
5126380b
OZ
394 if (ctx->count)
395 {
396 /* Fill rest of internal buffer */
397 for (; len && ctx->count < SHA512_BLOCK_SIZE; len--)
398 ctx->buf[ctx->count++] = *buf++;
399
400 if (ctx->count < SHA512_BLOCK_SIZE)
401 return;
402
403 /* Process data from internal buffer */
404 sha512_transform(ctx, ctx->buf);
405 ctx->nblocks++;
406 ctx->count = 0;
407 }
f312a837 408
5126380b
OZ
409 if (!len)
410 return;
411
412 /* Process data from input buffer */
413 while (len >= SHA512_BLOCK_SIZE)
f312a837 414 {
5126380b
OZ
415 sha512_transform(ctx, buf);
416 ctx->nblocks++;
417 buf += SHA512_BLOCK_SIZE;
418 len -= SHA512_BLOCK_SIZE;
f312a837 419 }
f312a837 420
5126380b
OZ
421 /* Copy remaining data to internal buffer */
422 memcpy(ctx->buf, buf, len);
423 ctx->count = len;
f312a837
PT
424}
425
5126380b
OZ
426/*
427 * The routine final terminates the computation and returns the digest. The
428 * handle is prepared for a new cycle, but adding bytes to the handle will the
429 * destroy the returned buffer.
430 *
431 * Returns: 64 bytes representing the digest. When used for sha384, we take the
432 * first 48 of those bytes.
f312a837
PT
433 */
434byte *
435sha512_final(struct sha512_context *ctx)
436{
437 u64 t, th, msb, lsb;
f312a837 438
5126380b 439 sha512_update(ctx, NULL, 0); /* flush */
f312a837 440
5126380b
OZ
441 t = ctx->nblocks;
442 th = 0;
f312a837
PT
443
444 /* multiply by 128 to make a byte count */
445 lsb = t << 7;
446 msb = (th << 7) | (t >> 57);
447 /* add the count */
448 t = lsb;
5126380b 449 if ((lsb += ctx->count) < t)
f312a837
PT
450 msb++;
451 /* multiply by 8 to make a bit count */
452 t = lsb;
453 lsb <<= 3;
454 msb <<= 3;
455 msb |= t >> 61;
456
5126380b
OZ
457 if (ctx->count < 112)
458 {
459 /* enough room */
460 ctx->buf[ctx->count++] = 0x80; /* pad */
461 while(ctx->count < 112)
462 ctx->buf[ctx->count++] = 0; /* pad */
f312a837
PT
463 }
464 else
5126380b
OZ
465 {
466 /* need one extra block */
467 ctx->buf[ctx->count++] = 0x80; /* pad character */
468 while(ctx->count < 128)
469 ctx->buf[ctx->count++] = 0;
470 sha512_update(ctx, NULL, 0); /* flush */
471 memset(ctx->buf, 0, 112); /* fill next block with zeroes */
f312a837 472 }
5126380b 473
f312a837 474 /* append the 128 bit count */
5126380b
OZ
475 put_u64(ctx->buf + 112, msb);
476 put_u64(ctx->buf + 120, lsb);
477 sha512_transform(ctx, ctx->buf);
478
479 byte *p = ctx->buf;
480#define X(a) do { put_u64(p, ctx->h##a); p += 8; } while(0)
481 X(0);
482 X(1);
483 X(2);
484 X(3);
485 X(4);
486 X(5);
487 X(6);
488 X(7);
f312a837
PT
489#undef X
490
5126380b 491 return ctx->buf;
f312a837
PT
492}
493
494
495/*
5126380b 496 * SHA512-HMAC
f312a837
PT
497 */
498
499static void
500sha512_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
501{
5126380b 502 struct sha512_context ctx;
f312a837 503
5126380b
OZ
504 sha512_init(&ctx);
505 sha512_update(&ctx, buffer, length);
506 memcpy(outbuf, sha512_final(&ctx), SHA512_SIZE);
f312a837
PT
507}
508
509void
510sha512_hmac_init(struct sha512_hmac_context *ctx, const byte *key, size_t keylen)
511{
512 byte keybuf[SHA512_BLOCK_SIZE], buf[SHA512_BLOCK_SIZE];
513
514 /* Hash the key if necessary */
515 if (keylen <= SHA512_BLOCK_SIZE)
516 {
517 memcpy(keybuf, key, keylen);
5126380b 518 memset(keybuf + keylen, 0, SHA512_BLOCK_SIZE - keylen);
f312a837
PT
519 }
520 else
521 {
522 sha512_hash_buffer(keybuf, key, keylen);
5126380b 523 memset(keybuf + SHA512_SIZE, 0, SHA512_BLOCK_SIZE - SHA512_SIZE);
f312a837
PT
524 }
525
526 /* Initialize the inner digest */
527 sha512_init(&ctx->ictx);
528 int i;
529 for (i = 0; i < SHA512_BLOCK_SIZE; i++)
530 buf[i] = keybuf[i] ^ 0x36;
531 sha512_update(&ctx->ictx, buf, SHA512_BLOCK_SIZE);
532
533 /* Initialize the outer digest */
534 sha512_init(&ctx->octx);
535 for (i = 0; i < SHA512_BLOCK_SIZE; i++)
536 buf[i] = keybuf[i] ^ 0x5c;
537 sha512_update(&ctx->octx, buf, SHA512_BLOCK_SIZE);
538}
539
5126380b
OZ
540void
541sha512_hmac_update(struct sha512_hmac_context *ctx, const byte *buf, size_t buflen)
f312a837
PT
542{
543 /* Just update the inner digest */
544 sha512_update(&ctx->ictx, buf, buflen);
545}
546
5126380b
OZ
547byte *
548sha512_hmac_final(struct sha512_hmac_context *ctx)
f312a837
PT
549{
550 /* Finish the inner digest */
551 byte *isha = sha512_final(&ctx->ictx);
552
553 /* Finish the outer digest */
554 sha512_update(&ctx->octx, isha, SHA512_SIZE);
555 return sha512_final(&ctx->octx);
556}
557
558
559/*
5126380b 560 * SHA384-HMAC
f312a837
PT
561 */
562
563static void
564sha384_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
565{
5126380b 566 struct sha384_context ctx;
f312a837 567
5126380b
OZ
568 sha384_init(&ctx);
569 sha384_update(&ctx, buffer, length);
570 memcpy(outbuf, sha384_final(&ctx), SHA384_SIZE);
f312a837
PT
571}
572
573void
574sha384_hmac_init(struct sha384_hmac_context *ctx, const byte *key, size_t keylen)
575{
576 byte keybuf[SHA384_BLOCK_SIZE], buf[SHA384_BLOCK_SIZE];
577
578 /* Hash the key if necessary */
579 if (keylen <= SHA384_BLOCK_SIZE)
580 {
581 memcpy(keybuf, key, keylen);
5126380b 582 memset(keybuf + keylen, 0, SHA384_BLOCK_SIZE - keylen);
f312a837
PT
583 }
584 else
585 {
586 sha384_hash_buffer(keybuf, key, keylen);
5126380b 587 memset(keybuf + SHA384_SIZE, 0, SHA384_BLOCK_SIZE - SHA384_SIZE);
f312a837
PT
588 }
589
590 /* Initialize the inner digest */
591 sha384_init(&ctx->ictx);
592 int i;
593 for (i = 0; i < SHA384_BLOCK_SIZE; i++)
594 buf[i] = keybuf[i] ^ 0x36;
595 sha384_update(&ctx->ictx, buf, SHA384_BLOCK_SIZE);
596
597 /* Initialize the outer digest */
598 sha384_init(&ctx->octx);
599 for (i = 0; i < SHA384_BLOCK_SIZE; i++)
600 buf[i] = keybuf[i] ^ 0x5c;
601 sha384_update(&ctx->octx, buf, SHA384_BLOCK_SIZE);
602}
603
5126380b
OZ
604void
605sha384_hmac_update(struct sha384_hmac_context *ctx, const byte *buf, size_t buflen)
f312a837
PT
606{
607 /* Just update the inner digest */
608 sha384_update(&ctx->ictx, buf, buflen);
609}
610
5126380b
OZ
611byte *
612sha384_hmac_final(struct sha384_hmac_context *ctx)
f312a837
PT
613{
614 /* Finish the inner digest */
615 byte *isha = sha384_final(&ctx->ictx);
616
617 /* Finish the outer digest */
618 sha384_update(&ctx->octx, isha, SHA384_SIZE);
619 return sha384_final(&ctx->octx);
620}