xref: /openbsd/usr.bin/dig/lib/isc/hmacsha.c (revision 1fb015a8)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: hmacsha.c,v 1.7 2020/09/14 08:40:44 florian Exp $ */
18 
19 /*
20  * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
21  * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
22  * draft-ietf-dnsext-tsig-sha-01.txt.
23  */
24 
25 #include <string.h>
26 
27 #include <isc/hmacsha.h>
28 #include <isc/sha1.h>
29 #include <isc/sha2.h>
30 #include <isc/util.h>
31 
32 void
isc_hmacsha1_init(isc_hmacsha1_t * ctx,const unsigned char * key,unsigned int len)33 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
34 		  unsigned int len)
35 {
36 	ctx->ctx = HMAC_CTX_new();
37 	RUNTIME_CHECK(ctx->ctx != NULL);
38 	RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
39 				   (int) len, EVP_sha1(), NULL) == 1);
40 }
41 
42 void
isc_hmacsha1_invalidate(isc_hmacsha1_t * ctx)43 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
44 	if (ctx->ctx == NULL)
45 		return;
46 	HMAC_CTX_free(ctx->ctx);
47 	ctx->ctx = NULL;
48 }
49 
50 void
isc_hmacsha1_update(isc_hmacsha1_t * ctx,const unsigned char * buf,unsigned int len)51 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
52 		   unsigned int len)
53 {
54 	RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
55 }
56 
57 void
isc_hmacsha1_sign(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)58 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
59 	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
60 
61 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
62 
63 	RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
64 	HMAC_CTX_free(ctx->ctx);
65 	ctx->ctx = NULL;
66 	memmove(digest, newdigest, len);
67 	explicit_bzero(newdigest, sizeof(newdigest));
68 }
69 
70 void
isc_hmacsha224_init(isc_hmacsha224_t * ctx,const unsigned char * key,unsigned int len)71 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
72 		    unsigned int len)
73 {
74 	ctx->ctx = HMAC_CTX_new();
75 	RUNTIME_CHECK(ctx->ctx != NULL);
76 	RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
77 				   (int) len, EVP_sha224(), NULL) == 1);
78 }
79 
80 void
isc_hmacsha224_invalidate(isc_hmacsha224_t * ctx)81 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
82 	if (ctx->ctx == NULL)
83 		return;
84 	HMAC_CTX_free(ctx->ctx);
85 	ctx->ctx = NULL;
86 }
87 
88 void
isc_hmacsha224_update(isc_hmacsha224_t * ctx,const unsigned char * buf,unsigned int len)89 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
90 		   unsigned int len)
91 {
92 	RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
93 }
94 
95 void
isc_hmacsha224_sign(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)96 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
97 	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
98 
99 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
100 
101 	RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
102 	HMAC_CTX_free(ctx->ctx);
103 	ctx->ctx = NULL;
104 	memmove(digest, newdigest, len);
105 	explicit_bzero(newdigest, sizeof(newdigest));
106 }
107 
108 void
isc_hmacsha256_init(isc_hmacsha256_t * ctx,const unsigned char * key,unsigned int len)109 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
110 		    unsigned int len)
111 {
112 	ctx->ctx = HMAC_CTX_new();
113 	RUNTIME_CHECK(ctx->ctx != NULL);
114 	RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
115 				   (int) len, EVP_sha256(), NULL) == 1);
116 }
117 
118 void
isc_hmacsha256_invalidate(isc_hmacsha256_t * ctx)119 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
120 	if (ctx->ctx == NULL)
121 		return;
122 	HMAC_CTX_free(ctx->ctx);
123 	ctx->ctx = NULL;
124 }
125 
126 void
isc_hmacsha256_update(isc_hmacsha256_t * ctx,const unsigned char * buf,unsigned int len)127 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
128 		   unsigned int len)
129 {
130 	RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
131 }
132 
133 void
isc_hmacsha256_sign(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)134 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
135 	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
136 
137 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
138 
139 	RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
140 	HMAC_CTX_free(ctx->ctx);
141 	ctx->ctx = NULL;
142 	memmove(digest, newdigest, len);
143 	explicit_bzero(newdigest, sizeof(newdigest));
144 }
145 
146 void
isc_hmacsha384_init(isc_hmacsha384_t * ctx,const unsigned char * key,unsigned int len)147 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
148 		    unsigned int len)
149 {
150 	ctx->ctx = HMAC_CTX_new();
151 	RUNTIME_CHECK(ctx->ctx != NULL);
152 	RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
153 				   (int) len, EVP_sha384(), NULL) == 1);
154 }
155 
156 void
isc_hmacsha384_invalidate(isc_hmacsha384_t * ctx)157 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
158 	if (ctx->ctx == NULL)
159 		return;
160 	HMAC_CTX_free(ctx->ctx);
161 	ctx->ctx = NULL;
162 }
163 
164 void
isc_hmacsha384_update(isc_hmacsha384_t * ctx,const unsigned char * buf,unsigned int len)165 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
166 		   unsigned int len)
167 {
168 	RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
169 }
170 
171 void
isc_hmacsha384_sign(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)172 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
173 	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
174 
175 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
176 
177 	RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
178 	HMAC_CTX_free(ctx->ctx);
179 	ctx->ctx = NULL;
180 	memmove(digest, newdigest, len);
181 	explicit_bzero(newdigest, sizeof(newdigest));
182 }
183 
184 void
isc_hmacsha512_init(isc_hmacsha512_t * ctx,const unsigned char * key,unsigned int len)185 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
186 		    unsigned int len)
187 {
188 	ctx->ctx = HMAC_CTX_new();
189 	RUNTIME_CHECK(ctx->ctx != NULL);
190 	RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
191 				   (int) len, EVP_sha512(), NULL) == 1);
192 }
193 
194 void
isc_hmacsha512_invalidate(isc_hmacsha512_t * ctx)195 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
196 	if (ctx->ctx == NULL)
197 		return;
198 	HMAC_CTX_free(ctx->ctx);
199 	ctx->ctx = NULL;
200 }
201 
202 void
isc_hmacsha512_update(isc_hmacsha512_t * ctx,const unsigned char * buf,unsigned int len)203 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
204 		   unsigned int len)
205 {
206 	RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
207 }
208 
209 void
isc_hmacsha512_sign(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)210 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
211 	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
212 
213 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
214 
215 	RUNTIME_CHECK(HMAC_Final(ctx->ctx, newdigest, NULL) == 1);
216 	HMAC_CTX_free(ctx->ctx);
217 	ctx->ctx = NULL;
218 	memmove(digest, newdigest, len);
219 	explicit_bzero(newdigest, sizeof(newdigest));
220 }
221 
222 /*
223  * Verify signature - finalize SHA1 operation and reapply SHA1, then
224  * compare to the supplied digest.
225  */
226 int
isc_hmacsha1_verify(isc_hmacsha1_t * ctx,unsigned char * digest,size_t len)227 isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
228 	unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
229 
230 	REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
231 	isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
232 	return (timingsafe_bcmp(digest, newdigest, len) == 0);
233 }
234 
235 /*
236  * Verify signature - finalize SHA224 operation and reapply SHA224, then
237  * compare to the supplied digest.
238  */
239 int
isc_hmacsha224_verify(isc_hmacsha224_t * ctx,unsigned char * digest,size_t len)240 isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
241 	unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
242 
243 	REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
244 	isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
245 	return (timingsafe_bcmp(digest, newdigest, len) == 0);
246 }
247 
248 /*
249  * Verify signature - finalize SHA256 operation and reapply SHA256, then
250  * compare to the supplied digest.
251  */
252 int
isc_hmacsha256_verify(isc_hmacsha256_t * ctx,unsigned char * digest,size_t len)253 isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
254 	unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
255 
256 	REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
257 	isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
258 	return (timingsafe_bcmp(digest, newdigest, len) == 0);
259 }
260 
261 /*
262  * Verify signature - finalize SHA384 operation and reapply SHA384, then
263  * compare to the supplied digest.
264  */
265 int
isc_hmacsha384_verify(isc_hmacsha384_t * ctx,unsigned char * digest,size_t len)266 isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
267 	unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
268 
269 	REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
270 	isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
271 	return (timingsafe_bcmp(digest, newdigest, len) == 0);
272 }
273 
274 /*
275  * Verify signature - finalize SHA512 operation and reapply SHA512, then
276  * compare to the supplied digest.
277  */
278 int
isc_hmacsha512_verify(isc_hmacsha512_t * ctx,unsigned char * digest,size_t len)279 isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
280 	unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
281 
282 	REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
283 	isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
284 	return (timingsafe_bcmp(digest, newdigest, len) == 0);
285 }
286