hmac_link.c

Go to the documentation of this file.
00001 /*
00002  * Portions Copyright (C) 2004-2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Portions Copyright (C) 1999-2002  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
00010  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
00011  * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE
00012  * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00013  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00014  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
00015  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00016  *
00017  * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
00018  *
00019  * Permission to use, copy, modify, and/or distribute this software for any
00020  * purpose with or without fee is hereby granted, provided that the above
00021  * copyright notice and this permission notice appear in all copies.
00022  *
00023  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
00024  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
00025  * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE
00026  * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00027  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00028  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
00029  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00030  */
00031 
00032 /*
00033  * Principal Author: Brian Wellington
00034  * $Id: hmac_link.c,v 1.19 2011/01/11 23:47:13 tbox Exp $
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         /* read private key file */
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, /*%< createctx2 */
00319         hmacmd5_destroyctx,
00320         hmacmd5_adddata,
00321         hmacmd5_sign,
00322         hmacmd5_verify,
00323         NULL, /*%< verify2 */
00324         NULL, /*%< computesecret */
00325         hmacmd5_compare,
00326         NULL, /*%< paramcompare */
00327         hmacmd5_generate,
00328         hmacmd5_isprivate,
00329         hmacmd5_destroy,
00330         hmacmd5_todns,
00331         hmacmd5_fromdns,
00332         hmacmd5_tofile,
00333         hmacmd5_parse,
00334         NULL, /*%< cleanup */
00335         NULL, /*%< fromlabel */
00336         NULL, /*%< dump */
00337         NULL, /*%< restore */
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         /* read private key file */
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, /*%< createctx2 */
00602         hmacsha1_destroyctx,
00603         hmacsha1_adddata,
00604         hmacsha1_sign,
00605         hmacsha1_verify,
00606         NULL, /* verify2 */
00607         NULL, /* computesecret */
00608         hmacsha1_compare,
00609         NULL, /* paramcompare */
00610         hmacsha1_generate,
00611         hmacsha1_isprivate,
00612         hmacsha1_destroy,
00613         hmacsha1_todns,
00614         hmacsha1_fromdns,
00615         hmacsha1_tofile,
00616         hmacsha1_parse,
00617         NULL, /* cleanup */
00618         NULL, /* fromlabel */
00619         NULL, /* dump */
00620         NULL, /* restore */
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         /* read private key file */
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, /*%< createctx2 */
00887         hmacsha224_destroyctx,
00888         hmacsha224_adddata,
00889         hmacsha224_sign,
00890         hmacsha224_verify,
00891         NULL, /* verify2 */
00892         NULL, /* computesecret */
00893         hmacsha224_compare,
00894         NULL, /* paramcompare */
00895         hmacsha224_generate,
00896         hmacsha224_isprivate,
00897         hmacsha224_destroy,
00898         hmacsha224_todns,
00899         hmacsha224_fromdns,
00900         hmacsha224_tofile,
00901         hmacsha224_parse,
00902         NULL, /* cleanup */
00903         NULL, /* fromlabel */
00904         NULL, /* dump */
00905         NULL, /* restore */
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         /* read private key file */
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, /*%< createctx2 */
01172         hmacsha256_destroyctx,
01173         hmacsha256_adddata,
01174         hmacsha256_sign,
01175         hmacsha256_verify,
01176         NULL, /* verify2 */
01177         NULL, /* computesecret */
01178         hmacsha256_compare,
01179         NULL, /* paramcompare */
01180         hmacsha256_generate,
01181         hmacsha256_isprivate,
01182         hmacsha256_destroy,
01183         hmacsha256_todns,
01184         hmacsha256_fromdns,
01185         hmacsha256_tofile,
01186         hmacsha256_parse,
01187         NULL, /* cleanup */
01188         NULL, /* fromlabel */
01189         NULL, /* dump */
01190         NULL, /* restore */
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         /* read private key file */
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, /*%< createctx2 */
01457         hmacsha384_destroyctx,
01458         hmacsha384_adddata,
01459         hmacsha384_sign,
01460         hmacsha384_verify,
01461         NULL, /* verify2 */
01462         NULL, /* computesecret */
01463         hmacsha384_compare,
01464         NULL, /* paramcompare */
01465         hmacsha384_generate,
01466         hmacsha384_isprivate,
01467         hmacsha384_destroy,
01468         hmacsha384_todns,
01469         hmacsha384_fromdns,
01470         hmacsha384_tofile,
01471         hmacsha384_parse,
01472         NULL, /* cleanup */
01473         NULL, /* fromlabel */
01474         NULL, /* dump */
01475         NULL, /* restore */
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         /* read private key file */
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, /*%< createctx2 */
01742         hmacsha512_destroyctx,
01743         hmacsha512_adddata,
01744         hmacsha512_sign,
01745         hmacsha512_verify,
01746         NULL, /* verify2 */
01747         NULL, /* computesecret */
01748         hmacsha512_compare,
01749         NULL, /* paramcompare */
01750         hmacsha512_generate,
01751         hmacsha512_isprivate,
01752         hmacsha512_destroy,
01753         hmacsha512_todns,
01754         hmacsha512_fromdns,
01755         hmacsha512_tofile,
01756         hmacsha512_parse,
01757         NULL, /* cleanup */
01758         NULL, /* fromlabel */
01759         NULL, /* dump */
01760         NULL, /* restore */
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 /*! \file */

Generated on Tue Apr 28 17:40:56 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha