1258945Sroberto/*
2280849Scy * Copyright (C) 2005-2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3258945Sroberto *
4258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any
5258945Sroberto * purpose with or without fee is hereby granted, provided that the above
6258945Sroberto * copyright notice and this permission notice appear in all copies.
7258945Sroberto *
8258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10258945Sroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14258945Sroberto * PERFORMANCE OF THIS SOFTWARE.
15258945Sroberto */
16258945Sroberto
17280849Scy/* $Id$ */
18258945Sroberto
19258945Sroberto/*
20258945Sroberto * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
21258945Sroberto * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
22258945Sroberto * draft-ietf-dnsext-tsig-sha-01.txt.
23258945Sroberto */
24258945Sroberto
25258945Sroberto#include "config.h"
26258945Sroberto
27258945Sroberto#include <isc/assertions.h>
28258945Sroberto#include <isc/hmacsha.h>
29280849Scy#include <isc/platform.h>
30258945Sroberto#include <isc/sha1.h>
31258945Sroberto#include <isc/sha2.h>
32258945Sroberto#include <isc/string.h>
33258945Sroberto#include <isc/types.h>
34258945Sroberto#include <isc/util.h>
35258945Sroberto
36280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH
37280849Scy
38280849Scyvoid
39280849Scyisc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
40280849Scy		  unsigned int len)
41280849Scy{
42280849Scy	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
43280849Scy}
44280849Scy
45280849Scyvoid
46280849Scyisc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
47280849Scy	HMAC_CTX_cleanup(ctx);
48280849Scy}
49280849Scy
50280849Scyvoid
51280849Scyisc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
52280849Scy		   unsigned int len)
53280849Scy{
54280849Scy	HMAC_Update(ctx, buf, (int) len);
55280849Scy}
56280849Scy
57280849Scyvoid
58280849Scyisc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
59280849Scy	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
60280849Scy
61280849Scy	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
62280849Scy
63280849Scy	HMAC_Final(ctx, newdigest, NULL);
64280849Scy	HMAC_CTX_cleanup(ctx);
65280849Scy	memcpy(digest, newdigest, len);
66280849Scy	memset(newdigest, 0, sizeof(newdigest));
67280849Scy}
68280849Scy
69280849Scyvoid
70280849Scyisc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
71280849Scy		    unsigned int len)
72280849Scy{
73280849Scy	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
74280849Scy}
75280849Scy
76280849Scyvoid
77280849Scyisc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
78280849Scy	HMAC_CTX_cleanup(ctx);
79280849Scy}
80280849Scy
81280849Scyvoid
82280849Scyisc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
83280849Scy		   unsigned int len)
84280849Scy{
85280849Scy	HMAC_Update(ctx, buf, (int) len);
86280849Scy}
87280849Scy
88280849Scyvoid
89280849Scyisc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
90280849Scy	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
91280849Scy
92280849Scy	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
93280849Scy
94280849Scy	HMAC_Final(ctx, newdigest, NULL);
95280849Scy	HMAC_CTX_cleanup(ctx);
96280849Scy	memcpy(digest, newdigest, len);
97280849Scy	memset(newdigest, 0, sizeof(newdigest));
98280849Scy}
99280849Scy
100280849Scyvoid
101280849Scyisc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
102280849Scy		    unsigned int len)
103280849Scy{
104280849Scy	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
105280849Scy}
106280849Scy
107280849Scyvoid
108280849Scyisc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
109280849Scy	HMAC_CTX_cleanup(ctx);
110280849Scy}
111280849Scy
112280849Scyvoid
113280849Scyisc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
114280849Scy		   unsigned int len)
115280849Scy{
116280849Scy	HMAC_Update(ctx, buf, (int) len);
117280849Scy}
118280849Scy
119280849Scyvoid
120280849Scyisc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
121280849Scy	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
122280849Scy
123280849Scy	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
124280849Scy
125280849Scy	HMAC_Final(ctx, newdigest, NULL);
126280849Scy	HMAC_CTX_cleanup(ctx);
127280849Scy	memcpy(digest, newdigest, len);
128280849Scy	memset(newdigest, 0, sizeof(newdigest));
129280849Scy}
130280849Scy
131280849Scyvoid
132280849Scyisc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
133280849Scy		    unsigned int len)
134280849Scy{
135280849Scy	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
136280849Scy}
137280849Scy
138280849Scyvoid
139280849Scyisc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
140280849Scy	HMAC_CTX_cleanup(ctx);
141280849Scy}
142280849Scy
143280849Scyvoid
144280849Scyisc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
145280849Scy		   unsigned int len)
146280849Scy{
147280849Scy	HMAC_Update(ctx, buf, (int) len);
148280849Scy}
149280849Scy
150280849Scyvoid
151280849Scyisc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
152280849Scy	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
153280849Scy
154280849Scy	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
155280849Scy
156280849Scy	HMAC_Final(ctx, newdigest, NULL);
157280849Scy	HMAC_CTX_cleanup(ctx);
158280849Scy	memcpy(digest, newdigest, len);
159280849Scy	memset(newdigest, 0, sizeof(newdigest));
160280849Scy}
161280849Scy
162280849Scyvoid
163280849Scyisc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
164280849Scy		    unsigned int len)
165280849Scy{
166280849Scy	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
167280849Scy}
168280849Scy
169280849Scyvoid
170280849Scyisc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
171280849Scy	HMAC_CTX_cleanup(ctx);
172280849Scy}
173280849Scy
174280849Scyvoid
175280849Scyisc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
176280849Scy		   unsigned int len)
177280849Scy{
178280849Scy	HMAC_Update(ctx, buf, (int) len);
179280849Scy}
180280849Scy
181280849Scyvoid
182280849Scyisc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
183280849Scy	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
184280849Scy
185280849Scy	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
186280849Scy
187280849Scy	HMAC_Final(ctx, newdigest, NULL);
188280849Scy	HMAC_CTX_cleanup(ctx);
189280849Scy	memcpy(digest, newdigest, len);
190280849Scy	memset(newdigest, 0, sizeof(newdigest));
191280849Scy}
192280849Scy
193280849Scy#else
194280849Scy
195258945Sroberto#define IPAD 0x36
196258945Sroberto#define OPAD 0x5C
197258945Sroberto
198258945Sroberto/*
199258945Sroberto * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
200258945Sroberto */
201258945Srobertovoid
202258945Srobertoisc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
203258945Sroberto		  unsigned int len)
204258945Sroberto{
205258945Sroberto	unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
206258945Sroberto	unsigned int i;
207258945Sroberto
208258945Sroberto	memset(ctx->key, 0, sizeof(ctx->key));
209258945Sroberto	if (len > sizeof(ctx->key)) {
210258945Sroberto		isc_sha1_t sha1ctx;
211258945Sroberto		isc_sha1_init(&sha1ctx);
212258945Sroberto		isc_sha1_update(&sha1ctx, key, len);
213258945Sroberto		isc_sha1_final(&sha1ctx, ctx->key);
214258945Sroberto	} else
215258945Sroberto		memcpy(ctx->key, key, len);
216258945Sroberto
217258945Sroberto	isc_sha1_init(&ctx->sha1ctx);
218258945Sroberto	memset(ipad, IPAD, sizeof(ipad));
219258945Sroberto	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
220258945Sroberto		ipad[i] ^= ctx->key[i];
221258945Sroberto	isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
222258945Sroberto}
223258945Sroberto
224258945Srobertovoid
225258945Srobertoisc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
226258945Sroberto	isc_sha1_invalidate(&ctx->sha1ctx);
227280849Scy	memset(ctx, 0, sizeof(*ctx));
228258945Sroberto}
229258945Sroberto
230258945Sroberto/*
231258945Sroberto * Update context to reflect the concatenation of another buffer full
232258945Sroberto * of bytes.
233258945Sroberto */
234258945Srobertovoid
235258945Srobertoisc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
236258945Sroberto		   unsigned int len)
237258945Sroberto{
238258945Sroberto	isc_sha1_update(&ctx->sha1ctx, buf, len);
239258945Sroberto}
240258945Sroberto
241258945Sroberto/*
242258945Sroberto * Compute signature - finalize SHA1 operation and reapply SHA1.
243258945Sroberto */
244258945Srobertovoid
245258945Srobertoisc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
246258945Sroberto	unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
247258945Sroberto	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
248258945Sroberto	unsigned int i;
249258945Sroberto
250258945Sroberto	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
251258945Sroberto	isc_sha1_final(&ctx->sha1ctx, newdigest);
252258945Sroberto
253258945Sroberto	memset(opad, OPAD, sizeof(opad));
254258945Sroberto	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
255258945Sroberto		opad[i] ^= ctx->key[i];
256258945Sroberto
257258945Sroberto	isc_sha1_init(&ctx->sha1ctx);
258258945Sroberto	isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
259258945Sroberto	isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
260258945Sroberto	isc_sha1_final(&ctx->sha1ctx, newdigest);
261258945Sroberto	isc_hmacsha1_invalidate(ctx);
262258945Sroberto	memcpy(digest, newdigest, len);
263258945Sroberto	memset(newdigest, 0, sizeof(newdigest));
264258945Sroberto}
265258945Sroberto
266258945Sroberto/*
267258945Sroberto * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
268258945Sroberto */
269258945Srobertovoid
270258945Srobertoisc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
271258945Sroberto		    unsigned int len)
272258945Sroberto{
273258945Sroberto	unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
274258945Sroberto	unsigned int i;
275258945Sroberto
276258945Sroberto	memset(ctx->key, 0, sizeof(ctx->key));
277258945Sroberto	if (len > sizeof(ctx->key)) {
278258945Sroberto		isc_sha224_t sha224ctx;
279258945Sroberto		isc_sha224_init(&sha224ctx);
280258945Sroberto		isc_sha224_update(&sha224ctx, key, len);
281258945Sroberto		isc_sha224_final(ctx->key, &sha224ctx);
282258945Sroberto	} else
283258945Sroberto		memcpy(ctx->key, key, len);
284258945Sroberto
285258945Sroberto	isc_sha224_init(&ctx->sha224ctx);
286258945Sroberto	memset(ipad, IPAD, sizeof(ipad));
287258945Sroberto	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
288258945Sroberto		ipad[i] ^= ctx->key[i];
289258945Sroberto	isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
290258945Sroberto}
291258945Sroberto
292258945Srobertovoid
293258945Srobertoisc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
294280849Scy	memset(ctx, 0, sizeof(*ctx));
295258945Sroberto}
296258945Sroberto
297258945Sroberto/*
298258945Sroberto * Update context to reflect the concatenation of another buffer full
299258945Sroberto * of bytes.
300258945Sroberto */
301258945Srobertovoid
302258945Srobertoisc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
303258945Sroberto		   unsigned int len)
304258945Sroberto{
305258945Sroberto	isc_sha224_update(&ctx->sha224ctx, buf, len);
306258945Sroberto}
307258945Sroberto
308258945Sroberto/*
309258945Sroberto * Compute signature - finalize SHA224 operation and reapply SHA224.
310258945Sroberto */
311258945Srobertovoid
312258945Srobertoisc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
313258945Sroberto	unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
314258945Sroberto	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
315258945Sroberto	unsigned int i;
316258945Sroberto
317258945Sroberto	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
318258945Sroberto	isc_sha224_final(newdigest, &ctx->sha224ctx);
319258945Sroberto
320258945Sroberto	memset(opad, OPAD, sizeof(opad));
321258945Sroberto	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
322258945Sroberto		opad[i] ^= ctx->key[i];
323258945Sroberto
324258945Sroberto	isc_sha224_init(&ctx->sha224ctx);
325258945Sroberto	isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
326258945Sroberto	isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
327258945Sroberto	isc_sha224_final(newdigest, &ctx->sha224ctx);
328258945Sroberto	memcpy(digest, newdigest, len);
329258945Sroberto	memset(newdigest, 0, sizeof(newdigest));
330258945Sroberto}
331258945Sroberto
332258945Sroberto/*
333258945Sroberto * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
334258945Sroberto */
335258945Srobertovoid
336258945Srobertoisc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
337258945Sroberto		    unsigned int len)
338258945Sroberto{
339258945Sroberto	unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
340258945Sroberto	unsigned int i;
341258945Sroberto
342258945Sroberto	memset(ctx->key, 0, sizeof(ctx->key));
343258945Sroberto	if (len > sizeof(ctx->key)) {
344258945Sroberto		isc_sha256_t sha256ctx;
345258945Sroberto		isc_sha256_init(&sha256ctx);
346258945Sroberto		isc_sha256_update(&sha256ctx, key, len);
347258945Sroberto		isc_sha256_final(ctx->key, &sha256ctx);
348258945Sroberto	} else
349258945Sroberto		memcpy(ctx->key, key, len);
350258945Sroberto
351258945Sroberto	isc_sha256_init(&ctx->sha256ctx);
352258945Sroberto	memset(ipad, IPAD, sizeof(ipad));
353258945Sroberto	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
354258945Sroberto		ipad[i] ^= ctx->key[i];
355258945Sroberto	isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
356258945Sroberto}
357258945Sroberto
358258945Srobertovoid
359258945Srobertoisc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
360280849Scy	memset(ctx, 0, sizeof(*ctx));
361258945Sroberto}
362258945Sroberto
363258945Sroberto/*
364258945Sroberto * Update context to reflect the concatenation of another buffer full
365258945Sroberto * of bytes.
366258945Sroberto */
367258945Srobertovoid
368258945Srobertoisc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
369258945Sroberto		   unsigned int len)
370258945Sroberto{
371258945Sroberto	isc_sha256_update(&ctx->sha256ctx, buf, len);
372258945Sroberto}
373258945Sroberto
374258945Sroberto/*
375258945Sroberto * Compute signature - finalize SHA256 operation and reapply SHA256.
376258945Sroberto */
377258945Srobertovoid
378258945Srobertoisc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
379258945Sroberto	unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
380258945Sroberto	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
381258945Sroberto	unsigned int i;
382258945Sroberto
383258945Sroberto	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
384258945Sroberto	isc_sha256_final(newdigest, &ctx->sha256ctx);
385258945Sroberto
386258945Sroberto	memset(opad, OPAD, sizeof(opad));
387258945Sroberto	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
388258945Sroberto		opad[i] ^= ctx->key[i];
389258945Sroberto
390258945Sroberto	isc_sha256_init(&ctx->sha256ctx);
391258945Sroberto	isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
392258945Sroberto	isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
393258945Sroberto	isc_sha256_final(newdigest, &ctx->sha256ctx);
394258945Sroberto	memcpy(digest, newdigest, len);
395258945Sroberto	memset(newdigest, 0, sizeof(newdigest));
396258945Sroberto}
397258945Sroberto
398258945Sroberto/*
399258945Sroberto * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
400258945Sroberto */
401258945Srobertovoid
402258945Srobertoisc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
403258945Sroberto		    unsigned int len)
404258945Sroberto{
405258945Sroberto	unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
406258945Sroberto	unsigned int i;
407258945Sroberto
408258945Sroberto	memset(ctx->key, 0, sizeof(ctx->key));
409258945Sroberto	if (len > sizeof(ctx->key)) {
410258945Sroberto		isc_sha384_t sha384ctx;
411258945Sroberto		isc_sha384_init(&sha384ctx);
412258945Sroberto		isc_sha384_update(&sha384ctx, key, len);
413258945Sroberto		isc_sha384_final(ctx->key, &sha384ctx);
414258945Sroberto	} else
415258945Sroberto		memcpy(ctx->key, key, len);
416258945Sroberto
417258945Sroberto	isc_sha384_init(&ctx->sha384ctx);
418258945Sroberto	memset(ipad, IPAD, sizeof(ipad));
419258945Sroberto	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
420258945Sroberto		ipad[i] ^= ctx->key[i];
421258945Sroberto	isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
422258945Sroberto}
423258945Sroberto
424258945Srobertovoid
425258945Srobertoisc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
426280849Scy	memset(ctx, 0, sizeof(*ctx));
427258945Sroberto}
428258945Sroberto
429258945Sroberto/*
430258945Sroberto * Update context to reflect the concatenation of another buffer full
431258945Sroberto * of bytes.
432258945Sroberto */
433258945Srobertovoid
434258945Srobertoisc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
435258945Sroberto		   unsigned int len)
436258945Sroberto{
437258945Sroberto	isc_sha384_update(&ctx->sha384ctx, buf, len);
438258945Sroberto}
439258945Sroberto
440258945Sroberto/*
441258945Sroberto * Compute signature - finalize SHA384 operation and reapply SHA384.
442258945Sroberto */
443258945Srobertovoid
444258945Srobertoisc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
445258945Sroberto	unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
446258945Sroberto	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
447258945Sroberto	unsigned int i;
448258945Sroberto
449258945Sroberto	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
450258945Sroberto	isc_sha384_final(newdigest, &ctx->sha384ctx);
451258945Sroberto
452258945Sroberto	memset(opad, OPAD, sizeof(opad));
453258945Sroberto	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
454258945Sroberto		opad[i] ^= ctx->key[i];
455258945Sroberto
456258945Sroberto	isc_sha384_init(&ctx->sha384ctx);
457258945Sroberto	isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
458258945Sroberto	isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
459258945Sroberto	isc_sha384_final(newdigest, &ctx->sha384ctx);
460258945Sroberto	memcpy(digest, newdigest, len);
461258945Sroberto	memset(newdigest, 0, sizeof(newdigest));
462258945Sroberto}
463258945Sroberto
464258945Sroberto/*
465258945Sroberto * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
466258945Sroberto */
467258945Srobertovoid
468258945Srobertoisc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
469258945Sroberto		    unsigned int len)
470258945Sroberto{
471258945Sroberto	unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
472258945Sroberto	unsigned int i;
473258945Sroberto
474258945Sroberto	memset(ctx->key, 0, sizeof(ctx->key));
475258945Sroberto	if (len > sizeof(ctx->key)) {
476258945Sroberto		isc_sha512_t sha512ctx;
477258945Sroberto		isc_sha512_init(&sha512ctx);
478258945Sroberto		isc_sha512_update(&sha512ctx, key, len);
479258945Sroberto		isc_sha512_final(ctx->key, &sha512ctx);
480258945Sroberto	} else
481258945Sroberto		memcpy(ctx->key, key, len);
482258945Sroberto
483258945Sroberto	isc_sha512_init(&ctx->sha512ctx);
484258945Sroberto	memset(ipad, IPAD, sizeof(ipad));
485258945Sroberto	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
486258945Sroberto		ipad[i] ^= ctx->key[i];
487258945Sroberto	isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
488258945Sroberto}
489258945Sroberto
490258945Srobertovoid
491258945Srobertoisc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
492280849Scy	memset(ctx, 0, sizeof(*ctx));
493258945Sroberto}
494258945Sroberto
495258945Sroberto/*
496258945Sroberto * Update context to reflect the concatenation of another buffer full
497258945Sroberto * of bytes.
498258945Sroberto */
499258945Srobertovoid
500258945Srobertoisc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
501258945Sroberto		   unsigned int len)
502258945Sroberto{
503258945Sroberto	isc_sha512_update(&ctx->sha512ctx, buf, len);
504258945Sroberto}
505258945Sroberto
506258945Sroberto/*
507258945Sroberto * Compute signature - finalize SHA512 operation and reapply SHA512.
508258945Sroberto */
509258945Srobertovoid
510258945Srobertoisc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
511258945Sroberto	unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
512258945Sroberto	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
513258945Sroberto	unsigned int i;
514258945Sroberto
515258945Sroberto	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
516258945Sroberto	isc_sha512_final(newdigest, &ctx->sha512ctx);
517258945Sroberto
518258945Sroberto	memset(opad, OPAD, sizeof(opad));
519258945Sroberto	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
520258945Sroberto		opad[i] ^= ctx->key[i];
521258945Sroberto
522258945Sroberto	isc_sha512_init(&ctx->sha512ctx);
523258945Sroberto	isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
524258945Sroberto	isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
525258945Sroberto	isc_sha512_final(newdigest, &ctx->sha512ctx);
526258945Sroberto	memcpy(digest, newdigest, len);
527258945Sroberto	memset(newdigest, 0, sizeof(newdigest));
528258945Sroberto}
529280849Scy#endif /* !ISC_PLATFORM_OPENSSLHASH */
530258945Sroberto
531258945Sroberto/*
532280849Scy * Verify signature - finalize SHA1 operation and reapply SHA1, then
533280849Scy * compare to the supplied digest.
534280849Scy */
535280849Scyisc_boolean_t
536280849Scyisc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
537280849Scy	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
538280849Scy
539280849Scy	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
540280849Scy	isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
541298695Sdelphij	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
542280849Scy}
543280849Scy
544280849Scy/*
545280849Scy * Verify signature - finalize SHA224 operation and reapply SHA224, then
546280849Scy * compare to the supplied digest.
547280849Scy */
548280849Scyisc_boolean_t
549280849Scyisc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
550280849Scy	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
551280849Scy
552280849Scy	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
553280849Scy	isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
554298695Sdelphij	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
555280849Scy}
556280849Scy
557280849Scy/*
558280849Scy * Verify signature - finalize SHA256 operation and reapply SHA256, then
559280849Scy * compare to the supplied digest.
560280849Scy */
561280849Scyisc_boolean_t
562280849Scyisc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
563280849Scy	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
564280849Scy
565280849Scy	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
566280849Scy	isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
567298695Sdelphij	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
568280849Scy}
569280849Scy
570280849Scy/*
571280849Scy * Verify signature - finalize SHA384 operation and reapply SHA384, then
572280849Scy * compare to the supplied digest.
573280849Scy */
574280849Scyisc_boolean_t
575280849Scyisc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
576280849Scy	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
577280849Scy
578280849Scy	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
579280849Scy	isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
580298695Sdelphij	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
581280849Scy}
582280849Scy
583280849Scy/*
584258945Sroberto * Verify signature - finalize SHA512 operation and reapply SHA512, then
585258945Sroberto * compare to the supplied digest.
586258945Sroberto */
587258945Srobertoisc_boolean_t
588258945Srobertoisc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
589258945Sroberto	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
590258945Sroberto
591258945Sroberto	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
592258945Sroberto	isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
593298695Sdelphij	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
594258945Sroberto}
595