00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <config.h>
00038
00039 #include <isc/buffer.h>
00040 #include <isc/hmacmd5.h>
00041 #include <isc/hmacsha.h>
00042 #include <isc/md5.h>
00043 #include <isc/sha1.h>
00044 #include <isc/mem.h>
00045 #include <isc/safe.h>
00046 #include <isc/string.h>
00047 #include <isc/util.h>
00048
00049 #include <dst/result.h>
00050
00051 #include "dst_internal.h"
00052 #include "dst_parse.h"
00053
00054 static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
00055
00056 struct dst_hmacmd5_key {
00057 unsigned char key[ISC_MD5_BLOCK_LENGTH];
00058 };
00059
00060 static isc_result_t
00061 getkeybits(dst_key_t *key, struct dst_private_element *element) {
00062
00063 if (element->length != 2)
00064 return (DST_R_INVALIDPRIVATEKEY);
00065
00066 key->key_bits = (element->data[0] << 8) + element->data[1];
00067
00068 return (ISC_R_SUCCESS);
00069 }
00070
00071 static isc_result_t
00072 hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
00073 isc_hmacmd5_t *hmacmd5ctx;
00074 dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
00075
00076 hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
00077 if (hmacmd5ctx == NULL)
00078 return (ISC_R_NOMEMORY);
00079 isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
00080 dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
00081 return (ISC_R_SUCCESS);
00082 }
00083
00084 static void
00085 hmacmd5_destroyctx(dst_context_t *dctx) {
00086 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
00087
00088 if (hmacmd5ctx != NULL) {
00089 isc_hmacmd5_invalidate(hmacmd5ctx);
00090 isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
00091 dctx->ctxdata.hmacmd5ctx = NULL;
00092 }
00093 }
00094
00095 static isc_result_t
00096 hmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
00097 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
00098
00099 isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
00100 return (ISC_R_SUCCESS);
00101 }
00102
00103 static isc_result_t
00104 hmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00105 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
00106 unsigned char *digest;
00107
00108 if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
00109 return (ISC_R_NOSPACE);
00110 digest = isc_buffer_used(sig);
00111 isc_hmacmd5_sign(hmacmd5ctx, digest);
00112 isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
00113
00114 return (ISC_R_SUCCESS);
00115 }
00116
00117 static isc_result_t
00118 hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
00119 isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
00120
00121 if (sig->length > ISC_MD5_DIGESTLENGTH)
00122 return (DST_R_VERIFYFAILURE);
00123
00124 if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
00125 return (ISC_R_SUCCESS);
00126 else
00127 return (DST_R_VERIFYFAILURE);
00128 }
00129
00130 static isc_boolean_t
00131 hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
00132 dst_hmacmd5_key_t *hkey1, *hkey2;
00133
00134 hkey1 = key1->keydata.hmacmd5;
00135 hkey2 = key2->keydata.hmacmd5;
00136
00137 if (hkey1 == NULL && hkey2 == NULL)
00138 return (ISC_TRUE);
00139 else if (hkey1 == NULL || hkey2 == NULL)
00140 return (ISC_FALSE);
00141
00142 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
00143 return (ISC_TRUE);
00144 else
00145 return (ISC_FALSE);
00146 }
00147
00148 static isc_result_t
00149 hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
00150 isc_buffer_t b;
00151 isc_result_t ret;
00152 unsigned int bytes;
00153 unsigned char data[ISC_SHA1_BLOCK_LENGTH];
00154
00155 UNUSED(callback);
00156
00157 bytes = (key->key_size + 7) / 8;
00158 if (bytes > ISC_SHA1_BLOCK_LENGTH) {
00159 bytes = ISC_SHA1_BLOCK_LENGTH;
00160 key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
00161 }
00162
00163 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
00164 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
00165
00166 if (ret != ISC_R_SUCCESS)
00167 return (ret);
00168
00169 isc_buffer_init(&b, data, bytes);
00170 isc_buffer_add(&b, bytes);
00171 ret = hmacmd5_fromdns(key, &b);
00172 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
00173
00174 return (ret);
00175 }
00176
00177 static isc_boolean_t
00178 hmacmd5_isprivate(const dst_key_t *key) {
00179 UNUSED(key);
00180 return (ISC_TRUE);
00181 }
00182
00183 static void
00184 hmacmd5_destroy(dst_key_t *key) {
00185 dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
00186
00187 memset(hkey, 0, sizeof(dst_hmacmd5_key_t));
00188 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t));
00189 key->keydata.hmacmd5 = NULL;
00190 }
00191
00192 static isc_result_t
00193 hmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
00194 dst_hmacmd5_key_t *hkey;
00195 unsigned int bytes;
00196
00197 REQUIRE(key->keydata.hmacmd5 != NULL);
00198
00199 hkey = key->keydata.hmacmd5;
00200
00201 bytes = (key->key_size + 7) / 8;
00202 if (isc_buffer_availablelength(data) < bytes)
00203 return (ISC_R_NOSPACE);
00204 isc_buffer_putmem(data, hkey->key, bytes);
00205
00206 return (ISC_R_SUCCESS);
00207 }
00208
00209 static isc_result_t
00210 hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
00211 dst_hmacmd5_key_t *hkey;
00212 int keylen;
00213 isc_region_t r;
00214 isc_md5_t md5ctx;
00215
00216 isc_buffer_remainingregion(data, &r);
00217 if (r.length == 0)
00218 return (ISC_R_SUCCESS);
00219
00220 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
00221 if (hkey == NULL)
00222 return (ISC_R_NOMEMORY);
00223
00224 memset(hkey->key, 0, sizeof(hkey->key));
00225
00226 if (r.length > ISC_SHA1_BLOCK_LENGTH) {
00227 isc_md5_init(&md5ctx);
00228 isc_md5_update(&md5ctx, r.base, r.length);
00229 isc_md5_final(&md5ctx, hkey->key);
00230 keylen = ISC_MD5_DIGESTLENGTH;
00231 } else {
00232 memmove(hkey->key, r.base, r.length);
00233 keylen = r.length;
00234 }
00235
00236 key->key_size = keylen * 8;
00237 key->keydata.hmacmd5 = hkey;
00238
00239 return (ISC_R_SUCCESS);
00240 }
00241
00242 static isc_result_t
00243 hmacmd5_tofile(const dst_key_t *key, const char *directory) {
00244 int cnt = 0;
00245 dst_hmacmd5_key_t *hkey;
00246 dst_private_t priv;
00247 int bytes = (key->key_size + 7) / 8;
00248 unsigned char buf[2];
00249
00250 if (key->keydata.hmacmd5 == NULL)
00251 return (DST_R_NULLKEY);
00252
00253 if (key->external)
00254 return (DST_R_EXTERNALKEY);
00255
00256 hkey = key->keydata.hmacmd5;
00257
00258 priv.elements[cnt].tag = TAG_HMACMD5_KEY;
00259 priv.elements[cnt].length = bytes;
00260 priv.elements[cnt++].data = hkey->key;
00261
00262 buf[0] = (key->key_bits >> 8) & 0xffU;
00263 buf[1] = key->key_bits & 0xffU;
00264 priv.elements[cnt].tag = TAG_HMACMD5_BITS;
00265 priv.elements[cnt].data = buf;
00266 priv.elements[cnt++].length = 2;
00267
00268 priv.nelements = cnt;
00269 return (dst__privstruct_writefile(key, &priv, directory));
00270 }
00271
00272 static isc_result_t
00273 hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00274 dst_private_t priv;
00275 isc_result_t result, tresult;
00276 isc_buffer_t b;
00277 isc_mem_t *mctx = key->mctx;
00278 unsigned int i;
00279
00280 UNUSED(pub);
00281
00282 result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx,
00283 &priv);
00284 if (result != ISC_R_SUCCESS)
00285 return (result);
00286
00287 if (key->external)
00288 result = DST_R_EXTERNALKEY;
00289
00290 key->key_bits = 0;
00291 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
00292 switch (priv.elements[i].tag) {
00293 case TAG_HMACMD5_KEY:
00294 isc_buffer_init(&b, priv.elements[i].data,
00295 priv.elements[i].length);
00296 isc_buffer_add(&b, priv.elements[i].length);
00297 tresult = hmacmd5_fromdns(key, &b);
00298 if (tresult != ISC_R_SUCCESS)
00299 result = tresult;
00300 break;
00301 case TAG_HMACMD5_BITS:
00302 tresult = getkeybits(key, &priv.elements[i]);
00303 if (tresult != ISC_R_SUCCESS)
00304 result = tresult;
00305 break;
00306 default:
00307 result = DST_R_INVALIDPRIVATEKEY;
00308 break;
00309 }
00310 }
00311 dst__privstruct_free(&priv, mctx);
00312 memset(&priv, 0, sizeof(priv));
00313 return (result);
00314 }
00315
00316 static dst_func_t hmacmd5_functions = {
00317 hmacmd5_createctx,
00318 NULL,
00319 hmacmd5_destroyctx,
00320 hmacmd5_adddata,
00321 hmacmd5_sign,
00322 hmacmd5_verify,
00323 NULL,
00324 NULL,
00325 hmacmd5_compare,
00326 NULL,
00327 hmacmd5_generate,
00328 hmacmd5_isprivate,
00329 hmacmd5_destroy,
00330 hmacmd5_todns,
00331 hmacmd5_fromdns,
00332 hmacmd5_tofile,
00333 hmacmd5_parse,
00334 NULL,
00335 NULL,
00336 NULL,
00337 NULL,
00338 };
00339
00340 isc_result_t
00341 dst__hmacmd5_init(dst_func_t **funcp) {
00342 REQUIRE(funcp != NULL);
00343 if (*funcp == NULL)
00344 *funcp = &hmacmd5_functions;
00345 return (ISC_R_SUCCESS);
00346 }
00347
00348 static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
00349
00350 struct dst_hmacsha1_key {
00351 unsigned char key[ISC_SHA1_BLOCK_LENGTH];
00352 };
00353
00354 static isc_result_t
00355 hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
00356 isc_hmacsha1_t *hmacsha1ctx;
00357 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
00358
00359 hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
00360 if (hmacsha1ctx == NULL)
00361 return (ISC_R_NOMEMORY);
00362 isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
00363 dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
00364 return (ISC_R_SUCCESS);
00365 }
00366
00367 static void
00368 hmacsha1_destroyctx(dst_context_t *dctx) {
00369 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
00370
00371 if (hmacsha1ctx != NULL) {
00372 isc_hmacsha1_invalidate(hmacsha1ctx);
00373 isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
00374 dctx->ctxdata.hmacsha1ctx = NULL;
00375 }
00376 }
00377
00378 static isc_result_t
00379 hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
00380 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
00381
00382 isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
00383 return (ISC_R_SUCCESS);
00384 }
00385
00386 static isc_result_t
00387 hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00388 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
00389 unsigned char *digest;
00390
00391 if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
00392 return (ISC_R_NOSPACE);
00393 digest = isc_buffer_used(sig);
00394 isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
00395 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
00396
00397 return (ISC_R_SUCCESS);
00398 }
00399
00400 static isc_result_t
00401 hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
00402 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
00403
00404 if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
00405 return (DST_R_VERIFYFAILURE);
00406
00407 if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
00408 return (ISC_R_SUCCESS);
00409 else
00410 return (DST_R_VERIFYFAILURE);
00411 }
00412
00413 static isc_boolean_t
00414 hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
00415 dst_hmacsha1_key_t *hkey1, *hkey2;
00416
00417 hkey1 = key1->keydata.hmacsha1;
00418 hkey2 = key2->keydata.hmacsha1;
00419
00420 if (hkey1 == NULL && hkey2 == NULL)
00421 return (ISC_TRUE);
00422 else if (hkey1 == NULL || hkey2 == NULL)
00423 return (ISC_FALSE);
00424
00425 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
00426 return (ISC_TRUE);
00427 else
00428 return (ISC_FALSE);
00429 }
00430
00431 static isc_result_t
00432 hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
00433 isc_buffer_t b;
00434 isc_result_t ret;
00435 unsigned int bytes;
00436 unsigned char data[ISC_SHA1_BLOCK_LENGTH];
00437
00438 UNUSED(callback);
00439
00440 bytes = (key->key_size + 7) / 8;
00441 if (bytes > ISC_SHA1_BLOCK_LENGTH) {
00442 bytes = ISC_SHA1_BLOCK_LENGTH;
00443 key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
00444 }
00445
00446 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
00447 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
00448
00449 if (ret != ISC_R_SUCCESS)
00450 return (ret);
00451
00452 isc_buffer_init(&b, data, bytes);
00453 isc_buffer_add(&b, bytes);
00454 ret = hmacsha1_fromdns(key, &b);
00455 memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
00456
00457 return (ret);
00458 }
00459
00460 static isc_boolean_t
00461 hmacsha1_isprivate(const dst_key_t *key) {
00462 UNUSED(key);
00463 return (ISC_TRUE);
00464 }
00465
00466 static void
00467 hmacsha1_destroy(dst_key_t *key) {
00468 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
00469
00470 memset(hkey, 0, sizeof(dst_hmacsha1_key_t));
00471 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t));
00472 key->keydata.hmacsha1 = NULL;
00473 }
00474
00475 static isc_result_t
00476 hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
00477 dst_hmacsha1_key_t *hkey;
00478 unsigned int bytes;
00479
00480 REQUIRE(key->keydata.hmacsha1 != NULL);
00481
00482 hkey = key->keydata.hmacsha1;
00483
00484 bytes = (key->key_size + 7) / 8;
00485 if (isc_buffer_availablelength(data) < bytes)
00486 return (ISC_R_NOSPACE);
00487 isc_buffer_putmem(data, hkey->key, bytes);
00488
00489 return (ISC_R_SUCCESS);
00490 }
00491
00492 static isc_result_t
00493 hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
00494 dst_hmacsha1_key_t *hkey;
00495 int keylen;
00496 isc_region_t r;
00497 isc_sha1_t sha1ctx;
00498
00499 isc_buffer_remainingregion(data, &r);
00500 if (r.length == 0)
00501 return (ISC_R_SUCCESS);
00502
00503 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
00504 if (hkey == NULL)
00505 return (ISC_R_NOMEMORY);
00506
00507 memset(hkey->key, 0, sizeof(hkey->key));
00508
00509 if (r.length > ISC_SHA1_BLOCK_LENGTH) {
00510 isc_sha1_init(&sha1ctx);
00511 isc_sha1_update(&sha1ctx, r.base, r.length);
00512 isc_sha1_final(&sha1ctx, hkey->key);
00513 keylen = ISC_SHA1_DIGESTLENGTH;
00514 } else {
00515 memmove(hkey->key, r.base, r.length);
00516 keylen = r.length;
00517 }
00518
00519 key->key_size = keylen * 8;
00520 key->keydata.hmacsha1 = hkey;
00521
00522 return (ISC_R_SUCCESS);
00523 }
00524
00525 static isc_result_t
00526 hmacsha1_tofile(const dst_key_t *key, const char *directory) {
00527 int cnt = 0;
00528 dst_hmacsha1_key_t *hkey;
00529 dst_private_t priv;
00530 int bytes = (key->key_size + 7) / 8;
00531 unsigned char buf[2];
00532
00533 if (key->keydata.hmacsha1 == NULL)
00534 return (DST_R_NULLKEY);
00535
00536 if (key->external)
00537 return (DST_R_EXTERNALKEY);
00538
00539 hkey = key->keydata.hmacsha1;
00540
00541 priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
00542 priv.elements[cnt].length = bytes;
00543 priv.elements[cnt++].data = hkey->key;
00544
00545 buf[0] = (key->key_bits >> 8) & 0xffU;
00546 buf[1] = key->key_bits & 0xffU;
00547 priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
00548 priv.elements[cnt].data = buf;
00549 priv.elements[cnt++].length = 2;
00550
00551 priv.nelements = cnt;
00552 return (dst__privstruct_writefile(key, &priv, directory));
00553 }
00554
00555 static isc_result_t
00556 hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00557 dst_private_t priv;
00558 isc_result_t result, tresult;
00559 isc_buffer_t b;
00560 isc_mem_t *mctx = key->mctx;
00561 unsigned int i;
00562
00563 UNUSED(pub);
00564
00565 result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
00566 &priv);
00567 if (result != ISC_R_SUCCESS)
00568 return (result);
00569
00570 if (key->external)
00571 result = DST_R_EXTERNALKEY;
00572
00573 key->key_bits = 0;
00574 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
00575 switch (priv.elements[i].tag) {
00576 case TAG_HMACSHA1_KEY:
00577 isc_buffer_init(&b, priv.elements[i].data,
00578 priv.elements[i].length);
00579 isc_buffer_add(&b, priv.elements[i].length);
00580 tresult = hmacsha1_fromdns(key, &b);
00581 if (tresult != ISC_R_SUCCESS)
00582 result = tresult;
00583 break;
00584 case TAG_HMACSHA1_BITS:
00585 tresult = getkeybits(key, &priv.elements[i]);
00586 if (tresult != ISC_R_SUCCESS)
00587 result = tresult;
00588 break;
00589 default:
00590 result = DST_R_INVALIDPRIVATEKEY;
00591 break;
00592 }
00593 }
00594 dst__privstruct_free(&priv, mctx);
00595 memset(&priv, 0, sizeof(priv));
00596 return (result);
00597 }
00598
00599 static dst_func_t hmacsha1_functions = {
00600 hmacsha1_createctx,
00601 NULL,
00602 hmacsha1_destroyctx,
00603 hmacsha1_adddata,
00604 hmacsha1_sign,
00605 hmacsha1_verify,
00606 NULL,
00607 NULL,
00608 hmacsha1_compare,
00609 NULL,
00610 hmacsha1_generate,
00611 hmacsha1_isprivate,
00612 hmacsha1_destroy,
00613 hmacsha1_todns,
00614 hmacsha1_fromdns,
00615 hmacsha1_tofile,
00616 hmacsha1_parse,
00617 NULL,
00618 NULL,
00619 NULL,
00620 NULL,
00621 };
00622
00623 isc_result_t
00624 dst__hmacsha1_init(dst_func_t **funcp) {
00625 REQUIRE(funcp != NULL);
00626 if (*funcp == NULL)
00627 *funcp = &hmacsha1_functions;
00628 return (ISC_R_SUCCESS);
00629 }
00630
00631 static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
00632
00633 struct dst_hmacsha224_key {
00634 unsigned char key[ISC_SHA224_BLOCK_LENGTH];
00635 };
00636
00637 static isc_result_t
00638 hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
00639 isc_hmacsha224_t *hmacsha224ctx;
00640 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
00641
00642 hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
00643 if (hmacsha224ctx == NULL)
00644 return (ISC_R_NOMEMORY);
00645 isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH);
00646 dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
00647 return (ISC_R_SUCCESS);
00648 }
00649
00650 static void
00651 hmacsha224_destroyctx(dst_context_t *dctx) {
00652 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
00653
00654 if (hmacsha224ctx != NULL) {
00655 isc_hmacsha224_invalidate(hmacsha224ctx);
00656 isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
00657 dctx->ctxdata.hmacsha224ctx = NULL;
00658 }
00659 }
00660
00661 static isc_result_t
00662 hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
00663 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
00664
00665 isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
00666 return (ISC_R_SUCCESS);
00667 }
00668
00669 static isc_result_t
00670 hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00671 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
00672 unsigned char *digest;
00673
00674 if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
00675 return (ISC_R_NOSPACE);
00676 digest = isc_buffer_used(sig);
00677 isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
00678 isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
00679
00680 return (ISC_R_SUCCESS);
00681 }
00682
00683 static isc_result_t
00684 hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
00685 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
00686
00687 if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
00688 return (DST_R_VERIFYFAILURE);
00689
00690 if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
00691 return (ISC_R_SUCCESS);
00692 else
00693 return (DST_R_VERIFYFAILURE);
00694 }
00695
00696 static isc_boolean_t
00697 hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
00698 dst_hmacsha224_key_t *hkey1, *hkey2;
00699
00700 hkey1 = key1->keydata.hmacsha224;
00701 hkey2 = key2->keydata.hmacsha224;
00702
00703 if (hkey1 == NULL && hkey2 == NULL)
00704 return (ISC_TRUE);
00705 else if (hkey1 == NULL || hkey2 == NULL)
00706 return (ISC_FALSE);
00707
00708 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH))
00709 return (ISC_TRUE);
00710 else
00711 return (ISC_FALSE);
00712 }
00713
00714 static isc_result_t
00715 hmacsha224_generate(dst_key_t *key, int pseudorandom_ok,
00716 void (*callback)(int))
00717 {
00718 isc_buffer_t b;
00719 isc_result_t ret;
00720 unsigned int bytes;
00721 unsigned char data[ISC_SHA224_BLOCK_LENGTH];
00722
00723 UNUSED(callback);
00724
00725 bytes = (key->key_size + 7) / 8;
00726 if (bytes > ISC_SHA224_BLOCK_LENGTH) {
00727 bytes = ISC_SHA224_BLOCK_LENGTH;
00728 key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
00729 }
00730
00731 memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
00732 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
00733
00734 if (ret != ISC_R_SUCCESS)
00735 return (ret);
00736
00737 isc_buffer_init(&b, data, bytes);
00738 isc_buffer_add(&b, bytes);
00739 ret = hmacsha224_fromdns(key, &b);
00740 memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
00741
00742 return (ret);
00743 }
00744
00745 static isc_boolean_t
00746 hmacsha224_isprivate(const dst_key_t *key) {
00747 UNUSED(key);
00748 return (ISC_TRUE);
00749 }
00750
00751 static void
00752 hmacsha224_destroy(dst_key_t *key) {
00753 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
00754
00755 memset(hkey, 0, sizeof(dst_hmacsha224_key_t));
00756 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t));
00757 key->keydata.hmacsha224 = NULL;
00758 }
00759
00760 static isc_result_t
00761 hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
00762 dst_hmacsha224_key_t *hkey;
00763 unsigned int bytes;
00764
00765 REQUIRE(key->keydata.hmacsha224 != NULL);
00766
00767 hkey = key->keydata.hmacsha224;
00768
00769 bytes = (key->key_size + 7) / 8;
00770 if (isc_buffer_availablelength(data) < bytes)
00771 return (ISC_R_NOSPACE);
00772 isc_buffer_putmem(data, hkey->key, bytes);
00773
00774 return (ISC_R_SUCCESS);
00775 }
00776
00777 static isc_result_t
00778 hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
00779 dst_hmacsha224_key_t *hkey;
00780 int keylen;
00781 isc_region_t r;
00782 isc_sha224_t sha224ctx;
00783
00784 isc_buffer_remainingregion(data, &r);
00785 if (r.length == 0)
00786 return (ISC_R_SUCCESS);
00787
00788 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
00789 if (hkey == NULL)
00790 return (ISC_R_NOMEMORY);
00791
00792 memset(hkey->key, 0, sizeof(hkey->key));
00793
00794 if (r.length > ISC_SHA224_BLOCK_LENGTH) {
00795 isc_sha224_init(&sha224ctx);
00796 isc_sha224_update(&sha224ctx, r.base, r.length);
00797 isc_sha224_final(hkey->key, &sha224ctx);
00798 keylen = ISC_SHA224_DIGESTLENGTH;
00799 } else {
00800 memmove(hkey->key, r.base, r.length);
00801 keylen = r.length;
00802 }
00803
00804 key->key_size = keylen * 8;
00805 key->keydata.hmacsha224 = hkey;
00806
00807 return (ISC_R_SUCCESS);
00808 }
00809
00810 static isc_result_t
00811 hmacsha224_tofile(const dst_key_t *key, const char *directory) {
00812 int cnt = 0;
00813 dst_hmacsha224_key_t *hkey;
00814 dst_private_t priv;
00815 int bytes = (key->key_size + 7) / 8;
00816 unsigned char buf[2];
00817
00818 if (key->keydata.hmacsha224 == NULL)
00819 return (DST_R_NULLKEY);
00820
00821 if (key->external)
00822 return (DST_R_EXTERNALKEY);
00823
00824 hkey = key->keydata.hmacsha224;
00825
00826 priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
00827 priv.elements[cnt].length = bytes;
00828 priv.elements[cnt++].data = hkey->key;
00829
00830 buf[0] = (key->key_bits >> 8) & 0xffU;
00831 buf[1] = key->key_bits & 0xffU;
00832 priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
00833 priv.elements[cnt].data = buf;
00834 priv.elements[cnt++].length = 2;
00835
00836 priv.nelements = cnt;
00837 return (dst__privstruct_writefile(key, &priv, directory));
00838 }
00839
00840 static isc_result_t
00841 hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00842 dst_private_t priv;
00843 isc_result_t result, tresult;
00844 isc_buffer_t b;
00845 isc_mem_t *mctx = key->mctx;
00846 unsigned int i;
00847
00848 UNUSED(pub);
00849
00850 result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
00851 &priv);
00852 if (result != ISC_R_SUCCESS)
00853 return (result);
00854
00855 if (key->external)
00856 result = DST_R_EXTERNALKEY;
00857
00858 key->key_bits = 0;
00859 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
00860 switch (priv.elements[i].tag) {
00861 case TAG_HMACSHA224_KEY:
00862 isc_buffer_init(&b, priv.elements[i].data,
00863 priv.elements[i].length);
00864 isc_buffer_add(&b, priv.elements[i].length);
00865 tresult = hmacsha224_fromdns(key, &b);
00866 if (tresult != ISC_R_SUCCESS)
00867 result = tresult;
00868 break;
00869 case TAG_HMACSHA224_BITS:
00870 tresult = getkeybits(key, &priv.elements[i]);
00871 if (tresult != ISC_R_SUCCESS)
00872 result = tresult;
00873 break;
00874 default:
00875 result = DST_R_INVALIDPRIVATEKEY;
00876 break;
00877 }
00878 }
00879 dst__privstruct_free(&priv, mctx);
00880 memset(&priv, 0, sizeof(priv));
00881 return (result);
00882 }
00883
00884 static dst_func_t hmacsha224_functions = {
00885 hmacsha224_createctx,
00886 NULL,
00887 hmacsha224_destroyctx,
00888 hmacsha224_adddata,
00889 hmacsha224_sign,
00890 hmacsha224_verify,
00891 NULL,
00892 NULL,
00893 hmacsha224_compare,
00894 NULL,
00895 hmacsha224_generate,
00896 hmacsha224_isprivate,
00897 hmacsha224_destroy,
00898 hmacsha224_todns,
00899 hmacsha224_fromdns,
00900 hmacsha224_tofile,
00901 hmacsha224_parse,
00902 NULL,
00903 NULL,
00904 NULL,
00905 NULL,
00906 };
00907
00908 isc_result_t
00909 dst__hmacsha224_init(dst_func_t **funcp) {
00910 REQUIRE(funcp != NULL);
00911 if (*funcp == NULL)
00912 *funcp = &hmacsha224_functions;
00913 return (ISC_R_SUCCESS);
00914 }
00915
00916 static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
00917
00918 struct dst_hmacsha256_key {
00919 unsigned char key[ISC_SHA256_BLOCK_LENGTH];
00920 };
00921
00922 static isc_result_t
00923 hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
00924 isc_hmacsha256_t *hmacsha256ctx;
00925 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
00926
00927 hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
00928 if (hmacsha256ctx == NULL)
00929 return (ISC_R_NOMEMORY);
00930 isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH);
00931 dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
00932 return (ISC_R_SUCCESS);
00933 }
00934
00935 static void
00936 hmacsha256_destroyctx(dst_context_t *dctx) {
00937 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
00938
00939 if (hmacsha256ctx != NULL) {
00940 isc_hmacsha256_invalidate(hmacsha256ctx);
00941 isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
00942 dctx->ctxdata.hmacsha256ctx = NULL;
00943 }
00944 }
00945
00946 static isc_result_t
00947 hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
00948 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
00949
00950 isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
00951 return (ISC_R_SUCCESS);
00952 }
00953
00954 static isc_result_t
00955 hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00956 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
00957 unsigned char *digest;
00958
00959 if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
00960 return (ISC_R_NOSPACE);
00961 digest = isc_buffer_used(sig);
00962 isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
00963 isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
00964
00965 return (ISC_R_SUCCESS);
00966 }
00967
00968 static isc_result_t
00969 hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
00970 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
00971
00972 if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
00973 return (DST_R_VERIFYFAILURE);
00974
00975 if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
00976 return (ISC_R_SUCCESS);
00977 else
00978 return (DST_R_VERIFYFAILURE);
00979 }
00980
00981 static isc_boolean_t
00982 hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
00983 dst_hmacsha256_key_t *hkey1, *hkey2;
00984
00985 hkey1 = key1->keydata.hmacsha256;
00986 hkey2 = key2->keydata.hmacsha256;
00987
00988 if (hkey1 == NULL && hkey2 == NULL)
00989 return (ISC_TRUE);
00990 else if (hkey1 == NULL || hkey2 == NULL)
00991 return (ISC_FALSE);
00992
00993 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH))
00994 return (ISC_TRUE);
00995 else
00996 return (ISC_FALSE);
00997 }
00998
00999 static isc_result_t
01000 hmacsha256_generate(dst_key_t *key, int pseudorandom_ok,
01001 void (*callback)(int))
01002 {
01003 isc_buffer_t b;
01004 isc_result_t ret;
01005 unsigned int bytes;
01006 unsigned char data[ISC_SHA256_BLOCK_LENGTH];
01007
01008 UNUSED(callback);
01009
01010 bytes = (key->key_size + 7) / 8;
01011 if (bytes > ISC_SHA256_BLOCK_LENGTH) {
01012 bytes = ISC_SHA256_BLOCK_LENGTH;
01013 key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
01014 }
01015
01016 memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
01017 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
01018
01019 if (ret != ISC_R_SUCCESS)
01020 return (ret);
01021
01022 isc_buffer_init(&b, data, bytes);
01023 isc_buffer_add(&b, bytes);
01024 ret = hmacsha256_fromdns(key, &b);
01025 memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
01026
01027 return (ret);
01028 }
01029
01030 static isc_boolean_t
01031 hmacsha256_isprivate(const dst_key_t *key) {
01032 UNUSED(key);
01033 return (ISC_TRUE);
01034 }
01035
01036 static void
01037 hmacsha256_destroy(dst_key_t *key) {
01038 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
01039
01040 memset(hkey, 0, sizeof(dst_hmacsha256_key_t));
01041 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t));
01042 key->keydata.hmacsha256 = NULL;
01043 }
01044
01045 static isc_result_t
01046 hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
01047 dst_hmacsha256_key_t *hkey;
01048 unsigned int bytes;
01049
01050 REQUIRE(key->keydata.hmacsha256 != NULL);
01051
01052 hkey = key->keydata.hmacsha256;
01053
01054 bytes = (key->key_size + 7) / 8;
01055 if (isc_buffer_availablelength(data) < bytes)
01056 return (ISC_R_NOSPACE);
01057 isc_buffer_putmem(data, hkey->key, bytes);
01058
01059 return (ISC_R_SUCCESS);
01060 }
01061
01062 static isc_result_t
01063 hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
01064 dst_hmacsha256_key_t *hkey;
01065 int keylen;
01066 isc_region_t r;
01067 isc_sha256_t sha256ctx;
01068
01069 isc_buffer_remainingregion(data, &r);
01070 if (r.length == 0)
01071 return (ISC_R_SUCCESS);
01072
01073 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
01074 if (hkey == NULL)
01075 return (ISC_R_NOMEMORY);
01076
01077 memset(hkey->key, 0, sizeof(hkey->key));
01078
01079 if (r.length > ISC_SHA256_BLOCK_LENGTH) {
01080 isc_sha256_init(&sha256ctx);
01081 isc_sha256_update(&sha256ctx, r.base, r.length);
01082 isc_sha256_final(hkey->key, &sha256ctx);
01083 keylen = ISC_SHA256_DIGESTLENGTH;
01084 } else {
01085 memmove(hkey->key, r.base, r.length);
01086 keylen = r.length;
01087 }
01088
01089 key->key_size = keylen * 8;
01090 key->keydata.hmacsha256 = hkey;
01091
01092 return (ISC_R_SUCCESS);
01093 }
01094
01095 static isc_result_t
01096 hmacsha256_tofile(const dst_key_t *key, const char *directory) {
01097 int cnt = 0;
01098 dst_hmacsha256_key_t *hkey;
01099 dst_private_t priv;
01100 int bytes = (key->key_size + 7) / 8;
01101 unsigned char buf[2];
01102
01103 if (key->keydata.hmacsha256 == NULL)
01104 return (DST_R_NULLKEY);
01105
01106 if (key->external)
01107 return (DST_R_EXTERNALKEY);
01108
01109 hkey = key->keydata.hmacsha256;
01110
01111 priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
01112 priv.elements[cnt].length = bytes;
01113 priv.elements[cnt++].data = hkey->key;
01114
01115 buf[0] = (key->key_bits >> 8) & 0xffU;
01116 buf[1] = key->key_bits & 0xffU;
01117 priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
01118 priv.elements[cnt].data = buf;
01119 priv.elements[cnt++].length = 2;
01120
01121 priv.nelements = cnt;
01122 return (dst__privstruct_writefile(key, &priv, directory));
01123 }
01124
01125 static isc_result_t
01126 hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
01127 dst_private_t priv;
01128 isc_result_t result, tresult;
01129 isc_buffer_t b;
01130 isc_mem_t *mctx = key->mctx;
01131 unsigned int i;
01132
01133 UNUSED(pub);
01134
01135 result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
01136 &priv);
01137 if (result != ISC_R_SUCCESS)
01138 return (result);
01139
01140 if (key->external)
01141 result = DST_R_EXTERNALKEY;
01142
01143 key->key_bits = 0;
01144 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
01145 switch (priv.elements[i].tag) {
01146 case TAG_HMACSHA256_KEY:
01147 isc_buffer_init(&b, priv.elements[i].data,
01148 priv.elements[i].length);
01149 isc_buffer_add(&b, priv.elements[i].length);
01150 tresult = hmacsha256_fromdns(key, &b);
01151 if (tresult != ISC_R_SUCCESS)
01152 result = tresult;
01153 break;
01154 case TAG_HMACSHA256_BITS:
01155 tresult = getkeybits(key, &priv.elements[i]);
01156 if (tresult != ISC_R_SUCCESS)
01157 result = tresult;
01158 break;
01159 default:
01160 result = DST_R_INVALIDPRIVATEKEY;
01161 break;
01162 }
01163 }
01164 dst__privstruct_free(&priv, mctx);
01165 memset(&priv, 0, sizeof(priv));
01166 return (result);
01167 }
01168
01169 static dst_func_t hmacsha256_functions = {
01170 hmacsha256_createctx,
01171 NULL,
01172 hmacsha256_destroyctx,
01173 hmacsha256_adddata,
01174 hmacsha256_sign,
01175 hmacsha256_verify,
01176 NULL,
01177 NULL,
01178 hmacsha256_compare,
01179 NULL,
01180 hmacsha256_generate,
01181 hmacsha256_isprivate,
01182 hmacsha256_destroy,
01183 hmacsha256_todns,
01184 hmacsha256_fromdns,
01185 hmacsha256_tofile,
01186 hmacsha256_parse,
01187 NULL,
01188 NULL,
01189 NULL,
01190 NULL,
01191 };
01192
01193 isc_result_t
01194 dst__hmacsha256_init(dst_func_t **funcp) {
01195 REQUIRE(funcp != NULL);
01196 if (*funcp == NULL)
01197 *funcp = &hmacsha256_functions;
01198 return (ISC_R_SUCCESS);
01199 }
01200
01201 static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
01202
01203 struct dst_hmacsha384_key {
01204 unsigned char key[ISC_SHA384_BLOCK_LENGTH];
01205 };
01206
01207 static isc_result_t
01208 hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
01209 isc_hmacsha384_t *hmacsha384ctx;
01210 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
01211
01212 hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
01213 if (hmacsha384ctx == NULL)
01214 return (ISC_R_NOMEMORY);
01215 isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH);
01216 dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
01217 return (ISC_R_SUCCESS);
01218 }
01219
01220 static void
01221 hmacsha384_destroyctx(dst_context_t *dctx) {
01222 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
01223
01224 if (hmacsha384ctx != NULL) {
01225 isc_hmacsha384_invalidate(hmacsha384ctx);
01226 isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
01227 dctx->ctxdata.hmacsha384ctx = NULL;
01228 }
01229 }
01230
01231 static isc_result_t
01232 hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
01233 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
01234
01235 isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
01236 return (ISC_R_SUCCESS);
01237 }
01238
01239 static isc_result_t
01240 hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
01241 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
01242 unsigned char *digest;
01243
01244 if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
01245 return (ISC_R_NOSPACE);
01246 digest = isc_buffer_used(sig);
01247 isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
01248 isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
01249
01250 return (ISC_R_SUCCESS);
01251 }
01252
01253 static isc_result_t
01254 hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
01255 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
01256
01257 if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
01258 return (DST_R_VERIFYFAILURE);
01259
01260 if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
01261 return (ISC_R_SUCCESS);
01262 else
01263 return (DST_R_VERIFYFAILURE);
01264 }
01265
01266 static isc_boolean_t
01267 hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
01268 dst_hmacsha384_key_t *hkey1, *hkey2;
01269
01270 hkey1 = key1->keydata.hmacsha384;
01271 hkey2 = key2->keydata.hmacsha384;
01272
01273 if (hkey1 == NULL && hkey2 == NULL)
01274 return (ISC_TRUE);
01275 else if (hkey1 == NULL || hkey2 == NULL)
01276 return (ISC_FALSE);
01277
01278 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH))
01279 return (ISC_TRUE);
01280 else
01281 return (ISC_FALSE);
01282 }
01283
01284 static isc_result_t
01285 hmacsha384_generate(dst_key_t *key, int pseudorandom_ok,
01286 void (*callback)(int))
01287 {
01288 isc_buffer_t b;
01289 isc_result_t ret;
01290 unsigned int bytes;
01291 unsigned char data[ISC_SHA384_BLOCK_LENGTH];
01292
01293 UNUSED(callback);
01294
01295 bytes = (key->key_size + 7) / 8;
01296 if (bytes > ISC_SHA384_BLOCK_LENGTH) {
01297 bytes = ISC_SHA384_BLOCK_LENGTH;
01298 key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
01299 }
01300
01301 memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
01302 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
01303
01304 if (ret != ISC_R_SUCCESS)
01305 return (ret);
01306
01307 isc_buffer_init(&b, data, bytes);
01308 isc_buffer_add(&b, bytes);
01309 ret = hmacsha384_fromdns(key, &b);
01310 memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
01311
01312 return (ret);
01313 }
01314
01315 static isc_boolean_t
01316 hmacsha384_isprivate(const dst_key_t *key) {
01317 UNUSED(key);
01318 return (ISC_TRUE);
01319 }
01320
01321 static void
01322 hmacsha384_destroy(dst_key_t *key) {
01323 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
01324
01325 memset(hkey, 0, sizeof(dst_hmacsha384_key_t));
01326 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t));
01327 key->keydata.hmacsha384 = NULL;
01328 }
01329
01330 static isc_result_t
01331 hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
01332 dst_hmacsha384_key_t *hkey;
01333 unsigned int bytes;
01334
01335 REQUIRE(key->keydata.hmacsha384 != NULL);
01336
01337 hkey = key->keydata.hmacsha384;
01338
01339 bytes = (key->key_size + 7) / 8;
01340 if (isc_buffer_availablelength(data) < bytes)
01341 return (ISC_R_NOSPACE);
01342 isc_buffer_putmem(data, hkey->key, bytes);
01343
01344 return (ISC_R_SUCCESS);
01345 }
01346
01347 static isc_result_t
01348 hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
01349 dst_hmacsha384_key_t *hkey;
01350 int keylen;
01351 isc_region_t r;
01352 isc_sha384_t sha384ctx;
01353
01354 isc_buffer_remainingregion(data, &r);
01355 if (r.length == 0)
01356 return (ISC_R_SUCCESS);
01357
01358 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
01359 if (hkey == NULL)
01360 return (ISC_R_NOMEMORY);
01361
01362 memset(hkey->key, 0, sizeof(hkey->key));
01363
01364 if (r.length > ISC_SHA384_BLOCK_LENGTH) {
01365 isc_sha384_init(&sha384ctx);
01366 isc_sha384_update(&sha384ctx, r.base, r.length);
01367 isc_sha384_final(hkey->key, &sha384ctx);
01368 keylen = ISC_SHA384_DIGESTLENGTH;
01369 } else {
01370 memmove(hkey->key, r.base, r.length);
01371 keylen = r.length;
01372 }
01373
01374 key->key_size = keylen * 8;
01375 key->keydata.hmacsha384 = hkey;
01376
01377 return (ISC_R_SUCCESS);
01378 }
01379
01380 static isc_result_t
01381 hmacsha384_tofile(const dst_key_t *key, const char *directory) {
01382 int cnt = 0;
01383 dst_hmacsha384_key_t *hkey;
01384 dst_private_t priv;
01385 int bytes = (key->key_size + 7) / 8;
01386 unsigned char buf[2];
01387
01388 if (key->keydata.hmacsha384 == NULL)
01389 return (DST_R_NULLKEY);
01390
01391 if (key->external)
01392 return (DST_R_EXTERNALKEY);
01393
01394 hkey = key->keydata.hmacsha384;
01395
01396 priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
01397 priv.elements[cnt].length = bytes;
01398 priv.elements[cnt++].data = hkey->key;
01399
01400 buf[0] = (key->key_bits >> 8) & 0xffU;
01401 buf[1] = key->key_bits & 0xffU;
01402 priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
01403 priv.elements[cnt].data = buf;
01404 priv.elements[cnt++].length = 2;
01405
01406 priv.nelements = cnt;
01407 return (dst__privstruct_writefile(key, &priv, directory));
01408 }
01409
01410 static isc_result_t
01411 hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
01412 dst_private_t priv;
01413 isc_result_t result, tresult;
01414 isc_buffer_t b;
01415 isc_mem_t *mctx = key->mctx;
01416 unsigned int i;
01417
01418 UNUSED(pub);
01419
01420 result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
01421 &priv);
01422 if (result != ISC_R_SUCCESS)
01423 return (result);
01424
01425 if (key->external)
01426 result = DST_R_EXTERNALKEY;
01427
01428 key->key_bits = 0;
01429 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
01430 switch (priv.elements[i].tag) {
01431 case TAG_HMACSHA384_KEY:
01432 isc_buffer_init(&b, priv.elements[i].data,
01433 priv.elements[i].length);
01434 isc_buffer_add(&b, priv.elements[i].length);
01435 tresult = hmacsha384_fromdns(key, &b);
01436 if (tresult != ISC_R_SUCCESS)
01437 result = tresult;
01438 break;
01439 case TAG_HMACSHA384_BITS:
01440 tresult = getkeybits(key, &priv.elements[i]);
01441 if (tresult != ISC_R_SUCCESS)
01442 result = tresult;
01443 break;
01444 default:
01445 result = DST_R_INVALIDPRIVATEKEY;
01446 break;
01447 }
01448 }
01449 dst__privstruct_free(&priv, mctx);
01450 memset(&priv, 0, sizeof(priv));
01451 return (result);
01452 }
01453
01454 static dst_func_t hmacsha384_functions = {
01455 hmacsha384_createctx,
01456 NULL,
01457 hmacsha384_destroyctx,
01458 hmacsha384_adddata,
01459 hmacsha384_sign,
01460 hmacsha384_verify,
01461 NULL,
01462 NULL,
01463 hmacsha384_compare,
01464 NULL,
01465 hmacsha384_generate,
01466 hmacsha384_isprivate,
01467 hmacsha384_destroy,
01468 hmacsha384_todns,
01469 hmacsha384_fromdns,
01470 hmacsha384_tofile,
01471 hmacsha384_parse,
01472 NULL,
01473 NULL,
01474 NULL,
01475 NULL,
01476 };
01477
01478 isc_result_t
01479 dst__hmacsha384_init(dst_func_t **funcp) {
01480 REQUIRE(funcp != NULL);
01481 if (*funcp == NULL)
01482 *funcp = &hmacsha384_functions;
01483 return (ISC_R_SUCCESS);
01484 }
01485
01486 static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
01487
01488 struct dst_hmacsha512_key {
01489 unsigned char key[ISC_SHA512_BLOCK_LENGTH];
01490 };
01491
01492 static isc_result_t
01493 hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
01494 isc_hmacsha512_t *hmacsha512ctx;
01495 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
01496
01497 hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
01498 if (hmacsha512ctx == NULL)
01499 return (ISC_R_NOMEMORY);
01500 isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH);
01501 dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
01502 return (ISC_R_SUCCESS);
01503 }
01504
01505 static void
01506 hmacsha512_destroyctx(dst_context_t *dctx) {
01507 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
01508
01509 if (hmacsha512ctx != NULL) {
01510 isc_hmacsha512_invalidate(hmacsha512ctx);
01511 isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
01512 dctx->ctxdata.hmacsha512ctx = NULL;
01513 }
01514 }
01515
01516 static isc_result_t
01517 hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
01518 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
01519
01520 isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
01521 return (ISC_R_SUCCESS);
01522 }
01523
01524 static isc_result_t
01525 hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
01526 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
01527 unsigned char *digest;
01528
01529 if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
01530 return (ISC_R_NOSPACE);
01531 digest = isc_buffer_used(sig);
01532 isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
01533 isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
01534
01535 return (ISC_R_SUCCESS);
01536 }
01537
01538 static isc_result_t
01539 hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
01540 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
01541
01542 if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
01543 return (DST_R_VERIFYFAILURE);
01544
01545 if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
01546 return (ISC_R_SUCCESS);
01547 else
01548 return (DST_R_VERIFYFAILURE);
01549 }
01550
01551 static isc_boolean_t
01552 hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
01553 dst_hmacsha512_key_t *hkey1, *hkey2;
01554
01555 hkey1 = key1->keydata.hmacsha512;
01556 hkey2 = key2->keydata.hmacsha512;
01557
01558 if (hkey1 == NULL && hkey2 == NULL)
01559 return (ISC_TRUE);
01560 else if (hkey1 == NULL || hkey2 == NULL)
01561 return (ISC_FALSE);
01562
01563 if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH))
01564 return (ISC_TRUE);
01565 else
01566 return (ISC_FALSE);
01567 }
01568
01569 static isc_result_t
01570 hmacsha512_generate(dst_key_t *key, int pseudorandom_ok,
01571 void (*callback)(int))
01572 {
01573 isc_buffer_t b;
01574 isc_result_t ret;
01575 unsigned int bytes;
01576 unsigned char data[ISC_SHA512_BLOCK_LENGTH];
01577
01578 UNUSED(callback);
01579
01580 bytes = (key->key_size + 7) / 8;
01581 if (bytes > ISC_SHA512_BLOCK_LENGTH) {
01582 bytes = ISC_SHA512_BLOCK_LENGTH;
01583 key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
01584 }
01585
01586 memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
01587 ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
01588
01589 if (ret != ISC_R_SUCCESS)
01590 return (ret);
01591
01592 isc_buffer_init(&b, data, bytes);
01593 isc_buffer_add(&b, bytes);
01594 ret = hmacsha512_fromdns(key, &b);
01595 memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
01596
01597 return (ret);
01598 }
01599
01600 static isc_boolean_t
01601 hmacsha512_isprivate(const dst_key_t *key) {
01602 UNUSED(key);
01603 return (ISC_TRUE);
01604 }
01605
01606 static void
01607 hmacsha512_destroy(dst_key_t *key) {
01608 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
01609
01610 memset(hkey, 0, sizeof(dst_hmacsha512_key_t));
01611 isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t));
01612 key->keydata.hmacsha512 = NULL;
01613 }
01614
01615 static isc_result_t
01616 hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
01617 dst_hmacsha512_key_t *hkey;
01618 unsigned int bytes;
01619
01620 REQUIRE(key->keydata.hmacsha512 != NULL);
01621
01622 hkey = key->keydata.hmacsha512;
01623
01624 bytes = (key->key_size + 7) / 8;
01625 if (isc_buffer_availablelength(data) < bytes)
01626 return (ISC_R_NOSPACE);
01627 isc_buffer_putmem(data, hkey->key, bytes);
01628
01629 return (ISC_R_SUCCESS);
01630 }
01631
01632 static isc_result_t
01633 hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
01634 dst_hmacsha512_key_t *hkey;
01635 int keylen;
01636 isc_region_t r;
01637 isc_sha512_t sha512ctx;
01638
01639 isc_buffer_remainingregion(data, &r);
01640 if (r.length == 0)
01641 return (ISC_R_SUCCESS);
01642
01643 hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
01644 if (hkey == NULL)
01645 return (ISC_R_NOMEMORY);
01646
01647 memset(hkey->key, 0, sizeof(hkey->key));
01648
01649 if (r.length > ISC_SHA512_BLOCK_LENGTH) {
01650 isc_sha512_init(&sha512ctx);
01651 isc_sha512_update(&sha512ctx, r.base, r.length);
01652 isc_sha512_final(hkey->key, &sha512ctx);
01653 keylen = ISC_SHA512_DIGESTLENGTH;
01654 } else {
01655 memmove(hkey->key, r.base, r.length);
01656 keylen = r.length;
01657 }
01658
01659 key->key_size = keylen * 8;
01660 key->keydata.hmacsha512 = hkey;
01661
01662 return (ISC_R_SUCCESS);
01663 }
01664
01665 static isc_result_t
01666 hmacsha512_tofile(const dst_key_t *key, const char *directory) {
01667 int cnt = 0;
01668 dst_hmacsha512_key_t *hkey;
01669 dst_private_t priv;
01670 int bytes = (key->key_size + 7) / 8;
01671 unsigned char buf[2];
01672
01673 if (key->keydata.hmacsha512 == NULL)
01674 return (DST_R_NULLKEY);
01675
01676 if (key->external)
01677 return (DST_R_EXTERNALKEY);
01678
01679 hkey = key->keydata.hmacsha512;
01680
01681 priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
01682 priv.elements[cnt].length = bytes;
01683 priv.elements[cnt++].data = hkey->key;
01684
01685 buf[0] = (key->key_bits >> 8) & 0xffU;
01686 buf[1] = key->key_bits & 0xffU;
01687 priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
01688 priv.elements[cnt].data = buf;
01689 priv.elements[cnt++].length = 2;
01690
01691 priv.nelements = cnt;
01692 return (dst__privstruct_writefile(key, &priv, directory));
01693 }
01694
01695 static isc_result_t
01696 hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
01697 dst_private_t priv;
01698 isc_result_t result, tresult;
01699 isc_buffer_t b;
01700 isc_mem_t *mctx = key->mctx;
01701 unsigned int i;
01702
01703 UNUSED(pub);
01704
01705 result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
01706 &priv);
01707 if (result != ISC_R_SUCCESS)
01708 return (result);
01709
01710 if (key->external)
01711 result = DST_R_EXTERNALKEY;
01712
01713 key->key_bits = 0;
01714 for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
01715 switch (priv.elements[i].tag) {
01716 case TAG_HMACSHA512_KEY:
01717 isc_buffer_init(&b, priv.elements[i].data,
01718 priv.elements[i].length);
01719 isc_buffer_add(&b, priv.elements[i].length);
01720 tresult = hmacsha512_fromdns(key, &b);
01721 if (tresult != ISC_R_SUCCESS)
01722 result = tresult;
01723 break;
01724 case TAG_HMACSHA512_BITS:
01725 tresult = getkeybits(key, &priv.elements[i]);
01726 if (tresult != ISC_R_SUCCESS)
01727 result = tresult;
01728 break;
01729 default:
01730 result = DST_R_INVALIDPRIVATEKEY;
01731 break;
01732 }
01733 }
01734 dst__privstruct_free(&priv, mctx);
01735 memset(&priv, 0, sizeof(priv));
01736 return (result);
01737 }
01738
01739 static dst_func_t hmacsha512_functions = {
01740 hmacsha512_createctx,
01741 NULL,
01742 hmacsha512_destroyctx,
01743 hmacsha512_adddata,
01744 hmacsha512_sign,
01745 hmacsha512_verify,
01746 NULL,
01747 NULL,
01748 hmacsha512_compare,
01749 NULL,
01750 hmacsha512_generate,
01751 hmacsha512_isprivate,
01752 hmacsha512_destroy,
01753 hmacsha512_todns,
01754 hmacsha512_fromdns,
01755 hmacsha512_tofile,
01756 hmacsha512_parse,
01757 NULL,
01758 NULL,
01759 NULL,
01760 NULL,
01761 };
01762
01763 isc_result_t
01764 dst__hmacsha512_init(dst_func_t **funcp) {
01765 REQUIRE(funcp != NULL);
01766 if (*funcp == NULL)
01767 *funcp = &hmacsha512_functions;
01768 return (ISC_R_SUCCESS);
01769 }
01770
01771