Annotation of embedaddon/ntp/lib/isc/hmacsha.c, revision 1.1.1.1
1.1 misho 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>