1/*	$NetBSD: hmacsha.c,v 1.6 2020/05/25 20:47:20 christos Exp $	*/
2
3/*
4 * Copyright (C) 2005-2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/* Id */
20
21/*
22 * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
23 * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
24 * draft-ietf-dnsext-tsig-sha-01.txt.
25 */
26
27#include "config.h"
28
29#include <isc/assertions.h>
30#include <isc/hmacsha.h>
31#include <isc/platform.h>
32#include <isc/sha1.h>
33#include <isc/sha2.h>
34#include <isc/string.h>
35#include <isc/types.h>
36#include <isc/util.h>
37
38#ifdef ISC_PLATFORM_OPENSSLHASH
39
40void
41isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
42		  unsigned int len)
43{
44	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
45}
46
47void
48isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
49	HMAC_CTX_cleanup(ctx);
50}
51
52void
53isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
54		   unsigned int len)
55{
56	HMAC_Update(ctx, buf, (int) len);
57}
58
59void
60isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
61	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
62
63	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
64
65	HMAC_Final(ctx, newdigest, NULL);
66	HMAC_CTX_cleanup(ctx);
67	memcpy(digest, newdigest, len);
68	memset(newdigest, 0, sizeof(newdigest));
69}
70
71void
72isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
73		    unsigned int len)
74{
75	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
76}
77
78void
79isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
80	HMAC_CTX_cleanup(ctx);
81}
82
83void
84isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
85		   unsigned int len)
86{
87	HMAC_Update(ctx, buf, (int) len);
88}
89
90void
91isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
92	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
93
94	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
95
96	HMAC_Final(ctx, newdigest, NULL);
97	HMAC_CTX_cleanup(ctx);
98	memcpy(digest, newdigest, len);
99	memset(newdigest, 0, sizeof(newdigest));
100}
101
102void
103isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
104		    unsigned int len)
105{
106	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
107}
108
109void
110isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
111	HMAC_CTX_cleanup(ctx);
112}
113
114void
115isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
116		   unsigned int len)
117{
118	HMAC_Update(ctx, buf, (int) len);
119}
120
121void
122isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
123	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
124
125	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
126
127	HMAC_Final(ctx, newdigest, NULL);
128	HMAC_CTX_cleanup(ctx);
129	memcpy(digest, newdigest, len);
130	memset(newdigest, 0, sizeof(newdigest));
131}
132
133void
134isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
135		    unsigned int len)
136{
137	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
138}
139
140void
141isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
142	HMAC_CTX_cleanup(ctx);
143}
144
145void
146isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
147		   unsigned int len)
148{
149	HMAC_Update(ctx, buf, (int) len);
150}
151
152void
153isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
154	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
155
156	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
157
158	HMAC_Final(ctx, newdigest, NULL);
159	HMAC_CTX_cleanup(ctx);
160	memcpy(digest, newdigest, len);
161	memset(newdigest, 0, sizeof(newdigest));
162}
163
164void
165isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
166		    unsigned int len)
167{
168	HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
169}
170
171void
172isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
173	HMAC_CTX_cleanup(ctx);
174}
175
176void
177isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
178		   unsigned int len)
179{
180	HMAC_Update(ctx, buf, (int) len);
181}
182
183void
184isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
185	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
186
187	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
188
189	HMAC_Final(ctx, newdigest, NULL);
190	HMAC_CTX_cleanup(ctx);
191	memcpy(digest, newdigest, len);
192	memset(newdigest, 0, sizeof(newdigest));
193}
194
195#else
196
197#define IPAD 0x36
198#define OPAD 0x5C
199
200/*
201 * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
202 */
203void
204isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
205		  unsigned int len)
206{
207	unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
208	unsigned int i;
209
210	memset(ctx->key, 0, sizeof(ctx->key));
211	if (len > sizeof(ctx->key)) {
212		isc_sha1_t sha1ctx;
213		isc_sha1_init(&sha1ctx);
214		isc_sha1_update(&sha1ctx, key, len);
215		isc_sha1_final(&sha1ctx, ctx->key);
216	} else
217		memcpy(ctx->key, key, len);
218
219	isc_sha1_init(&ctx->sha1ctx);
220	memset(ipad, IPAD, sizeof(ipad));
221	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
222		ipad[i] ^= ctx->key[i];
223	isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
224}
225
226void
227isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
228	isc_sha1_invalidate(&ctx->sha1ctx);
229	memset(ctx, 0, sizeof(*ctx));
230}
231
232/*
233 * Update context to reflect the concatenation of another buffer full
234 * of bytes.
235 */
236void
237isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
238		   unsigned int len)
239{
240	isc_sha1_update(&ctx->sha1ctx, buf, len);
241}
242
243/*
244 * Compute signature - finalize SHA1 operation and reapply SHA1.
245 */
246void
247isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
248	unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
249	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
250	unsigned int i;
251
252	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
253	isc_sha1_final(&ctx->sha1ctx, newdigest);
254
255	memset(opad, OPAD, sizeof(opad));
256	for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
257		opad[i] ^= ctx->key[i];
258
259	isc_sha1_init(&ctx->sha1ctx);
260	isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
261	isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
262	isc_sha1_final(&ctx->sha1ctx, newdigest);
263	isc_hmacsha1_invalidate(ctx);
264	memcpy(digest, newdigest, len);
265	memset(newdigest, 0, sizeof(newdigest));
266}
267
268/*
269 * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
270 */
271void
272isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
273		    unsigned int len)
274{
275	unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
276	unsigned int i;
277
278	memset(ctx->key, 0, sizeof(ctx->key));
279	if (len > sizeof(ctx->key)) {
280		isc_sha224_t sha224ctx;
281		isc_sha224_init(&sha224ctx);
282		isc_sha224_update(&sha224ctx, key, len);
283		isc_sha224_final(ctx->key, &sha224ctx);
284	} else
285		memcpy(ctx->key, key, len);
286
287	isc_sha224_init(&ctx->sha224ctx);
288	memset(ipad, IPAD, sizeof(ipad));
289	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
290		ipad[i] ^= ctx->key[i];
291	isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
292}
293
294void
295isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
296	memset(ctx, 0, sizeof(*ctx));
297}
298
299/*
300 * Update context to reflect the concatenation of another buffer full
301 * of bytes.
302 */
303void
304isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
305		   unsigned int len)
306{
307	isc_sha224_update(&ctx->sha224ctx, buf, len);
308}
309
310/*
311 * Compute signature - finalize SHA224 operation and reapply SHA224.
312 */
313void
314isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
315	unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
316	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
317	unsigned int i;
318
319	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
320	isc_sha224_final(newdigest, &ctx->sha224ctx);
321
322	memset(opad, OPAD, sizeof(opad));
323	for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
324		opad[i] ^= ctx->key[i];
325
326	isc_sha224_init(&ctx->sha224ctx);
327	isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
328	isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
329	isc_sha224_final(newdigest, &ctx->sha224ctx);
330	memcpy(digest, newdigest, len);
331	memset(newdigest, 0, sizeof(newdigest));
332}
333
334/*
335 * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
336 */
337void
338isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
339		    unsigned int len)
340{
341	unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
342	unsigned int i;
343
344	memset(ctx->key, 0, sizeof(ctx->key));
345	if (len > sizeof(ctx->key)) {
346		isc_sha256_t sha256ctx;
347		isc_sha256_init(&sha256ctx);
348		isc_sha256_update(&sha256ctx, key, len);
349		isc_sha256_final(ctx->key, &sha256ctx);
350	} else
351		memcpy(ctx->key, key, len);
352
353	isc_sha256_init(&ctx->sha256ctx);
354	memset(ipad, IPAD, sizeof(ipad));
355	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
356		ipad[i] ^= ctx->key[i];
357	isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
358}
359
360void
361isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
362	memset(ctx, 0, sizeof(*ctx));
363}
364
365/*
366 * Update context to reflect the concatenation of another buffer full
367 * of bytes.
368 */
369void
370isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
371		   unsigned int len)
372{
373	isc_sha256_update(&ctx->sha256ctx, buf, len);
374}
375
376/*
377 * Compute signature - finalize SHA256 operation and reapply SHA256.
378 */
379void
380isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
381	unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
382	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
383	unsigned int i;
384
385	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
386	isc_sha256_final(newdigest, &ctx->sha256ctx);
387
388	memset(opad, OPAD, sizeof(opad));
389	for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
390		opad[i] ^= ctx->key[i];
391
392	isc_sha256_init(&ctx->sha256ctx);
393	isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
394	isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
395	isc_sha256_final(newdigest, &ctx->sha256ctx);
396	memcpy(digest, newdigest, len);
397	memset(newdigest, 0, sizeof(newdigest));
398}
399
400/*
401 * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
402 */
403void
404isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
405		    unsigned int len)
406{
407	unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
408	unsigned int i;
409
410	memset(ctx->key, 0, sizeof(ctx->key));
411	if (len > sizeof(ctx->key)) {
412		isc_sha384_t sha384ctx;
413		isc_sha384_init(&sha384ctx);
414		isc_sha384_update(&sha384ctx, key, len);
415		isc_sha384_final(ctx->key, &sha384ctx);
416	} else
417		memcpy(ctx->key, key, len);
418
419	isc_sha384_init(&ctx->sha384ctx);
420	memset(ipad, IPAD, sizeof(ipad));
421	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
422		ipad[i] ^= ctx->key[i];
423	isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
424}
425
426void
427isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
428	memset(ctx, 0, sizeof(*ctx));
429}
430
431/*
432 * Update context to reflect the concatenation of another buffer full
433 * of bytes.
434 */
435void
436isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
437		   unsigned int len)
438{
439	isc_sha384_update(&ctx->sha384ctx, buf, len);
440}
441
442/*
443 * Compute signature - finalize SHA384 operation and reapply SHA384.
444 */
445void
446isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
447	unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
448	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
449	unsigned int i;
450
451	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
452	isc_sha384_final(newdigest, &ctx->sha384ctx);
453
454	memset(opad, OPAD, sizeof(opad));
455	for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
456		opad[i] ^= ctx->key[i];
457
458	isc_sha384_init(&ctx->sha384ctx);
459	isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
460	isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
461	isc_sha384_final(newdigest, &ctx->sha384ctx);
462	memcpy(digest, newdigest, len);
463	memset(newdigest, 0, sizeof(newdigest));
464}
465
466/*
467 * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
468 */
469void
470isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
471		    unsigned int len)
472{
473	unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
474	unsigned int i;
475
476	memset(ctx->key, 0, sizeof(ctx->key));
477	if (len > sizeof(ctx->key)) {
478		isc_sha512_t sha512ctx;
479		isc_sha512_init(&sha512ctx);
480		isc_sha512_update(&sha512ctx, key, len);
481		isc_sha512_final(ctx->key, &sha512ctx);
482	} else
483		memcpy(ctx->key, key, len);
484
485	isc_sha512_init(&ctx->sha512ctx);
486	memset(ipad, IPAD, sizeof(ipad));
487	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
488		ipad[i] ^= ctx->key[i];
489	isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
490}
491
492void
493isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
494	memset(ctx, 0, sizeof(*ctx));
495}
496
497/*
498 * Update context to reflect the concatenation of another buffer full
499 * of bytes.
500 */
501void
502isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
503		   unsigned int len)
504{
505	isc_sha512_update(&ctx->sha512ctx, buf, len);
506}
507
508/*
509 * Compute signature - finalize SHA512 operation and reapply SHA512.
510 */
511void
512isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
513	unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
514	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
515	unsigned int i;
516
517	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
518	isc_sha512_final(newdigest, &ctx->sha512ctx);
519
520	memset(opad, OPAD, sizeof(opad));
521	for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
522		opad[i] ^= ctx->key[i];
523
524	isc_sha512_init(&ctx->sha512ctx);
525	isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
526	isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
527	isc_sha512_final(newdigest, &ctx->sha512ctx);
528	memcpy(digest, newdigest, len);
529	memset(newdigest, 0, sizeof(newdigest));
530}
531#endif /* !ISC_PLATFORM_OPENSSLHASH */
532
533/*
534 * Verify signature - finalize SHA1 operation and reapply SHA1, then
535 * compare to the supplied digest.
536 */
537isc_boolean_t
538isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
539	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
540
541	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
542	isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
543	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
544}
545
546/*
547 * Verify signature - finalize SHA224 operation and reapply SHA224, then
548 * compare to the supplied digest.
549 */
550isc_boolean_t
551isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
552	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
553
554	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
555	isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
556	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
557}
558
559/*
560 * Verify signature - finalize SHA256 operation and reapply SHA256, then
561 * compare to the supplied digest.
562 */
563isc_boolean_t
564isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
565	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
566
567	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
568	isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
569	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
570}
571
572/*
573 * Verify signature - finalize SHA384 operation and reapply SHA384, then
574 * compare to the supplied digest.
575 */
576isc_boolean_t
577isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
578	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
579
580	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
581	isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
582	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
583}
584
585/*
586 * Verify signature - finalize SHA512 operation and reapply SHA512, then
587 * compare to the supplied digest.
588 */
589isc_boolean_t
590isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
591	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
592
593	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
594	isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
595	return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0));
596}
597