ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
2728d0618e15ee3a2ecc5f6d15acd7898e6de85aTinderbox User * Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#ifdef PKCS11CRYPTO
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <config.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#include <pk11/site.h>
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#ifndef PK11_DH_DISABLE
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <ctype.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/mem.h>
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt#include <isc/safe.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/string.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dst/result.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_internal.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_parse.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include "dst_pkcs11.h"
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/pk11.h>
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/internal.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define WANT_DH_PRIMES
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/constants.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <pkcs11/pkcs11.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * PKCS#3 DH keys:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * mechanisms:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_DH_PKCS_PARAMETER_GEN,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_DH_PKCS_KEY_PAIR_GEN,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * CKM_DH_PKCS_DERIVE
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * domain parameters:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * object class CKO_DOMAIN_PARAMETERS
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * key type CKK_DH
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_PRIME (prime p)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_BASE (base g)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * optional attribute CKA_PRIME_BITS (p length in bits)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * public key:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * object class CKO_PUBLIC_KEY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * key type CKK_DH
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_PRIME (prime p)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_BASE (base g)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_VALUE (public value y)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * private key:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * object class CKO_PRIVATE_KEY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * key type CKK_DH
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_PRIME (prime p)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_BASE (base g)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * attribute CKA_VALUE (private value x)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * optional attribute CKA_VALUE_BITS (x length in bits)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * reuse CKA_PRIVATE_EXPONENT for key pair private value
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define CKA_VALUE2 CKA_PRIVATE_EXPONENT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL truevalue = TRUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic CK_BBOOL falsevalue = FALSE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define DST_RET(a) {ret = a; goto err;}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void pkcs11dh_destroy(dst_key_t *key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_loadpriv(const dst_key_t *key,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_SESSION_HANDLE session,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE *hKey)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_DH;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE keyTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_BASE, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_VALUE, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt const pk11_object_t *priv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((priv->object != CK_INVALID_HANDLE) && priv->ontoken) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *hKey = priv->object;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(priv, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[6].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[6].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(priv, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[7].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[7].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[7].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(priv, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(DST_R_INVALIDPRIVATEKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[8].pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[8].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[8].ulValueLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_CALL(pkcs_C_CreateObject,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (session, keyTemplate, (CK_ULONG) 9, hKey),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_COMPUTESECRETFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rv == CKR_OK)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 6; i <= 8; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (keyTemplate[i].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(keyTemplate[i].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate[i].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_t *secret)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG secLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE keyTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE valTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_VALUE, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *secValue;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(pub->keydata.pkey != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(priv->keydata.pkey != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(priv->keydata.pkey->repr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPUBLICKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt secLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_INVALIDPUBLICKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt priv->keydata.pkey->reqlogon, NULL,
f5c17a057fc5974bb51d7bc8c5827a7fd6dc9aeeEvan Hunt pk11_get_best_token(OP_DH));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.ulParameterLen = attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (mech.pParameter == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(mech.pParameter, attr->pValue, mech.ulParameterLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_DeriveKey,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (ctx.session, &mech, hKey,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt keyTemplate, (CK_ULONG) 6, &hDerived),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_COMPUTESECRETFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = valTemplate;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (ctx.session, hDerived, attr, (CK_ULONG) 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr->pValue, 0, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (ctx.session, hDerived, attr, (CK_ULONG) 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* strip leading zeros */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt secValue = (CK_BYTE_PTR) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < attr->ulValueLen; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (secValue[i] != 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_availableregion(secret, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < attr->ulValueLen - i)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOSPACE);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, secValue + i, attr->ulValueLen - i);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(secret, attr->ulValueLen - i);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = ISC_R_SUCCESS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (hDerived != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(ctx.session, hDerived);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (valTemplate[0].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(valTemplate[0].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman valTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(pub->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt valTemplate[0].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt valTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(ctx.session, hKey);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (mech.pParameter != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(mech.pParameter, mech.ulParameterLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(&ctx);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_compare(const dst_key_t *key1, const dst_key_t *key2) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh1, *dh2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr1, *attr2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh1 = key1->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh2 = key2->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((dh1 == NULL) && (dh2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((dh1 == NULL) || (dh2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (((attr1 != NULL) || (attr2 != NULL)) &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen)))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (!dh1->ontoken && !dh2->ontoken)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if (dh1->ontoken || dh2->ontoken ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (dh1->object != dh2->object))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh1, *dh2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr1, *attr2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh1 = key1->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh2 = key2->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((dh1 == NULL) && (dh2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((dh1 == NULL) || (dh2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr1 = pk11_attribute_bytype(dh1, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr2 = pk11_attribute_bytype(dh2, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((attr1 == NULL) && (attr2 == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else if ((attr1 == NULL) || (attr2 == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (attr1->ulValueLen != attr2->ulValueLen) ||
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt !isc_safe_memequal(attr1->pValue, attr2->pValue,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt attr1->ulValueLen))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TRUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_KEY_TYPE keyType = CKK_DH;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG bits = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE dTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE pTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_BASE, NULL, 0 }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE pubTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIME, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_BASE, NULL, 0 },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE privTemplate[] =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt };
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh = NULL;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t *pk11_ctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(callback);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pk11_ctx == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOMEMORY);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE,
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ISC_FALSE, NULL, pk11_get_best_token(OP_DH));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto err;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bits = key->key_size;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((generator == 0) &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ((bits == 768) || (bits == 1024) || (bits == 1536))) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bits == 768) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_get(key->mctx, sizeof(pk11_dh_bn768));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[4].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(pubTemplate[4].pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt pk11_dh_bn768, sizeof(pk11_dh_bn768));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else if (bits == 1024) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[4].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(pubTemplate[4].pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt pk11_dh_bn1024, sizeof(pk11_dh_bn1024));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue =
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[4].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(pubTemplate[4].pValue,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt pk11_dh_bn1536, sizeof(pk11_dh_bn1536));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].pValue = isc_mem_get(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt sizeof(pk11_dh_bn2));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[5].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(pubTemplate[5].pValue, pk11_dh_bn2,
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt sizeof(pk11_dh_bn2));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GenerateKey,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &mech,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dTemplate, (CK_ULONG) 5, &domainparams),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, domainparams,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate, (CK_ULONG) 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[0].pValue = isc_mem_get(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pTemplate[0].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[1].pValue = isc_mem_get(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[1].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pTemplate[1].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, domainparams,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate, (CK_ULONG) 2),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue = pTemplate[0].pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[0].pValue = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].pValue = pTemplate[1].pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[1].pValue = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GenerateKeyPair,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, &mech,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate, (CK_ULONG) 6,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt privTemplate, (CK_ULONG) 7,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt &pub, &priv),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh, 0, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = dh;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh->repr, 0, sizeof(*attr) * 4);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->attrcnt = 4;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = dh->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_PRIME;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].pValue = pubTemplate[4].pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].ulValueLen = pubTemplate[4].ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_BASE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].pValue = pubTemplate[5].pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].ulValueLen = pubTemplate[5].ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].pValue =NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr += 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr->pValue, 0, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, pub, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(attr->pValue, 0, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_RET(pkcs_C_GetAttributeValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pk11_ctx->session, priv, attr, 1),
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_R_CRYPTOFAILURE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->type = CKA_VALUE2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_destroy(key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (priv != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pub != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (domainparams != CK_INVALID_HANDLE)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[4].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pubTemplate[4].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman pubTemplate[4].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[4].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pubTemplate[5].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pubTemplate[5].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman pubTemplate[5].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pubTemplate[5].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pTemplate[0].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pTemplate[0].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman pTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[0].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[0].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (pTemplate[1].pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pTemplate[1].pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman pTemplate[1].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[1].pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pTemplate[1].ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(pk11_ctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_boolean_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_isprivate(const dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_FALSE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_TF((attr != NULL) || dh->ontoken));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_destroy(dst_key_t *key) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST((dh->object == CK_INVALID_HANDLE) || dh->ontoken);
e20788e1216ed720aefa84f3295f7899d9f28c22Mark Andrews
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(dh);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(dh, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_BASE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(attr->pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(dh, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, dh, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic void
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntuint16_toregion(isc_uint16_t val, isc_region_t *region) {
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt *region->base = (val & 0xff00) >> 8;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(region, 1);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt *region->base = (val & 0x00ff);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(region, 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_uint16_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntuint16_fromregion(isc_region_t *region) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_uint16_t val;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned char *cp = region->base;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt val = ((unsigned int)(cp[0])) << 8;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt val |= ((unsigned int)(cp[1]));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(region, 2);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (val);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) {
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_uint16_t dnslen, plen = 0, glen = 0, publen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *prime = NULL, *base = NULL, *pub = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(key->keydata.pkey != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(dh);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(dh, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub = (CK_BYTE *) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt publen = (isc_uint16_t) attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = (CK_BYTE *) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen = (isc_uint16_t) attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_BASE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt base = (CK_BYTE *) attr->pValue;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt glen = (isc_uint16_t) attr->ulValueLen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE((prime != NULL) && (base != NULL) && (pub != NULL));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_availableregion(data, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt if ((glen == 1) && isc_safe_memequal(pk11_dh_bn2, base, glen) &&
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (((plen == sizeof(pk11_dh_bn768)) &&
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt isc_safe_memequal(pk11_dh_bn768, prime, plen)) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ((plen == sizeof(pk11_dh_bn1024)) &&
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt isc_safe_memequal(pk11_dh_bn1024, prime, plen)) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ((plen == sizeof(pk11_dh_bn1536)) &&
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt isc_safe_memequal(pk11_dh_bn1536, prime, plen)))) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt glen = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dnslen = plen + glen + publen + 6;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (r.length < (unsigned int) dnslen)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_NOSPACE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt uint16_toregion(plen, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (plen == 1) {
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt if (isc_safe_memequal(pk11_dh_bn768, prime,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt sizeof(pk11_dh_bn768)))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *r.base = 1;
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt else if (isc_safe_memequal(pk11_dh_bn1024, prime,
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt sizeof(pk11_dh_bn1024)))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *r.base = 2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *r.base = 3;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, prime, plen);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, plen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt uint16_toregion(glen, &r);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (glen > 0)
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, base, glen);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, glen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt uint16_toregion(publen, &r);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(r.base, pub, publen);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, publen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_add(data, dnslen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman pk11_object_t *dh = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_region_t r;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_uint16_t plen, glen, plen_, glen_, publen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *prime = NULL, *base = NULL, *pub = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int special = 0;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_remainingregion(data, &r);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length == 0) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman result = ISC_R_SUCCESS;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (dh == NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman result = ISC_R_NOMEMORY;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh, 0, sizeof(*dh));
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman result = DST_R_INVALIDPUBLICKEY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Read the prime length. 1 & 2 are table entries, > 16 means a
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * prime follows, otherwise an error.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < 2)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen = uint16_fromregion(&r);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (plen < 16 && plen != 1 && plen != 2)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < plen)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen_ = plen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (plen == 1 || plen == 2) {
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt if (plen == 1) {
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt special = *r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, 1);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt } else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt special = uint16_fromregion(&r);
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (special) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 1:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = pk11_dh_bn768;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen_ = sizeof(pk11_dh_bn768);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = pk11_dh_bn1024;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen_ = sizeof(pk11_dh_bn1024);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 3:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = pk11_dh_bn1536;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt plen_ = sizeof(pk11_dh_bn1536);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, plen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Read the generator length. This should be 0 if the prime was
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * special, but it might not be. If it's 0 and the prime is not
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * special, we have a problem.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < 2)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt glen = uint16_fromregion(&r);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < glen)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt glen_ = glen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (special != 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (glen == 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt base = pk11_dh_bn2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt glen_ = sizeof(pk11_dh_bn2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt base = r.base;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (!isc_safe_memequal(base, pk11_dh_bn2, glen))
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman base = pk11_dh_bn2;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman glen_ = sizeof(pk11_dh_bn2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt else {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (glen == 0)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt base = r.base;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, glen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < 2)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt publen = uint16_fromregion(&r);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (r.length < publen)
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman goto cleanup;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub = r.base;
ce9f893e21d2ffc6f6a78bf226c038c396740aebEvan Hunt isc_region_consume(&r, publen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(prime, plen_);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh->repr, 0, sizeof(*attr) * 3);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->attrcnt = 3;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = dh->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_PRIME;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].pValue = isc_mem_get(key->mctx, plen_);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[0].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr[0].pValue, prime, plen_);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].ulValueLen = (CK_ULONG) plen_;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_BASE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].pValue = isc_mem_get(key->mctx, glen_);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[1].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr[1].pValue, base, glen_);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].ulValueLen = (CK_ULONG) glen_;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].pValue = isc_mem_get(key->mctx, publen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr[2].pValue == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto nomemory;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(attr[2].pValue, pub, publen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].ulValueLen = (CK_ULONG) publen;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_buffer_forward(data, plen + glen + publen + 6);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = dh;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman nomemory:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(dh);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(dh, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_BASE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (attr->pValue != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(attr->pValue,
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh->repr != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman result = ISC_R_NOMEMORY;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman cleanup:
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman if (dh != NULL) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(dh, sizeof(*dh));
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_mem_put(key->mctx, dh, sizeof(*dh));
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman }
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_tofile(const dst_key_t *key, const char *directory) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int i;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *prime = NULL, *base = NULL, *pub = NULL, *prv = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_private_t priv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned char *bufs[4];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (key->keydata.pkey == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NULLKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (key->external)
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt return (DST_R_EXTERNALKEY);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh = key->keydata.pkey;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (attr = pk11_attribute_first(dh);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr != NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_next(dh, attr))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (attr->type) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pub = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_VALUE2:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prv = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_PRIME:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt prime = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case CKA_BASE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt base = attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if ((prime == NULL) || (base == NULL) ||
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (pub == NULL) || (prv == NULL))
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (DST_R_NULLKEY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(bufs, 0, sizeof(bufs));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < 4; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bufs[i] = isc_mem_get(key->mctx, prime->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bufs[i] == NULL) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = ISC_R_NOMEMORY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto fail;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(bufs[i], 0, prime->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_DH_PRIME;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) prime->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], prime->pValue, prime->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_DH_GENERATOR;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) base->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], base->pValue, base->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_DH_PRIVATE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) prv->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], prv->pValue, prv->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].tag = TAG_DH_PUBLIC;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].length = (unsigned short) pub->ulValueLen;
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bufs[i], pub->pValue, pub->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.elements[i].data = bufs[i];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt priv.nelements = i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = dst__privstruct_writefile(key, &priv, directory);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fail:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < 4; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bufs[i] == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(bufs[i], prime->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_put(key->mctx, bufs[i], prime->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic isc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntpkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst_private_t priv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t ret;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int i;
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_object_t *dh = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ATTRIBUTE *attr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_mem_t *mctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt UNUSED(pub);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt mctx = key->mctx;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* read private key file */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (ret != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt if (key->external)
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt DST_RET(DST_R_EXTERNALKEY);
3249da26fc28297265d444a1f3647f1e6700a2a0Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh, 0, sizeof(*dh));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->keydata.pkey = dh;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (dh->repr == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt memset(dh->repr, 0, sizeof(*attr) * 4);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dh->attrcnt = 4;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = dh->repr;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[0].type = CKA_PRIME;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[1].type = CKA_BASE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[2].type = CKA_VALUE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr[3].type = CKA_VALUE2;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < priv.nelements; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_BYTE *bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt bn = isc_mem_get(key->mctx, priv.elements[i].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (bn == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt DST_RET(ISC_R_NOMEMORY);
1b255a0c4eaccf0feff70328a8c108a22abfbf3cEvan Hunt memmove(bn, priv.elements[i].data, priv.elements[i].length);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (priv.elements[i].tag) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_DH_PRIME:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_DH_GENERATOR:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_BASE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_DH_PRIVATE:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_VALUE2);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case TAG_DH_PUBLIC:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_VALUE);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->pValue = bn;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr->ulValueLen = priv.elements[i].length;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst__privstruct_free(&priv, mctx);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt attr = pk11_attribute_bytype(dh, CKA_PRIME);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt INSIST(attr != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt err:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_destroy(key);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt dst__privstruct_free(&priv, mctx);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(&priv, sizeof(priv));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ret);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntstatic dst_func_t pkcs11dh_functions = {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< createctx */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< createctx2 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< destroyctx */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< adddata */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< sign */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< verify */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< verify2 */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_computesecret,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_compare,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_paramcompare,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_generate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_isprivate,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_destroy,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_todns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_fromdns,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_tofile,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pkcs11dh_parse,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< cleanup */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< fromlabel */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< dump */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt NULL, /*%< restore */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt};
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_result_t
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdst__pkcs11dh_init(dst_func_t **funcp) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt REQUIRE(funcp != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (*funcp == NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *funcp = &pkcs11dh_functions;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (ISC_R_SUCCESS);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif /* !PK11_DH_DISABLE */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#else /* PKCS11CRYPTO */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan HuntEMPTY_TRANSLATION_UNIT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif /* PKCS11CRYPTO */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*! \file */