3421 lines
101 KiB
Diff
3421 lines
101 KiB
Diff
commit 50e3f06823696c74eea90a77e16b28da1f79cd47
|
|
Author: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
Date: Wed Jun 30 14:33:33 2021 +0200
|
|
|
|
SOFT: Remove deprecated OpenSSL functions
|
|
|
|
All low level RSA, EC_KEY, and DH functions are deprecated in OpenSSL 3.0.
|
|
Update the code to not use any of those.
|
|
|
|
Change the digest operation context to store the OpenSSL digest context,
|
|
instead of the deprecated way of retrieving and restoring the digest state.
|
|
This makes the digest operation context 'non savable'.
|
|
|
|
Also remove support for OpenSSL < v1.1.1. This code used even more
|
|
low level OpenSSL functions.
|
|
|
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
|
diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c
|
|
index 5ca22693..43fd17c3 100644
|
|
--- a/usr/lib/soft_stdll/soft_specific.c
|
|
+++ b/usr/lib/soft_stdll/soft_specific.c
|
|
@@ -26,10 +26,6 @@
|
|
|
|
#include <openssl/opensslv.h>
|
|
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
-#define NO_EC 1
|
|
-#endif
|
|
-
|
|
#include "pkcs11types.h"
|
|
#include "defs.h"
|
|
#include "host_defs.h"
|
|
@@ -54,14 +50,10 @@
|
|
#include <openssl/crypto.h>
|
|
#include <openssl/cmac.h>
|
|
#include <openssl/ec.h>
|
|
-
|
|
-/*
|
|
- * In order to make opencryptoki compatible with
|
|
- * OpenSSL 1.1 API Changes and backward compatible
|
|
- * we need to check for its version
|
|
- */
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
-#define OLDER_OPENSSL
|
|
+#include <openssl/bn.h>
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+#include <openssl/core_names.h>
|
|
+#include <openssl/param_build.h>
|
|
#endif
|
|
|
|
#define MAX_GENERIC_KEY_SIZE 256
|
|
@@ -76,7 +68,10 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = {
|
|
#if !(NODSA)
|
|
{CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}},
|
|
#endif
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ /* OpenSSL 3.0 supports single-DES only with the legacy provider */
|
|
{CKM_DES_KEY_GEN, {8, 8, CKF_GENERATE}},
|
|
+#endif
|
|
{CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}},
|
|
#if !(NOCDMF)
|
|
{CKM_CDMF_KEY_GEN, {0, 0, CKF_GENERATE}},
|
|
@@ -120,10 +115,13 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = {
|
|
{CKM_DH_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR}},
|
|
#endif
|
|
/* End code contributed by Corrent corp. */
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ /* OpenSSL 3.0 supports single-DES only with the legacy provider */
|
|
{CKM_DES_ECB, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
{CKM_DES_CBC, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
{CKM_DES_CBC_PAD,
|
|
{8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
+#endif
|
|
#if !(NOCDMF)
|
|
{CKM_CDMF_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
{CKM_CDMF_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
@@ -286,58 +284,6 @@ CK_RV token_specific_des_ecb(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- CK_RV rc;
|
|
- DES_key_schedule des_key2;
|
|
- const_DES_cblock key_val_SSL, in_key_data;
|
|
- DES_cblock out_key_data;
|
|
- unsigned int i, j;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- // get the key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- // Create the key schedule
|
|
- memcpy(&key_val_SSL, attr->pValue, 8);
|
|
- DES_set_key_unchecked(&key_val_SSL, &des_key2);
|
|
-
|
|
- // the des decrypt will only fail if the data length is not evenly divisible
|
|
- // by 8
|
|
- if (in_data_len % DES_BLOCK_SIZE) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
- return CKR_DATA_LEN_RANGE;
|
|
- }
|
|
- // Both the encrypt and the decrypt are done 8 bytes at a time
|
|
- if (encrypt) {
|
|
- for (i = 0; i < in_data_len; i = i + 8) {
|
|
- memcpy(in_key_data, in_data + i, 8);
|
|
- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
|
|
- DES_ENCRYPT);
|
|
- memcpy(out_data + i, out_key_data, 8);
|
|
- }
|
|
-
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- } else {
|
|
-
|
|
- for (j = 0; j < in_data_len; j = j + 8) {
|
|
- memcpy(in_key_data, in_data + j, 8);
|
|
- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
|
|
- DES_DECRYPT);
|
|
- memcpy(out_data + j, out_key_data, 8);
|
|
- }
|
|
-
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- }
|
|
-
|
|
- return rc;
|
|
-#else
|
|
const EVP_CIPHER *cipher = EVP_des_ecb();
|
|
EVP_CIPHER_CTX *ctx = NULL;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
@@ -384,7 +330,6 @@ done:
|
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata,
|
|
@@ -394,47 +339,6 @@ CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- CK_RV rc;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- DES_cblock ivec;
|
|
- DES_key_schedule des_key2;
|
|
- const_DES_cblock key_val_SSL;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- // get the key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- // Create the key schedule
|
|
- memcpy(&key_val_SSL, attr->pValue, 8);
|
|
- DES_set_key_unchecked(&key_val_SSL, &des_key2);
|
|
-
|
|
- memcpy(&ivec, init_v, 8);
|
|
- // the des decrypt will only fail if the data length is not evenly divisible
|
|
- // by 8
|
|
- if (in_data_len % DES_BLOCK_SIZE) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
- return CKR_DATA_LEN_RANGE;
|
|
- }
|
|
-
|
|
- if (encrypt) {
|
|
- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
|
|
- DES_ENCRYPT);
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- } else {
|
|
- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
|
|
- DES_DECRYPT);
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- }
|
|
-
|
|
- return rc;
|
|
-#else
|
|
const EVP_CIPHER *cipher = EVP_des_cbc();
|
|
EVP_CIPHER_CTX *ctx = NULL;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
@@ -481,7 +385,6 @@ done:
|
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata,
|
|
@@ -491,80 +394,6 @@ CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- CK_RV rc;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- CK_BYTE key_value[3 * DES_KEY_SIZE];
|
|
- CK_KEY_TYPE keytype;
|
|
- unsigned int k, j;
|
|
- DES_key_schedule des_key1;
|
|
- DES_key_schedule des_key2;
|
|
- DES_key_schedule des_key3;
|
|
- const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data;
|
|
- DES_cblock out_key_data;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- // get the key type
|
|
- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n");
|
|
- return rc;
|
|
- }
|
|
-
|
|
- // get the key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- if (keytype == CKK_DES2) {
|
|
- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
|
|
- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
- } else {
|
|
- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
|
|
- }
|
|
-
|
|
- // The key as passed is a 24 byte long string containing three des keys
|
|
- // pick them apart and create the 3 corresponding key schedules
|
|
- memcpy(&key_SSL1, key_value, 8);
|
|
- memcpy(&key_SSL2, key_value + 8, 8);
|
|
- memcpy(&key_SSL3, key_value + 16, 8);
|
|
- DES_set_key_unchecked(&key_SSL1, &des_key1);
|
|
- DES_set_key_unchecked(&key_SSL2, &des_key2);
|
|
- DES_set_key_unchecked(&key_SSL3, &des_key3);
|
|
-
|
|
- // the des decrypt will only fail if the data length is not evenly divisible
|
|
- // by 8
|
|
- if (in_data_len % DES_BLOCK_SIZE) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
- return CKR_DATA_LEN_RANGE;
|
|
- }
|
|
- // the encrypt and decrypt are done 8 bytes at a time
|
|
- if (encrypt) {
|
|
- for (k = 0; k < in_data_len; k = k + 8) {
|
|
- memcpy(in_key_data, in_data + k, 8);
|
|
- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
|
|
- (DES_cblock *) & out_key_data,
|
|
- &des_key1, &des_key2, &des_key3, DES_ENCRYPT);
|
|
- memcpy(out_data + k, out_key_data, 8);
|
|
- }
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- } else {
|
|
- for (j = 0; j < in_data_len; j = j + 8) {
|
|
- memcpy(in_key_data, in_data + j, 8);
|
|
- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
|
|
- (DES_cblock *) & out_key_data,
|
|
- &des_key1, &des_key2, &des_key3, DES_DECRYPT);
|
|
- memcpy(out_data + j, out_key_data, 8);
|
|
- }
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- }
|
|
-
|
|
- return rc;
|
|
-#else
|
|
const EVP_CIPHER *cipher = EVP_des_ede3_ecb();
|
|
EVP_CIPHER_CTX *ctx = NULL;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
@@ -624,7 +453,6 @@ done:
|
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata,
|
|
@@ -634,78 +462,6 @@ CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- CK_RV rc = CKR_OK;
|
|
- CK_BYTE key_value[3 * DES_KEY_SIZE];
|
|
- CK_KEY_TYPE keytype;
|
|
- DES_key_schedule des_key1;
|
|
- DES_key_schedule des_key2;
|
|
- DES_key_schedule des_key3;
|
|
- const_DES_cblock key_SSL1, key_SSL2, key_SSL3;
|
|
- DES_cblock ivec;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- // get the key type
|
|
- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n");
|
|
- return rc;
|
|
- }
|
|
-
|
|
- // get the key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- if (keytype == CKK_DES2) {
|
|
- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
|
|
- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
- } else {
|
|
- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
|
|
- }
|
|
-
|
|
- // The key as passed in is a 24 byte string containing 3 keys
|
|
- // pick it apart and create the key schedules
|
|
- memcpy(&key_SSL1, key_value, 8);
|
|
- memcpy(&key_SSL2, key_value + 8, 8);
|
|
- memcpy(&key_SSL3, key_value + 16, 8);
|
|
- DES_set_key_unchecked(&key_SSL1, &des_key1);
|
|
- DES_set_key_unchecked(&key_SSL2, &des_key2);
|
|
- DES_set_key_unchecked(&key_SSL3, &des_key3);
|
|
-
|
|
- memcpy(ivec, init_v, sizeof(ivec));
|
|
-
|
|
- // the des decrypt will only fail if the data length is not evenly divisible
|
|
- // by 8
|
|
- if (in_data_len % DES_BLOCK_SIZE) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
- return CKR_DATA_LEN_RANGE;
|
|
- }
|
|
- // Encrypt or decrypt the data
|
|
- if (encrypt) {
|
|
- DES_ede3_cbc_encrypt(in_data,
|
|
- out_data,
|
|
- in_data_len,
|
|
- &des_key1,
|
|
- &des_key2, &des_key3, &ivec, DES_ENCRYPT);
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- } else {
|
|
- DES_ede3_cbc_encrypt(in_data,
|
|
- out_data,
|
|
- in_data_len,
|
|
- &des_key1,
|
|
- &des_key2, &des_key3, &ivec, DES_DECRYPT);
|
|
-
|
|
- *out_data_len = in_data_len;
|
|
- rc = CKR_OK;
|
|
- }
|
|
-
|
|
- return rc;
|
|
-#else
|
|
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
|
|
EVP_CIPHER_CTX *ctx = NULL;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
@@ -765,7 +521,6 @@ done:
|
|
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
@@ -795,14 +550,20 @@ CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
// convert from the local PKCS11 template representation to
|
|
// the underlying requirement
|
|
// returns the pointer to the local key representation
|
|
-static void *rsa_convert_public_key(OBJECT *key_obj)
|
|
+static EVP_PKEY *rsa_convert_public_key(OBJECT *key_obj)
|
|
{
|
|
CK_BBOOL rc;
|
|
CK_ATTRIBUTE *modulus = NULL;
|
|
CK_ATTRIBUTE *pub_exp = NULL;
|
|
-
|
|
- RSA *rsa;
|
|
+ EVP_PKEY *pkey = NULL;
|
|
BIGNUM *bn_mod, *bn_exp;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ EVP_PKEY_CTX *pctx = NULL;
|
|
+ OSSL_PARAM_BLD *tmpl = NULL;
|
|
+ OSSL_PARAM *params = NULL;
|
|
+#else
|
|
+ RSA *rsa;
|
|
+#endif
|
|
|
|
rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
|
|
&modulus);
|
|
@@ -813,12 +574,7 @@ static void *rsa_convert_public_key(OBJECT *key_obj)
|
|
if (rc != CKR_OK)
|
|
return NULL;
|
|
|
|
- // Create an RSA key struct to return
|
|
- rsa = RSA_new();
|
|
- if (rsa == NULL)
|
|
- return NULL;
|
|
-
|
|
- // Create and init BIGNUM structs to stick in the RSA struct
|
|
+ // Create and init BIGNUM structs
|
|
bn_mod = BN_new();
|
|
bn_exp = BN_new();
|
|
|
|
@@ -827,24 +583,74 @@ static void *rsa_convert_public_key(OBJECT *key_obj)
|
|
free(bn_mod);
|
|
if (bn_exp)
|
|
free(bn_exp);
|
|
- RSA_free(rsa);
|
|
return NULL;
|
|
}
|
|
- // Convert from strings to BIGNUMs and stick them in the RSA struct
|
|
+ // Convert from strings to BIGNUMs
|
|
BN_bin2bn((unsigned char *) modulus->pValue, modulus->ulValueLen, bn_mod);
|
|
BN_bin2bn((unsigned char *) pub_exp->pValue, pub_exp->ulValueLen, bn_exp);
|
|
|
|
-#ifdef OLDER_OPENSSL
|
|
- rsa->n = bn_mod;
|
|
- rsa->e = bn_exp;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ // Create an RSA key struct to return
|
|
+ rsa = RSA_new();
|
|
+ if (rsa == NULL) {
|
|
+ if (bn_mod)
|
|
+ free(bn_mod);
|
|
+ if (bn_exp)
|
|
+ free(bn_exp);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
RSA_set0_key(rsa, bn_mod, bn_exp, NULL);
|
|
+
|
|
+ pkey = EVP_PKEY_new();
|
|
+ if (pkey == NULL) {
|
|
+ RSA_free(rsa);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
|
+ RSA_free(rsa);
|
|
+ EVP_PKEY_free(pkey);
|
|
+ return NULL;
|
|
+ }
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_exp))
|
|
+ goto out;
|
|
+
|
|
+ params = OSSL_PARAM_BLD_to_param(tmpl);
|
|
+ if (params == NULL)
|
|
+ goto out;
|
|
+
|
|
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
|
|
+ if (pctx == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (!EVP_PKEY_fromdata_init(pctx) ||
|
|
+ !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params))
|
|
+ goto out;
|
|
+
|
|
+out:
|
|
+ if (pctx != NULL)
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ if (tmpl != NULL)
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ if (params != NULL)
|
|
+ OSSL_PARAM_free(params);
|
|
+ if (bn_mod != NULL)
|
|
+ BN_free(bn_mod);
|
|
+ if (bn_exp != NULL)
|
|
+ BN_free(bn_exp);
|
|
#endif
|
|
|
|
- return (void *) rsa;
|
|
+ return pkey;
|
|
}
|
|
|
|
-static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
+static EVP_PKEY *rsa_convert_private_key(OBJECT *key_obj)
|
|
{
|
|
CK_ATTRIBUTE *modulus = NULL;
|
|
CK_ATTRIBUTE *pub_exp = NULL;
|
|
@@ -854,9 +660,15 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
CK_ATTRIBUTE *exp1 = NULL;
|
|
CK_ATTRIBUTE *exp2 = NULL;
|
|
CK_ATTRIBUTE *coeff = NULL;
|
|
-
|
|
+ EVP_PKEY *pkey = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ EVP_PKEY_CTX *pctx = NULL;
|
|
+ OSSL_PARAM_BLD *tmpl = NULL;
|
|
+ OSSL_PARAM *params = NULL;
|
|
+#else
|
|
RSA *rsa;
|
|
RSA_METHOD *meth;
|
|
+#endif
|
|
BIGNUM *bn_mod, *bn_pub_exp, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2,
|
|
*bn_cf;
|
|
|
|
@@ -873,6 +685,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
if (!prime2 && !modulus) {
|
|
return NULL;
|
|
}
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
// Create and init all the RSA and BIGNUM structs we need.
|
|
rsa = RSA_new();
|
|
if (rsa == NULL)
|
|
@@ -884,17 +698,6 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
* Token doesn't implement RSA and, instead, calls OpenSSL for it.
|
|
* So to avoid it we set RSA methods to the default rsa methods.
|
|
*/
|
|
-#ifdef OLDER_OPENSSL
|
|
- if (rsa->engine) {
|
|
- meth = (RSA_METHOD *) rsa->meth;
|
|
- const RSA_METHOD *meth2 = RSA_PKCS1_SSLeay();
|
|
- meth->rsa_pub_enc = meth2->rsa_pub_enc;
|
|
- meth->rsa_pub_dec = meth2->rsa_pub_dec;
|
|
- meth->rsa_priv_enc = meth2->rsa_priv_enc;
|
|
- meth->rsa_priv_dec = meth2->rsa_priv_dec;
|
|
- meth->rsa_mod_exp = meth2->rsa_mod_exp;
|
|
- meth->bn_mod_exp = meth2->bn_mod_exp;
|
|
-#else
|
|
/*
|
|
* XXX I dont see a better way than to ignore this warning for now.
|
|
* Note that the GCC pragma also works for clang.
|
|
@@ -912,8 +715,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
RSA_meth_set_mod_exp(meth, RSA_meth_get_mod_exp(meth2));
|
|
RSA_meth_set_bn_mod_exp(meth, RSA_meth_get_bn_mod_exp(meth2));
|
|
# pragma GCC diagnostic pop
|
|
-#endif
|
|
}
|
|
+#endif
|
|
|
|
bn_mod = BN_new();
|
|
bn_pub_exp = BN_new();
|
|
@@ -926,33 +729,14 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
|
|
if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) ||
|
|
(bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) ||
|
|
- (bn_pub_exp == NULL) || (bn_mod == NULL)) {
|
|
- if (rsa)
|
|
- RSA_free(rsa);
|
|
- if (bn_mod)
|
|
- BN_free(bn_mod);
|
|
- if (bn_pub_exp)
|
|
- BN_free(bn_pub_exp);
|
|
- if (bn_priv_exp)
|
|
- BN_free(bn_priv_exp);
|
|
- if (bn_p1)
|
|
- BN_free(bn_p1);
|
|
- if (bn_p2)
|
|
- BN_free(bn_p2);
|
|
- if (bn_e1)
|
|
- BN_free(bn_e1);
|
|
- if (bn_e2)
|
|
- BN_free(bn_e2);
|
|
- if (bn_cf)
|
|
- BN_free(bn_cf);
|
|
- return NULL;
|
|
- }
|
|
+ (bn_pub_exp == NULL) || (bn_mod == NULL))
|
|
+ goto out;
|
|
|
|
// CRT key?
|
|
if (prime1) {
|
|
- if (!prime2 || !exp1 || !exp2 || !coeff) {
|
|
- return NULL;
|
|
- }
|
|
+ if (!prime2 || !exp1 || !exp2 || !coeff)
|
|
+ goto out;
|
|
+
|
|
// Even though this is CRT key, OpenSSL requires the
|
|
// modulus and exponents filled in or encrypt and decrypt will
|
|
// not work
|
|
@@ -969,20 +753,44 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
BN_bin2bn((unsigned char *) exp1->pValue, exp1->ulValueLen, bn_e1);
|
|
BN_bin2bn((unsigned char *) exp2->pValue, exp2->ulValueLen, bn_e2);
|
|
BN_bin2bn((unsigned char *) coeff->pValue, coeff->ulValueLen, bn_cf);
|
|
-#ifdef OLDER_OPENSSL
|
|
- rsa->n = bn_mod;
|
|
- rsa->d = bn_priv_exp;
|
|
- rsa->p = bn_p1;
|
|
- rsa->q = bn_p2;
|
|
- rsa->dmp1 = bn_e1;
|
|
- rsa->dmq1 = bn_e2;
|
|
- rsa->iqmp = bn_cf;
|
|
-#else
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp);
|
|
+ bn_mod = NULL;
|
|
+ bn_pub_exp = NULL;
|
|
+ bn_priv_exp = NULL;
|
|
RSA_set0_factors(rsa, bn_p1, bn_p2);
|
|
+ bn_p1 = NULL;
|
|
+ bn_p2 = NULL;
|
|
RSA_set0_crt_params(rsa, bn_e1, bn_e2, bn_cf);
|
|
+ bn_e1 = NULL;
|
|
+ bn_e2 = NULL;
|
|
+ bn_cf = NULL;
|
|
+
|
|
+ pkey = EVP_PKEY_new();
|
|
+ if (pkey == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
|
|
+ goto out;
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR1, bn_p1) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR2, bn_p2) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT1,
|
|
+ bn_e1) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT2,
|
|
+ bn_e2) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
|
|
+ bn_cf))
|
|
+ goto out;
|
|
#endif
|
|
- return rsa;
|
|
} else { // must be a non-CRT key
|
|
if (!priv_exp) {
|
|
return NULL;
|
|
@@ -993,15 +801,90 @@ static void *rsa_convert_private_key(OBJECT *key_obj)
|
|
bn_pub_exp);
|
|
BN_bin2bn((unsigned char *) priv_exp->pValue, priv_exp->ulValueLen,
|
|
bn_priv_exp);
|
|
-#ifdef OLDER_OPENSSL
|
|
- rsa->n = bn_mod;
|
|
- rsa->d = bn_priv_exp;
|
|
-#else
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp);
|
|
+ bn_mod = NULL;
|
|
+ bn_pub_exp = NULL;
|
|
+ bn_priv_exp = NULL;
|
|
+
|
|
+ pkey = EVP_PKEY_new();
|
|
+ if (pkey == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
|
|
+ goto out;
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp))
|
|
+ goto out;
|
|
#endif
|
|
}
|
|
|
|
- return (void *) rsa;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ params = OSSL_PARAM_BLD_to_param(tmpl);
|
|
+ if (params == NULL)
|
|
+ goto out;
|
|
+
|
|
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
|
|
+ if (pctx == NULL)
|
|
+ goto out;
|
|
+
|
|
+ if (!EVP_PKEY_fromdata_init(pctx) ||
|
|
+ !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params))
|
|
+ goto out;
|
|
+
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ OSSL_PARAM_free(params);
|
|
+ BN_free(bn_mod);
|
|
+ BN_free(bn_pub_exp);
|
|
+ BN_free(bn_priv_exp);
|
|
+ BN_free(bn_p1);
|
|
+ BN_free(bn_p2);
|
|
+ BN_free(bn_e1);
|
|
+ BN_free(bn_e2);
|
|
+ BN_free(bn_cf);
|
|
+#endif
|
|
+
|
|
+ return pkey;
|
|
+out:
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (rsa)
|
|
+ RSA_free(rsa);
|
|
+#else
|
|
+ if (pctx != NULL)
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ if (tmpl != NULL)
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ if (params != NULL)
|
|
+ OSSL_PARAM_free(params);
|
|
+#endif
|
|
+ if (pkey)
|
|
+ EVP_PKEY_free(pkey);
|
|
+ if (bn_mod)
|
|
+ BN_free(bn_mod);
|
|
+ if (bn_pub_exp)
|
|
+ BN_free(bn_pub_exp);
|
|
+ if (bn_priv_exp)
|
|
+ BN_free(bn_priv_exp);
|
|
+ if (bn_p1)
|
|
+ BN_free(bn_p1);
|
|
+ if (bn_p2)
|
|
+ BN_free(bn_p2);
|
|
+ if (bn_e1)
|
|
+ BN_free(bn_e1);
|
|
+ if (bn_e2)
|
|
+ BN_free(bn_e2);
|
|
+ if (bn_cf)
|
|
+ BN_free(bn_cf);
|
|
+
|
|
+ return NULL;
|
|
}
|
|
|
|
static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
@@ -1012,14 +895,16 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
CK_BBOOL flag;
|
|
CK_RV rc;
|
|
CK_ULONG BNLength;
|
|
- RSA *rsa = NULL;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ const RSA *rsa = NULL;
|
|
const BIGNUM *bignum = NULL;
|
|
+#else
|
|
+ BIGNUM *bignum = NULL;
|
|
+#endif
|
|
CK_BYTE *ssl_ptr = NULL;
|
|
BIGNUM *e = NULL;
|
|
-#ifndef OLDER_OPENSSL
|
|
EVP_PKEY *pkey = NULL;
|
|
EVP_PKEY_CTX *ctx = NULL;
|
|
-#endif
|
|
|
|
rc = template_attribute_get_ulong(publ_tmpl, CKA_MODULUS_BITS, &mod_bits);
|
|
if (rc != CKR_OK) {
|
|
@@ -1052,20 +937,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
}
|
|
BN_bin2bn(publ_exp->pValue, publ_exp->ulValueLen, e);
|
|
|
|
-#ifdef OLDER_OPENSSL
|
|
- rsa = RSA_new();
|
|
- if (rsa == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- if (!RSA_generate_key_ex(rsa, mod_bits, e, NULL)) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
- }
|
|
- bignum = rsa->n;
|
|
-#else
|
|
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
|
|
if (ctx == NULL) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
@@ -1084,22 +955,36 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto done;
|
|
}
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, e) != 1) {
|
|
+#else
|
|
+ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) != 1) {
|
|
+#endif
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto done;
|
|
}
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ e = NULL; // will be freed as part of the context
|
|
+#endif
|
|
if (EVP_PKEY_keygen(ctx, &pkey) != 1) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto done;
|
|
}
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto done;
|
|
}
|
|
RSA_get0_key(rsa, &bignum, NULL, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1122,12 +1007,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
}
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// Public Exponent
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->e;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_key(rsa, NULL, &bignum, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1166,6 +1059,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
}
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// local = TRUE
|
|
//
|
|
@@ -1189,10 +1086,14 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
// to force the system to not return this for RSA keys..
|
|
|
|
// Add the modulus to the private key information
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->n;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_key(rsa, &bignum, NULL, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1215,12 +1116,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
}
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// Private Exponent
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->d;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_key(rsa, NULL, NULL, &bignum);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1245,13 +1154,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// prime #1: p
|
|
- //
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->p;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_factors(rsa, &bignum, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1276,13 +1192,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// prime #2: q
|
|
- //
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->q;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_factors(rsa, NULL, &bignum);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1307,13 +1230,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// exponent 1: d mod(p-1)
|
|
- //
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->dmp1;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_crt_params(rsa, &bignum, NULL, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1338,13 +1268,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// exponent 2: d mod(q-1)
|
|
- //
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->dmq1;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_crt_params(rsa, NULL, &bignum, NULL);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1369,13 +1306,21 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
// CRT coefficient: q_inverse mod(p)
|
|
- //
|
|
-#ifdef OLDER_OPENSSL
|
|
- bignum = rsa->iqmp;
|
|
-#else
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
RSA_get0_crt_params(rsa, NULL, NULL, &bignum);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
|
|
+ &bignum)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
#endif
|
|
BNLength = BN_num_bytes(bignum);
|
|
ssl_ptr = malloc(BNLength);
|
|
@@ -1400,6 +1345,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
ssl_ptr = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(bignum);
|
|
+ bignum = NULL;
|
|
+#endif
|
|
|
|
flag = TRUE;
|
|
rc = build_attribute(CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr);
|
|
@@ -1415,16 +1364,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
}
|
|
|
|
done:
|
|
-#ifdef OLDER_OPENSSL
|
|
- if (e != NULL)
|
|
- BN_free(e);
|
|
- if (rsa != NULL)
|
|
- RSA_free(rsa);
|
|
- if (ssl_ptr != NULL) {
|
|
- OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
- free(ssl_ptr);
|
|
- }
|
|
-#else
|
|
if (ssl_ptr != NULL) {
|
|
OPENSSL_cleanse(ssl_ptr, BNLength);
|
|
free(ssl_ptr);
|
|
@@ -1433,6 +1372,11 @@ done:
|
|
EVP_PKEY_free(pkey);
|
|
if (ctx != NULL)
|
|
EVP_PKEY_CTX_free(ctx);
|
|
+ if (e != NULL)
|
|
+ BN_free(e);
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (bignum != NULL)
|
|
+ BN_free(bignum);
|
|
#endif
|
|
return rc;
|
|
}
|
|
@@ -1457,60 +1401,17 @@ static CK_RV os_specific_rsa_encrypt(CK_BYTE *in_data,
|
|
CK_ULONG in_data_len,
|
|
CK_BYTE *out_data, OBJECT *key_obj)
|
|
{
|
|
-#ifdef OLDER_OPENSSL
|
|
- CK_RV rc;
|
|
- RSA *rsa;
|
|
- int size;
|
|
-
|
|
- // Convert the local representation to an RSA representation
|
|
- rsa = (RSA *) rsa_convert_public_key(key_obj);
|
|
- if (rsa == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- return rc;
|
|
- }
|
|
- // Do an RSA public encryption
|
|
- size =
|
|
- RSA_public_encrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING);
|
|
- if (size == -1) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_ARGUMENTS_BAD;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- rc = CKR_OK;
|
|
-
|
|
-done:
|
|
- RSA_free(rsa);
|
|
-
|
|
- return rc;
|
|
-#else
|
|
EVP_PKEY_CTX *ctx = NULL;
|
|
EVP_PKEY *pkey = NULL;
|
|
- RSA *rsa = NULL;
|
|
CK_RV rc;
|
|
size_t outlen = in_data_len;
|
|
|
|
- rsa = (RSA *)rsa_convert_public_key(key_obj);
|
|
- if (rsa == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- return rc;
|
|
- }
|
|
-
|
|
- pkey = EVP_PKEY_new();
|
|
+ pkey = rsa_convert_public_key(key_obj);
|
|
if (pkey == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rc = CKR_HOST_MEMORY;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
+ return rc;
|
|
}
|
|
- rsa = NULL; /* freed together with pkey */
|
|
|
|
ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
|
if (ctx == NULL) {
|
|
@@ -1538,76 +1439,28 @@ done:
|
|
|
|
rc = CKR_OK;
|
|
done:
|
|
- if (rsa != NULL)
|
|
- RSA_free(rsa);
|
|
if (pkey != NULL)
|
|
EVP_PKEY_free(pkey);
|
|
if (ctx != NULL)
|
|
EVP_PKEY_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
static CK_RV os_specific_rsa_decrypt(CK_BYTE *in_data,
|
|
CK_ULONG in_data_len,
|
|
CK_BYTE *out_data, OBJECT *key_obj)
|
|
{
|
|
-#ifdef OLDER_OPENSSL
|
|
- CK_RV rc;
|
|
- RSA *rsa;
|
|
- int size;
|
|
-
|
|
- // Convert the local key representation to an RSA key representaion
|
|
- rsa = (RSA *) rsa_convert_private_key(key_obj);
|
|
- if (rsa == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- return rc;
|
|
- }
|
|
- // Do the private decryption
|
|
- size =
|
|
- RSA_private_decrypt(in_data_len, in_data, out_data, rsa,
|
|
- RSA_NO_PADDING);
|
|
-
|
|
- if (size == -1) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- rc = CKR_OK;
|
|
-
|
|
-done:
|
|
- RSA_free(rsa);
|
|
-
|
|
- return rc;
|
|
-#else
|
|
EVP_PKEY_CTX *ctx = NULL;
|
|
EVP_PKEY *pkey = NULL;
|
|
- RSA *rsa = NULL;
|
|
size_t outlen = in_data_len;
|
|
CK_RV rc;
|
|
|
|
- rsa = (RSA *)rsa_convert_private_key(key_obj);
|
|
- if (rsa == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rc = CKR_FUNCTION_FAILED;
|
|
- return rc;
|
|
- }
|
|
-
|
|
- pkey = EVP_PKEY_new();
|
|
+ pkey = rsa_convert_private_key(key_obj);
|
|
if (pkey == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rc = CKR_HOST_MEMORY;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
+ return rc;
|
|
}
|
|
- rsa = NULL; /* freed together with pkey */
|
|
|
|
ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
|
if (ctx == NULL) {
|
|
@@ -1635,14 +1488,11 @@ done:
|
|
|
|
rc = CKR_OK;
|
|
done:
|
|
- if (rsa != NULL)
|
|
- RSA_free(rsa);
|
|
if (pkey != NULL)
|
|
EVP_PKEY_free(pkey);
|
|
if (ctx != NULL)
|
|
EVP_PKEY_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_rsa_encrypt(STDLL_TokData_t *tokdata, CK_BYTE *in_data,
|
|
@@ -2407,48 +2257,6 @@ CK_RV token_specific_aes_ecb(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- AES_KEY ssl_aes_key;
|
|
- unsigned int i;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0,
|
|
- * so this is fine */
|
|
- CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE);
|
|
- CK_RV rc;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- memset(&ssl_aes_key, 0, sizeof(AES_KEY));
|
|
-
|
|
- // get key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- // AES_ecb_encrypt encrypts only a single block, so we have to break up the
|
|
- // input data here
|
|
- if (encrypt) {
|
|
- AES_set_encrypt_key((unsigned char *) attr->pValue,
|
|
- (attr->ulValueLen * 8), &ssl_aes_key);
|
|
- for (i = 0; i < loops; i++) {
|
|
- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
|
|
- (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
|
|
- &ssl_aes_key, AES_ENCRYPT);
|
|
- }
|
|
- } else {
|
|
- AES_set_decrypt_key((unsigned char *) attr->pValue,
|
|
- (attr->ulValueLen * 8), &ssl_aes_key);
|
|
- for (i = 0; i < loops; i++) {
|
|
- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
|
|
- (unsigned char *) out_data + (i * AES_BLOCK_SIZE),
|
|
- &ssl_aes_key, AES_DECRYPT);
|
|
- }
|
|
- }
|
|
- *out_data_len = in_data_len;
|
|
-
|
|
- return CKR_OK;
|
|
-#else
|
|
CK_RV rc;
|
|
int outlen;
|
|
unsigned char akey[32];
|
|
@@ -2505,7 +2313,6 @@ done:
|
|
OPENSSL_cleanse(akey, sizeof(akey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata,
|
|
@@ -2515,38 +2322,6 @@ CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *out_data_len,
|
|
OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
- AES_KEY ssl_aes_key;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- CK_RV rc;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- memset(&ssl_aes_key, 0, sizeof(AES_KEY));
|
|
-
|
|
- // get key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key\n");
|
|
- return rc;
|
|
- }
|
|
- // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike
|
|
- // AES_ecb_encrypt, so no looping required.
|
|
- if (encrypt) {
|
|
- AES_set_encrypt_key((unsigned char *) attr->pValue,
|
|
- (attr->ulValueLen * 8), &ssl_aes_key);
|
|
- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
|
|
- in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT);
|
|
- } else {
|
|
- AES_set_decrypt_key((unsigned char *) attr->pValue,
|
|
- (attr->ulValueLen * 8), &ssl_aes_key);
|
|
- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
|
|
- in_data_len, &ssl_aes_key, init_v, AES_DECRYPT);
|
|
- }
|
|
- *out_data_len = in_data_len;
|
|
-
|
|
- return CKR_OK;
|
|
-#else
|
|
CK_RV rc;
|
|
int outlen;
|
|
unsigned char akey[32];
|
|
@@ -2603,7 +2378,6 @@ done:
|
|
OPENSSL_cleanse(akey, sizeof(akey));
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return rc;
|
|
-#endif
|
|
}
|
|
|
|
CK_RV token_specific_aes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
@@ -2716,275 +2490,145 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
|
|
TEMPLATE *publ_tmpl,
|
|
TEMPLATE *priv_tmpl)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
CK_RV rv;
|
|
CK_BBOOL rc;
|
|
CK_ATTRIBUTE *prime_attr = NULL;
|
|
CK_ATTRIBUTE *base_attr = NULL;
|
|
CK_ATTRIBUTE *temp_attr = NULL;
|
|
CK_ATTRIBUTE *value_bits_attr = NULL;
|
|
- CK_BYTE *temp_byte;
|
|
+ CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL;
|
|
CK_ULONG temp_bn_len;
|
|
- DH *dh;
|
|
- BIGNUM *bn_p;
|
|
- BIGNUM *bn_g;
|
|
- const BIGNUM *temp_bn;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ DH *dh = NULL;
|
|
+#else
|
|
+ EVP_PKEY_CTX *pctx = NULL;
|
|
+ OSSL_PARAM_BLD *tmpl = NULL;
|
|
+ OSSL_PARAM *osparams = NULL;
|
|
+#endif
|
|
+ BIGNUM *bn_p = NULL;
|
|
+ BIGNUM *bn_g = NULL;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ const BIGNUM *temp_bn = NULL;
|
|
+#else
|
|
+ BIGNUM *temp_bn = NULL;
|
|
+#endif
|
|
+ EVP_PKEY *params = NULL, *pkey = NULL;
|
|
+ EVP_PKEY_CTX *ctx = NULL;
|
|
|
|
UNUSED(tokdata);
|
|
|
|
rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr);
|
|
if (rv != CKR_OK) {
|
|
TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
|
|
- return rv;
|
|
+ goto done;
|
|
}
|
|
rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr);
|
|
if (rv != CKR_OK) {
|
|
TRACE_ERROR("Could not find CKA_BASE for the key.\n");
|
|
- return rv;
|
|
+ goto done;
|
|
}
|
|
|
|
if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) {
|
|
TRACE_ERROR("CKA_PRIME attribute value is invalid.\n");
|
|
- return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
+ goto done;
|
|
}
|
|
|
|
- dh = DH_new();
|
|
- if (dh == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
- // Create and init BIGNUM structs to stick in the DH struct
|
|
+ // Create and init BIGNUM structs
|
|
bn_p = BN_new();
|
|
bn_g = BN_new();
|
|
if (bn_g == NULL || bn_p == NULL) {
|
|
- if (bn_g)
|
|
- BN_free(bn_g);
|
|
- if (bn_p)
|
|
- BN_free(bn_p);
|
|
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- return CKR_HOST_MEMORY;
|
|
+ rv = CKR_HOST_MEMORY;
|
|
+ goto done;
|
|
}
|
|
- // Convert from strings to BIGNUMs and stick them in the DH struct
|
|
+ // Convert from strings to BIGNUMs
|
|
BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen,
|
|
bn_p);
|
|
BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g);
|
|
- dh->p = bn_p;
|
|
- dh->g = bn_g;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ dh = DH_new();
|
|
+ if (dh == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ DH_set0_pqg(dh, bn_p, NULL, bn_g);
|
|
+ /* bn_p and bn_q freed together with dh */
|
|
+ bn_p = NULL;
|
|
+ bn_g = NULL;
|
|
+
|
|
+ params = EVP_PKEY_new();
|
|
+ if (params == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
+ rv = CKR_HOST_MEMORY;
|
|
+ goto done;
|
|
+ }
|
|
|
|
- // Generate the DH Key
|
|
- if (!DH_generate_key(dh)) {
|
|
+ if (EVP_PKEY_assign_DH(params, dh) != 1) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- DH_free(dh);
|
|
- return CKR_FUNCTION_FAILED;
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
+ dh = NULL; /* freed together with params */
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL)
|
|
+ goto done;
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, bn_p) ||
|
|
+ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, bn_g))
|
|
+ goto done;
|
|
+
|
|
+ osparams = OSSL_PARAM_BLD_to_param(tmpl);
|
|
+ if (osparams == NULL)
|
|
+ goto done;
|
|
+
|
|
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
|
|
+ if (pctx == NULL)
|
|
+ goto done;
|
|
+
|
|
+ if (!EVP_PKEY_fromdata_init(pctx) ||
|
|
+ !EVP_PKEY_fromdata(pctx, ¶ms, EVP_PKEY_PUBLIC_KEY, osparams))
|
|
+ goto done;
|
|
+#endif
|
|
+
|
|
+ ctx = EVP_PKEY_CTX_new(params, NULL);
|
|
+ if (ctx == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
+ rv = CKR_HOST_MEMORY;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_keygen_init(ctx) != 1
|
|
+ || EVP_PKEY_keygen(ctx, &pkey) != 1
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ /* dh is freed together with pkey */
|
|
+ || (dh = (DH *)EVP_PKEY_get0_DH(pkey)) == NULL) {
|
|
+#else
|
|
+ ) {
|
|
+#endif
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
}
|
|
+
|
|
// Extract the public and private key components from the DH struct,
|
|
// and insert them in the publ_tmpl and priv_tmpl
|
|
|
|
//
|
|
// pub_key
|
|
//
|
|
- //temp_bn = BN_new();
|
|
- temp_bn = dh->pub_key;
|
|
- temp_bn_len = BN_num_bytes(temp_bn);
|
|
- temp_byte = malloc(temp_bn_len);
|
|
- temp_bn_len = BN_bn2bin(temp_bn, temp_byte);
|
|
- // in bytes
|
|
- rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_DEVEL("build_attribute failed\n");
|
|
- DH_free(dh);
|
|
- free(temp_byte);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
- rc = template_update_attribute(publ_tmpl, temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("template_update_attribute failed\n");
|
|
- free(temp_attr);
|
|
- DH_free(dh);
|
|
- free(temp_byte);
|
|
- return rc;
|
|
- }
|
|
- free(temp_byte);
|
|
-
|
|
- //
|
|
- // priv_key
|
|
- //
|
|
- //temp_bn = BN_new();
|
|
- temp_bn = dh->priv_key;
|
|
- temp_bn_len = BN_num_bytes(temp_bn);
|
|
- temp_byte = malloc(temp_bn_len);
|
|
- temp_bn_len = BN_bn2bin(temp_bn, temp_byte);
|
|
- // in bytes
|
|
- rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_DEVEL("build_attribute failed\n");
|
|
- DH_free(dh);
|
|
- free(temp_byte);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
- rc = template_update_attribute(priv_tmpl, temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("template_update_attribute failed\n");
|
|
- free(temp_attr);
|
|
- DH_free(dh);
|
|
- free(temp_byte);
|
|
- return rc;
|
|
- }
|
|
- free(temp_byte);
|
|
-
|
|
- // Update CKA_VALUE_BITS attribute in the private key
|
|
- value_bits_attr =
|
|
- (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
|
|
- if (value_bits_attr == NULL) {
|
|
- TRACE_ERROR("malloc failed\n");
|
|
- DH_free(dh);
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
- value_bits_attr->type = CKA_VALUE_BITS;
|
|
- value_bits_attr->ulValueLen = sizeof(CK_ULONG);
|
|
- value_bits_attr->pValue =
|
|
- (CK_BYTE *) value_bits_attr + sizeof(CK_ATTRIBUTE);
|
|
- *(CK_ULONG *) value_bits_attr->pValue = 8 * temp_bn_len;
|
|
- rc = template_update_attribute(priv_tmpl, value_bits_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("template_update_attribute failed\n");
|
|
- free(value_bits_attr);
|
|
- DH_free(dh);
|
|
- return rc;
|
|
- }
|
|
-
|
|
- // Add prime and base to the private key template
|
|
- rc = build_attribute(CKA_PRIME,
|
|
- (unsigned char *) prime_attr->pValue,
|
|
- prime_attr->ulValueLen, &temp_attr); // in bytes
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_DEVEL("build_attribute failed\n");
|
|
- DH_free(dh);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
- rc = template_update_attribute(priv_tmpl, temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("template_update_attribute failed\n");
|
|
- free(temp_attr);
|
|
- DH_free(dh);
|
|
- return rc;
|
|
- }
|
|
-
|
|
- rc = build_attribute(CKA_BASE,
|
|
- (unsigned char *) base_attr->pValue,
|
|
- base_attr->ulValueLen, &temp_attr); // in bytes
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_DEVEL("build_attribute failed\n");
|
|
- DH_free(dh);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
- rc = template_update_attribute(priv_tmpl, temp_attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("template_update_attribute failed\n");
|
|
- free(temp_attr);
|
|
- DH_free(dh);
|
|
- return rc;
|
|
- }
|
|
-
|
|
- // Cleanup DH key
|
|
- DH_free(dh);
|
|
-
|
|
- return CKR_OK;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ DH_get0_key(dh, &temp_bn, NULL);
|
|
#else
|
|
- CK_RV rv;
|
|
- CK_BBOOL rc;
|
|
- CK_ATTRIBUTE *prime_attr = NULL;
|
|
- CK_ATTRIBUTE *base_attr = NULL;
|
|
- CK_ATTRIBUTE *temp_attr = NULL;
|
|
- CK_ATTRIBUTE *value_bits_attr = NULL;
|
|
- CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL;
|
|
- CK_ULONG temp_bn_len;
|
|
- DH *dh = NULL;
|
|
- BIGNUM *bn_p = NULL;
|
|
- BIGNUM *bn_g = NULL;
|
|
- const BIGNUM *temp_bn = NULL;
|
|
- EVP_PKEY *params = NULL, *pkey = NULL;
|
|
- EVP_PKEY_CTX *ctx = NULL;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr);
|
|
- if (rv != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_PRIME for the key.\n");
|
|
- goto done;
|
|
- }
|
|
- rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr);
|
|
- if (rv != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_BASE for the key.\n");
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) {
|
|
- TRACE_ERROR("CKA_PRIME attribute value is invalid.\n");
|
|
- rv = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- dh = DH_new();
|
|
- if (dh == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
- }
|
|
- // Create and init BIGNUM structs to stick in the DH struct
|
|
- bn_p = BN_new();
|
|
- bn_g = BN_new();
|
|
- if (bn_g == NULL || bn_p == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rv = CKR_HOST_MEMORY;
|
|
- goto done;
|
|
- }
|
|
- // Convert from strings to BIGNUMs and stick them in the DH struct
|
|
- BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen,
|
|
- bn_p);
|
|
- BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g);
|
|
- DH_set0_pqg(dh, bn_p, NULL, bn_g);
|
|
- /* bn_p and bn_q freed together with dh */
|
|
- bn_p = NULL;
|
|
- bn_g = NULL;
|
|
-
|
|
- params = EVP_PKEY_new();
|
|
- if (params == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rv = CKR_HOST_MEMORY;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (EVP_PKEY_assign_DH(params, dh) != 1) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- goto done;
|
|
- }
|
|
- dh = NULL; /* freed together with params */
|
|
-
|
|
- ctx = EVP_PKEY_CTX_new(params, NULL);
|
|
- if (ctx == NULL) {
|
|
- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rv = CKR_HOST_MEMORY;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (EVP_PKEY_keygen_init(ctx) != 1
|
|
- || EVP_PKEY_keygen(ctx, &pkey) != 1
|
|
- /* dh is freed together with pkey */
|
|
- || (dh = EVP_PKEY_get0_DH(pkey)) == NULL) {
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &temp_bn)) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
goto done;
|
|
}
|
|
-
|
|
- // Extract the public and private key components from the DH struct,
|
|
- // and insert them in the publ_tmpl and priv_tmpl
|
|
-
|
|
- //
|
|
- // pub_key
|
|
- //
|
|
- DH_get0_key(dh, &temp_bn, NULL);
|
|
+#endif
|
|
|
|
temp_bn_len = BN_num_bytes(temp_bn);
|
|
temp_byte = malloc(temp_bn_len);
|
|
@@ -3001,11 +2645,23 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
|
|
free(temp_attr);
|
|
goto done;
|
|
}
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(temp_bn);
|
|
+ temp_bn = NULL;
|
|
+#endif
|
|
|
|
//
|
|
// priv_key
|
|
//
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
DH_get0_key(dh, NULL, &temp_bn);
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &temp_bn)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto done;
|
|
+ }
|
|
+#endif
|
|
temp_bn_len = BN_num_bytes(temp_bn);
|
|
temp_byte2 = malloc(temp_bn_len);
|
|
temp_bn_len = BN_bn2bin(temp_bn, temp_byte2);
|
|
@@ -3022,6 +2678,10 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
|
|
free(temp_attr);
|
|
goto done;
|
|
}
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ BN_free(temp_bn);
|
|
+ temp_bn = NULL;
|
|
+#endif
|
|
|
|
// Update CKA_VALUE_BITS attribute in the private key
|
|
value_bits_attr =
|
|
@@ -3086,8 +2746,17 @@ done:
|
|
EVP_PKEY_free(params);
|
|
free(temp_byte);
|
|
free(temp_byte2);
|
|
- return rv;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (pctx != NULL)
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ if (tmpl != NULL)
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ if (osparams != NULL)
|
|
+ OSSL_PARAM_free(osparams);
|
|
+ if (temp_bn != NULL)
|
|
+ BN_free(temp_bn);
|
|
#endif
|
|
+ return rv;
|
|
} /* end token_specific_dh_key_pair_gen() */
|
|
#endif
|
|
/* End code contributed by Corrent corp. */
|
|
@@ -3106,11 +2775,6 @@ CK_RV token_specific_get_mechanism_info(STDLL_TokData_t *tokdata,
|
|
return ock_generic_get_mechanism_info(tokdata, type, pInfo);
|
|
}
|
|
|
|
-#ifdef OLDER_OPENSSL
|
|
-#define EVP_MD_meth_get_app_datasize(md) md->ctx_size
|
|
-#define EVP_MD_CTX_md_data(ctx) ctx->md_data
|
|
-#endif
|
|
-
|
|
static const EVP_MD *md_from_mech(CK_MECHANISM *mech)
|
|
{
|
|
const EVP_MD *md = NULL;
|
|
@@ -3168,16 +2832,13 @@ static const EVP_MD *md_from_mech(CK_MECHANISM *mech)
|
|
return md;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
|
|
{
|
|
const EVP_MD *md;
|
|
EVP_MD_CTX *md_ctx;
|
|
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- md_ctx = EVP_MD_CTX_create();
|
|
-#else
|
|
md_ctx = EVP_MD_CTX_new();
|
|
-#endif
|
|
if (md_ctx == NULL)
|
|
return NULL;
|
|
|
|
@@ -3185,11 +2846,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
|
|
if (md == NULL ||
|
|
!EVP_DigestInit_ex(md_ctx, md, NULL)) {
|
|
TRACE_ERROR("md_from_mech or EVP_DigestInit_ex failed\n");
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
-#endif
|
|
return NULL;
|
|
}
|
|
|
|
@@ -3198,11 +2855,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
|
|
ctx->context = malloc(ctx->context_len);
|
|
if (ctx->context == NULL) {
|
|
TRACE_ERROR("malloc failed\n");
|
|
- #if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
- #else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
- #endif
|
|
ctx->context_len = 0;
|
|
return NULL;
|
|
}
|
|
@@ -3221,27 +2874,60 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx)
|
|
|
|
return md_ctx;
|
|
}
|
|
+#endif
|
|
+
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+static void token_specific_sha_free(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
+ CK_BYTE *context, CK_ULONG context_len)
|
|
+{
|
|
+ UNUSED(tokdata);
|
|
+ UNUSED(sess);
|
|
+ UNUSED(context_len);
|
|
+
|
|
+ EVP_MD_CTX_free((EVP_MD_CTX *)context);
|
|
+}
|
|
+#endif
|
|
|
|
CK_RV token_specific_sha_init(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
CK_MECHANISM *mech)
|
|
{
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *md_ctx;
|
|
+#else
|
|
+ const EVP_MD *md;
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
ctx->mech.ulParameterLen = mech->ulParameterLen;
|
|
ctx->mech.mechanism = mech->mechanism;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
md_ctx = md_ctx_from_context(ctx);
|
|
if (md_ctx == NULL) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
return CKR_HOST_MEMORY;
|
|
}
|
|
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
+#else
|
|
+ ctx->context_len = 1;
|
|
+ ctx->context = (CK_BYTE *)EVP_MD_CTX_new();
|
|
+ if (ctx->context == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
+ return CKR_HOST_MEMORY;
|
|
+ }
|
|
+
|
|
+ md = md_from_mech(&ctx->mech);
|
|
+ if (md == NULL ||
|
|
+ !EVP_DigestInit_ex((EVP_MD_CTX *)ctx->context, md, NULL)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
+ ctx->state_unsaveable = CK_TRUE;
|
|
+ ctx->context_free_func = token_specific_sha_free;
|
|
#endif
|
|
|
|
return CKR_OK;
|
|
@@ -3253,7 +2939,9 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
{
|
|
unsigned int len;
|
|
CK_RV rc = CKR_OK;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *md_ctx;
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
@@ -3263,6 +2951,7 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
if (!in_data || !out_data)
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
/* Recreate the OpenSSL MD context from the saved context */
|
|
md_ctx = md_ctx_from_context(ctx);
|
|
if (md_ctx == NULL) {
|
|
@@ -3275,21 +2964,38 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
|
|
if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len) ||
|
|
!EVP_DigestFinal(md_ctx, out_data, &len)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto out;
|
|
}
|
|
|
|
*out_data_len = len;
|
|
+#else
|
|
+ if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
|
|
+ return CKR_BUFFER_TOO_SMALL;
|
|
+ }
|
|
+
|
|
+ len = *out_data_len;
|
|
+ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len) ||
|
|
+ !EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
+ *out_data_len = len;
|
|
+#endif
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
out:
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
-#endif
|
|
free(ctx->context);
|
|
+#else
|
|
+ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
|
|
+#endif
|
|
ctx->context = NULL;
|
|
ctx->context_len = 0;
|
|
+ ctx->context_free_func = NULL;
|
|
|
|
return rc;
|
|
}
|
|
@@ -3297,7 +3003,9 @@ out:
|
|
CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
CK_BYTE *in_data, CK_ULONG in_data_len)
|
|
{
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *md_ctx;
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
@@ -3307,6 +3015,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
if (!in_data)
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
/* Recreate the OpenSSL MD context from the saved context */
|
|
md_ctx = md_ctx_from_context(ctx);
|
|
if (md_ctx == NULL) {
|
|
@@ -3315,24 +3024,24 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
}
|
|
|
|
if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len)) {
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
-#endif
|
|
free(ctx->context);
|
|
ctx->context = NULL;
|
|
ctx->context_len = 0;
|
|
+ ctx->context_free_func = NULL;
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
/* Save context data for later use */
|
|
memcpy(ctx->context, EVP_MD_CTX_md_data(md_ctx), ctx->context_len);
|
|
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
+#else
|
|
+ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
#endif
|
|
|
|
return CKR_OK;
|
|
@@ -3343,7 +3052,9 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
{
|
|
unsigned int len;
|
|
CK_RV rc = CKR_OK;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *md_ctx;
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
@@ -3353,6 +3064,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
if (!out_data)
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
/* Recreate the OpenSSL MD context from the saved context */
|
|
md_ctx = md_ctx_from_context(ctx);
|
|
if (md_ctx == NULL) {
|
|
@@ -3370,14 +3082,30 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx,
|
|
*out_data_len = len;
|
|
|
|
out:
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- EVP_MD_CTX_destroy(md_ctx);
|
|
-#else
|
|
EVP_MD_CTX_free(md_ctx);
|
|
-#endif
|
|
free(ctx->context);
|
|
ctx->context = NULL;
|
|
ctx->context_len = 0;
|
|
+ ctx->context_free_func = NULL;
|
|
+#else
|
|
+ if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
|
|
+ return CKR_BUFFER_TOO_SMALL;
|
|
+ }
|
|
+
|
|
+ len = *out_data_len;
|
|
+ if (!EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
+ *out_data_len = len;
|
|
+
|
|
+ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context);
|
|
+ ctx->context = NULL;
|
|
+ ctx->context_len = 0;
|
|
+ ctx->context_free_func = NULL;
|
|
+#endif
|
|
|
|
return rc;
|
|
}
|
|
@@ -3897,99 +3625,26 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
CK_ULONG message_len, OBJECT *key, CK_BYTE *mac,
|
|
CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
int rc;
|
|
- CK_RV rv = CKR_OK;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- CK_KEY_TYPE keytype;
|
|
- CMAC_CTX *cmac_ctx;
|
|
- const EVP_CIPHER *cipher;
|
|
- size_t maclen;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- if (first) {
|
|
- // get the key type
|
|
- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key.\n");
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
-
|
|
- // get the key value
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
|
|
- return rc;
|
|
- }
|
|
- switch (keytype) {
|
|
- case CKK_DES2:
|
|
- cipher = EVP_des_ede_cbc();
|
|
- break;
|
|
- case CKK_DES3:
|
|
- cipher = EVP_des_ede3_cbc();
|
|
- break;
|
|
- default:
|
|
- TRACE_ERROR("Invalid key type: %lu\n", keytype);
|
|
- return CKR_KEY_TYPE_INCONSISTENT;
|
|
- }
|
|
- if (cipher == NULL) {
|
|
- TRACE_ERROR("Failed to allocate cipher\n");
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- cmac_ctx = CMAC_CTX_new();
|
|
- if (cmac_ctx == NULL) {
|
|
- TRACE_ERROR("Failed to allocate CMAC context\n");
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Init failed\n");
|
|
- CMAC_CTX_free(cmac_ctx);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
-
|
|
- *ctx = cmac_ctx;
|
|
- }
|
|
-
|
|
- cmac_ctx = (CMAC_CTX *)*ctx;
|
|
-
|
|
- rc = CMAC_Update(cmac_ctx, message, message_len);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Update failed\n");
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- }
|
|
-
|
|
- if (last) {
|
|
- maclen = AES_BLOCK_SIZE;
|
|
- rc = CMAC_Final(cmac_ctx, mac, &maclen);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Final failed\n");
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- }
|
|
- }
|
|
-
|
|
- if (last || (first && rv != CKR_OK)) {
|
|
- CMAC_CTX_free(cmac_ctx);
|
|
- *ctx = NULL;
|
|
- }
|
|
-
|
|
- return rv;
|
|
-#else
|
|
- int rc;
|
|
- size_t maclen;
|
|
+ size_t maclen;
|
|
CK_RV rv = CKR_OK;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
CK_KEY_TYPE keytype;
|
|
const EVP_CIPHER *cipher;
|
|
struct cmac_ctx {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *mctx;
|
|
EVP_PKEY_CTX *pctx;
|
|
EVP_PKEY *pkey;
|
|
+#else
|
|
+ EVP_MAC *mac;
|
|
+ EVP_MAC_CTX *mctx;
|
|
+#endif
|
|
};
|
|
struct cmac_ctx *cmac = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ OSSL_PARAM params[2];
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
@@ -4031,10 +3686,11 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
cmac->mctx = EVP_MD_CTX_new();
|
|
if (cmac->mctx == NULL) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
- rv = ERR_HOST_MEMORY;
|
|
+ rv = CKR_HOST_MEMORY;
|
|
goto err;
|
|
}
|
|
|
|
@@ -4053,6 +3709,31 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
+#else
|
|
+ cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
|
|
+ if (cmac->mac == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ cmac->mctx = EVP_MAC_CTX_new(cmac->mac);
|
|
+ if (cmac->mctx == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
+ rv = CKR_HOST_MEMORY;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
|
|
+ (char *)EVP_CIPHER_get0_name(cipher), 0);
|
|
+ params[1] = OSSL_PARAM_construct_end();
|
|
+
|
|
+ if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto err;
|
|
+ }
|
|
+#endif
|
|
|
|
*ctx = cmac;
|
|
}
|
|
@@ -4064,9 +3745,17 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len);
|
|
+#else
|
|
+ rc = EVP_MAC_update(cmac->mctx, message, message_len);
|
|
+#endif
|
|
if (rc != 1 || message_len > INT_MAX) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
TRACE_ERROR("EVP_DigestSignUpdate failed\n");
|
|
+#else
|
|
+ TRACE_ERROR("EVP_MAC_update failed\n");
|
|
+#endif
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
@@ -4074,15 +3763,28 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
if (last) {
|
|
maclen = AES_BLOCK_SIZE;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen);
|
|
+#else
|
|
+ rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen);
|
|
+#endif
|
|
if (rc != 1) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
TRACE_ERROR("EVP_DigestSignFinal failed\n");
|
|
+#else
|
|
+ TRACE_ERROR("EVP_MAC_final failed\n");
|
|
+#endif
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
|
|
EVP_PKEY_free(cmac->pkey);
|
|
+#else
|
|
+ EVP_MAC_CTX_free(cmac->mctx);
|
|
+ EVP_MAC_free(cmac->mac);
|
|
+#endif
|
|
free(cmac);
|
|
*ctx = NULL;
|
|
}
|
|
@@ -4090,15 +3792,21 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
return CKR_OK;
|
|
err:
|
|
if (cmac != NULL) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (cmac->mctx != NULL)
|
|
EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
|
|
if (cmac->pkey != NULL)
|
|
EVP_PKEY_free(cmac->pkey);
|
|
+#else
|
|
+ if (cmac->mctx != NULL)
|
|
+ EVP_MAC_CTX_free(cmac->mctx);
|
|
+ if (cmac->mac != NULL)
|
|
+ EVP_MAC_free(cmac->mac);
|
|
+#endif
|
|
free(cmac);
|
|
}
|
|
*ctx = NULL;
|
|
return rv;
|
|
-#endif
|
|
}
|
|
|
|
|
|
@@ -4106,93 +3814,25 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
CK_ULONG message_len, OBJECT *key, CK_BYTE *mac,
|
|
CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx)
|
|
{
|
|
-#if OPENSSL_VERSION_NUMBER < 0x10101000L
|
|
- int rc;
|
|
- CK_RV rv = CKR_OK;
|
|
- CK_ATTRIBUTE *attr = NULL;
|
|
- CMAC_CTX *cmac_ctx;
|
|
- const EVP_CIPHER *cipher;
|
|
- size_t maclen;
|
|
-
|
|
- UNUSED(tokdata);
|
|
-
|
|
- if (first) {
|
|
- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
|
|
- if (rc != CKR_OK) {
|
|
- TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
|
|
- return rc;
|
|
- }
|
|
-
|
|
- switch (attr->ulValueLen * 8) {
|
|
- case 128:
|
|
- cipher = EVP_aes_128_cbc();
|
|
- break;
|
|
- case 192:
|
|
- cipher = EVP_aes_192_cbc();
|
|
- break;
|
|
- case 256:
|
|
- cipher = EVP_aes_256_cbc();
|
|
- break;
|
|
- default:
|
|
- TRACE_ERROR("Invalid key size: %lu\n", attr->ulValueLen);
|
|
- return CKR_KEY_TYPE_INCONSISTENT;
|
|
- }
|
|
- if (cipher == NULL) {
|
|
- TRACE_ERROR("Failed to allocate cipher\n");
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- cmac_ctx = CMAC_CTX_new();
|
|
- if (cmac_ctx == NULL) {
|
|
- TRACE_ERROR("Failed to allocate CMAC context\n");
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Init failed\n");
|
|
- CMAC_CTX_free(cmac_ctx);
|
|
- return CKR_FUNCTION_FAILED;
|
|
- }
|
|
-
|
|
- *ctx = cmac_ctx;
|
|
- }
|
|
-
|
|
- cmac_ctx = (CMAC_CTX *)*ctx;
|
|
-
|
|
- rc = CMAC_Update(cmac_ctx, message, message_len);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Update failed\n");
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- }
|
|
-
|
|
- if (last) {
|
|
- maclen = AES_BLOCK_SIZE;
|
|
- rc = CMAC_Final(cmac_ctx, mac, &maclen);
|
|
- if (rc != 1) {
|
|
- TRACE_ERROR("CMAC_Final failed\n");
|
|
- rv = CKR_FUNCTION_FAILED;
|
|
- }
|
|
- }
|
|
-
|
|
- if (last || (first && rv != CKR_OK)) {
|
|
- CMAC_CTX_free(cmac_ctx);
|
|
- *ctx = NULL;
|
|
- }
|
|
-
|
|
- return rv;
|
|
-#else
|
|
int rc;
|
|
size_t maclen;
|
|
CK_RV rv = CKR_OK;
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
const EVP_CIPHER *cipher;
|
|
struct cmac_ctx {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX *mctx;
|
|
EVP_PKEY_CTX *pctx;
|
|
EVP_PKEY *pkey;
|
|
+#else
|
|
+ EVP_MAC *mac;
|
|
+ EVP_MAC_CTX *mctx;
|
|
+#endif
|
|
};
|
|
struct cmac_ctx *cmac = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ OSSL_PARAM params[2];
|
|
+#endif
|
|
|
|
UNUSED(tokdata);
|
|
|
|
@@ -4229,6 +3869,7 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
cmac->mctx = EVP_MD_CTX_new();
|
|
if (cmac->mctx == NULL) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
@@ -4251,6 +3892,31 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
+#else
|
|
+ cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
|
|
+ if (cmac->mac == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ cmac->mctx = EVP_MAC_CTX_new(cmac->mac);
|
|
+ if (cmac->mctx == NULL) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
+ rv = CKR_HOST_MEMORY;
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
|
|
+ (char *)EVP_CIPHER_get0_name(cipher), 0);
|
|
+ params[1] = OSSL_PARAM_construct_end();
|
|
+
|
|
+ if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) {
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
+ rv = CKR_FUNCTION_FAILED;
|
|
+ goto err;
|
|
+ }
|
|
+#endif
|
|
|
|
*ctx = cmac;
|
|
}
|
|
@@ -4262,9 +3928,17 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len);
|
|
+#else
|
|
+ rc = EVP_MAC_update(cmac->mctx, message, message_len);
|
|
+#endif
|
|
if (rc != 1 || message_len > INT_MAX) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
TRACE_ERROR("EVP_DigestSignUpdate failed\n");
|
|
+#else
|
|
+ TRACE_ERROR("EVP_MAC_update failed\n");
|
|
+#endif
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
@@ -4272,15 +3946,28 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
if (last) {
|
|
maclen = AES_BLOCK_SIZE;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen);
|
|
+#else
|
|
+ rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen);
|
|
+#endif
|
|
if (rc != 1) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
TRACE_ERROR("EVP_DigestSignFinal failed\n");
|
|
+#else
|
|
+ TRACE_ERROR("EVP_MAC_final failed\n");
|
|
+#endif
|
|
rv = CKR_FUNCTION_FAILED;
|
|
goto err;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
|
|
EVP_PKEY_free(cmac->pkey);
|
|
+#else
|
|
+ EVP_MAC_CTX_free(cmac->mctx);
|
|
+ EVP_MAC_free(cmac->mac);
|
|
+#endif
|
|
free(cmac);
|
|
*ctx = NULL;
|
|
}
|
|
@@ -4288,37 +3975,90 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
|
|
return CKR_OK;
|
|
err:
|
|
if (cmac != NULL) {
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (cmac->mctx != NULL)
|
|
EVP_MD_CTX_free(cmac->mctx); /* frees pctx */
|
|
if (cmac->pkey != NULL)
|
|
EVP_PKEY_free(cmac->pkey);
|
|
+#else
|
|
+ if (cmac->mctx != NULL)
|
|
+ EVP_MAC_CTX_free(cmac->mctx);
|
|
+ if (cmac->mac != NULL)
|
|
+ EVP_MAC_free(cmac->mac);
|
|
+#endif
|
|
free(cmac);
|
|
}
|
|
*ctx = NULL;
|
|
return rv;
|
|
-#endif
|
|
}
|
|
|
|
#ifndef NO_EC
|
|
|
|
-static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
|
|
- EC_KEY **key)
|
|
+static int curve_nid_from_params(const CK_BYTE *params, CK_ULONG params_len)
|
|
{
|
|
const unsigned char *oid;
|
|
ASN1_OBJECT *obj = NULL;
|
|
- EC_KEY *ec_key = NULL;
|
|
int nid;
|
|
- CK_RV rc = CKR_OK;
|
|
|
|
oid = params;
|
|
obj = d2i_ASN1_OBJECT(NULL, &oid, params_len);
|
|
if (obj == NULL) {
|
|
TRACE_ERROR("curve not supported by OpenSSL.\n");
|
|
- rc = CKR_CURVE_NOT_SUPPORTED;
|
|
- goto out;
|
|
+ return NID_undef;
|
|
}
|
|
|
|
nid = OBJ_obj2nid(obj);
|
|
+ ASN1_OBJECT_free(obj);
|
|
+
|
|
+ return nid;
|
|
+}
|
|
+
|
|
+static int ec_prime_len_from_nid(int nid)
|
|
+{
|
|
+ EC_GROUP *group;
|
|
+ int primelen;
|
|
+
|
|
+ group = EC_GROUP_new_by_curve_name(nid);
|
|
+ if (group == NULL)
|
|
+ return -1;
|
|
+
|
|
+ primelen = EC_GROUP_order_bits(group);
|
|
+
|
|
+ EC_GROUP_free(group);
|
|
+
|
|
+ if ((primelen % 8) == 0)
|
|
+ return primelen / 8;
|
|
+ else
|
|
+ return (primelen / 8) + 1;
|
|
+}
|
|
+
|
|
+int ec_prime_len_from_pkey(EVP_PKEY *pkey)
|
|
+{
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ return (EC_GROUP_order_bits(EC_KEY_get0_group(
|
|
+ EVP_PKEY_get0_EC_KEY(pkey))) + 7) / 8;
|
|
+#else
|
|
+ size_t curve_len;
|
|
+ char curve[80];
|
|
+
|
|
+ if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
|
|
+ curve, sizeof(curve), &curve_len))
|
|
+ return -1;
|
|
+
|
|
+ return ec_prime_len_from_nid(OBJ_sn2nid(curve));
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
|
|
+ EC_KEY **key)
|
|
+{
|
|
+ EC_KEY *ec_key = NULL;
|
|
+ int nid;
|
|
+ CK_RV rc = CKR_OK;
|
|
+
|
|
+ nid = curve_nid_from_params(params, params_len);
|
|
if (nid == NID_undef) {
|
|
TRACE_ERROR("curve not supported by OpenSSL.\n");
|
|
rc = CKR_CURVE_NOT_SUPPORTED;
|
|
@@ -4333,9 +4073,6 @@ static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len,
|
|
}
|
|
|
|
out:
|
|
- if (obj != NULL)
|
|
- ASN1_OBJECT_free(obj);
|
|
-
|
|
if (rc != CKR_OK) {
|
|
if (ec_key != NULL)
|
|
EC_KEY_free(ec_key);
|
|
@@ -4347,16 +4084,97 @@ out:
|
|
|
|
return CKR_OK;
|
|
}
|
|
+#endif
|
|
+
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+static CK_RV build_pkey_from_params(OSSL_PARAM_BLD *tmpl, int selection,
|
|
+ EVP_PKEY **pkey)
|
|
+{
|
|
+
|
|
+ OSSL_PARAM *params = NULL;
|
|
+ EVP_PKEY_CTX *pctx = NULL;
|
|
+ CK_RV rc = CKR_OK;
|
|
+
|
|
+ params = OSSL_PARAM_BLD_to_param(tmpl);
|
|
+ if (params == NULL) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_to_param failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
|
+ if (pctx == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new_id failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!EVP_PKEY_fromdata_init(pctx) ||
|
|
+ !EVP_PKEY_fromdata(pctx, pkey, selection, params)) {
|
|
+ TRACE_ERROR("EVP_PKEY_fromdata failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ pctx = EVP_PKEY_CTX_new(*pkey, NULL);
|
|
+ if (pctx == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
|
|
+ if (EVP_PKEY_check(pctx) != 1) {
|
|
+ TRACE_ERROR("EVP_PKEY_check failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+ } else {
|
|
+ if (EVP_PKEY_public_check(pctx) != 1) {
|
|
+ TRACE_ERROR("EVP_PKEY_public_check failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (pctx != NULL)
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
+ if (params != NULL)
|
|
+ OSSL_PARAM_free(params);
|
|
+
|
|
+ if (rc != 0 && *pkey != NULL) {
|
|
+ EVP_PKEY_free(*pkey);
|
|
+ *pkey = NULL;
|
|
+ }
|
|
+
|
|
+ return rc;
|
|
+}
|
|
+#endif
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
|
|
- CK_ULONG data_len, CK_BBOOL allow_raw)
|
|
+ CK_ULONG data_len, CK_BBOOL allow_raw,
|
|
+ int nid, EVP_PKEY **ec_pkey)
|
|
+#else
|
|
+static CK_RV fill_ec_key_from_pubkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data,
|
|
+ CK_ULONG data_len, CK_BBOOL allow_raw,
|
|
+ int nid, EVP_PKEY **ec_pkey)
|
|
+#endif
|
|
{
|
|
CK_BYTE *ecpoint = NULL;
|
|
CK_ULONG ecpoint_len, privlen;
|
|
CK_BBOOL allocated = FALSE;
|
|
+
|
|
CK_RV rc;
|
|
|
|
- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
|
|
+ privlen = ec_prime_len_from_nid(nid);
|
|
+ if (privlen <= 0) {
|
|
+ TRACE_ERROR("ec_prime_len_from_nid failed\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
+ goto out;
|
|
+ }
|
|
|
|
rc = ec_point_from_public_data(data, data_len, privlen, allow_raw,
|
|
&allocated, &ecpoint, &ecpoint_len);
|
|
@@ -4365,6 +4183,7 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
|
|
goto out;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (!EC_KEY_oct2key(ec_key, ecpoint, ecpoint_len, NULL)) {
|
|
TRACE_ERROR("EC_KEY_oct2key failed\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
@@ -4377,6 +4196,34 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
|
|
goto out;
|
|
}
|
|
|
|
+ *ec_pkey = EVP_PKEY_new();
|
|
+ if (*ec_pkey == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed.\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) {
|
|
+ TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#else
|
|
+ if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
|
|
+ OSSL_PKEY_PARAM_PUB_KEY,
|
|
+ ecpoint, ecpoint_len)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rc = build_pkey_from_params(tmpl, EVP_PKEY_PUBLIC_KEY, ec_pkey);
|
|
+ if (rc != CKR_OK) {
|
|
+ TRACE_ERROR("build_pkey_from_params failed\n");
|
|
+ goto out;
|
|
+ }
|
|
+ #endif
|
|
+
|
|
out:
|
|
if (allocated && ecpoint != NULL)
|
|
free(ecpoint);
|
|
@@ -4384,12 +4231,26 @@ out:
|
|
return rc;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data,
|
|
- CK_ULONG data_len)
|
|
+ CK_ULONG data_len, EVP_PKEY **ec_pkey)
|
|
+#else
|
|
+static CK_RV fill_ec_key_from_privkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data,
|
|
+ CK_ULONG data_len, int nid,
|
|
+ EVP_PKEY **ec_pkey)
|
|
+#endif
|
|
{
|
|
EC_POINT *point = NULL;
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ EC_GROUP *group = NULL;
|
|
+ BIGNUM *bn_priv = NULL;
|
|
+ unsigned char *pub_key = NULL;
|
|
+ unsigned int pub_key_len;
|
|
+ point_conversion_form_t form;
|
|
+#endif
|
|
CK_RV rc = CKR_OK;
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (!EC_KEY_oct2priv(ec_key, data, data_len)) {
|
|
TRACE_ERROR("EC_KEY_oct2priv failed\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
@@ -4422,18 +4283,102 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data,
|
|
goto out;
|
|
}
|
|
|
|
+ *ec_pkey = EVP_PKEY_new();
|
|
+ if (*ec_pkey == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed.\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) {
|
|
+ TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#else
|
|
+ group = EC_GROUP_new_by_curve_name(nid);
|
|
+ if (group == NULL) {
|
|
+ TRACE_ERROR("EC_GROUP_new_by_curve_name failed\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ point = EC_POINT_new(group);
|
|
+ if (point == NULL) {
|
|
+ TRACE_ERROR("EC_POINT_new failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ bn_priv = BN_bin2bn(data, data_len, NULL);
|
|
+ if (bn_priv == NULL) {
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!EC_POINT_mul(group, point, bn_priv, NULL, NULL, NULL)) {
|
|
+ TRACE_ERROR("EC_POINT_mul failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ form = EC_GROUP_get_point_conversion_form(group);
|
|
+ pub_key_len = EC_POINT_point2buf(group, point, form, &pub_key,
|
|
+ NULL);
|
|
+ if (pub_key_len == 0) {
|
|
+ TRACE_ERROR("EC_POINT_point2buf failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
|
+ pub_key, pub_key_len)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, bn_priv)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_BN failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rc = build_pkey_from_params(tmpl, EVP_PKEY_KEYPAIR, ec_pkey);
|
|
+ if (rc != CKR_OK) {
|
|
+ TRACE_ERROR("build_pkey_from_params failed\n");
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
+
|
|
out:
|
|
if (point != NULL)
|
|
EC_POINT_free(point);
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (group != NULL)
|
|
+ EC_GROUP_free(group);
|
|
+ if (bn_priv != NULL)
|
|
+ BN_free(bn_priv);
|
|
+ if (pub_key != NULL)
|
|
+ OPENSSL_free(pub_key);
|
|
+#endif
|
|
|
|
return rc;
|
|
}
|
|
|
|
-static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
|
|
+
|
|
+
|
|
+static CK_RV make_ec_key_from_template(TEMPLATE *template, EVP_PKEY **pkey)
|
|
{
|
|
CK_ATTRIBUTE *attr = NULL;
|
|
CK_OBJECT_CLASS keyclass;
|
|
+ EVP_PKEY *ec_pkey = NULL;
|
|
+ int nid;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
EC_KEY *ec_key = NULL;
|
|
+#else
|
|
+ OSSL_PARAM_BLD *tmpl = NULL;
|
|
+#endif
|
|
CK_RV rc;
|
|
|
|
rc = template_attribute_get_ulong(template, CKA_CLASS, &keyclass);
|
|
@@ -4448,9 +4393,32 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
|
|
goto out;
|
|
}
|
|
|
|
+ nid = curve_nid_from_params(attr->pValue, attr->ulValueLen);
|
|
+ if (nid == NID_undef) {
|
|
+ TRACE_ERROR("curve not supported by OpenSSL.\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key);
|
|
if (rc != CKR_OK)
|
|
goto out;
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
|
|
+ OBJ_nid2sn(nid), 0)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
|
|
switch (keyclass) {
|
|
case CKO_PUBLIC_KEY:
|
|
@@ -4460,8 +4428,13 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
|
|
goto out;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
rc = fill_ec_key_from_pubkey(ec_key, attr->pValue, attr->ulValueLen,
|
|
- FALSE);
|
|
+ FALSE, nid, &ec_pkey);
|
|
+#else
|
|
+ rc = fill_ec_key_from_pubkey(tmpl, attr->pValue, attr->ulValueLen,
|
|
+ FALSE, nid, &ec_pkey);
|
|
+#endif
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("fill_ec_key_from_pubkey failed\n");
|
|
goto out;
|
|
@@ -4475,7 +4448,14 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
|
|
goto out;
|
|
}
|
|
|
|
- rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen,
|
|
+ &ec_pkey);
|
|
+#else
|
|
+ rc = fill_ec_key_from_privkey(tmpl, attr->pValue, attr->ulValueLen,
|
|
+ nid, &ec_pkey);
|
|
+
|
|
+#endif
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("fill_ec_key_from_privkey failed\n");
|
|
goto out;
|
|
@@ -4487,17 +4467,30 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key)
|
|
goto out;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ ec_key = NULL;
|
|
+#endif
|
|
+
|
|
rc = CKR_OK;
|
|
|
|
out:
|
|
+#if OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (tmpl != NULL)
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+#endif
|
|
+
|
|
if (rc != CKR_OK) {
|
|
+ if (ec_pkey != NULL)
|
|
+ EVP_PKEY_free(ec_pkey);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
if (ec_key != NULL)
|
|
EC_KEY_free(ec_key);
|
|
+#endif
|
|
|
|
return rc;
|
|
}
|
|
|
|
- *key = ec_key;
|
|
+ *pkey = ec_pkey;
|
|
|
|
return CKR_OK;
|
|
}
|
|
@@ -4508,10 +4501,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
{
|
|
|
|
CK_ATTRIBUTE *attr = NULL, *ec_point_attr, *value_attr, *parms_attr;
|
|
- EC_KEY *ec_key = NULL;
|
|
- BN_CTX *ctx = NULL;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ const EC_KEY *ec_key = NULL;
|
|
+ BN_CTX *bnctx = NULL;
|
|
+#else
|
|
+ BIGNUM *bn_d = NULL;
|
|
+#endif
|
|
CK_BYTE *ecpoint = NULL, *enc_ecpoint = NULL, *d = NULL;
|
|
CK_ULONG ecpoint_len, enc_ecpoint_len, d_len;
|
|
+ EVP_PKEY_CTX *ctx = NULL;
|
|
+ EVP_PKEY *ec_pkey = NULL;
|
|
+ int nid;
|
|
CK_RV rc;
|
|
|
|
UNUSED(tokdata);
|
|
@@ -4520,29 +4520,83 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
if (rc != CKR_OK)
|
|
goto out;
|
|
|
|
- rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key);
|
|
- if (rc != CKR_OK)
|
|
+ nid = curve_nid_from_params(attr->pValue, attr->ulValueLen);
|
|
+ if (nid == NID_undef) {
|
|
+ TRACE_ERROR("curve not supported by OpenSSL.\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
goto out;
|
|
+ }
|
|
|
|
- if (!EC_KEY_generate_key(ec_key)) {
|
|
- TRACE_ERROR("Failed to generate an EC key.\n");
|
|
+ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
|
+ if (ctx == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto out;
|
|
}
|
|
|
|
- ctx = BN_CTX_new();
|
|
- if (ctx == NULL) {
|
|
+ if (EVP_PKEY_keygen_init(ctx) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_keygen_init failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_set_ec_paramgen_curve_nid failed\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_keygen(ctx, &ec_pkey) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_keygen failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ ec_key = EVP_PKEY_get0_EC_KEY(ec_pkey);
|
|
+ if (ec_key == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_get0_EC_KEY failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ bnctx = BN_CTX_new();
|
|
+ if (bnctx == NULL) {
|
|
rc = CKR_HOST_MEMORY;
|
|
goto out;
|
|
}
|
|
|
|
ecpoint_len = EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED,
|
|
- &ecpoint, ctx);
|
|
+ &ecpoint, bnctx);
|
|
if (ecpoint_len == 0) {
|
|
TRACE_ERROR("Failed to get the EC Point compressed.\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto out;
|
|
}
|
|
+#else
|
|
+ if (!EVP_PKEY_get_octet_string_param(ec_pkey,
|
|
+ OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
|
|
+ NULL, 0, &ecpoint_len)) {
|
|
+ TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ecpoint = OPENSSL_zalloc(ecpoint_len);
|
|
+ if (ecpoint == NULL) {
|
|
+ TRACE_ERROR("OPENSSL_zalloc failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!EVP_PKEY_get_octet_string_param(ec_pkey,
|
|
+ OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
|
|
+ ecpoint, ecpoint_len, &ecpoint_len)) {
|
|
+ TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
|
|
rc = ber_encode_OCTET_STRING(FALSE, &enc_ecpoint, &enc_ecpoint_len,
|
|
ecpoint, ecpoint_len);
|
|
@@ -4564,12 +4618,30 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
goto out;
|
|
}
|
|
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
d_len = EC_KEY_priv2buf(ec_key, &d);
|
|
if (d_len == 0) {
|
|
TRACE_ERROR("Failed to get the EC private key.\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto out;
|
|
}
|
|
+#else
|
|
+ if (!EVP_PKEY_get_bn_param(ec_pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn_d)) {
|
|
+ TRACE_ERROR("EVP_PKEY_get_bn_param failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ d_len = ec_prime_len_from_nid(nid);
|
|
+ d = OPENSSL_zalloc(d_len);
|
|
+ if (d == NULL) {
|
|
+ TRACE_ERROR("OPENSSL_zalloc failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ BN_bn2binpad(bn_d, d, d_len);
|
|
+#endif
|
|
|
|
rc = build_attribute(CKA_VALUE, d, d_len, &value_attr);
|
|
if (rc != CKR_OK) {
|
|
@@ -4602,10 +4674,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
rc = CKR_OK;
|
|
|
|
out:
|
|
- if (ctx)
|
|
- BN_CTX_free(ctx);
|
|
- if (ec_key != NULL)
|
|
- EC_KEY_free(ec_key);
|
|
+ if (ctx != NULL)
|
|
+ EVP_PKEY_CTX_free(ctx);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (bnctx != NULL)
|
|
+ BN_CTX_free(bnctx);
|
|
+#else
|
|
+ if (bn_d != NULL)
|
|
+ BN_free(bn_d);
|
|
+#endif
|
|
+ if (ec_pkey != NULL)
|
|
+ EVP_PKEY_free(ec_pkey);
|
|
if (ecpoint != NULL)
|
|
OPENSSL_free(ecpoint);
|
|
if (enc_ecpoint != NULL)
|
|
@@ -4621,11 +4700,15 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
CK_BYTE *out_data, CK_ULONG *out_data_len,
|
|
OBJECT *key_obj)
|
|
{
|
|
- EC_KEY *ec_key;
|
|
- ECDSA_SIG *sig;
|
|
+ EVP_PKEY *ec_key;
|
|
+ ECDSA_SIG *sig = NULL;
|
|
const BIGNUM *r, *s;
|
|
CK_ULONG privlen, n;
|
|
CK_RV rc = CKR_OK;
|
|
+ EVP_PKEY_CTX *ctx = NULL;
|
|
+ size_t siglen;
|
|
+ CK_BYTE *sigbuf = NULL;
|
|
+ const unsigned char *p;
|
|
|
|
UNUSED(tokdata);
|
|
UNUSED(sess);
|
|
@@ -4636,16 +4719,54 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
- sig = ECDSA_do_sign(in_data, in_data_len, ec_key);
|
|
+ ctx = EVP_PKEY_CTX_new(ec_key, NULL);
|
|
+ if (ctx == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_sign_init(ctx) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_sign_init failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_sign(ctx, NULL, &siglen, in_data, in_data_len) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_sign failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ sigbuf = malloc(siglen);
|
|
+ if (sigbuf == NULL) {
|
|
+ TRACE_ERROR("malloc failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_sign(ctx, sigbuf, &siglen, in_data, in_data_len) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_sign failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ p = sigbuf;
|
|
+ sig = d2i_ECDSA_SIG(NULL, &p, siglen);
|
|
if (sig == NULL) {
|
|
- TRACE_ERROR("ECDSA_do_sign failed\n");
|
|
+ TRACE_ERROR("d2i_ECDSA_SIG failed\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
goto out;
|
|
}
|
|
|
|
ECDSA_SIG_get0(sig, &r, &s);
|
|
|
|
- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
|
|
+ privlen = ec_prime_len_from_pkey(ec_key);
|
|
+ if (privlen <= 0) {
|
|
+ TRACE_ERROR("ec_prime_len_from_pkey failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
|
|
/* Insert leading 0x00's if r or s shorter than privlen */
|
|
n = privlen - BN_num_bytes(r);
|
|
@@ -4662,7 +4783,11 @@ out:
|
|
if (sig != NULL)
|
|
ECDSA_SIG_free(sig);
|
|
if (ec_key != NULL)
|
|
- EC_KEY_free(ec_key);
|
|
+ EVP_PKEY_free(ec_key);
|
|
+ if (sigbuf != NULL)
|
|
+ free(sigbuf);
|
|
+ if (ctx != NULL)
|
|
+ EVP_PKEY_CTX_free(ctx);
|
|
|
|
return rc;
|
|
}
|
|
@@ -4674,11 +4799,14 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
|
|
CK_BYTE *signature,
|
|
CK_ULONG signature_len, OBJECT *key_obj)
|
|
{
|
|
- EC_KEY *ec_key;
|
|
+ EVP_PKEY *ec_key;
|
|
CK_ULONG privlen;
|
|
ECDSA_SIG *sig = NULL;
|
|
BIGNUM *r = NULL, *s = NULL;
|
|
CK_RV rc = CKR_OK;
|
|
+ size_t siglen;
|
|
+ CK_BYTE *sigbuf = NULL;
|
|
+ EVP_PKEY_CTX *ctx = NULL;
|
|
|
|
UNUSED(tokdata);
|
|
UNUSED(sess);
|
|
@@ -4687,7 +4815,12 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8;
|
|
+ privlen = ec_prime_len_from_pkey(ec_key);
|
|
+ if (privlen <= 0) {
|
|
+ TRACE_ERROR("ec_prime_len_from_pkey failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
|
|
if (signature_len < 2 * privlen) {
|
|
TRACE_ERROR("Signature is too short\n");
|
|
@@ -4715,7 +4848,27 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata,
|
|
goto out;
|
|
}
|
|
|
|
- rc = ECDSA_do_verify(in_data, in_data_len, sig, ec_key);
|
|
+ siglen = i2d_ECDSA_SIG(sig, &sigbuf);
|
|
+ if (siglen <= 0) {
|
|
+ TRACE_ERROR("i2d_ECDSA_SIG failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ ctx = EVP_PKEY_CTX_new(ec_key, NULL);
|
|
+ if (ctx == NULL) {
|
|
+ TRACE_ERROR("EVP_PKEY_CTX_new failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (EVP_PKEY_verify_init(ctx) <= 0) {
|
|
+ TRACE_ERROR("EVP_PKEY_verify_init failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rc = EVP_PKEY_verify(ctx, sigbuf, siglen, in_data, in_data_len);
|
|
switch (rc) {
|
|
case 0:
|
|
rc = CKR_SIGNATURE_INVALID;
|
|
@@ -4732,7 +4885,11 @@ out:
|
|
if (sig != NULL)
|
|
ECDSA_SIG_free(sig);
|
|
if (ec_key != NULL)
|
|
- EC_KEY_free(ec_key);
|
|
+ EVP_PKEY_free(ec_key);
|
|
+ if (sigbuf != NULL)
|
|
+ OPENSSL_free(sigbuf);
|
|
+ if (ctx != NULL)
|
|
+ EVP_PKEY_CTX_free(ctx);
|
|
|
|
return rc;
|
|
}
|
|
@@ -4746,43 +4903,118 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata,
|
|
CK_ULONG *secret_value_len,
|
|
CK_BYTE *oid, CK_ULONG oid_length)
|
|
{
|
|
- EC_KEY *ec_pub = NULL, *ec_priv = NULL;
|
|
- CK_ULONG privlen;
|
|
- int secret_len;
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ EC_KEY *pub = NULL, *priv = NULL;
|
|
+#else
|
|
+ OSSL_PARAM_BLD *tmpl = NULL;
|
|
+#endif
|
|
+ EVP_PKEY *ec_pub = NULL, *ec_priv = NULL;
|
|
+ EVP_PKEY_CTX *ctx = NULL;
|
|
+ size_t secret_len;
|
|
+ int nid;
|
|
CK_RV rc;
|
|
|
|
UNUSED(tokdata);
|
|
|
|
- rc = make_ec_key_from_params(oid, oid_length, &ec_priv);
|
|
+ nid = curve_nid_from_params(oid, oid_length);
|
|
+ if (nid == NID_undef) {
|
|
+ TRACE_ERROR("curve not supported by OpenSSL.\n");
|
|
+ rc = CKR_CURVE_NOT_SUPPORTED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ rc = make_ec_key_from_params(oid, oid_length, &priv);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("make_ec_key_from_params failed\n");
|
|
goto out;
|
|
}
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
|
|
+ OBJ_nid2sn(nid), 0)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
|
|
- rc = fill_ec_key_from_privkey(ec_priv, priv_bytes, priv_length);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ rc = fill_ec_key_from_privkey(priv, priv_bytes, priv_length, &ec_priv);
|
|
+#else
|
|
+ rc = fill_ec_key_from_privkey(tmpl, priv_bytes, priv_length, nid, &ec_priv);
|
|
+#endif
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("fill_ec_key_from_privkey failed\n");
|
|
goto out;
|
|
}
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ priv = NULL;
|
|
+#else
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ tmpl = NULL;
|
|
+#endif
|
|
|
|
- rc = make_ec_key_from_params(oid, oid_length, &ec_pub);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ rc = make_ec_key_from_params(oid, oid_length, &pub);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("make_ec_key_from_params failed\n");
|
|
goto out;
|
|
}
|
|
+#else
|
|
+ tmpl = OSSL_PARAM_BLD_new();
|
|
+ if (tmpl == NULL) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n");
|
|
+ rc = CKR_HOST_MEMORY;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
|
|
+ OBJ_nid2sn(nid), 0)) {
|
|
+ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n");
|
|
+ rc = CKR_FUNCTION_FAILED;
|
|
+ goto out;
|
|
+ }
|
|
+#endif
|
|
|
|
- rc = fill_ec_key_from_pubkey(ec_pub, pub_bytes, pub_length, TRUE);
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ rc = fill_ec_key_from_pubkey(pub, pub_bytes, pub_length, TRUE, nid,
|
|
+ &ec_pub);
|
|
+#else
|
|
+ rc = fill_ec_key_from_pubkey(tmpl, pub_bytes, pub_length, TRUE, nid,
|
|
+ &ec_pub);
|
|
+#endif
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("fill_ec_key_from_pubkey failed\n");
|
|
goto out;
|
|
}
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ pub = NULL;
|
|
+#else
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+ tmpl = NULL;
|
|
+#endif
|
|
|
|
- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_priv)) + 7) / 8;
|
|
+ ctx = EVP_PKEY_CTX_new(ec_priv, NULL);
|
|
+ if (ctx == NULL) {
|
|
+ TRACE_DEVEL("EVP_PKEY_CTX_new failed\n");
|
|
+ goto out;
|
|
+ }
|
|
|
|
- secret_len = ECDH_compute_key(secret_value, privlen,
|
|
- EC_KEY_get0_public_key(ec_pub), ec_priv,
|
|
- NULL);
|
|
- if (secret_len <= 0) {
|
|
+ if (EVP_PKEY_derive_init(ctx) <= 0 ||
|
|
+ EVP_PKEY_derive_set_peer(ctx, ec_pub) <= 0) {
|
|
+ TRACE_DEVEL("EVP_PKEY_derive_init/EVP_PKEY_derive_set_peer failed\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ secret_len = ec_prime_len_from_nid(nid);
|
|
+ if (EVP_PKEY_derive(ctx, secret_value, &secret_len) <= 0) {
|
|
TRACE_DEVEL("ECDH_compute_key failed\n");
|
|
rc = CKR_FUNCTION_FAILED;
|
|
*secret_value_len = 0;
|
|
@@ -4792,10 +5024,21 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata,
|
|
*secret_value_len = secret_len;
|
|
|
|
out:
|
|
+#if !OPENSSL_VERSION_PREREQ(3, 0)
|
|
+ if (priv != NULL)
|
|
+ EC_KEY_free(priv);
|
|
+ if (pub != NULL)
|
|
+ EC_KEY_free(pub);
|
|
+#else
|
|
+ if (tmpl != NULL)
|
|
+ OSSL_PARAM_BLD_free(tmpl);
|
|
+#endif
|
|
if (ec_priv != NULL)
|
|
- EC_KEY_free(ec_priv);
|
|
+ EVP_PKEY_free(ec_priv);
|
|
if (ec_pub != NULL)
|
|
- EC_KEY_free(ec_pub);
|
|
+ EVP_PKEY_free(ec_pub);
|
|
+ if (ctx != NULL)
|
|
+ EVP_PKEY_CTX_free(ctx);
|
|
|
|
return rc;
|
|
}
|
|
@@ -4807,7 +5050,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
{
|
|
CK_KEY_TYPE keytype;
|
|
#ifndef NO_EC
|
|
- EC_KEY *ec_key = NULL;
|
|
+ EVP_PKEY *ec_key = NULL;
|
|
#endif
|
|
CK_RV rc;
|
|
|
|
@@ -4824,7 +5067,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
/* Check if OpenSSL supports the curve */
|
|
rc = make_ec_key_from_template(obj->template, &ec_key);
|
|
if (ec_key != NULL)
|
|
- EC_KEY_free(ec_key);
|
|
+ EVP_PKEY_free(ec_key);
|
|
return rc;
|
|
#endif
|
|
|