bind - Removed version tag from contrib directory and updated README.DRAGONFLY.
[dragonfly.git] / contrib / bind / lib / isc / hmacsha.c
1 /*
2  * Copyright (C) 2005-2007  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.8 2007/08/27 03:27:53 marka 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 "config.h"
26
27 #include <isc/assertions.h>
28 #include <isc/hmacsha.h>
29 #include <isc/sha1.h>
30 #include <isc/sha2.h>
31 #include <isc/string.h>
32 #include <isc/types.h>
33 #include <isc/util.h>
34
35 #define IPAD 0x36
36 #define OPAD 0x5C
37
38 /*
39  * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
40  */
41 void
42 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
43                   unsigned int len)
44 {
45         unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
46         unsigned int i;
47
48         memset(ctx->key, 0, sizeof(ctx->key));
49         if (len > sizeof(ctx->key)) {
50                 isc_sha1_t sha1ctx;
51                 isc_sha1_init(&sha1ctx);
52                 isc_sha1_update(&sha1ctx, key, len);
53                 isc_sha1_final(&sha1ctx, ctx->key);
54         } else
55                 memcpy(ctx->key, key, len);
56
57         isc_sha1_init(&ctx->sha1ctx);
58         memset(ipad, IPAD, sizeof(ipad));
59         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
60                 ipad[i] ^= ctx->key[i];
61         isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
62 }
63
64 void
65 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
66         isc_sha1_invalidate(&ctx->sha1ctx);
67         memset(ctx->key, 0, sizeof(ctx->key));
68         memset(ctx, 0, sizeof(ctx));
69 }
70
71 /*
72  * Update context to reflect the concatenation of another buffer full
73  * of bytes.
74  */
75 void
76 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
77                    unsigned int len)
78 {
79         isc_sha1_update(&ctx->sha1ctx, buf, len);
80 }
81
82 /*
83  * Compute signature - finalize SHA1 operation and reapply SHA1.
84  */
85 void
86 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
87         unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
88         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
89         unsigned int i;
90
91         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
92         isc_sha1_final(&ctx->sha1ctx, newdigest);
93
94         memset(opad, OPAD, sizeof(opad));
95         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
96                 opad[i] ^= ctx->key[i];
97
98         isc_sha1_init(&ctx->sha1ctx);
99         isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
100         isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
101         isc_sha1_final(&ctx->sha1ctx, newdigest);
102         isc_hmacsha1_invalidate(ctx);
103         memcpy(digest, newdigest, len);
104         memset(newdigest, 0, sizeof(newdigest));
105 }
106
107 /*
108  * Verify signature - finalize SHA1 operation and reapply SHA1, then
109  * compare to the supplied digest.
110  */
111 isc_boolean_t
112 isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
113         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
114
115         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
116         isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
117         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
118 }
119
120 /*
121  * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
122  */
123 void
124 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
125                     unsigned int len)
126 {
127         unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
128         unsigned int i;
129
130         memset(ctx->key, 0, sizeof(ctx->key));
131         if (len > sizeof(ctx->key)) {
132                 isc_sha224_t sha224ctx;
133                 isc_sha224_init(&sha224ctx);
134                 isc_sha224_update(&sha224ctx, key, len);
135                 isc_sha224_final(ctx->key, &sha224ctx);
136         } else
137                 memcpy(ctx->key, key, len);
138
139         isc_sha224_init(&ctx->sha224ctx);
140         memset(ipad, IPAD, sizeof(ipad));
141         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
142                 ipad[i] ^= ctx->key[i];
143         isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
144 }
145
146 void
147 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
148         memset(ctx->key, 0, sizeof(ctx->key));
149         memset(ctx, 0, sizeof(ctx));
150 }
151
152 /*
153  * Update context to reflect the concatenation of another buffer full
154  * of bytes.
155  */
156 void
157 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
158                    unsigned int len)
159 {
160         isc_sha224_update(&ctx->sha224ctx, buf, len);
161 }
162
163 /*
164  * Compute signature - finalize SHA224 operation and reapply SHA224.
165  */
166 void
167 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
168         unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
169         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
170         unsigned int i;
171
172         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
173         isc_sha224_final(newdigest, &ctx->sha224ctx);
174
175         memset(opad, OPAD, sizeof(opad));
176         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
177                 opad[i] ^= ctx->key[i];
178
179         isc_sha224_init(&ctx->sha224ctx);
180         isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
181         isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
182         isc_sha224_final(newdigest, &ctx->sha224ctx);
183         memcpy(digest, newdigest, len);
184         memset(newdigest, 0, sizeof(newdigest));
185 }
186
187 /*
188  * Verify signature - finalize SHA224 operation and reapply SHA224, then
189  * compare to the supplied digest.
190  */
191 isc_boolean_t
192 isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
193         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
194
195         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
196         isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
197         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
198 }
199
200 /*
201  * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
202  */
203 void
204 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
205                     unsigned int len)
206 {
207         unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
208         unsigned int i;
209
210         memset(ctx->key, 0, sizeof(ctx->key));
211         if (len > sizeof(ctx->key)) {
212                 isc_sha256_t sha256ctx;
213                 isc_sha256_init(&sha256ctx);
214                 isc_sha256_update(&sha256ctx, key, len);
215                 isc_sha256_final(ctx->key, &sha256ctx);
216         } else
217                 memcpy(ctx->key, key, len);
218
219         isc_sha256_init(&ctx->sha256ctx);
220         memset(ipad, IPAD, sizeof(ipad));
221         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
222                 ipad[i] ^= ctx->key[i];
223         isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
224 }
225
226 void
227 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
228         memset(ctx->key, 0, sizeof(ctx->key));
229         memset(ctx, 0, sizeof(ctx));
230 }
231
232 /*
233  * Update context to reflect the concatenation of another buffer full
234  * of bytes.
235  */
236 void
237 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
238                    unsigned int len)
239 {
240         isc_sha256_update(&ctx->sha256ctx, buf, len);
241 }
242
243 /*
244  * Compute signature - finalize SHA256 operation and reapply SHA256.
245  */
246 void
247 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
248         unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
249         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
250         unsigned int i;
251
252         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
253         isc_sha256_final(newdigest, &ctx->sha256ctx);
254
255         memset(opad, OPAD, sizeof(opad));
256         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
257                 opad[i] ^= ctx->key[i];
258
259         isc_sha256_init(&ctx->sha256ctx);
260         isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
261         isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
262         isc_sha256_final(newdigest, &ctx->sha256ctx);
263         memcpy(digest, newdigest, len);
264         memset(newdigest, 0, sizeof(newdigest));
265 }
266
267 /*
268  * Verify signature - finalize SHA256 operation and reapply SHA256, then
269  * compare to the supplied digest.
270  */
271 isc_boolean_t
272 isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
273         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
274
275         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
276         isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
277         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
278 }
279
280 /*
281  * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
282  */
283 void
284 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
285                     unsigned int len)
286 {
287         unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
288         unsigned int i;
289
290         memset(ctx->key, 0, sizeof(ctx->key));
291         if (len > sizeof(ctx->key)) {
292                 isc_sha384_t sha384ctx;
293                 isc_sha384_init(&sha384ctx);
294                 isc_sha384_update(&sha384ctx, key, len);
295                 isc_sha384_final(ctx->key, &sha384ctx);
296         } else
297                 memcpy(ctx->key, key, len);
298
299         isc_sha384_init(&ctx->sha384ctx);
300         memset(ipad, IPAD, sizeof(ipad));
301         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
302                 ipad[i] ^= ctx->key[i];
303         isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
304 }
305
306 void
307 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
308         memset(ctx->key, 0, sizeof(ctx->key));
309         memset(ctx, 0, sizeof(ctx));
310 }
311
312 /*
313  * Update context to reflect the concatenation of another buffer full
314  * of bytes.
315  */
316 void
317 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
318                    unsigned int len)
319 {
320         isc_sha384_update(&ctx->sha384ctx, buf, len);
321 }
322
323 /*
324  * Compute signature - finalize SHA384 operation and reapply SHA384.
325  */
326 void
327 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
328         unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
329         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
330         unsigned int i;
331
332         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
333         isc_sha384_final(newdigest, &ctx->sha384ctx);
334
335         memset(opad, OPAD, sizeof(opad));
336         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
337                 opad[i] ^= ctx->key[i];
338
339         isc_sha384_init(&ctx->sha384ctx);
340         isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
341         isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
342         isc_sha384_final(newdigest, &ctx->sha384ctx);
343         memcpy(digest, newdigest, len);
344         memset(newdigest, 0, sizeof(newdigest));
345 }
346
347 /*
348  * Verify signature - finalize SHA384 operation and reapply SHA384, then
349  * compare to the supplied digest.
350  */
351 isc_boolean_t
352 isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
353         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
354
355         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
356         isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
357         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
358 }
359
360 /*
361  * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
362  */
363 void
364 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
365                     unsigned int len)
366 {
367         unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
368         unsigned int i;
369
370         memset(ctx->key, 0, sizeof(ctx->key));
371         if (len > sizeof(ctx->key)) {
372                 isc_sha512_t sha512ctx;
373                 isc_sha512_init(&sha512ctx);
374                 isc_sha512_update(&sha512ctx, key, len);
375                 isc_sha512_final(ctx->key, &sha512ctx);
376         } else
377                 memcpy(ctx->key, key, len);
378
379         isc_sha512_init(&ctx->sha512ctx);
380         memset(ipad, IPAD, sizeof(ipad));
381         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
382                 ipad[i] ^= ctx->key[i];
383         isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
384 }
385
386 void
387 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
388         memset(ctx->key, 0, sizeof(ctx->key));
389         memset(ctx, 0, sizeof(ctx));
390 }
391
392 /*
393  * Update context to reflect the concatenation of another buffer full
394  * of bytes.
395  */
396 void
397 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
398                    unsigned int len)
399 {
400         isc_sha512_update(&ctx->sha512ctx, buf, len);
401 }
402
403 /*
404  * Compute signature - finalize SHA512 operation and reapply SHA512.
405  */
406 void
407 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
408         unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
409         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
410         unsigned int i;
411
412         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
413         isc_sha512_final(newdigest, &ctx->sha512ctx);
414
415         memset(opad, OPAD, sizeof(opad));
416         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
417                 opad[i] ^= ctx->key[i];
418
419         isc_sha512_init(&ctx->sha512ctx);
420         isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
421         isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
422         isc_sha512_final(newdigest, &ctx->sha512ctx);
423         memcpy(digest, newdigest, len);
424         memset(newdigest, 0, sizeof(newdigest));
425 }
426
427 /*
428  * Verify signature - finalize SHA512 operation and reapply SHA512, then
429  * compare to the supplied digest.
430  */
431 isc_boolean_t
432 isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
433         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
434
435         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
436         isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
437         return (ISC_TF(memcmp(digest, newdigest, len) == 0));
438 }