4 * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC")
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.
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.
19 /* Id: hmacsha.c,v 1.8 2007/08/27 03:27:53 marka Exp */
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.
29 #include <isc/assertions.h>
30 #include <isc/hmacsha.h>
33 #include <isc/string.h>
34 #include <isc/types.h>
41 * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key.
44 isc_hmacsha1_init(isc_hmacsha1_t
*ctx
, const unsigned char *key
,
47 unsigned char ipad
[ISC_SHA1_BLOCK_LENGTH
];
50 memset(ctx
->key
, 0, sizeof(ctx
->key
));
51 if (len
> sizeof(ctx
->key
)) {
53 isc_sha1_init(&sha1ctx
);
54 isc_sha1_update(&sha1ctx
, key
, len
);
55 isc_sha1_final(&sha1ctx
, ctx
->key
);
57 memcpy(ctx
->key
, key
, len
);
59 isc_sha1_init(&ctx
->sha1ctx
);
60 memset(ipad
, IPAD
, sizeof(ipad
));
61 for (i
= 0; i
< ISC_SHA1_BLOCK_LENGTH
; i
++)
62 ipad
[i
] ^= ctx
->key
[i
];
63 isc_sha1_update(&ctx
->sha1ctx
, ipad
, sizeof(ipad
));
67 isc_hmacsha1_invalidate(isc_hmacsha1_t
*ctx
) {
68 isc_sha1_invalidate(&ctx
->sha1ctx
);
69 memset(ctx
->key
, 0, sizeof(ctx
->key
));
70 memset(ctx
, 0, sizeof(ctx
));
74 * Update context to reflect the concatenation of another buffer full
78 isc_hmacsha1_update(isc_hmacsha1_t
*ctx
, const unsigned char *buf
,
81 isc_sha1_update(&ctx
->sha1ctx
, buf
, len
);
85 * Compute signature - finalize SHA1 operation and reapply SHA1.
88 isc_hmacsha1_sign(isc_hmacsha1_t
*ctx
, unsigned char *digest
, size_t len
) {
89 unsigned char opad
[ISC_SHA1_BLOCK_LENGTH
];
90 unsigned char newdigest
[ISC_SHA1_DIGESTLENGTH
];
93 REQUIRE(len
<= ISC_SHA1_DIGESTLENGTH
);
94 isc_sha1_final(&ctx
->sha1ctx
, newdigest
);
96 memset(opad
, OPAD
, sizeof(opad
));
97 for (i
= 0; i
< ISC_SHA1_BLOCK_LENGTH
; i
++)
98 opad
[i
] ^= ctx
->key
[i
];
100 isc_sha1_init(&ctx
->sha1ctx
);
101 isc_sha1_update(&ctx
->sha1ctx
, opad
, sizeof(opad
));
102 isc_sha1_update(&ctx
->sha1ctx
, newdigest
, ISC_SHA1_DIGESTLENGTH
);
103 isc_sha1_final(&ctx
->sha1ctx
, newdigest
);
104 isc_hmacsha1_invalidate(ctx
);
105 memcpy(digest
, newdigest
, len
);
106 memset(newdigest
, 0, sizeof(newdigest
));
110 * Verify signature - finalize SHA1 operation and reapply SHA1, then
111 * compare to the supplied digest.
114 isc_hmacsha1_verify(isc_hmacsha1_t
*ctx
, unsigned char *digest
, size_t len
) {
115 unsigned char newdigest
[ISC_SHA1_DIGESTLENGTH
];
117 REQUIRE(len
<= ISC_SHA1_DIGESTLENGTH
);
118 isc_hmacsha1_sign(ctx
, newdigest
, ISC_SHA1_DIGESTLENGTH
);
119 return (ISC_TF(memcmp(digest
, newdigest
, len
) == 0));
123 * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key.
126 isc_hmacsha224_init(isc_hmacsha224_t
*ctx
, const unsigned char *key
,
129 unsigned char ipad
[ISC_SHA224_BLOCK_LENGTH
];
132 memset(ctx
->key
, 0, sizeof(ctx
->key
));
133 if (len
> sizeof(ctx
->key
)) {
134 isc_sha224_t sha224ctx
;
135 isc_sha224_init(&sha224ctx
);
136 isc_sha224_update(&sha224ctx
, key
, len
);
137 isc_sha224_final(ctx
->key
, &sha224ctx
);
139 memcpy(ctx
->key
, key
, len
);
141 isc_sha224_init(&ctx
->sha224ctx
);
142 memset(ipad
, IPAD
, sizeof(ipad
));
143 for (i
= 0; i
< ISC_SHA224_BLOCK_LENGTH
; i
++)
144 ipad
[i
] ^= ctx
->key
[i
];
145 isc_sha224_update(&ctx
->sha224ctx
, ipad
, sizeof(ipad
));
149 isc_hmacsha224_invalidate(isc_hmacsha224_t
*ctx
) {
150 memset(ctx
->key
, 0, sizeof(ctx
->key
));
151 memset(ctx
, 0, sizeof(ctx
));
155 * Update context to reflect the concatenation of another buffer full
159 isc_hmacsha224_update(isc_hmacsha224_t
*ctx
, const unsigned char *buf
,
162 isc_sha224_update(&ctx
->sha224ctx
, buf
, len
);
166 * Compute signature - finalize SHA224 operation and reapply SHA224.
169 isc_hmacsha224_sign(isc_hmacsha224_t
*ctx
, unsigned char *digest
, size_t len
) {
170 unsigned char opad
[ISC_SHA224_BLOCK_LENGTH
];
171 unsigned char newdigest
[ISC_SHA224_DIGESTLENGTH
];
174 REQUIRE(len
<= ISC_SHA224_DIGESTLENGTH
);
175 isc_sha224_final(newdigest
, &ctx
->sha224ctx
);
177 memset(opad
, OPAD
, sizeof(opad
));
178 for (i
= 0; i
< ISC_SHA224_BLOCK_LENGTH
; i
++)
179 opad
[i
] ^= ctx
->key
[i
];
181 isc_sha224_init(&ctx
->sha224ctx
);
182 isc_sha224_update(&ctx
->sha224ctx
, opad
, sizeof(opad
));
183 isc_sha224_update(&ctx
->sha224ctx
, newdigest
, ISC_SHA224_DIGESTLENGTH
);
184 isc_sha224_final(newdigest
, &ctx
->sha224ctx
);
185 memcpy(digest
, newdigest
, len
);
186 memset(newdigest
, 0, sizeof(newdigest
));
190 * Verify signature - finalize SHA224 operation and reapply SHA224, then
191 * compare to the supplied digest.
194 isc_hmacsha224_verify(isc_hmacsha224_t
*ctx
, unsigned char *digest
, size_t len
) {
195 unsigned char newdigest
[ISC_SHA224_DIGESTLENGTH
];
197 REQUIRE(len
<= ISC_SHA224_DIGESTLENGTH
);
198 isc_hmacsha224_sign(ctx
, newdigest
, ISC_SHA224_DIGESTLENGTH
);
199 return (ISC_TF(memcmp(digest
, newdigest
, len
) == 0));
203 * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key.
206 isc_hmacsha256_init(isc_hmacsha256_t
*ctx
, const unsigned char *key
,
209 unsigned char ipad
[ISC_SHA256_BLOCK_LENGTH
];
212 memset(ctx
->key
, 0, sizeof(ctx
->key
));
213 if (len
> sizeof(ctx
->key
)) {
214 isc_sha256_t sha256ctx
;
215 isc_sha256_init(&sha256ctx
);
216 isc_sha256_update(&sha256ctx
, key
, len
);
217 isc_sha256_final(ctx
->key
, &sha256ctx
);
219 memcpy(ctx
->key
, key
, len
);
221 isc_sha256_init(&ctx
->sha256ctx
);
222 memset(ipad
, IPAD
, sizeof(ipad
));
223 for (i
= 0; i
< ISC_SHA256_BLOCK_LENGTH
; i
++)
224 ipad
[i
] ^= ctx
->key
[i
];
225 isc_sha256_update(&ctx
->sha256ctx
, ipad
, sizeof(ipad
));
229 isc_hmacsha256_invalidate(isc_hmacsha256_t
*ctx
) {
230 memset(ctx
->key
, 0, sizeof(ctx
->key
));
231 memset(ctx
, 0, sizeof(ctx
));
235 * Update context to reflect the concatenation of another buffer full
239 isc_hmacsha256_update(isc_hmacsha256_t
*ctx
, const unsigned char *buf
,
242 isc_sha256_update(&ctx
->sha256ctx
, buf
, len
);
246 * Compute signature - finalize SHA256 operation and reapply SHA256.
249 isc_hmacsha256_sign(isc_hmacsha256_t
*ctx
, unsigned char *digest
, size_t len
) {
250 unsigned char opad
[ISC_SHA256_BLOCK_LENGTH
];
251 unsigned char newdigest
[ISC_SHA256_DIGESTLENGTH
];
254 REQUIRE(len
<= ISC_SHA256_DIGESTLENGTH
);
255 isc_sha256_final(newdigest
, &ctx
->sha256ctx
);
257 memset(opad
, OPAD
, sizeof(opad
));
258 for (i
= 0; i
< ISC_SHA256_BLOCK_LENGTH
; i
++)
259 opad
[i
] ^= ctx
->key
[i
];
261 isc_sha256_init(&ctx
->sha256ctx
);
262 isc_sha256_update(&ctx
->sha256ctx
, opad
, sizeof(opad
));
263 isc_sha256_update(&ctx
->sha256ctx
, newdigest
, ISC_SHA256_DIGESTLENGTH
);
264 isc_sha256_final(newdigest
, &ctx
->sha256ctx
);
265 memcpy(digest
, newdigest
, len
);
266 memset(newdigest
, 0, sizeof(newdigest
));
270 * Verify signature - finalize SHA256 operation and reapply SHA256, then
271 * compare to the supplied digest.
274 isc_hmacsha256_verify(isc_hmacsha256_t
*ctx
, unsigned char *digest
, size_t len
) {
275 unsigned char newdigest
[ISC_SHA256_DIGESTLENGTH
];
277 REQUIRE(len
<= ISC_SHA256_DIGESTLENGTH
);
278 isc_hmacsha256_sign(ctx
, newdigest
, ISC_SHA256_DIGESTLENGTH
);
279 return (ISC_TF(memcmp(digest
, newdigest
, len
) == 0));
283 * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key.
286 isc_hmacsha384_init(isc_hmacsha384_t
*ctx
, const unsigned char *key
,
289 unsigned char ipad
[ISC_SHA384_BLOCK_LENGTH
];
292 memset(ctx
->key
, 0, sizeof(ctx
->key
));
293 if (len
> sizeof(ctx
->key
)) {
294 isc_sha384_t sha384ctx
;
295 isc_sha384_init(&sha384ctx
);
296 isc_sha384_update(&sha384ctx
, key
, len
);
297 isc_sha384_final(ctx
->key
, &sha384ctx
);
299 memcpy(ctx
->key
, key
, len
);
301 isc_sha384_init(&ctx
->sha384ctx
);
302 memset(ipad
, IPAD
, sizeof(ipad
));
303 for (i
= 0; i
< ISC_SHA384_BLOCK_LENGTH
; i
++)
304 ipad
[i
] ^= ctx
->key
[i
];
305 isc_sha384_update(&ctx
->sha384ctx
, ipad
, sizeof(ipad
));
309 isc_hmacsha384_invalidate(isc_hmacsha384_t
*ctx
) {
310 memset(ctx
->key
, 0, sizeof(ctx
->key
));
311 memset(ctx
, 0, sizeof(ctx
));
315 * Update context to reflect the concatenation of another buffer full
319 isc_hmacsha384_update(isc_hmacsha384_t
*ctx
, const unsigned char *buf
,
322 isc_sha384_update(&ctx
->sha384ctx
, buf
, len
);
326 * Compute signature - finalize SHA384 operation and reapply SHA384.
329 isc_hmacsha384_sign(isc_hmacsha384_t
*ctx
, unsigned char *digest
, size_t len
) {
330 unsigned char opad
[ISC_SHA384_BLOCK_LENGTH
];
331 unsigned char newdigest
[ISC_SHA384_DIGESTLENGTH
];
334 REQUIRE(len
<= ISC_SHA384_DIGESTLENGTH
);
335 isc_sha384_final(newdigest
, &ctx
->sha384ctx
);
337 memset(opad
, OPAD
, sizeof(opad
));
338 for (i
= 0; i
< ISC_SHA384_BLOCK_LENGTH
; i
++)
339 opad
[i
] ^= ctx
->key
[i
];
341 isc_sha384_init(&ctx
->sha384ctx
);
342 isc_sha384_update(&ctx
->sha384ctx
, opad
, sizeof(opad
));
343 isc_sha384_update(&ctx
->sha384ctx
, newdigest
, ISC_SHA384_DIGESTLENGTH
);
344 isc_sha384_final(newdigest
, &ctx
->sha384ctx
);
345 memcpy(digest
, newdigest
, len
);
346 memset(newdigest
, 0, sizeof(newdigest
));
350 * Verify signature - finalize SHA384 operation and reapply SHA384, then
351 * compare to the supplied digest.
354 isc_hmacsha384_verify(isc_hmacsha384_t
*ctx
, unsigned char *digest
, size_t len
) {
355 unsigned char newdigest
[ISC_SHA384_DIGESTLENGTH
];
357 REQUIRE(len
<= ISC_SHA384_DIGESTLENGTH
);
358 isc_hmacsha384_sign(ctx
, newdigest
, ISC_SHA384_DIGESTLENGTH
);
359 return (ISC_TF(memcmp(digest
, newdigest
, len
) == 0));
363 * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key.
366 isc_hmacsha512_init(isc_hmacsha512_t
*ctx
, const unsigned char *key
,
369 unsigned char ipad
[ISC_SHA512_BLOCK_LENGTH
];
372 memset(ctx
->key
, 0, sizeof(ctx
->key
));
373 if (len
> sizeof(ctx
->key
)) {
374 isc_sha512_t sha512ctx
;
375 isc_sha512_init(&sha512ctx
);
376 isc_sha512_update(&sha512ctx
, key
, len
);
377 isc_sha512_final(ctx
->key
, &sha512ctx
);
379 memcpy(ctx
->key
, key
, len
);
381 isc_sha512_init(&ctx
->sha512ctx
);
382 memset(ipad
, IPAD
, sizeof(ipad
));
383 for (i
= 0; i
< ISC_SHA512_BLOCK_LENGTH
; i
++)
384 ipad
[i
] ^= ctx
->key
[i
];
385 isc_sha512_update(&ctx
->sha512ctx
, ipad
, sizeof(ipad
));
389 isc_hmacsha512_invalidate(isc_hmacsha512_t
*ctx
) {
390 memset(ctx
->key
, 0, sizeof(ctx
->key
));
391 memset(ctx
, 0, sizeof(ctx
));
395 * Update context to reflect the concatenation of another buffer full
399 isc_hmacsha512_update(isc_hmacsha512_t
*ctx
, const unsigned char *buf
,
402 isc_sha512_update(&ctx
->sha512ctx
, buf
, len
);
406 * Compute signature - finalize SHA512 operation and reapply SHA512.
409 isc_hmacsha512_sign(isc_hmacsha512_t
*ctx
, unsigned char *digest
, size_t len
) {
410 unsigned char opad
[ISC_SHA512_BLOCK_LENGTH
];
411 unsigned char newdigest
[ISC_SHA512_DIGESTLENGTH
];
414 REQUIRE(len
<= ISC_SHA512_DIGESTLENGTH
);
415 isc_sha512_final(newdigest
, &ctx
->sha512ctx
);
417 memset(opad
, OPAD
, sizeof(opad
));
418 for (i
= 0; i
< ISC_SHA512_BLOCK_LENGTH
; i
++)
419 opad
[i
] ^= ctx
->key
[i
];
421 isc_sha512_init(&ctx
->sha512ctx
);
422 isc_sha512_update(&ctx
->sha512ctx
, opad
, sizeof(opad
));
423 isc_sha512_update(&ctx
->sha512ctx
, newdigest
, ISC_SHA512_DIGESTLENGTH
);
424 isc_sha512_final(newdigest
, &ctx
->sha512ctx
);
425 memcpy(digest
, newdigest
, len
);
426 memset(newdigest
, 0, sizeof(newdigest
));
430 * Verify signature - finalize SHA512 operation and reapply SHA512, then
431 * compare to the supplied digest.
434 isc_hmacsha512_verify(isc_hmacsha512_t
*ctx
, unsigned char *digest
, size_t len
) {
435 unsigned char newdigest
[ISC_SHA512_DIGESTLENGTH
];
437 REQUIRE(len
<= ISC_SHA512_DIGESTLENGTH
);
438 isc_hmacsha512_sign(ctx
, newdigest
, ISC_SHA512_DIGESTLENGTH
);
439 return (ISC_TF(memcmp(digest
, newdigest
, len
) == 0));