void pk11_rand_seed_fromfile(const char *randomfile) { pk11_context_t ctx; FILE *stream = NULL; size_t cc = 0; isc_result_t ret; ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, ISC_FALSE, NULL, 0); if ((ret != ISC_R_SUCCESS) && (ret != PK11_R_NODIGESTSERVICE) && (ret != PK11_R_NOAESSERVICE)) return; RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); ret = isc_stdio_open(randomfile, "r", &stream); if (ret != ISC_R_SUCCESS) goto cleanup; ret = isc_stdio_read(seed, 1, SEEDSIZE, stream, &cc); if (ret!= ISC_R_SUCCESS) goto cleanup; ret = isc_stdio_close(stream); stream = NULL; if (ret!= ISC_R_SUCCESS) goto cleanup; (void) pkcs_C_SeedRandom(ctx.session, seed, (CK_ULONG) cc); cleanup: if (stream != NULL) (void) isc_stdio_close(stream); pk11_return_session(&ctx); }
void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_MD5_HMAC; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, (CK_ULONG) len } }; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx->object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx->session, keyTemplate, (CK_ULONG) 6, &ctx->object)); INSIST(ctx->object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); }
void isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, unsigned int len) { CK_RV rv; CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; unsigned char ipad[PADLEN]; unsigned int i; RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL); if (len > PADLEN) { CK_BYTE_PTR kPart; CK_ULONG kl; PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); DE_CONST(key, kPart); PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, kPart, (CK_ULONG) len)); kl = ISC_MD5_DIGESTLENGTH; PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, (CK_BYTE_PTR) ctx->key, &kl)); } else memmove(ctx->key, key, len); PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); memset(ipad, IPAD, PADLEN); for (i = 0; i < PADLEN; i++) ipad[i] ^= ctx->key[i]; PK11_FATALCHECK(pkcs_C_DigestUpdate, (ctx->session, ipad, (CK_ULONG) PADLEN)); }
isc_result_t isc_gost_init(isc_gost_t *ctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 }; int ret = ISC_R_SUCCESS; ret = pk11_get_session(ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, 0); if (ret != ISC_R_SUCCESS) return (ret); PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE); return (ret); }
static void isc_aes_crypt(const unsigned char *key, CK_ULONG keylen, const unsigned char *in, unsigned char *out) { CK_RV rv; CK_MECHANISM mech = { CKM_AES_ECB, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_AES; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_ENCRYPT, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, keylen } }; CK_ULONG blocklen; CK_BYTE_PTR pData; pk11_context_t ctx; DE_CONST(key, keyTemplate[5].pValue); RUNTIME_CHECK(pk11_get_session(&ctx, OP_AES, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); ctx.object = CK_INVALID_HANDLE; PK11_FATALCHECK(pkcs_C_CreateObject, (ctx.session, keyTemplate, (CK_ULONG) 6, &ctx.object)); INSIST(ctx.object != CK_INVALID_HANDLE); PK11_FATALCHECK(pkcs_C_EncryptInit, (ctx.session, &mech, ctx.object)); DE_CONST(in, pData); blocklen = (CK_ULONG) ISC_AES_BLOCK_LENGTH; PK11_FATALCHECK(pkcs_C_Encrypt, (ctx.session, pData, (CK_ULONG) ISC_AES_BLOCK_LENGTH, out, &blocklen)); RUNTIME_CHECK(blocklen == (CK_ULONG) ISC_AES_BLOCK_LENGTH); (void) pkcs_C_DestroyObject(ctx.session, ctx.object); ctx.object = CK_INVALID_HANDLE; pk11_return_session(&ctx); }
isc_result_t pk11_rand_bytes(unsigned char *buf, int num) { isc_result_t ret; CK_RV rv; pk11_context_t ctx; ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, NULL, 0); if (ret != ISC_R_SUCCESS) return (ret); RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); rv = pkcs_C_GenerateRandom(ctx.session, (CK_BYTE_PTR) buf, (CK_ULONG) num); pk11_return_session(&ctx); if (rv == CKR_OK) return (ISC_R_SUCCESS); else return (DST_R_CRYPTOFAILURE); }
static isc_result_t pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = {0, NULL, 0 }; CK_SLOT_ID slotid; pk11_context_t *pk11_ctx; pk11_object_t *ec = key->keydata.pkey; isc_result_t ret; REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || dctx->key->key_alg == DST_ALG_ECDSA384); REQUIRE(ec != NULL); if (dctx->key->key_alg == DST_ALG_ECDSA256) mech.mechanism = CKM_SHA256; else mech.mechanism = CKM_SHA384; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (ec->ontoken && (dctx->use == DO_SIGN)) slotid = ec->slot; else slotid = pk11_get_best_token(OP_EC); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ec->reqlogon, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; return (ISC_R_SUCCESS); err: pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_ULONG bits = 0; CK_BYTE pubexp[5]; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if (exp == 0) { /* RSA_F4 0x10001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 1; pubTemplate[6].ulValueLen = 3; } else { /* F5 0x100000001 */ pubexp[0] = 1; pubexp[1] = 0; pubexp[2] = 0; pubexp[3] = 0; pubexp[4] = 1; pubTemplate[6].ulValueLen = 5; } PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); key->keydata.pkey = rsa; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 8); rsa->attrcnt = 8; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; attr[2].type = CKA_PRIVATE_EXPONENT; attr[3].type = CKA_PRIME_1; attr[4].type = CKA_PRIME_2; attr[5].type = CKA_EXPONENT_1; attr[6].type = CKA_EXPONENT_2; attr[7].type = CKA_COEFFICIENT; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 2), DST_R_CRYPTOFAILURE); attr += 2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); for (i = 0; i <= 5; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 6), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { CK_RV rv; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; unsigned int i; UNUSED(pin); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) return (ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); rsa->object = CK_INVALID_HANDLE; rsa->ontoken = ISC_TRUE; rsa->reqlogon = ISC_TRUE; key->keydata.pkey = rsa; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[1].type = CKA_PUBLIC_EXPONENT; ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, rsa->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(rsa, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(rsa, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); attr = rsa->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); for (i = 0; i <= 1; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); keyClass = CKO_PRIVATE_KEY; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); }
static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, dst_key_t *pub) { CK_RV rv; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE searchTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_LABEL, NULL, 0 } }; CK_ULONG cnt; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *pubattr; pk11_object_t *rsa; pk11_object_t *pubrsa; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; if (label == NULL) return (DST_R_NOENGINE); rsa = key->keydata.pkey; pubrsa = pub->keydata.pkey; rsa->object = CK_INVALID_HANDLE; rsa->ontoken = ISC_TRUE; rsa->reqlogon = ISC_TRUE; rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) return (ISC_R_NOMEMORY); memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr->type = CKA_MODULUS; pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; attr++; attr->type = CKA_PUBLIC_EXPONENT; pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); if (ret != ISC_R_SUCCESS) goto err; pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) DST_RET(ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, rsa->slot); if (ret != ISC_R_SUCCESS) goto err; attr = pk11_attribute_bytype(rsa, CKA_LABEL); if (attr == NULL) { attr = pk11_attribute_bytype(rsa, CKA_ID); INSIST(attr != NULL); searchTemplate[3].type = CKA_ID; } searchTemplate[3].pValue = attr->pValue; searchTemplate[3].ulValueLen = attr->ulValueLen; PK11_RET(pkcs_C_FindObjectsInit, (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_FindObjects, (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), DST_R_CRYPTOFAILURE); (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); if (cnt == 0) DST_RET(ISC_R_NOTFOUND); if (cnt > 1) DST_RET(ISC_R_EXISTS); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); return (ISC_R_SUCCESS); err: if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } return (ret); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 }; CK_ULONG len = sizeof(buf); pk11_context_t pctx; char *lib_name = NULL; int error = 0; int c, errflg = 0; unsigned int count = 1000; unsigned int i; struct timespec starttime; struct timespec endtime; while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); break; case 'n': count = atoi(isc_commandline_argument); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tssha1 [-m module] [-s slot] [-n count]\n"); exit(1); } /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_FALSE, NULL, slot); if (result != ISC_R_SUCCESS) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); exit(1); } hSession = pctx.session; /* Randomize the buffer */ rv = pkcs_C_GenerateRandom(hSession, buf, len); if (rv != CKR_OK) { fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); goto exit_session; } if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { perror("clock_gettime(start)"); goto exit_session; } /* Initialize Digest */ rv = pkcs_C_DigestInit(hSession, &mech); if (rv != CKR_OK) { fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv); goto exit_session; } for (i = 0; i < count; i++) { /* Digest buffer */ rv = pkcs_C_DigestUpdate(hSession, buf, len); if (rv != CKR_OK) { fprintf(stderr, "C_DigestUpdate[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } } /* Finalize Digest (unconditionally) */ len = 20U; rv = pkcs_C_DigestFinal(hSession, buf, &len); if ((rv != CKR_OK) && !error) fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv); if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { perror("clock_gettime(end)"); goto exit_session; } endtime.tv_sec -= starttime.tv_sec; endtime.tv_nsec -= starttime.tv_nsec; while (endtime.tv_nsec < 0) { endtime.tv_sec -= 1; endtime.tv_nsec += 1000000000; } printf("%uK digested bytes in %ld.%09lds\n", i, endtime.tv_sec, endtime.tv_nsec); if (i > 0) printf("%g digested bytes/s\n", 1024 * i / ((double) endtime.tv_sec + (double) endtime.tv_nsec / 1000000000.)); exit_session: pk11_return_session(&pctx); pk11_shutdown(); exit(error); }
static isc_result_t pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 }; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 7, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); key->keydata.pkey = gost; gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (gost->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(gost->repr, 0, sizeof(*attr) * 2); gost->attrcnt = 2; attr = gost->repr; attr[0].type = CKA_VALUE; attr[1].type = CKA_VALUE2; attr = gost->repr; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11gost_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, NULL, 0 }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_ATTRIBUTE *attr; pk11_object_t *gost; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); if (ret != ISC_R_SUCCESS) goto err; gost = key->keydata.pkey; if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = gost->ontoken; pk11_ctx->object = gost->object; goto token_key; } for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 8, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE; CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DSA; CK_ULONG bits = 0; CK_ATTRIBUTE dpTemplate[] = { { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }, }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp), DST_R_CRYPTOFAILURE); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); key->keydata.pkey = dsa; dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); if (dsa->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dsa->repr, 0, sizeof(*attr) * 5); dsa->attrcnt = 5; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[1].type = CKA_SUBPRIME; attr[2].type = CKA_BASE; attr[3].type = CKA_VALUE; attr[4].type = CKA_VALUE2; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); for (i = 0; i <= 2; i++) { attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); if (attr[i].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr[i].pValue, 0, attr[i].ulValueLen); } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, dp, attr, 3), DST_R_CRYPTOFAILURE); pubTemplate[5].pValue = attr[0].pValue; pubTemplate[5].ulValueLen = attr[0].ulValueLen; pubTemplate[6].pValue = attr[1].pValue; pubTemplate[6].ulValueLen = attr[1].ulValueLen; pubTemplate[7].pValue = attr[2].pValue; pubTemplate[7].ulValueLen = attr[2].ulValueLen; mech.mechanism = CKM_DSA_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 8, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = dsa->repr; attr += 3; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (dp != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, }; CK_ATTRIBUTE *attr; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_FALSE, rsa->reqlogon, NULL, pk11_get_best_token(OP_RSA)); if (ret != ISC_R_SUCCESS) goto err; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[5].type == attr->type); keyTemplate[5].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[5].pValue, attr->pValue, attr->ulValueLen); keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; if (pk11_numbits(attr->pValue, attr->ulValueLen) > maxbits && maxbits != 0) DST_RET(DST_R_VERIFYFAILURE); break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 7, &pk11_ctx->object), ISC_R_FAILURE); switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_VerifyInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { 0, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, NULL, 0 }, { CKA_PUBLIC_EXPONENT, NULL, 0 }, { CKA_PRIVATE_EXPONENT, NULL, 0 }, { CKA_PRIME_1, NULL, 0 }, { CKA_PRIME_2, NULL, 0 }, { CKA_EXPONENT_1, NULL, 0 }, { CKA_EXPONENT_2, NULL, 0 }, { CKA_COEFFICIENT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_SLOT_ID slotid; pk11_object_t *rsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; REQUIRE(key->key_alg == DST_ALG_RSAMD5 || key->key_alg == DST_ALG_RSASHA1 || key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); rsa = key->keydata.pkey; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); if (rsa->ontoken) slotid = rsa->slot; else slotid = pk11_get_best_token(OP_RSA); ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, rsa->reqlogon, NULL, slotid); if (ret != ISC_R_SUCCESS) goto err; if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = rsa->ontoken; pk11_ctx->object = rsa->object; goto token_key; } for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_PRIVATE_EXPONENT: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_1: INSIST(keyTemplate[9].type == attr->type); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; case CKA_PRIME_2: INSIST(keyTemplate[10].type == attr->type); keyTemplate[10].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[10].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[10].pValue, attr->pValue, attr->ulValueLen); keyTemplate[10].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_1: INSIST(keyTemplate[11].type == attr->type); keyTemplate[11].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[11].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[11].pValue, attr->pValue, attr->ulValueLen); keyTemplate[11].ulValueLen = attr->ulValueLen; break; case CKA_EXPONENT_2: INSIST(keyTemplate[12].type == attr->type); keyTemplate[12].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[12].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[12].pValue, attr->pValue, attr->ulValueLen); keyTemplate[12].ulValueLen = attr->ulValueLen; break; case CKA_COEFFICIENT: INSIST(keyTemplate[13].type == attr->type); keyTemplate[13].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[13].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[13].pValue, attr->pValue, attr->ulValueLen); keyTemplate[13].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 14, &pk11_ctx->object), ISC_R_FAILURE); token_key: switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: mech.mechanism = CKM_MD5_RSA_PKCS; break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: mech.mechanism = CKM_SHA1_RSA_PKCS; break; case DST_ALG_RSASHA256: mech.mechanism = CKM_SHA256_RSA_PKCS; break; case DST_ALG_RSASHA512: mech.mechanism = CKM_SHA512_RSA_PKCS; break; default: INSIST(0); } PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_EC; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 } }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } }; CK_ATTRIBUTE *attr; pk11_object_t *ec; pk11_context_t *pk11_ctx; isc_result_t ret; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); UNUSED(unused); UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_EC)); if (ret != ISC_R_SUCCESS) goto err; ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); key->keydata.pkey = ec; ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); if (ec->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(ec->repr, 0, sizeof(*attr) * 3); ec->attrcnt = 3; attr = ec->repr; attr[0].type = CKA_EC_PARAMS; attr[1].type = CKA_EC_POINT; attr[2].type = CKA_VALUE; attr = &pubTemplate[5]; SETCURVE(); PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); attr = &pubTemplate[5]; FREECURVE(); attr = ec->repr; SETCURVE(); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); if (key->key_alg == DST_ALG_ECDSA256) key->key_size = DNS_KEY_ECDSA256SIZE * 4; else key->key_size = DNS_KEY_ECDSA384SIZE * 4; return (ISC_R_SUCCESS); err: pkcs11ecdsa_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 }; CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE; CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS; CK_KEY_TYPE keyType = CKK_DH; CK_ULONG bits = 0; CK_ATTRIBUTE dTemplate[] = { { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) } }; CK_ATTRIBUTE pTemplate[] = { { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 } }; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; CK_ATTRIBUTE pubTemplate[] = { { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, }; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE privTemplate[] = { { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, }; CK_ATTRIBUTE *attr; pk11_object_t *dh = NULL; pk11_context_t *pk11_ctx; isc_result_t ret; UNUSED(callback); pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) goto err; bits = key->key_size; if ((generator == 0) && ((bits == 768) || (bits == 1024) || (bits == 1536))) { if (bits == 768) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn768)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn768, sizeof(pk11_dh_bn768)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768); } else if (bits == 1024) { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1024, sizeof(pk11_dh_bn1024)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024); } else { pubTemplate[4].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536)); if (pubTemplate[4].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[4].pValue, pk11_dh_bn1536, sizeof(pk11_dh_bn1536)); pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536); } pubTemplate[5].pValue = isc_mem_get(key->mctx, sizeof(pk11_dh_bn2)); if (pubTemplate[5].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(pubTemplate[5].pValue, pk11_dh_bn2, sizeof(pk11_dh_bn2)); pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2); } else { PK11_RET(pkcs_C_GenerateKey, (pk11_ctx->session, &mech, dTemplate, (CK_ULONG) 5, &domainparams), DST_R_CRYPTOFAILURE); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pTemplate[0].pValue = isc_mem_get(key->mctx, pTemplate[0].ulValueLen); if (pTemplate[0].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); pTemplate[1].pValue = isc_mem_get(key->mctx, pTemplate[1].ulValueLen); if (pTemplate[1].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, domainparams, pTemplate, (CK_ULONG) 2), DST_R_CRYPTOFAILURE); pubTemplate[4].pValue = pTemplate[0].pValue; pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen; pTemplate[0].pValue = NULL; pubTemplate[5].pValue = pTemplate[1].pValue; pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen; pTemplate[1].pValue = NULL; } mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; PK11_RET(pkcs_C_GenerateKeyPair, (pk11_ctx->session, &mech, pubTemplate, (CK_ULONG) 6, privTemplate, (CK_ULONG) 7, &pub, &priv), DST_R_CRYPTOFAILURE); dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); if (dh == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh, 0, sizeof(*dh)); key->keydata.pkey = dh; dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dh->repr == NULL) DST_RET(ISC_R_NOMEMORY); memset(dh->repr, 0, sizeof(*attr) * 4); dh->attrcnt = 4; attr = dh->repr; attr[0].type = CKA_PRIME; attr[0].pValue = pubTemplate[4].pValue; attr[0].ulValueLen = pubTemplate[4].ulValueLen; pubTemplate[4].pValue = NULL; attr[1].type = CKA_BASE; attr[1].pValue = pubTemplate[5].pValue; attr[1].ulValueLen = pubTemplate[5].ulValueLen; pubTemplate[5].pValue =NULL; attr += 2; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); attr++; attr->type = CKA_VALUE; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), DST_R_CRYPTOFAILURE); attr->type = CKA_VALUE2; (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); err: pkcs11dh_destroy(key); if (priv != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); if (domainparams != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); if (pubTemplate[4].pValue != NULL) { memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen); isc_mem_put(key->mctx, pubTemplate[4].pValue, pubTemplate[4].ulValueLen); } if (pubTemplate[5].pValue != NULL) { memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen); isc_mem_put(key->mctx, pubTemplate[5].pValue, pubTemplate[5].ulValueLen); } if (pTemplate[0].pValue != NULL) { memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); isc_mem_put(key->mctx, pTemplate[0].pValue, pTemplate[0].ulValueLen); } if (pTemplate[1].pValue != NULL) { memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); isc_mem_put(key->mctx, pTemplate[1].pValue, pTemplate[1].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
static isc_result_t pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { CK_RV rv; CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_ATTRIBUTE *attr; CK_ULONG secLen; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) } }; CK_ATTRIBUTE valTemplate[] = { { CKA_VALUE, NULL, 0 } }; CK_BYTE *secValue; pk11_context_t ctx; isc_result_t ret; unsigned int i; isc_region_t r; REQUIRE(pub->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey != NULL); REQUIRE(priv->keydata.pkey->repr != NULL); attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); REQUIRE(attr != NULL); secLen = attr->ulValueLen; attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); if (attr == NULL) return (DST_R_INVALIDPUBLICKEY); ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); if (ret != ISC_R_SUCCESS) return (ret); mech.ulParameterLen = attr->ulValueLen; mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen); if (mech.pParameter == NULL) DST_RET(ISC_R_NOMEMORY); memmove(mech.pParameter, attr->pValue, mech.ulParameterLen); ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey); if (ret != ISC_R_SUCCESS) goto err; PK11_RET(pkcs_C_DeriveKey, (ctx.session, &mech, hKey, keyTemplate, (CK_ULONG) 6, &hDerived), DST_R_COMPUTESECRETFAILURE); attr = valTemplate; PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen); if (attr->pValue == NULL) DST_RET(ISC_R_NOMEMORY); memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (ctx.session, hDerived, attr, (CK_ULONG) 1), DST_R_CRYPTOFAILURE); /* strip leading zeros */ secValue = (CK_BYTE_PTR) attr->pValue; for (i = 0; i < attr->ulValueLen; i++) if (secValue[i] != 0) break; isc_buffer_availableregion(secret, &r); if (r.length < attr->ulValueLen - i) DST_RET(ISC_R_NOSPACE); memmove(r.base, secValue + i, attr->ulValueLen - i); isc_buffer_add(secret, attr->ulValueLen - i); ret = ISC_R_SUCCESS; err: if (hDerived != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx.session, hDerived); if (valTemplate[0].pValue != NULL) { memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen); isc_mem_put(pub->mctx, valTemplate[0].pValue, valTemplate[0].ulValueLen); } if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) (void) pkcs_C_DestroyObject(ctx.session, hKey); if (mech.pParameter != NULL) { memset(mech.pParameter, 0, mech.ulParameterLen); isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); } pk11_return_session(&ctx); return (ret); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; CK_ATTRIBUTE sTemplate[] = { { CKA_LABEL, label, (CK_ULONG) sizeof(label) }, }; CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE; CK_ULONG found = 0; pk11_context_t pctx; char *lib_name = NULL; char *pin = NULL; int error = 0; int c, errflg = 0; unsigned int count = 1000; unsigned int i; struct timespec starttime; struct timespec endtime; while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); break; case 'p': pin = isc_commandline_argument; break; case 'n': count = atoi(isc_commandline_argument); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tfind [-m module] [-s slot] [-p pin] [-n count]\n"); exit(1); } /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); if (pin == NULL) pin = getpassphrase("Enter Pin: "); result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_TRUE, (const char *) pin, slot); if (result != ISC_R_SUCCESS) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); exit(1); } if (pin != NULL) memset(pin, 0, strlen((char *)pin)); hSession = pctx.session; if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { perror("clock_gettime(start)"); goto exit_objects; } for (i = 0; !error && (i < count); i++) { rv = pkcs_C_FindObjectsInit(hSession, sTemplate, 1); if (rv != CKR_OK) { fprintf(stderr, "C_FindObjectsInit[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } rv = pkcs_C_FindObjects(hSession, &sKey, 1, &found); if (rv != CKR_OK) { fprintf(stderr, "C_FindObjects[%u]: Error = 0x%.8lX\n", i, rv); error = 1; /* no break here! */ } rv = pkcs_C_FindObjectsFinal(hSession); if (rv != CKR_OK) { fprintf(stderr, "C_FindObjectsFinal[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } } if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { perror("clock_gettime(end)"); goto exit_objects; } endtime.tv_sec -= starttime.tv_sec; endtime.tv_nsec -= starttime.tv_nsec; while (endtime.tv_nsec < 0) { endtime.tv_sec -= 1; endtime.tv_nsec += 1000000000; } printf("%u object searches in %ld.%09lds\n", i, endtime.tv_sec, endtime.tv_nsec); if (i > 0) printf("%g object searches/s\n", 1024 * i / ((double) endtime.tv_sec + (double) endtime.tv_nsec / 1000000000.)); exit_objects: pk11_return_session(&pctx); pk11_shutdown(); exit(error); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession; CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; CK_ULONG len; pk11_context_t pctx; pk11_optype_t op_type = OP_DIGEST; char *lib_name = NULL; char *pin = NULL; int error = 0; isc_boolean_t logon = ISC_TRUE; int c, errflg = 0; size_t sum = 0; unsigned int i; while ((c = isc_commandline_parse(argc, argv, ":m:s:np:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); op_type = OP_ANY; break; case 'n': logon = ISC_FALSE; break; case 'p': pin = isc_commandline_argument; break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tpkcs11-md5sum [-m module] [-s slot] [-n|-p pin]\n"); exit(1); } pk11_result_register(); /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); if (logon && pin == NULL) pin = getpassphrase("Enter Pin: "); result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, logon, (const char *) pin, slot); if ((result != ISC_R_SUCCESS) && (result != PK11_R_NORANDOMSERVICE) && (result != PK11_R_NOAESSERVICE)) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); exit(1); } if (pin != NULL) memset(pin, 0, strlen((char *)pin)); hSession = pctx.session; rv = pkcs_C_DigestInit(hSession, &mech); if (rv != CKR_OK) { fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv); error = 1; goto exit_session; } for (;;) { size_t n; for (;;) { n = fread(buffer + sum, 1, BLOCKSIZE - sum, stdin); sum += n; if (sum == BLOCKSIZE) break; if (n == 0) { if (ferror(stdin)) { fprintf(stderr, "fread failed\n"); error = 1; goto exit_session; } goto partial_block; } if (feof(stdin)) goto partial_block; } rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer, (CK_ULONG) BLOCKSIZE); if (rv != CKR_OK) { fprintf(stderr, "C_DigestUpdate: Error = 0x%.8lX\n", rv); error = 1; goto exit_session; } } partial_block: if (sum > 0) { rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer, (CK_ULONG) sum); if (rv != CKR_OK) { fprintf(stderr, "C_DigestUpdate: Error = 0x%.8lX\n", rv); error = 1; goto exit_session; } } len = 16; rv = pkcs_C_DigestFinal(hSession, (CK_BYTE_PTR) digest, &len); if (rv != CKR_OK) { fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv); error = 1; goto exit_session; } if (len != 16) { fprintf(stderr, "C_DigestFinal: bad length = %lu\n", len); error = 1; } for (i = 0; i < 16; i++) printf("%02x", digest[i] & 0xff); printf("\n"); exit_session: pk11_return_session(&pctx); (void) pk11_finalize(); exit(error); }
static isc_result_t pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { CK_RV rv; CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_DSA; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_PRIME, NULL, 0 }, { CKA_SUBPRIME, NULL, 0 }, { CKA_BASE, NULL, 0 }, { CKA_VALUE, NULL, 0 } }; CK_ATTRIBUTE *attr; pk11_object_t *dsa; pk11_context_t *pk11_ctx; isc_result_t ret; unsigned int i; pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, sizeof(*pk11_ctx)); if (pk11_ctx == NULL) return (ISC_R_NOMEMORY); ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); if (ret != ISC_R_SUCCESS) goto err; dsa = key->keydata.pkey; if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { pk11_ctx->ontoken = dsa->ontoken; pk11_ctx->object = dsa->object; goto token_key; } for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[6].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; break; case CKA_SUBPRIME: INSIST(keyTemplate[7].type == attr->type); keyTemplate[7].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[7].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); keyTemplate[7].ulValueLen = attr->ulValueLen; break; case CKA_BASE: INSIST(keyTemplate[8].type == attr->type); keyTemplate[8].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[8].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); keyTemplate[8].ulValueLen = attr->ulValueLen; break; case CKA_VALUE2: INSIST(keyTemplate[9].type == CKA_VALUE); keyTemplate[9].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); if (keyTemplate[9].pValue == NULL) DST_RET(ISC_R_NOMEMORY); memmove(keyTemplate[9].pValue, attr->pValue, attr->ulValueLen); keyTemplate[9].ulValueLen = attr->ulValueLen; break; } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = ISC_FALSE; PK11_RET(pkcs_C_CreateObject, (pk11_ctx->session, keyTemplate, (CK_ULONG) 10, &pk11_ctx->object), ISC_R_FAILURE); token_key: PK11_RET(pkcs_C_SignInit, (pk11_ctx->session, &mech, pk11_ctx->object), ISC_R_FAILURE); dctx->ctxdata.pk11_ctx = pk11_ctx; for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } return (ISC_R_SUCCESS); err: if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { memset(keyTemplate[i].pValue, 0, keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); memset(pk11_ctx, 0, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; CK_OBJECT_HANDLE *hKey; CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY; CK_KEY_TYPE kType = CKK_RSA; CK_ATTRIBUTE kTemplate[] = { { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, { CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) } }; pk11_context_t pctx; char *lib_name = NULL; char *pin = NULL; int error = 0; int c, errflg = 0; int ontoken = 0; unsigned int count = 1000; unsigned int i; struct timespec starttime; struct timespec endtime; while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); break; case 'p': pin = isc_commandline_argument; break; case 't': ontoken = 1; break; case 'n': count = atoi(isc_commandline_argument); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tpubrsa [-m module] [-s slot] [-p pin] " "[-t] [-n count]\n"); exit(1); } /* Allocate hanles */ hKey = (CK_SESSION_HANDLE *) malloc(count * sizeof(CK_SESSION_HANDLE)); if (hKey == NULL) { perror("malloc"); exit(1); } for (i = 0; i < count; i++) hKey[i] = CK_INVALID_HANDLE; /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); if (pin == NULL) pin = getpassphrase("Enter Pin: "); result = pk11_get_session(&pctx, OP_ANY, ISC_TRUE, ISC_TRUE, (const char *) pin, slot); if (result != ISC_R_SUCCESS) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); free(hKey); exit(1); } if (pin != NULL) memset(pin, 0, strlen((char *)pin)); hSession = pctx.session; if (ontoken) kTemplate[2].pValue = &truevalue; if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { perror("clock_gettime(start)"); goto exit_objects; } for (i = 0; i < count; i++) { (void) snprintf(label, sizeof(label), "obj%u", i); kTemplate[4].ulValueLen = strlen(label); rv = pkcs_C_CreateObject(hSession, kTemplate, 8, &hKey[i]); if (rv != CKR_OK) { fprintf(stderr, "C_CreateObject[%u]: Error = 0x%.8lX\n", i, rv); error = 1; if (i == 0) goto exit_objects; break; } } if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { perror("clock_gettime(end)"); goto exit_objects; } endtime.tv_sec -= starttime.tv_sec; endtime.tv_nsec -= starttime.tv_nsec; while (endtime.tv_nsec < 0) { endtime.tv_sec -= 1; endtime.tv_nsec += 1000000000; } printf("%u public RSA keys in %ld.%09lds\n", i, endtime.tv_sec, endtime.tv_nsec); if (i > 0) printf("%g public RSA keys/s\n", 1024 * i / ((double) endtime.tv_sec + (double) endtime.tv_nsec / 1000000000.)); exit_objects: for (i = 0; i < count; i++) { /* Destroy objects */ if (hKey[i] == CK_INVALID_HANDLE) continue; rv = pkcs_C_DestroyObject(hSession, hKey[i]); if ((rv != CKR_OK) && !errflg) { fprintf(stderr, "C_DestroyObject[%u]: Error = 0x%.8lX\n", i, rv); errflg = 1; } } free(hKey); pk11_return_session(&pctx); pk11_shutdown(); exit(error); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; CK_ULONG len = sizeof(buf); pk11_context_t pctx; pk11_optype_t op_type = OP_RAND; char *lib_name = NULL; int error = 0; int c, errflg = 0; unsigned int count = 1000; unsigned int i; struct timespec starttime; struct timespec endtime; while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); op_type = OP_ANY; break; case 'n': count = atoi(isc_commandline_argument); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\trandom [-m module] [-s slot] [-n count]\n"); exit(1); } pk11_result_register(); /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, ISC_FALSE, NULL, slot); if ((result != ISC_R_SUCCESS) && (result != PK11_R_NODIGESTSERVICE) && (result != PK11_R_NOAESSERVICE)) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); exit(1); } hSession = pctx.session; if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { perror("clock_gettime(start)"); goto exit_session; } for (i = 0; i < count; i++) { /* Get random bytes */ rv = pkcs_C_GenerateRandom(hSession, buf, len); if (rv != CKR_OK) { fprintf(stderr, "C_GenerateRandom[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } } if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { perror("clock_gettime(end)"); goto exit_session; } endtime.tv_sec -= starttime.tv_sec; endtime.tv_nsec -= starttime.tv_nsec; while (endtime.tv_nsec < 0) { endtime.tv_sec -= 1; endtime.tv_nsec += 1000000000; } printf("%uK random bytes in %ld.%09lds\n", i, endtime.tv_sec, endtime.tv_nsec); if (i > 0) printf("%g random bytes/s\n", 1024 * i / ((double) endtime.tv_sec + (double) endtime.tv_nsec / 1000000000.)); exit_session: pk11_return_session(&pctx); (void) pk11_finalize(); exit(error); }
int main(int argc, char *argv[]) { isc_result_t result; CK_RV rv; CK_SLOT_ID slot = 0; CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; CK_ULONG len; CK_ULONG slen; CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY; CK_KEY_TYPE kType = CKK_RSA; CK_ATTRIBUTE kTemplate[] = { { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, { CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) } }; CK_MECHANISM mech = { CKM_SHA1_RSA_PKCS, NULL, 0 }; pk11_context_t pctx; pk11_optype_t op_type = OP_RSA; char *lib_name = NULL; char *pin = NULL; int error = 0; int c, errflg = 0; int ontoken = 0; unsigned int count = 1000; unsigned int i; struct timespec starttime; struct timespec endtime; while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { switch (c) { case 'm': lib_name = isc_commandline_argument; break; case 's': slot = atoi(isc_commandline_argument); op_type = OP_ANY; break; case 'p': pin = isc_commandline_argument; break; case 't': ontoken = 1; break; case 'n': count = atoi(isc_commandline_argument); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", isc_commandline_option); errflg++; break; case '?': default: fprintf(stderr, "Unrecognised option: -%c\n", isc_commandline_option); errflg++; } } if (errflg) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\tverify [-m module] [-s slot] [-p pin] " "[-t] [-n count]\n"); exit(1); } pk11_result_register(); /* Initialize the CRYPTOKI library */ if (lib_name != NULL) pk11_set_lib_name(lib_name); if (pin == NULL) pin = getpassphrase("Enter Pin: "); result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, ISC_TRUE, (const char *) pin, slot); if ((result != ISC_R_SUCCESS) && (result != PK11_R_NORANDOMSERVICE) && (result != PK11_R_NODIGESTSERVICE) && (result != PK11_R_NOAESSERVICE)) { fprintf(stderr, "Error initializing PKCS#11: %s\n", isc_result_totext(result)); exit(1); } if (pin != NULL) memset(pin, 0, strlen((char *)pin)); hSession = pctx.session; /* Create the private RSA key */ if (ontoken) kTemplate[2].pValue = &truevalue; rv = pkcs_C_CreateObject(hSession, kTemplate, 7, &hKey); if (rv != CKR_OK) { fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv); error = 1; goto exit_key; } /* Randomize the buffer */ len = (CK_ULONG) sizeof(buf); rv = pkcs_C_GenerateRandom(hSession, buf, len); if (rv != CKR_OK) { fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); goto exit_key; } if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { perror("clock_gettime(start)"); goto exit_key; } for (i = 0; i < count; i++) { /* Initialize Verify */ rv = pkcs_C_VerifyInit(hSession, &mech, hKey); if (rv != CKR_OK) { fprintf(stderr, "C_VerifyInit[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } /* Perform Verify */ slen = (CK_ULONG) sizeof(sig); rv = pkcs_C_Verify(hSession, buf, len, sig, slen); if ((rv != CKR_OK) && (rv != CKR_SIGNATURE_INVALID)) { fprintf(stderr, "C_Verify[%u]: Error = 0x%.8lX\n", i, rv); error = 1; break; } } if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { perror("clock_gettime(end)"); goto exit_key; } endtime.tv_sec -= starttime.tv_sec; endtime.tv_nsec -= starttime.tv_nsec; while (endtime.tv_nsec < 0) { endtime.tv_sec -= 1; endtime.tv_nsec += 1000000000; } printf("%u RSA verify in %ld.%09lds\n", i, endtime.tv_sec, endtime.tv_nsec); if (i > 0) printf("%g RSA verify/s\n", 1024 * i / ((double) endtime.tv_sec + (double) endtime.tv_nsec / 1000000000.)); exit_key: if (hKey != CK_INVALID_HANDLE) { rv = pkcs_C_DestroyObject(hSession, hKey); if (rv != CKR_OK) { fprintf(stderr, "C_DestroyObject: Error = 0x%.8lX\n", rv); errflg = 1; } } pk11_return_session(&pctx); (void) pk11_finalize(); exit(error); }
ATF_TC_BODY(isc_gost_private, tc) { isc_result_t result; unsigned char privraw[31] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; #ifdef HAVE_OPENSSL_GOST unsigned char rbuf[32]; unsigned char privasn1[70] = { 0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }; unsigned char abuf[71]; unsigned char gost_dummy_key[71] = { 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b, 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 }; EVP_PKEY *pkey; EC_KEY *eckey; BIGNUM *privkey; const BIGNUM *privkey1; const unsigned char *p; int len; unsigned char *q; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* raw parse */ privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL); ATF_REQUIRE(privkey != NULL); p = gost_dummy_key; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(gost_dummy_key)) != NULL); ATF_REQUIRE(pkey != NULL); ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1); BN_clear_free(privkey); /* asn1 tofile */ len = i2d_PrivateKey(pkey, NULL); ATF_REQUIRE(len == 70); q = abuf; ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len); ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0); EVP_PKEY_free(pkey); /* asn1 parse */ p = privasn1; pkey = NULL; ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) len) != NULL); ATF_REQUIRE(pkey != NULL); eckey = EVP_PKEY_get0(pkey); ATF_REQUIRE(eckey != NULL); privkey1 = EC_KEY_get0_private_key(eckey); len = BN_num_bytes(privkey1); ATF_REQUIRE(len == 31); ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len); ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0); dns_test_end(); #else CK_BBOOL truevalue = TRUE; CK_BBOOL falsevalue = FALSE; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_KEY_TYPE keyType = CKK_GOSTR3410; CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, { CKA_VALUE, privraw, sizeof(privraw) }, { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, (CK_ULONG) sizeof(pk11_gost_a_paramset) }, { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, (CK_ULONG) sizeof(pk11_gost_paramset) } }; CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; CK_BYTE sig[64]; CK_ULONG siglen; pk11_context_t pk11_ctx; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE(result == ISC_R_SUCCESS); /* create the private key */ memset(&pk11_ctx, 0, sizeof(pk11_ctx)); ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)) == ISC_R_SUCCESS); pk11_ctx.object = CK_INVALID_HANDLE; pk11_ctx.ontoken = ISC_FALSE; ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate, (CK_ULONG) 9, &pk11_ctx.object) == CKR_OK); ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE); /* sign something */ ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech, pk11_ctx.object) == CKR_OK); siglen = 0; ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, NULL, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64, sig, &siglen) == CKR_OK); ATF_REQUIRE(siglen == 64); dns_test_end(); #endif };