hmacsha.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005-2007, 2009, 2011-2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 /*
00020  * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
00021  * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
00022  * draft-ietf-dnsext-tsig-sha-01.txt.
00023  */
00024 
00025 #include "config.h"
00026 
00027 #include <isc/assertions.h>
00028 #include <isc/hmacsha.h>
00029 #include <isc/platform.h>
00030 #include <isc/safe.h>
00031 #include <isc/sha1.h>
00032 #include <isc/sha2.h>
00033 #include <isc/string.h>
00034 #include <isc/types.h>
00035 #include <isc/util.h>
00036 
00037 #if PKCS11CRYPTO
00038 #include <pk11/internal.h>
00039 #include <pk11/pk11.h>
00040 #endif
00041 
00042 #ifdef ISC_PLATFORM_OPENSSLHASH
00043 void
00044 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
00045                   unsigned int len)
00046 {
00047 #ifdef HMAC_RETURN_INT
00048         RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
00049                                 (int) len, EVP_sha1()) == 1);
00050 #else
00051         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
00052 #endif
00053 }
00054 
00055 void
00056 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
00057         HMAC_CTX_cleanup(ctx);
00058 }
00059 
00060 void
00061 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
00062                    unsigned int len)
00063 {
00064 #ifdef HMAC_RETURN_INT
00065         RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
00066 #else
00067         HMAC_Update(ctx, buf, (int) len);
00068 #endif
00069 }
00070 
00071 void
00072 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
00073         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
00074 
00075         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
00076 
00077 #ifdef HMAC_RETURN_INT
00078         RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
00079 #else
00080         HMAC_Final(ctx, newdigest, NULL);
00081 #endif
00082         HMAC_CTX_cleanup(ctx);
00083         memmove(digest, newdigest, len);
00084         memset(newdigest, 0, sizeof(newdigest));
00085 }
00086 
00087 void
00088 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
00089                     unsigned int len)
00090 {
00091 #ifdef HMAC_RETURN_INT
00092         RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
00093                                 (int) len, EVP_sha224()) == 1);
00094 #else
00095         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
00096 #endif
00097 }
00098 
00099 void
00100 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
00101         HMAC_CTX_cleanup(ctx);
00102 }
00103 
00104 void
00105 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
00106                    unsigned int len)
00107 {
00108 #ifdef HMAC_RETURN_INT
00109         RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
00110 #else
00111         HMAC_Update(ctx, buf, (int) len);
00112 #endif
00113 }
00114 
00115 void
00116 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
00117         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
00118 
00119         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
00120 
00121 #ifdef HMAC_RETURN_INT
00122         RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
00123 #else
00124         HMAC_Final(ctx, newdigest, NULL);
00125 #endif
00126         HMAC_CTX_cleanup(ctx);
00127         memmove(digest, newdigest, len);
00128         memset(newdigest, 0, sizeof(newdigest));
00129 }
00130 
00131 void
00132 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
00133                     unsigned int len)
00134 {
00135 #ifdef HMAC_RETURN_INT
00136         RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
00137                                 (int) len, EVP_sha256()) == 1);
00138 #else
00139         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
00140 #endif
00141 }
00142 
00143 void
00144 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
00145         HMAC_CTX_cleanup(ctx);
00146 }
00147 
00148 void
00149 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
00150                    unsigned int len)
00151 {
00152 #ifdef HMAC_RETURN_INT
00153         RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
00154 #else
00155         HMAC_Update(ctx, buf, (int) len);
00156 #endif
00157 }
00158 
00159 void
00160 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
00161         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
00162 
00163         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
00164 
00165 #ifdef HMAC_RETURN_INT
00166         RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
00167 #else
00168         HMAC_Final(ctx, newdigest, NULL);
00169 #endif
00170         HMAC_CTX_cleanup(ctx);
00171         memmove(digest, newdigest, len);
00172         memset(newdigest, 0, sizeof(newdigest));
00173 }
00174 
00175 void
00176 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
00177                     unsigned int len)
00178 {
00179 #ifdef HMAC_RETURN_INT
00180         RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
00181                                 (int) len, EVP_sha384()) == 1);
00182 #else
00183         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
00184 #endif
00185 }
00186 
00187 void
00188 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
00189         HMAC_CTX_cleanup(ctx);
00190 }
00191 
00192 void
00193 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
00194                    unsigned int len)
00195 {
00196 #ifdef HMAC_RETURN_INT
00197         RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
00198 #else
00199         HMAC_Update(ctx, buf, (int) len);
00200 #endif
00201 }
00202 
00203 void
00204 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
00205         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
00206 
00207         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
00208 
00209 #ifdef HMAC_RETURN_INT
00210         RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
00211 #else
00212         HMAC_Final(ctx, newdigest, NULL);
00213 #endif
00214         HMAC_CTX_cleanup(ctx);
00215         memmove(digest, newdigest, len);
00216         memset(newdigest, 0, sizeof(newdigest));
00217 }
00218 
00219 void
00220 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
00221                     unsigned int len)
00222 {
00223 #ifdef HMAC_RETURN_INT
00224         RUNTIME_CHECK(HMAC_Init(ctx, (const void *) key,
00225                                 (int) len, EVP_sha512()) == 1);
00226 #else
00227         HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
00228 #endif
00229 }
00230 
00231 void
00232 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
00233         HMAC_CTX_cleanup(ctx);
00234 }
00235 
00236 void
00237 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
00238                    unsigned int len)
00239 {
00240 #ifdef HMAC_RETURN_INT
00241         RUNTIME_CHECK(HMAC_Update(ctx, buf, (int) len) == 1);
00242 #else
00243         HMAC_Update(ctx, buf, (int) len);
00244 #endif
00245 }
00246 
00247 void
00248 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
00249         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
00250 
00251         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
00252 
00253 #ifdef HMAC_RETURN_INT
00254         RUNTIME_CHECK(HMAC_Final(ctx, newdigest, NULL) == 1);
00255 #else
00256         HMAC_Final(ctx, newdigest, NULL);
00257 #endif
00258         HMAC_CTX_cleanup(ctx);
00259         memmove(digest, newdigest, len);
00260         memset(newdigest, 0, sizeof(newdigest));
00261 }
00262 
00263 #elif PKCS11CRYPTO
00264 
00265 static CK_BBOOL truevalue = TRUE;
00266 static CK_BBOOL falsevalue = FALSE;
00267 
00268 void
00269 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
00270                  unsigned int len)
00271 {
00272         CK_RV rv;
00273         CK_MECHANISM mech = { CKM_SHA_1_HMAC, NULL, 0 };
00274         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
00275         CK_KEY_TYPE keyType = CKK_SHA_1_HMAC;
00276         CK_ATTRIBUTE keyTemplate[] =
00277         {
00278                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00279                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00280                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00281                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00282                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00283                 { CKA_VALUE, NULL, (CK_ULONG) len }
00284         };
00285 
00286         DE_CONST(key, keyTemplate[5].pValue);
00287         RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00288                                        ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00289         ctx->object = CK_INVALID_HANDLE;
00290         PK11_FATALCHECK(pkcs_C_CreateObject,
00291                         (ctx->session, keyTemplate,
00292                          (CK_ULONG) 6, &ctx->object));
00293         INSIST(ctx->object != CK_INVALID_HANDLE);
00294         PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
00295 }
00296 
00297 void
00298 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
00299         CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH];
00300         CK_ULONG len = ISC_SHA1_DIGESTLENGTH;
00301 
00302         if (ctx->handle == NULL)
00303                 return;
00304         (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
00305         memset(garbage, 0, sizeof(garbage));
00306         if (ctx->object != CK_INVALID_HANDLE)
00307                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00308         ctx->object = CK_INVALID_HANDLE;
00309         pk11_return_session(ctx);
00310 }
00311 
00312 void
00313 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
00314                    unsigned int len)
00315 {
00316         CK_RV rv;
00317         CK_BYTE_PTR pPart;
00318 
00319         DE_CONST(buf, pPart);
00320         PK11_FATALCHECK(pkcs_C_SignUpdate,
00321                         (ctx->session, pPart, (CK_ULONG) len));
00322 }
00323 
00324 void
00325 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
00326         CK_RV rv;
00327         CK_BYTE newdigest[ISC_SHA1_DIGESTLENGTH];
00328         CK_ULONG psl = ISC_SHA1_DIGESTLENGTH;
00329 
00330         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
00331 
00332         PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
00333         if (ctx->object != CK_INVALID_HANDLE)
00334                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00335         ctx->object = CK_INVALID_HANDLE;
00336         pk11_return_session(ctx);
00337         memmove(digest, newdigest, len);
00338         memset(newdigest, 0, sizeof(newdigest));
00339 }
00340 
00341 void
00342 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
00343                     unsigned int len)
00344 {
00345         CK_RV rv;
00346         CK_MECHANISM mech = { CKM_SHA224_HMAC, NULL, 0 };
00347         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
00348         CK_KEY_TYPE keyType = CKK_SHA224_HMAC;
00349         CK_ATTRIBUTE keyTemplate[] =
00350         {
00351                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00352                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00353                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00354                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00355                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00356                 { CKA_VALUE, NULL, (CK_ULONG) len }
00357         };
00358 
00359         DE_CONST(key, keyTemplate[5].pValue);
00360         RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00361                                        ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00362         ctx->object = CK_INVALID_HANDLE;
00363         PK11_FATALCHECK(pkcs_C_CreateObject,
00364                         (ctx->session, keyTemplate,
00365                          (CK_ULONG) 6, &ctx->object));
00366         INSIST(ctx->object != CK_INVALID_HANDLE);
00367         PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
00368 }
00369 
00370 void
00371 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
00372         CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH];
00373         CK_ULONG len = ISC_SHA224_DIGESTLENGTH;
00374 
00375         if (ctx->handle == NULL)
00376                 return;
00377         (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
00378         memset(garbage, 0, sizeof(garbage));
00379         if (ctx->object != CK_INVALID_HANDLE)
00380                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00381         ctx->object = CK_INVALID_HANDLE;
00382         pk11_return_session(ctx);
00383 }
00384 
00385 void
00386 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
00387                       unsigned int len)
00388 {
00389         CK_RV rv;
00390         CK_BYTE_PTR pPart;
00391 
00392         DE_CONST(buf, pPart);
00393         PK11_FATALCHECK(pkcs_C_SignUpdate,
00394                         (ctx->session, pPart, (CK_ULONG) len));
00395 }
00396 
00397 void
00398 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
00399         CK_RV rv;
00400         CK_BYTE newdigest[ISC_SHA224_DIGESTLENGTH];
00401         CK_ULONG psl = ISC_SHA224_DIGESTLENGTH;
00402 
00403         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
00404 
00405         PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
00406         if (ctx->object != CK_INVALID_HANDLE)
00407                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00408         ctx->object = CK_INVALID_HANDLE;
00409         pk11_return_session(ctx);
00410         memmove(digest, newdigest, len);
00411         memset(newdigest, 0, sizeof(newdigest));
00412 }
00413 
00414 void
00415 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
00416                     unsigned int len)
00417 {
00418         CK_RV rv;
00419         CK_MECHANISM mech = { CKM_SHA256_HMAC, NULL, 0 };
00420         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
00421         CK_KEY_TYPE keyType = CKK_SHA256_HMAC;
00422         CK_ATTRIBUTE keyTemplate[] =
00423         {
00424                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00425                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00426                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00427                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00428                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00429                 { CKA_VALUE, NULL, (CK_ULONG) len }
00430         };
00431 
00432         DE_CONST(key, keyTemplate[5].pValue);
00433         RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00434                                        ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00435         ctx->object = CK_INVALID_HANDLE;
00436         PK11_FATALCHECK(pkcs_C_CreateObject,
00437                         (ctx->session, keyTemplate,
00438                          (CK_ULONG) 6, &ctx->object));
00439         INSIST(ctx->object != CK_INVALID_HANDLE);
00440         PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
00441 }
00442 
00443 void
00444 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
00445         CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH];
00446         CK_ULONG len = ISC_SHA256_DIGESTLENGTH;
00447 
00448         if (ctx->handle == NULL)
00449                 return;
00450         (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
00451         memset(garbage, 0, sizeof(garbage));
00452         if (ctx->object != CK_INVALID_HANDLE)
00453                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00454         ctx->object = CK_INVALID_HANDLE;
00455         pk11_return_session(ctx);
00456 }
00457 
00458 void
00459 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
00460                       unsigned int len)
00461 {
00462         CK_RV rv;
00463         CK_BYTE_PTR pPart;
00464 
00465         DE_CONST(buf, pPart);
00466         PK11_FATALCHECK(pkcs_C_SignUpdate,
00467                         (ctx->session, pPart, (CK_ULONG) len));
00468 }
00469 
00470 void
00471 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
00472         CK_RV rv;
00473         CK_BYTE newdigest[ISC_SHA256_DIGESTLENGTH];
00474         CK_ULONG psl = ISC_SHA256_DIGESTLENGTH;
00475 
00476         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
00477 
00478         PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
00479         if (ctx->object != CK_INVALID_HANDLE)
00480                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00481         ctx->object = CK_INVALID_HANDLE;
00482         pk11_return_session(ctx);
00483         memmove(digest, newdigest, len);
00484         memset(newdigest, 0, sizeof(newdigest));
00485 }
00486 
00487 void
00488 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
00489                     unsigned int len)
00490 {
00491         CK_RV rv;
00492         CK_MECHANISM mech = { CKM_SHA384_HMAC, NULL, 0 };
00493         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
00494         CK_KEY_TYPE keyType = CKK_SHA384_HMAC;
00495         CK_ATTRIBUTE keyTemplate[] =
00496         {
00497                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00498                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00499                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00500                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00501                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00502                 { CKA_VALUE, NULL, (CK_ULONG) len }
00503         };
00504 
00505         DE_CONST(key, keyTemplate[5].pValue);
00506         RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00507                                        ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00508         ctx->object = CK_INVALID_HANDLE;
00509         PK11_FATALCHECK(pkcs_C_CreateObject,
00510                         (ctx->session, keyTemplate,
00511                          (CK_ULONG) 6, &ctx->object));
00512         INSIST(ctx->object != CK_INVALID_HANDLE);
00513         PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
00514 }
00515 
00516 void
00517 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
00518         CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH];
00519         CK_ULONG len = ISC_SHA384_DIGESTLENGTH;
00520 
00521         if (ctx->handle == NULL)
00522                 return;
00523         (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
00524         memset(garbage, 0, sizeof(garbage));
00525         if (ctx->object != CK_INVALID_HANDLE)
00526                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00527         ctx->object = CK_INVALID_HANDLE;
00528         pk11_return_session(ctx);
00529 }
00530 
00531 void
00532 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
00533                       unsigned int len)
00534 {
00535         CK_RV rv;
00536         CK_BYTE_PTR pPart;
00537 
00538         DE_CONST(buf, pPart);
00539         PK11_FATALCHECK(pkcs_C_SignUpdate,
00540                         (ctx->session, pPart, (CK_ULONG) len));
00541 }
00542 
00543 void
00544 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
00545         CK_RV rv;
00546         CK_BYTE newdigest[ISC_SHA384_DIGESTLENGTH];
00547         CK_ULONG psl = ISC_SHA384_DIGESTLENGTH;
00548 
00549         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
00550 
00551         PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
00552         if (ctx->object != CK_INVALID_HANDLE)
00553                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00554         ctx->object = CK_INVALID_HANDLE;
00555         pk11_return_session(ctx);
00556         memmove(digest, newdigest, len);
00557         memset(newdigest, 0, sizeof(newdigest));
00558 }
00559 
00560 void
00561 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
00562                     unsigned int len)
00563 {
00564         CK_RV rv;
00565         CK_MECHANISM mech = { CKM_SHA512_HMAC, NULL, 0 };
00566         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
00567         CK_KEY_TYPE keyType = CKK_SHA512_HMAC;
00568         CK_ATTRIBUTE keyTemplate[] =
00569         {
00570                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00571                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00572                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00573                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00574                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00575                 { CKA_VALUE, NULL, (CK_ULONG) len }
00576         };
00577 
00578         DE_CONST(key, keyTemplate[5].pValue);
00579         RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
00580                                        ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
00581         ctx->object = CK_INVALID_HANDLE;
00582         PK11_FATALCHECK(pkcs_C_CreateObject,
00583                         (ctx->session, keyTemplate,
00584                          (CK_ULONG) 6, &ctx->object));
00585         INSIST(ctx->object != CK_INVALID_HANDLE);
00586         PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
00587 }
00588 
00589 void
00590 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
00591         CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH];
00592         CK_ULONG len = ISC_SHA512_DIGESTLENGTH;
00593 
00594         if (ctx->handle == NULL)
00595                 return;
00596         (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
00597         memset(garbage, 0, sizeof(garbage));
00598         if (ctx->object != CK_INVALID_HANDLE)
00599                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00600         ctx->object = CK_INVALID_HANDLE;
00601         pk11_return_session(ctx);
00602 }
00603 
00604 void
00605 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
00606                       unsigned int len)
00607 {
00608         CK_RV rv;
00609         CK_BYTE_PTR pPart;
00610 
00611         DE_CONST(buf, pPart);
00612         PK11_FATALCHECK(pkcs_C_SignUpdate,
00613                         (ctx->session, pPart, (CK_ULONG) len));
00614 }
00615 
00616 void
00617 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
00618         CK_RV rv;
00619         CK_BYTE newdigest[ISC_SHA512_DIGESTLENGTH];
00620         CK_ULONG psl = ISC_SHA512_DIGESTLENGTH;
00621 
00622         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
00623 
00624         PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl));
00625         if (ctx->object != CK_INVALID_HANDLE)
00626                 (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
00627         ctx->object = CK_INVALID_HANDLE;
00628         pk11_return_session(ctx);
00629         memmove(digest, newdigest, len);
00630         memset(newdigest, 0, sizeof(newdigest));
00631 }
00632 
00633 #else
00634 
00635 #define IPAD 0x36
00636 #define OPAD 0x5C
00637 
00638 /*
00639  * Start HMAC-SHA1 process.  Initialize an sha1 context and digest the key.
00640  */
00641 void
00642 isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
00643                   unsigned int len)
00644 {
00645         unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
00646         unsigned int i;
00647 
00648         memset(ctx->key, 0, sizeof(ctx->key));
00649         if (len > sizeof(ctx->key)) {
00650                 isc_sha1_t sha1ctx;
00651                 isc_sha1_init(&sha1ctx);
00652                 isc_sha1_update(&sha1ctx, key, len);
00653                 isc_sha1_final(&sha1ctx, ctx->key);
00654         } else
00655                 memmove(ctx->key, key, len);
00656 
00657         isc_sha1_init(&ctx->sha1ctx);
00658         memset(ipad, IPAD, sizeof(ipad));
00659         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
00660                 ipad[i] ^= ctx->key[i];
00661         isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
00662 }
00663 
00664 void
00665 isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
00666         isc_sha1_invalidate(&ctx->sha1ctx);
00667         memset(ctx, 0, sizeof(*ctx));
00668 }
00669 
00670 /*
00671  * Update context to reflect the concatenation of another buffer full
00672  * of bytes.
00673  */
00674 void
00675 isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
00676                    unsigned int len)
00677 {
00678         isc_sha1_update(&ctx->sha1ctx, buf, len);
00679 }
00680 
00681 /*
00682  * Compute signature - finalize SHA1 operation and reapply SHA1.
00683  */
00684 void
00685 isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
00686         unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
00687         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
00688         unsigned int i;
00689 
00690         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
00691         isc_sha1_final(&ctx->sha1ctx, newdigest);
00692 
00693         memset(opad, OPAD, sizeof(opad));
00694         for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
00695                 opad[i] ^= ctx->key[i];
00696 
00697         isc_sha1_init(&ctx->sha1ctx);
00698         isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
00699         isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
00700         isc_sha1_final(&ctx->sha1ctx, newdigest);
00701         isc_hmacsha1_invalidate(ctx);
00702         memmove(digest, newdigest, len);
00703         memset(newdigest, 0, sizeof(newdigest));
00704 }
00705 
00706 /*
00707  * Start HMAC-SHA224 process.  Initialize an sha224 context and digest the key.
00708  */
00709 void
00710 isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
00711                     unsigned int len)
00712 {
00713         unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
00714         unsigned int i;
00715 
00716         memset(ctx->key, 0, sizeof(ctx->key));
00717         if (len > sizeof(ctx->key)) {
00718                 isc_sha224_t sha224ctx;
00719                 isc_sha224_init(&sha224ctx);
00720                 isc_sha224_update(&sha224ctx, key, len);
00721                 isc_sha224_final(ctx->key, &sha224ctx);
00722         } else
00723                 memmove(ctx->key, key, len);
00724 
00725         isc_sha224_init(&ctx->sha224ctx);
00726         memset(ipad, IPAD, sizeof(ipad));
00727         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
00728                 ipad[i] ^= ctx->key[i];
00729         isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
00730 }
00731 
00732 void
00733 isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
00734         memset(ctx, 0, sizeof(*ctx));
00735 }
00736 
00737 /*
00738  * Update context to reflect the concatenation of another buffer full
00739  * of bytes.
00740  */
00741 void
00742 isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
00743                    unsigned int len)
00744 {
00745         isc_sha224_update(&ctx->sha224ctx, buf, len);
00746 }
00747 
00748 /*
00749  * Compute signature - finalize SHA224 operation and reapply SHA224.
00750  */
00751 void
00752 isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
00753         unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
00754         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
00755         unsigned int i;
00756 
00757         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
00758         isc_sha224_final(newdigest, &ctx->sha224ctx);
00759 
00760         memset(opad, OPAD, sizeof(opad));
00761         for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
00762                 opad[i] ^= ctx->key[i];
00763 
00764         isc_sha224_init(&ctx->sha224ctx);
00765         isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
00766         isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
00767         isc_sha224_final(newdigest, &ctx->sha224ctx);
00768         memmove(digest, newdigest, len);
00769         memset(newdigest, 0, sizeof(newdigest));
00770 }
00771 
00772 /*
00773  * Start HMAC-SHA256 process.  Initialize an sha256 context and digest the key.
00774  */
00775 void
00776 isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
00777                     unsigned int len)
00778 {
00779         unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
00780         unsigned int i;
00781 
00782         memset(ctx->key, 0, sizeof(ctx->key));
00783         if (len > sizeof(ctx->key)) {
00784                 isc_sha256_t sha256ctx;
00785                 isc_sha256_init(&sha256ctx);
00786                 isc_sha256_update(&sha256ctx, key, len);
00787                 isc_sha256_final(ctx->key, &sha256ctx);
00788         } else
00789                 memmove(ctx->key, key, len);
00790 
00791         isc_sha256_init(&ctx->sha256ctx);
00792         memset(ipad, IPAD, sizeof(ipad));
00793         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
00794                 ipad[i] ^= ctx->key[i];
00795         isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
00796 }
00797 
00798 void
00799 isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
00800         memset(ctx, 0, sizeof(*ctx));
00801 }
00802 
00803 /*
00804  * Update context to reflect the concatenation of another buffer full
00805  * of bytes.
00806  */
00807 void
00808 isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
00809                    unsigned int len)
00810 {
00811         isc_sha256_update(&ctx->sha256ctx, buf, len);
00812 }
00813 
00814 /*
00815  * Compute signature - finalize SHA256 operation and reapply SHA256.
00816  */
00817 void
00818 isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
00819         unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
00820         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
00821         unsigned int i;
00822 
00823         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
00824         isc_sha256_final(newdigest, &ctx->sha256ctx);
00825 
00826         memset(opad, OPAD, sizeof(opad));
00827         for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
00828                 opad[i] ^= ctx->key[i];
00829 
00830         isc_sha256_init(&ctx->sha256ctx);
00831         isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
00832         isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
00833         isc_sha256_final(newdigest, &ctx->sha256ctx);
00834         memmove(digest, newdigest, len);
00835         memset(newdigest, 0, sizeof(newdigest));
00836 }
00837 
00838 /*
00839  * Start HMAC-SHA384 process.  Initialize an sha384 context and digest the key.
00840  */
00841 void
00842 isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
00843                     unsigned int len)
00844 {
00845         unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
00846         unsigned int i;
00847 
00848         memset(ctx->key, 0, sizeof(ctx->key));
00849         if (len > sizeof(ctx->key)) {
00850                 isc_sha384_t sha384ctx;
00851                 isc_sha384_init(&sha384ctx);
00852                 isc_sha384_update(&sha384ctx, key, len);
00853                 isc_sha384_final(ctx->key, &sha384ctx);
00854         } else
00855                 memmove(ctx->key, key, len);
00856 
00857         isc_sha384_init(&ctx->sha384ctx);
00858         memset(ipad, IPAD, sizeof(ipad));
00859         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
00860                 ipad[i] ^= ctx->key[i];
00861         isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
00862 }
00863 
00864 void
00865 isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
00866         memset(ctx, 0, sizeof(*ctx));
00867 }
00868 
00869 /*
00870  * Update context to reflect the concatenation of another buffer full
00871  * of bytes.
00872  */
00873 void
00874 isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
00875                    unsigned int len)
00876 {
00877         isc_sha384_update(&ctx->sha384ctx, buf, len);
00878 }
00879 
00880 /*
00881  * Compute signature - finalize SHA384 operation and reapply SHA384.
00882  */
00883 void
00884 isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
00885         unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
00886         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
00887         unsigned int i;
00888 
00889         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
00890         isc_sha384_final(newdigest, &ctx->sha384ctx);
00891 
00892         memset(opad, OPAD, sizeof(opad));
00893         for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
00894                 opad[i] ^= ctx->key[i];
00895 
00896         isc_sha384_init(&ctx->sha384ctx);
00897         isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
00898         isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
00899         isc_sha384_final(newdigest, &ctx->sha384ctx);
00900         memmove(digest, newdigest, len);
00901         memset(newdigest, 0, sizeof(newdigest));
00902 }
00903 
00904 /*
00905  * Start HMAC-SHA512 process.  Initialize an sha512 context and digest the key.
00906  */
00907 void
00908 isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
00909                     unsigned int len)
00910 {
00911         unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
00912         unsigned int i;
00913 
00914         memset(ctx->key, 0, sizeof(ctx->key));
00915         if (len > sizeof(ctx->key)) {
00916                 isc_sha512_t sha512ctx;
00917                 isc_sha512_init(&sha512ctx);
00918                 isc_sha512_update(&sha512ctx, key, len);
00919                 isc_sha512_final(ctx->key, &sha512ctx);
00920         } else
00921                 memmove(ctx->key, key, len);
00922 
00923         isc_sha512_init(&ctx->sha512ctx);
00924         memset(ipad, IPAD, sizeof(ipad));
00925         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
00926                 ipad[i] ^= ctx->key[i];
00927         isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
00928 }
00929 
00930 void
00931 isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
00932         memset(ctx, 0, sizeof(*ctx));
00933 }
00934 
00935 /*
00936  * Update context to reflect the concatenation of another buffer full
00937  * of bytes.
00938  */
00939 void
00940 isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
00941                    unsigned int len)
00942 {
00943         isc_sha512_update(&ctx->sha512ctx, buf, len);
00944 }
00945 
00946 /*
00947  * Compute signature - finalize SHA512 operation and reapply SHA512.
00948  */
00949 void
00950 isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
00951         unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
00952         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
00953         unsigned int i;
00954 
00955         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
00956         isc_sha512_final(newdigest, &ctx->sha512ctx);
00957 
00958         memset(opad, OPAD, sizeof(opad));
00959         for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
00960                 opad[i] ^= ctx->key[i];
00961 
00962         isc_sha512_init(&ctx->sha512ctx);
00963         isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
00964         isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
00965         isc_sha512_final(newdigest, &ctx->sha512ctx);
00966         memmove(digest, newdigest, len);
00967         memset(newdigest, 0, sizeof(newdigest));
00968 }
00969 #endif /* !ISC_PLATFORM_OPENSSLHASH */
00970 
00971 /*
00972  * Verify signature - finalize SHA1 operation and reapply SHA1, then
00973  * compare to the supplied digest.
00974  */
00975 isc_boolean_t
00976 isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
00977         unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
00978 
00979         REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
00980         isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
00981         return (isc_safe_memcmp(digest, newdigest, len));
00982 }
00983 
00984 /*
00985  * Verify signature - finalize SHA224 operation and reapply SHA224, then
00986  * compare to the supplied digest.
00987  */
00988 isc_boolean_t
00989 isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
00990         unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
00991 
00992         REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
00993         isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
00994         return (isc_safe_memcmp(digest, newdigest, len));
00995 }
00996 
00997 /*
00998  * Verify signature - finalize SHA256 operation and reapply SHA256, then
00999  * compare to the supplied digest.
01000  */
01001 isc_boolean_t
01002 isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
01003         unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
01004 
01005         REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
01006         isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
01007         return (isc_safe_memcmp(digest, newdigest, len));
01008 }
01009 
01010 /*
01011  * Verify signature - finalize SHA384 operation and reapply SHA384, then
01012  * compare to the supplied digest.
01013  */
01014 isc_boolean_t
01015 isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
01016         unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
01017 
01018         REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
01019         isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
01020         return (isc_safe_memcmp(digest, newdigest, len));
01021 }
01022 
01023 /*
01024  * Verify signature - finalize SHA512 operation and reapply SHA512, then
01025  * compare to the supplied digest.
01026  */
01027 isc_boolean_t
01028 isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
01029         unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
01030 
01031         REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
01032         isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
01033         return (isc_safe_memcmp(digest, newdigest, len));
01034 }

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