Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / lib / isc / hmacsha.c
blob8cca337d32cd2676689f184f2a09f1177aa9cab1
1 /* $NetBSD$ */
3 /*
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.
27 #include "config.h"
29 #include <isc/assertions.h>
30 #include <isc/hmacsha.h>
31 #include <isc/sha1.h>
32 #include <isc/sha2.h>
33 #include <isc/string.h>
34 #include <isc/types.h>
35 #include <isc/util.h>
37 #define IPAD 0x36
38 #define OPAD 0x5C
41 * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key.
43 void
44 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
45 unsigned int len)
47 unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
48 unsigned int i;
50 memset(ctx->key, 0, sizeof(ctx->key));
51 if (len > sizeof(ctx->key)) {
52 isc_sha1_t sha1ctx;
53 isc_sha1_init(&sha1ctx);
54 isc_sha1_update(&sha1ctx, key, len);
55 isc_sha1_final(&sha1ctx, ctx->key);
56 } else
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));
66 void
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
75 * of bytes.
77 void
78 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
79 unsigned int len)
81 isc_sha1_update(&ctx->sha1ctx, buf, len);
85 * Compute signature - finalize SHA1 operation and reapply SHA1.
87 void
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];
91 unsigned int i;
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.
113 isc_boolean_t
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.
125 void
126 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
127 unsigned int len)
129 unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
130 unsigned int i;
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);
138 } else
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));
148 void
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
156 * of bytes.
158 void
159 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
160 unsigned int len)
162 isc_sha224_update(&ctx->sha224ctx, buf, len);
166 * Compute signature - finalize SHA224 operation and reapply SHA224.
168 void
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];
172 unsigned int i;
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.
193 isc_boolean_t
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.
205 void
206 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
207 unsigned int len)
209 unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
210 unsigned int i;
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);
218 } else
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));
228 void
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
236 * of bytes.
238 void
239 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
240 unsigned int len)
242 isc_sha256_update(&ctx->sha256ctx, buf, len);
246 * Compute signature - finalize SHA256 operation and reapply SHA256.
248 void
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];
252 unsigned int i;
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.
273 isc_boolean_t
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.
285 void
286 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
287 unsigned int len)
289 unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
290 unsigned int i;
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);
298 } else
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));
308 void
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
316 * of bytes.
318 void
319 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
320 unsigned int len)
322 isc_sha384_update(&ctx->sha384ctx, buf, len);
326 * Compute signature - finalize SHA384 operation and reapply SHA384.
328 void
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];
332 unsigned int i;
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.
353 isc_boolean_t
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.
365 void
366 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
367 unsigned int len)
369 unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
370 unsigned int i;
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);
378 } else
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));
388 void
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
396 * of bytes.
398 void
399 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
400 unsigned int len)
402 isc_sha512_update(&ctx->sha512ctx, buf, len);
406 * Compute signature - finalize SHA512 operation and reapply SHA512.
408 void
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];
412 unsigned int i;
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.
433 isc_boolean_t
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));