Compare commits

...

No commits in common. "c8" and "c9-beta" have entirely different histories.
c8 ... c9-beta

18 changed files with 1562 additions and 2570 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opencryptoki-3.22.0.tar.gz
SOURCES/opencryptoki-3.23.0.tar.gz

1
.opencryptoki.metadata Normal file
View File

@ -0,0 +1 @@
0d70d0a5170a79fc358107d07a62bea1b476e0cc SOURCES/opencryptoki-3.23.0.tar.gz

View File

@ -1,27 +0,0 @@
diff -up opencryptoki-3.21.0/misc/pkcsslotd.service.in.me opencryptoki-3.21.0/misc/pkcsslotd.service.in
--- opencryptoki-3.21.0/misc/pkcsslotd.service.in.me 2023-05-16 20:50:08.128841932 +0200
+++ opencryptoki-3.21.0/misc/pkcsslotd.service.in 2023-05-16 21:19:35.208570589 +0200
@@ -22,17 +22,17 @@ PrivateUsers=no
PrivateNetwork=no
RestrictAddressFamilies=AF_UNIX AF_NETLINK
IPAddressDeny=any
-ProtectClock=yes
+#ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
-ProtectKernelLogs=yes
+#ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectHome=yes
-ProtectHostname=yes
-ProtectProc=default
+#ProtectHostname=yes
+#ProtectProc=default
ProtectSystem=strict
-ReadWritePaths=@localstatedir@
-ProcSubset=all
+ReadWritePaths=@localstatedir@ /run
+#ProcSubset=all
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictNamespaces=yes

View File

@ -0,0 +1,50 @@
commit 2d68f8626d15b9697a29a377a63bbdf35b42ee36
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Tue Feb 13 16:20:06 2024 +0100
EP11 pkey option: add new PKEY_MODE parms to ep11 config file
Add two new parameter values ENABLE4EXTR and ENABLE4ALL to the ep11token
PKEY_MODE config option. Older ep11 card firmware enforces the restriction that
keys can not have CKA_EXTRACTABLE=true and CKA_IBM_PROTKEY_EXTRACTABLE=true at
the same time. With newer card firmware this restriction is removed and a new
control point is introduced to allow checking for this feature.
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11tok.conf b/usr/lib/ep11_stdll/ep11tok.conf
index 19c9963f..afe237b9 100644
--- a/usr/lib/ep11_stdll/ep11tok.conf
+++ b/usr/lib/ep11_stdll/ep11tok.conf
@@ -104,7 +104,7 @@
# disabled and additional hardware and firmware prerequisites are met. AES-XTS
# is not supported via the EP11 coprocessor itself.
#
-# PKEY_MODE DISABLED | DEFAULT | ENABLE4NONEXTR
+# PKEY_MODE DISABLED | DEFAULT | ENABLE4NONEXTR | ENABLE4EXTR | ENABLE4ALL
#
# DISABLED : Protected key support disabled. All key operations
# are performed via EP11 coprocessor, even if a
@@ -119,6 +119,22 @@
# but not CKA_IBM_PROTKEY_EXTRACTABLE, new keys get
# CKA_IBM_PROTKEY_EXTRACTABLE=true internally.
#
+# Control point 75 (XCP_CPB_ALLOW_COMBINED_EXTRACT) must be enabled for all
+# APQNs accessible by the token for the following parameters.
+#
+# ENABLE4EXTR : If the application did not specify
+# CKA_IBM_PROTKEY_EXTRACTABLE in its template, new keys
+# of any type with CKA_EXTRACTABLE=true get
+# CKA_IBM_PROTKEY_EXTRACTABLE=true and a protected key
+# is automatically created at first use of the key.
+#
+# ENABLE4ALL : If the application did not specify
+# CKA_IBM_PROTKEY_EXTRACTABLE in its template, new keys
+# of any type, regardless of the CKA_EXTRACTABLE
+# attribute, get CKA_IBM_PROTKEY_EXTRACTABLE=true and
+# a protected key is automatically created at first
+# use of the key.
+#
# --------------------------------------------------------------------------
#
# Specify the expected wrapping key verification pattern. When specified, all

View File

@ -0,0 +1,222 @@
commit a6192bb9c3263fb691da87b3a1ed5f66f887b09a
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Tue Feb 13 16:35:53 2024 +0100
EP11 pkey option: handle new PKEY_MODE parms for new objects
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index d5964a9c..d1efd8c5 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1239,6 +1239,33 @@ CK_RV ep11tok_pkey_check_aes_xts(STDLL_TokData_t *tokdata, OBJECT *key_obj,
return CKR_OK;
}
+CK_RV ep11tok_pkey_add_protkey_attr_to_tmpl(TEMPLATE *tmpl)
+{
+ CK_ATTRIBUTE *pkey_attr = NULL;
+ CK_BBOOL btrue = CK_TRUE;
+ CK_RV ret;
+
+ if (!template_attribute_find(tmpl, CKA_IBM_PROTKEY_EXTRACTABLE, &pkey_attr)) {
+ ret = build_attribute(CKA_IBM_PROTKEY_EXTRACTABLE, &btrue,
+ sizeof(CK_BBOOL), &pkey_attr);
+ if (ret != CKR_OK) {
+ TRACE_ERROR("build_attribute failed with ret=0x%lx\n", ret);
+ goto done;
+ }
+ ret = template_update_attribute(tmpl, pkey_attr);
+ if (ret != CKR_OK) {
+ TRACE_ERROR("update_attribute failed with ret=0x%lx\n", ret);
+ free(pkey_attr);
+ goto done;
+ }
+ }
+
+ ret = CKR_OK;
+
+done:
+ return ret;
+}
+
/**
* This function is called whenever a new object is created. It sets
* attribute CKA_IBM_PROTKEY_EXTRACTABLE according to the PKEY_MODE token
@@ -1254,7 +1281,7 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
CK_ULONG mode, TEMPLATE *tmpl)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
- CK_ATTRIBUTE *pkey_attr = NULL, *ecp_attr = NULL, *sensitive_attr = NULL;
+ CK_ATTRIBUTE *ecp_attr = NULL, *sensitive_attr = NULL;
CK_BBOOL extractable, sensitive, btrue = CK_TRUE;
CK_BBOOL add_pkey_extractable = CK_FALSE;
CK_RV ret;
@@ -1314,23 +1341,62 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
add_pkey_extractable = CK_TRUE;
break;
}
-
if (add_pkey_extractable) {
- if (!template_attribute_find(tmpl, CKA_IBM_PROTKEY_EXTRACTABLE, &pkey_attr)) {
- ret = build_attribute(CKA_IBM_PROTKEY_EXTRACTABLE,
- (CK_BBOOL *)&btrue, sizeof(CK_BBOOL),
- &pkey_attr);
- if (ret != CKR_OK) {
- TRACE_ERROR("build_attribute failed with ret=0x%lx\n", ret);
- goto done;
- }
- ret = template_update_attribute(tmpl, pkey_attr);
- if (ret != CKR_OK) {
- TRACE_ERROR("update_attribute failed with ret=0x%lx\n", ret);
- free(pkey_attr);
- goto done;
- }
- }
+ ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
+ if (ret != CKR_OK)
+ goto done;
+ }
+ break;
+ case PKEY_MODE_ENABLE4EXTR:
+ /* If the application did not specify CKA_IBM_PROTKEY_EXTRACTABLE in
+ * its template, new keys of any type with CKA_EXTRACTABLE=true get
+ * CKA_IBM_PROTKEY_EXTRACTABLE=true and a protected key is automatically
+ * created at first use of the key.
+ */
+ switch (class) {
+ case CKO_PUBLIC_KEY:
+ if (template_attribute_get_non_empty(tmpl, CKA_EC_PARAMS, &ecp_attr) == CKR_OK &&
+ pkey_op_supported_by_cpacf(ep11_data->msa_level, CKM_ECDSA, tmpl))
+ add_pkey_extractable = CK_TRUE;
+ /* Note that the explicit parm CKM_ECDSA just tells the
+ * function that it's not AES here. It covers all EC and ED
+ * mechs */
+ break;
+ default:
+ ret = template_attribute_get_bool(tmpl, CKA_EXTRACTABLE, &extractable);
+ if (ret == CKR_OK && extractable) // Einziger Unterschied: extractable, statt !extractable
+ add_pkey_extractable = CK_TRUE;
+ break;
+ }
+ if (add_pkey_extractable) {
+ ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
+ if (ret != CKR_OK)
+ goto done;
+ }
+ break;
+ case PKEY_MODE_ENABLE4ALL:
+ /* If the application did not specify CKA_IBM_PROTKEY_EXTRACTABLE in
+ * its template, new keys of any type, regardless of CKA_EXTRACTABLE,
+ * get CKA_IBM_PROTKEY_EXTRACTABLE=true and a protected key is
+ * automatically created at first use of the key.
+ */
+ switch (class) {
+ case CKO_PUBLIC_KEY:
+ if (template_attribute_get_non_empty(tmpl, CKA_EC_PARAMS, &ecp_attr) == CKR_OK &&
+ pkey_op_supported_by_cpacf(ep11_data->msa_level, CKM_ECDSA, tmpl))
+ add_pkey_extractable = CK_TRUE;
+ /* Note that the explicit parm CKM_ECDSA just tells the
+ * function that it's not AES here. It covers all EC and ED
+ * mechs */
+ break;
+ default:
+ add_pkey_extractable = CK_TRUE;
+ break;
+ }
+ if (add_pkey_extractable) {
+ ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
+ if (ret != CKR_OK)
+ goto done;
}
break;
default:
@@ -12188,6 +12254,10 @@ static CK_RV ep11_config_set_pkey_mode(ep11_private_data_t *ep11_data,
ep11_data->pkey_mode = PKEY_MODE_DEFAULT;
else if (strcmp(strval, "ENABLE4NONEXTR") == 0)
ep11_data->pkey_mode = PKEY_MODE_ENABLE4NONEXTR;
+ else if (strcmp(strval, "ENABLE4EXTR") == 0)
+ ep11_data->pkey_mode = PKEY_MODE_ENABLE4EXTR;
+ else if (strcmp(strval, "ENABLE4ALL") == 0)
+ ep11_data->pkey_mode = PKEY_MODE_ENABLE4ALL;
else {
TRACE_ERROR("%s unsupported PKEY mode : '%s'\n", __func__, strval);
OCK_SYSLOG(LOG_ERR,"%s: Error: unsupported PKEY mode '%s' "
@@ -13252,6 +13322,7 @@ typedef struct cp_handler_data {
int first;
size_t max_cp_index;
CK_BBOOL error;
+ CK_BBOOL allow_combined_extract;
} cp_handler_data_t;
static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
@@ -13329,6 +13400,27 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
}
}
+ /* Combined extract is only supported if all APQNs support it */
+ if (max_cp_index < XCP_CPB_ALLOW_COMBINED_EXTRACT ||
+ (cp[CP_BYTE_NO(XCP_CPB_ALLOW_COMBINED_EXTRACT)] &
+ CP_BIT_MASK(XCP_CPB_ALLOW_COMBINED_EXTRACT)) == 0) {
+ data->allow_combined_extract = CK_FALSE;
+
+ if (ep11_data->pkey_mode == PKEY_MODE_ENABLE4EXTR ||
+ ep11_data->pkey_mode == PKEY_MODE_ENABLE4ALL) {
+ TRACE_ERROR("Control point setting for adapter %02X.%04X does not "
+ "allow combined extract, but PKEY_MODE ENABLE4EXTR or "
+ "ENABLE4ALL specified in ep11 token config file.\n",
+ adapter, domain);
+ OCK_SYSLOG(LOG_ERR,
+ "Control point setting for adapter %02X.%04X does not "
+ "allow combined extract, but PKEY_MODE ENABLE4EXTR or "
+ "ENABLE4ALL specified in ep11 token config file.\n",
+ adapter, domain);
+ data->error = TRUE;
+ }
+ }
+
/* Check FIPS-session related CPs for non-FIPS-session mode */
if (!ep11_data->fips_session_mode) {
if (max_cp_index >= XCP_CPB_ALLOW_NONSESSION &&
@@ -13392,6 +13484,7 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
* to older cards default to ON. CPs being OFF disable functionality.
*/
memset(data.combined_cp, 0xff, sizeof(data.combined_cp));
+ data.allow_combined_extract = CK_TRUE;
data.first = 1;
rc = handle_all_ep11_cards(&ep11_data->target_list, control_point_handler,
&data);
@@ -13410,6 +13503,11 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
print_control_points(cp, *cp_len, data.max_cp_index);
#endif
+ if (data.allow_combined_extract == CK_FALSE)
+ __sync_or_and_fetch(&ep11_data->pkey_combined_extract_supported, 0);
+ else
+ __sync_or_and_fetch(&ep11_data->pkey_combined_extract_supported, 1);
+
return data.error ? CKR_DEVICE_ERROR : CKR_OK;
}
diff --git a/usr/lib/ep11_stdll/ep11_specific.h b/usr/lib/ep11_stdll/ep11_specific.h
index deb8f45f..16d3c719 100644
--- a/usr/lib/ep11_stdll/ep11_specific.h
+++ b/usr/lib/ep11_stdll/ep11_specific.h
@@ -241,6 +241,8 @@ typedef struct {
#define PKEY_MODE_DISABLED 0
#define PKEY_MODE_DEFAULT 1
#define PKEY_MODE_ENABLE4NONEXTR 2
+#define PKEY_MODE_ENABLE4EXTR 3
+#define PKEY_MODE_ENABLE4ALL 4
#define PQC_BYTE_NO(idx) (((idx) - 1) / 8)
#define PQC_BIT_IN_BYTE(idx) (((idx - 1)) % 8)
@@ -278,6 +280,7 @@ typedef struct {
int fips_session_mode;
int optimize_single_ops;
int pkey_mode;
+ volatile int pkey_combined_extract_supported;
volatile int pkey_wrap_supported;
int pkey_wrap_support_checked;
char pkey_mk_vp[PKEY_MK_VP_LENGTH];

View File

@ -0,0 +1,62 @@
commit 88a01a9c4ba237431d89e3999cd6fdfddd10a51a
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Thu Mar 7 17:42:11 2024 +0100
EP11 pkey option: handle new PKEY_MODE parms in eligibility check
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index d1efd8c5..a163587c 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1080,6 +1080,26 @@ static CK_BBOOL ep11tok_pkey_session_ok_for_obj(SESSION *session,
return CK_TRUE;
}
+/*
+ * Returns true if the given key object is eligible to get a protected key
+ * attribute, false otherwise.
+ */
+CK_BBOOL ep11tok_pkey_obj_eligible_for_pkey_support(ep11_private_data_t *ep11_data,
+ OBJECT *key_obj)
+{
+ if (object_is_attr_bound(key_obj) || !ep11_data->pkey_wrap_supported ||
+ !object_is_pkey_extractable(key_obj)) {
+ return CK_FALSE;
+ }
+
+ if (!ep11_data->pkey_combined_extract_supported &&
+ object_is_extractable(key_obj)) {
+ return CK_FALSE;
+ }
+
+ return CK_TRUE;
+}
+
/**
* Checks if the preconditions for using the related protected key of
* the given secure key object are met. The caller of this routine must
@@ -1135,6 +1155,8 @@ CK_RV ep11tok_pkey_check(STDLL_TokData_t *tokdata, SESSION *session,
break;
case PKEY_MODE_DEFAULT:
case PKEY_MODE_ENABLE4NONEXTR:
+ case PKEY_MODE_ENABLE4EXTR:
+ case PKEY_MODE_ENABLE4ALL:
/* Use existing pkeys, re-create invalid pkeys, and also create new
* pkeys for secret/private keys that do not already have one. EC
* public keys that are pkey-extractable, can always be used via CPACF
@@ -1149,12 +1171,8 @@ CK_RV ep11tok_pkey_check(STDLL_TokData_t *tokdata, SESSION *session,
if (ep11tok_pkey_get_firmware_mk_vp(tokdata, session) != CKR_OK)
goto done;
- if (object_is_extractable(key_obj) ||
- !object_is_pkey_extractable(key_obj) ||
- object_is_attr_bound(key_obj) ||
- !ep11_data->pkey_wrap_supported) {
+ if (!ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data, key_obj))
goto done;
- }
if (template_attribute_get_non_empty(key_obj->template,
CKA_IBM_OPAQUE_PKEY,

View File

@ -0,0 +1,555 @@
commit b9e33fced0654aac939182957bf2eba2eda77872
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Wed Feb 21 13:48:15 2024 +0100
EP11 pkey option: add NO_PKEY compile option for EP11 token
On 32-bit s390 platforms, the pkey related assembler code parts won't
compile. Therefore, add NO_PKEY compile switches where necessary.
The NO_PKEY compile switch is already handled in configure.ac.
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index a163587c..114c4ce1 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -60,7 +60,9 @@
#include <openssl/ec.h>
#include "ep11_specific.h"
+#ifndef NO_PKEY
#include "pkey_utils.h"
+#endif
CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
CK_MECHANISM_TYPE_PTR mlist,
@@ -256,11 +258,13 @@ static const version_req_t reencrypt_single_req_versions[] = {
#define NUM_REENCRYPT_SINGLE_REQ (sizeof(reencrypt_single_req_versions) / \
sizeof(version_req_t))
+#ifndef NO_PKEY
static const CK_VERSION ibm_cex7p_cpacf_wrap_support = { .major = 7, .minor = 15 };
static const version_req_t ibm_cpacf_wrap_req_versions[] = {
{ .card_type = 7, .min_firmware_version = &ibm_cex7p_cpacf_wrap_support }
};
#define NUM_CPACF_WRAP_REQ (sizeof(ibm_cpacf_wrap_req_versions) / sizeof(version_req_t))
+#endif /* NO_PKEY */
static const CK_ULONG ibm_cex_ab_ecdh_api_version = 3;
static const version_req_t ibm_ab_ecdh_req_versions[] = {
@@ -504,6 +508,7 @@ static CK_BBOOL ep11tok_pkey_option_disabled(STDLL_TokData_t *tokdata)
return CK_FALSE;
}
+#ifndef NO_PKEY
/**
* Callback function used by handle_all_ep11_cards() for creating a protected
* key via the given APQN (adaper,domain).
@@ -1283,6 +1288,7 @@ CK_RV ep11tok_pkey_add_protkey_attr_to_tmpl(TEMPLATE *tmpl)
done:
return ret;
}
+#endif /* NO_PKEY */
/**
* This function is called whenever a new object is created. It sets
@@ -1299,9 +1305,12 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
CK_ULONG mode, TEMPLATE *tmpl)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
- CK_ATTRIBUTE *ecp_attr = NULL, *sensitive_attr = NULL;
- CK_BBOOL extractable, sensitive, btrue = CK_TRUE;
- CK_BBOOL add_pkey_extractable = CK_FALSE;
+ CK_ATTRIBUTE *sensitive_attr = NULL;
+ CK_BBOOL sensitive, btrue = CK_TRUE;
+#ifndef NO_PKEY
+ CK_ATTRIBUTE *ecp_attr = NULL;
+ CK_BBOOL extractable, add_pkey_extractable = CK_FALSE;
+#endif
CK_RV ret;
UNUSED(mode);
@@ -1331,6 +1340,7 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
}
}
+#ifndef NO_PKEY
switch (ep11_data->pkey_mode) {
case PKEY_MODE_DISABLED:
/* Nothing to do */
@@ -1423,6 +1433,7 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
goto done;
break;
}
+#endif /* NO_PKEY */
ret = CKR_OK;
@@ -1431,6 +1442,19 @@ done:
return ret;
}
+#ifdef NO_PKEY
+CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
+ CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech)
+{
+ UNUSED(tokdata);
+ UNUSED(session);
+ UNUSED(hkey);
+ UNUSED(mech);
+
+ return CK_FALSE;
+}
+#endif /* NO_PKEY */
+
static CK_RV check_ab_supported(CK_KEY_TYPE type) {
switch(type) {
case CKK_AES:
@@ -2837,8 +2861,10 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
goto error;
}
+#ifndef NO_PKEY
ep11_data->msa_level = get_msa_level();
TRACE_INFO("MSA level = %i\n", ep11_data->msa_level);
+#endif
if (pthread_mutex_init(&ep11_data->raw2key_wrap_blob_mutex, NULL) != 0) {
TRACE_ERROR("Initializing Wrap-Blob lock failed.\n");
@@ -2847,19 +2873,20 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
}
ep11_data->raw2key_wrap_blob_l = 0;
-
if (pthread_mutex_init(&ep11_data->pkey_mutex, NULL) != 0) {
TRACE_ERROR("Initializing PKEY lock failed.\n");
rc = CKR_CANT_LOCK;
goto error;
}
+#ifndef NO_PKEY
if (!ep11tok_pkey_option_disabled(tokdata) &&
!ep11_data->fips_session_mode) {
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, NULL);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
goto error;
}
+#endif /* NO_PKEY */
if (ep11_data->vhsm_mode || ep11_data->fips_session_mode) {
if (pthread_mutex_init(&ep11_data->session_mutex, NULL) != 0) {
@@ -3178,7 +3205,11 @@ static CK_RV import_aes_xts_key(STDLL_TokData_t *tokdata, SESSION *sess,
if (rc != CKR_OK)
goto import_aes_xts_key_end;
+#ifndef NO_PKEY
rc = ep11tok_pkey_check_aes_xts(tokdata, aes_xts_key_obj, CKM_AES_XTS);
+#else
+ rc = CKR_FUNCTION_NOT_SUPPORTED;
+#endif
if (rc != CKR_OK) {
TRACE_ERROR("%s EP11 AES XTS is not supported: rc=0x%lx\n", __func__, rc);
goto import_aes_xts_key_end;
@@ -4562,10 +4593,12 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
return rc;
}
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, sess);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
return rc;
+#endif /* NO_PKEY */
memset(blob, 0, sizeof(blob));
memset(blobreenc, 0, sizeof(blobreenc));
@@ -4797,10 +4830,12 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session,
goto error;
}
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, session);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
goto error;
+#endif /* NO_PKEY */
rc = object_mgr_create_skel(tokdata, session, new_attrs, new_attrs_len,
MODE_KEYGEN, CKO_SECRET_KEY, ktype, &key_obj);
@@ -4820,7 +4855,11 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session,
if (mech->mechanism == CKM_AES_XTS_KEY_GEN) {
xts = TRUE;
+#ifndef NO_PKEY
rc = ep11tok_pkey_check_aes_xts(tokdata, key_obj, mech->mechanism);
+#else
+ rc = CKR_FUNCTION_NOT_SUPPORTED;
+#endif
if (rc != CKR_OK) {
TRACE_ERROR("%s EP11 AES XTS is not supported: rc=0x%lx\n",
__func__, rc);
@@ -5812,7 +5851,9 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session,
CK_BYTE *out_data, CK_ULONG *out_data_len,
OBJECT *key_obj )
{
+#ifndef NO_PKEY
SIGN_VERIFY_CONTEXT *ctx = &(session->sign_ctx);
+#endif
CK_RV rc;
size_t keyblobsize = 0;
CK_BYTE *keyblob;
@@ -5826,6 +5867,7 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session,
return rc;
}
+#ifndef NO_PKEY
rc = ep11tok_pkey_check(tokdata, session, key_obj, &ctx->mech);
switch (rc) {
case CKR_OK:
@@ -5837,6 +5879,7 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session,
default:
goto done;
}
+#endif /* NO_PKEY */
mech.mechanism = CKM_ECDSA;
mech.pParameter = NULL;
@@ -5856,7 +5899,9 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session,
TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
}
+#ifndef NO_PKEY
done:
+#endif
return rc;
}
@@ -5866,7 +5911,9 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session,
CK_BYTE *out_data, CK_ULONG out_data_len,
OBJECT *key_obj )
{
+#ifndef NO_PKEY
SIGN_VERIFY_CONTEXT *ctx = &(session->verify_ctx);
+#endif
CK_RV rc;
CK_BYTE *spki;
size_t spki_len = 0;
@@ -5880,6 +5927,7 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session,
return rc;
}
+#ifndef NO_PKEY
rc = ep11tok_pkey_check(tokdata, session, key_obj, &ctx->mech);
switch (rc) {
case CKR_OK:
@@ -5891,6 +5939,7 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session,
default:
goto done;
}
+#endif /* NO_PKEY */
mech.mechanism = CKM_ECDSA;
mech.pParameter = NULL;
@@ -5911,7 +5960,9 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session,
TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
}
+#ifndef NO_PKEY
done:
+#endif
return rc;
}
@@ -5981,6 +6032,7 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata,
return rc;
}
+#ifndef NO_PKEY
/**
* This routine is currently only used when the operation is performed using
* a protected key. Therefore we don't have (and don't need) an ep11
@@ -6062,6 +6114,7 @@ CK_RV token_specific_aes_xts(STDLL_TokData_t *tokdata, SESSION *session,
return pkey_aes_xts(key_obj, init_v, in_data, in_data_len,
out_data, out_data_len, encrypt, initial, final, iv);
}
+#endif /* NO_PKEY */
struct EP11_KYBER_MECH {
CK_MECHANISM mech;
@@ -6829,10 +6882,12 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t *tokdata, SESSION *session,
goto error;
}
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, session);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
goto error;
+#endif /* NO_PKEY */
/* Start creating the key object */
rc = object_mgr_create_skel(tokdata, session, new_attrs1, new_attrs1_len,
@@ -8554,10 +8609,12 @@ CK_RV ep11tok_generate_key_pair(STDLL_TokData_t * tokdata, SESSION * sess,
if (rc != CKR_OK)
goto error;
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, sess);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
goto error;
+#endif /* NO_PKEY */
/* Now build the skeleton key. */
rc = object_mgr_create_skel(tokdata, sess, pPublicKeyTemplate,
@@ -9202,6 +9259,7 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
goto done;
}
+#ifndef NO_PKEY
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
@@ -9239,6 +9297,7 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
free(ep11_sign_state);
goto done;
}
+#endif /* NO_PKEY */
if (mech->mechanism == CKM_IBM_ECDSA_OTHER) {
rc = ep11tok_ecdsa_other_mech_adjust(mech, &mech_ep11);
@@ -9340,6 +9399,9 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
CK_ULONG in_data_len, CK_BYTE * signature,
CK_ULONG * sig_len)
{
+#ifdef NO_PKEY
+ UNUSED(length_only);
+#endif
CK_RV rc;
SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx;
size_t keyblobsize = 0;
@@ -9355,6 +9417,7 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
+#ifndef NO_PKEY
if (ctx->pkey_active) {
/* Note that Edwards curves in general are not yet supported in
* opencryptoki. These two special IBM specific ED mechs are only
@@ -9372,6 +9435,7 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
}
goto done; /* no ep11 fallback possible */
}
+#endif /* NO_PKEY */
RETRY_SESSION_SINGLE_APQN_START(rc, tokdata)
RETRY_UPDATE_BLOB_START(tokdata, target_info,
@@ -9394,7 +9458,9 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
}
+#ifndef NO_PKEY
done:
+#endif
object_put(tokdata, key_obj, TRUE);
key_obj = NULL;
@@ -9638,6 +9704,7 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
goto done;
}
+#ifndef NO_PKEY
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
@@ -9675,6 +9742,7 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
free(ep11_sign_state);
goto done;
}
+#endif /* NO_PKEY */
if (mech->mechanism == CKM_IBM_ECDSA_OTHER) {
rc = ep11tok_ecdsa_other_mech_adjust(mech, &mech_ep11);
@@ -9787,6 +9855,7 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
+#ifndef NO_PKEY
if (ctx->pkey_active) {
/* Note that Edwards curves in general are not yet supported in
* opencryptoki. These two special IBM specific ED mechs are only
@@ -9805,6 +9874,7 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
}
goto done; /* no ep11 fallback possible */
}
+#endif /* NO_PKEY */
RETRY_SESSION_SINGLE_APQN_START(rc, tokdata)
RETRY_UPDATE_BLOB_START(tokdata, target_info,
@@ -9827,7 +9897,9 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
}
+#ifndef NO_PKEY
done:
+#endif
object_put(tokdata, key_obj, TRUE);
key_obj = NULL;
@@ -10561,6 +10633,7 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
goto error;
}
+#ifndef NO_PKEY
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
@@ -10604,6 +10677,7 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
free(ep11_state);
goto done;
}
+#endif /* NO_PKEY */
/*
* ep11_state is allocated large enough to hold 2 times the max state blob.
@@ -11150,10 +11224,12 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
goto done;
}
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, session);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
goto error;
+#endif /* NO_PKEY */
/* Start creating the key object */
rc = object_mgr_create_skel(tokdata, session, new_attrs, new_attrs_len,
@@ -11878,6 +11954,7 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
}
break;
+#ifndef NO_PKEY
case CKM_IBM_CPACF_WRAP:
if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) <= 0) {
TRACE_INFO("%s Mech '%s' banned due to host library version\n",
@@ -11895,6 +11972,7 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
goto out;
}
break;
+#endif /* NO_PKEY */
case CKM_IBM_BTC_DERIVE:
if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3_1) < 0) {
@@ -12268,6 +12346,7 @@ static CK_RV ep11_config_set_pkey_mode(ep11_private_data_t *ep11_data,
{
if (strcmp(strval, "DISABLED") == 0)
ep11_data->pkey_mode = PKEY_MODE_DISABLED;
+#ifndef NO_PKEY
else if (strcmp(strval, "DEFAULT") == 0)
ep11_data->pkey_mode = PKEY_MODE_DEFAULT;
else if (strcmp(strval, "ENABLE4NONEXTR") == 0)
@@ -12276,6 +12355,7 @@ static CK_RV ep11_config_set_pkey_mode(ep11_private_data_t *ep11_data,
ep11_data->pkey_mode = PKEY_MODE_ENABLE4EXTR;
else if (strcmp(strval, "ENABLE4ALL") == 0)
ep11_data->pkey_mode = PKEY_MODE_ENABLE4ALL;
+#endif /* NO_PKEY */
else {
TRACE_ERROR("%s unsupported PKEY mode : '%s'\n", __func__, strval);
OCK_SYSLOG(LOG_ERR,"%s: Error: unsupported PKEY mode '%s' "
@@ -12456,7 +12536,11 @@ static CK_RV read_adapter_config_file(STDLL_TokData_t * tokdata,
sizeof(ep11_data->token_config_filename) - 1] = '\0';
ep11_data->target_list.length = 0;
+#ifndef NO_PKEY
ep11_data->pkey_mode = PKEY_MODE_DEFAULT;
+#else
+ ep11_data->pkey_mode = PKEY_MODE_DISABLED;
+#endif
/* Default to use default libica library for digests */
ep11_data->digest_libica = 1;
@@ -14695,10 +14779,12 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata,
}
}
+#ifndef NO_PKEY
/* Ensure the firmware master key verification pattern is available */
rc = ep11tok_pkey_get_firmware_mk_vp(tokdata, session);
if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED)
return rc;
+#endif /* NO_PKEY */
node = new_tmpl->attribute_list;
while (node) {
@@ -14734,6 +14820,7 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata,
goto out;
}
break;
+#ifndef NO_PKEY
case CKA_IBM_PROTKEY_EXTRACTABLE:
if (ep11_data->pkey_wrap_supported) {
rc = add_to_attribute_array(&attributes, &num_attributes,
@@ -14746,6 +14833,7 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata,
}
}
break;
+#endif /* NO_PKEY */
default:
/* Either non-boolean, or read-only */
break;
diff --git a/usr/lib/ep11_stdll/ep11_stdll.mk b/usr/lib/ep11_stdll/ep11_stdll.mk
index 6a1d68be..e543c514 100644
--- a/usr/lib/ep11_stdll/ep11_stdll.mk
+++ b/usr/lib/ep11_stdll/ep11_stdll.mk
@@ -41,7 +41,7 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = usr/lib/common/asn1.c \
usr/lib/common/trace.c usr/lib/common/mech_list.c \
usr/lib/common/shared_memory.c usr/lib/common/attributes.c \
usr/lib/common/sw_crypt.c usr/lib/common/profile_obj.c \
- usr/lib/common/dlist.c usr/lib/common/pkey_utils.c \
+ usr/lib/common/dlist.c \
usr/lib/ep11_stdll/new_host.c usr/lib/common/mech_openssl.c \
usr/lib/ep11_stdll/ep11_specific.c \
usr/lib/ep11_stdll/ep11_session.c \
@@ -53,3 +53,8 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = usr/lib/common/asn1.c \
usr/lib/common/pqc_supported.c \
usr/lib/hsm_mk_change/hsm_mk_change.c \
usr/lib/common/btree.c usr/lib/common/sess_mgr.c
+
+if !NO_PKEY
+opencryptoki_stdll_libpkcs11_ep11_la_SOURCES += \
+ usr/lib/common/pkey_utils.c
+endif
diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h
index 304e3eb9..17a5bcf0 100644
--- a/usr/lib/ep11_stdll/tok_struct.h
+++ b/usr/lib/ep11_stdll/tok_struct.h
@@ -115,8 +115,13 @@ token_spec_t token_specific = {
// AES
NULL, // aes_key_gen,
NULL, // aes_xts_key_gen
+#ifndef NO_PKEY
&token_specific_aes_ecb,
&token_specific_aes_cbc,
+#else
+ NULL, // aes_ecb
+ NULL, // aes_cbc
+#endif
NULL, // aes_ctr
NULL, // aes_gcm_init
NULL, // aes_gcm
@@ -125,8 +130,13 @@ token_spec_t token_specific = {
NULL, // aes_ofb
NULL, // aes_cfb
NULL, // aes_mac
+#ifndef NO_PKEY
&token_specific_aes_cmac,
&token_specific_aes_xts, // aes_xts
+#else
+ NULL, // aes_cmac
+ NULL, // aes_xts
+#endif
// DSA
NULL, // dsa_generate_keypair,
NULL, // dsa_sign

View File

@ -0,0 +1,61 @@
commit 0bdcc661e64950e5ea11d950484631ba90e69426
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Thu Mar 7 17:51:40 2024 +0100
EP11 pkey option: consolidate code parts, no logic change
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 114c4ce1..9f855934 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1369,11 +1369,6 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
add_pkey_extractable = CK_TRUE;
break;
}
- if (add_pkey_extractable) {
- ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
- if (ret != CKR_OK)
- goto done;
- }
break;
case PKEY_MODE_ENABLE4EXTR:
/* If the application did not specify CKA_IBM_PROTKEY_EXTRACTABLE in
@@ -1396,11 +1391,6 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
add_pkey_extractable = CK_TRUE;
break;
}
- if (add_pkey_extractable) {
- ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
- if (ret != CKR_OK)
- goto done;
- }
break;
case PKEY_MODE_ENABLE4ALL:
/* If the application did not specify CKA_IBM_PROTKEY_EXTRACTABLE in
@@ -1421,11 +1411,6 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
add_pkey_extractable = CK_TRUE;
break;
}
- if (add_pkey_extractable) {
- ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
- if (ret != CKR_OK)
- goto done;
- }
break;
default:
TRACE_ERROR("PKEY_MODE %i unsupported.\n", ep11_data->pkey_mode);
@@ -1433,6 +1418,12 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
goto done;
break;
}
+
+ if (add_pkey_extractable) {
+ ret = ep11tok_pkey_add_protkey_attr_to_tmpl(tmpl);
+ if (ret != CKR_OK)
+ goto done;
+ }
#endif /* NO_PKEY */
ret = CKR_OK;

View File

@ -0,0 +1,26 @@
commit 88761bc4bd560801ec8a18b96cc82586dd719ca3
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Tue Mar 12 17:13:33 2024 +0100
EP11: add check if protected-key support available at all
If it is already known that the PKEY wrap is not supported or not
functioning (for whatever reason), then don't report the XTS
mechanisms as supported.
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 9f855934..7850e43f 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -12001,7 +12001,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
case CKM_AES_XTS:
case CKM_AES_XTS_KEY_GEN:
- if (ep11tok_pkey_option_disabled(tokdata) || ep11_data->msa_level < 4 ||
+ if ((ep11_data->pkey_wrap_support_checked && !ep11_data->pkey_wrap_supported) ||
+ ep11tok_pkey_option_disabled(tokdata) || ep11_data->msa_level < 4 ||
ep11tok_is_mechanism_supported(tokdata, CKM_IBM_CPACF_WRAP) != CKR_OK ||
ep11tok_is_mechanism_supported(tokdata, CKM_AES_KEY_GEN) != CKR_OK) {
TRACE_INFO("%s Mech '%s' not suppported\n", __func__,

View File

@ -0,0 +1,31 @@
commit 99b87ff678abfb71ba05741d1942e8ac723110c8
Author: Joerg Schmidbauer <jschmidb@de.ibm.com>
Date: Tue Mar 12 17:30:36 2024 +0100
EP11: consider combined-extract for XTS pkey check
Signed-off-by: Joerg Schmidbauer <jschmidb@de.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 7850e43f..e2c9a77e 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1248,14 +1248,15 @@ CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
CK_RV ep11tok_pkey_check_aes_xts(STDLL_TokData_t *tokdata, OBJECT *key_obj,
CK_MECHANISM_TYPE type)
{
+ ep11_private_data_t *ep11_data = tokdata->private_data;
+
if (ep11tok_is_mechanism_supported(tokdata, type) != CKR_OK) {
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
return CKR_MECHANISM_INVALID;
}
- if (object_is_extractable(key_obj) ||
- !object_is_pkey_extractable(key_obj) ||
- object_is_attr_bound(key_obj)) {
+ if (!ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data, key_obj)) {
+ TRACE_ERROR("Key not eligible for pkey support\n");
return CKR_TEMPLATE_INCONSISTENT;
}

View File

@ -0,0 +1,306 @@
commit 5b20a1454ca464b07e7686340a579d8b1870e572
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed Mar 20 08:44:25 2024 +0100
EP11: Reject combined extract attribute settings if it is not supported
In case the control point setting of the adapters do not allow that attributes
CKA_EXTRACTABLE and CKA_IBM_PROTKEY_EXTRACTABLE are both true, then reject
this with CKR_TEMPLATE_INCONSISTENT.
The EP11 code would reject that with CKR_FUNCTION_CANCELED, which for EP11
it means that it violates an internal policy (i.e. control point settings),
but in PKCS#11 this return code has a totally different meaning. So reject
such situations explicitly with the correct return code.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index e2c9a77e..b5d788bf 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1089,20 +1089,23 @@ static CK_BBOOL ep11tok_pkey_session_ok_for_obj(SESSION *session,
* Returns true if the given key object is eligible to get a protected key
* attribute, false otherwise.
*/
-CK_BBOOL ep11tok_pkey_obj_eligible_for_pkey_support(ep11_private_data_t *ep11_data,
- OBJECT *key_obj)
+static CK_RV ep11tok_pkey_obj_eligible_for_pkey_support(
+ ep11_private_data_t *ep11_data,
+ OBJECT *key_obj)
{
if (object_is_attr_bound(key_obj) || !ep11_data->pkey_wrap_supported ||
!object_is_pkey_extractable(key_obj)) {
- return CK_FALSE;
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
if (!ep11_data->pkey_combined_extract_supported &&
object_is_extractable(key_obj)) {
- return CK_FALSE;
+ TRACE_ERROR("Combined extract not supported, but CKA_EXTRACTABLE "
+ "and CKA_IBM_PROTKEY_EXTRACTABLE are both TRUE\n");
+ return CKR_TEMPLATE_INCONSISTENT;
}
- return CK_TRUE;
+ return CKR_OK;
}
/**
@@ -1176,7 +1179,8 @@ CK_RV ep11tok_pkey_check(STDLL_TokData_t *tokdata, SESSION *session,
if (ep11tok_pkey_get_firmware_mk_vp(tokdata, session) != CKR_OK)
goto done;
- if (!ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data, key_obj))
+ ret = ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data, key_obj);
+ if (ret != CKR_OK)
goto done;
if (template_attribute_get_non_empty(key_obj->template,
@@ -1218,11 +1222,14 @@ done:
/**
* Wrapper function around ep11tok_pkey_check for the case where we don't
* have a key object. This function is called externally from new_host.c.
+ * Returns CKR_OK if pkey usage is OK, CKR_FUNCTION_NOT_SUPPORTED if pkey
+ * is not supported, or any other return code in case of an error. In such
+ * cases the calling function should itself return with an error, because
+ * neither the secure key nor the protected key path will work.
*/
-CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
- CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech)
+CK_RV ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
+ CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech)
{
- CK_BBOOL success = CK_FALSE;
size_t keyblobsize = 0;
CK_BYTE *keyblob;
OBJECT *key_obj;
@@ -1232,17 +1239,15 @@ CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
READ_LOCK);
if (ret != CKR_OK) {
TRACE_ERROR("%s no blob ret=0x%lx\n", __func__, ret);
- return CK_FALSE;
+ return ret;
}
ret = ep11tok_pkey_check(tokdata, session, key_obj, mech);
- if (ret == CKR_OK)
- success = CK_TRUE;
object_put(tokdata, key_obj, TRUE);
key_obj = NULL;
- return success;
+ return ret;
}
CK_RV ep11tok_pkey_check_aes_xts(STDLL_TokData_t *tokdata, OBJECT *key_obj,
@@ -1255,7 +1260,8 @@ CK_RV ep11tok_pkey_check_aes_xts(STDLL_TokData_t *tokdata, OBJECT *key_obj,
return CKR_MECHANISM_INVALID;
}
- if (!ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data, key_obj)) {
+ if (ep11tok_pkey_obj_eligible_for_pkey_support(ep11_data,
+ key_obj) != CKR_OK) {
TRACE_ERROR("Key not eligible for pkey support\n");
return CKR_TEMPLATE_INCONSISTENT;
}
@@ -1307,10 +1313,10 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_ATTRIBUTE *sensitive_attr = NULL;
- CK_BBOOL sensitive, btrue = CK_TRUE;
+ CK_BBOOL sensitive, extractable, pkey_extractable, btrue = CK_TRUE;
#ifndef NO_PKEY
CK_ATTRIBUTE *ecp_attr = NULL;
- CK_BBOOL extractable, add_pkey_extractable = CK_FALSE;
+ CK_BBOOL add_pkey_extractable = CK_FALSE;
#endif
CK_RV ret;
@@ -1341,6 +1347,25 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *tokdata,
}
}
+ if (!ep11_data->pkey_combined_extract_supported) {
+ ret = template_attribute_get_bool(tmpl, CKA_EXTRACTABLE, &extractable);
+ if (ret != CKR_OK)
+ extractable = FALSE;
+
+ ret = template_attribute_get_bool(tmpl, CKA_IBM_PROTKEY_EXTRACTABLE,
+ &pkey_extractable);
+ if (ret != CKR_OK)
+ pkey_extractable = FALSE;
+
+ if (extractable && pkey_extractable) {
+ /* The EP11 call would return CKR_FUNCTION_CANCELED in that case */
+ TRACE_ERROR("Combined extract not supported, but CKA_EXTRACTABLE "
+ "and CKA_IBM_PROTKEY_EXTRACTABLE are both TRUE\n");
+ ret = CKR_TEMPLATE_INCONSISTENT;
+ goto done;
+ }
+ }
+
#ifndef NO_PKEY
switch (ep11_data->pkey_mode) {
case PKEY_MODE_DISABLED:
diff --git a/usr/lib/ep11_stdll/ep11_specific.h b/usr/lib/ep11_stdll/ep11_specific.h
index 16d3c719..9ba28cb8 100644
--- a/usr/lib/ep11_stdll/ep11_specific.h
+++ b/usr/lib/ep11_stdll/ep11_specific.h
@@ -585,8 +585,8 @@ CK_BBOOL ep11tok_libica_mech_available(STDLL_TokData_t *tokdata,
CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata,
CK_TOKEN_INFO_PTR pInfo);
-CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
- CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech);
+CK_RV ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
+ CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech);
CK_RV ep11tok_set_operation_state(STDLL_TokData_t *tokdata, SESSION *session);
diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c
index 299a1d3c..f84d0810 100644
--- a/usr/lib/ep11_stdll/new_host.c
+++ b/usr/lib/ep11_stdll/new_host.c
@@ -2080,9 +2080,15 @@ CK_RV SC_EncryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->encr_ctx.multi_init = FALSE;
sess->encr_ctx.multi = FALSE;
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(pMechanism)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
/* In case of a single part encrypt operation we don't need the
* EncryptInit, instead we can use the EncryptSingle which is much
* faster. In case of multi-part operations we are doing the EncryptInit
@@ -2179,9 +2185,16 @@ CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, sess->encr_ctx.key,
+ &sess->encr_ctx.mech);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(&sess->encr_ctx.mech)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, sess->encr_ctx.key, &sess->encr_ctx.mech)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
rc = ep11tok_encrypt_single(tokdata, sess, &sess->encr_ctx.mech,
length_only, sess->encr_ctx.key,
pData, ulDataLen, pEncryptedData,
@@ -2408,9 +2421,15 @@ CK_RV SC_DecryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->decr_ctx.multi_init = FALSE;
sess->decr_ctx.multi = FALSE;
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(pMechanism)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
/* In case of a single part decrypt operation we don't need the
* DecryptInit, instead we can use the EncryptSingle which is much
* faster. In case of multi-part operations we are doing the DecryptInit
@@ -2508,9 +2527,16 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, sess->decr_ctx.key,
+ &sess->decr_ctx.mech);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(&sess->decr_ctx.mech)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, sess->decr_ctx.key, &sess->decr_ctx.mech)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
rc = ep11tok_decrypt_single(tokdata, sess, &sess->decr_ctx.mech,
length_only, sess->decr_ctx.key,
pEncryptedData, ulEncryptedDataLen,
@@ -2992,9 +3018,15 @@ CK_RV SC_SignInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->sign_ctx.multi_init = FALSE;
sess->sign_ctx.multi = FALSE;
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(pMechanism)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
/* In case of a single part sign operation we don't need the SignInit,
* instead we can use the SignSingle which is much faster.
* In case of multi-part operations we are doing the SignInit when
@@ -3101,9 +3133,16 @@ CK_RV SC_Sign(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, sess->sign_ctx.key,
+ &sess->sign_ctx.mech);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(&sess->sign_ctx.mech)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, sess->sign_ctx.key, &sess->sign_ctx.mech)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
rc = ep11tok_sign_single(tokdata, sess, &sess->sign_ctx.mech,
length_only, sess->sign_ctx.key,
pData, ulDataLen, pSignature, pulSignatureLen);
@@ -3391,9 +3430,15 @@ CK_RV SC_VerifyInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->verify_ctx.multi_init = FALSE;
sess->verify_ctx.multi = FALSE;
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(pMechanism)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
/* In case of a single part verify operation we don't need the
* VerifyInit, instead we can use the VerifySingle which is much
* faster. In case of multi-part operations we are doing the VerifyInit
@@ -3497,9 +3542,16 @@ CK_RV SC_Verify(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
+ rc = ep11tok_pkey_usage_ok(tokdata, sess, sess->verify_ctx.key,
+ &sess->verify_ctx.mech);
+ if (rc != CKR_OK && rc != CKR_FUNCTION_NOT_SUPPORTED) {
+ /* CKR_FUNCTION_NOT_SUPPORTED indicates pkey support is not available,
+ but the ep11 fallback can be tried */
+ goto done;
+ }
if ((ep11tok_optimize_single_ops(tokdata) ||
ep11tok_mech_single_only(&sess->verify_ctx.mech)) &&
- !ep11tok_pkey_usage_ok(tokdata, sess, sess->verify_ctx.key, &sess->verify_ctx.mech)) {
+ rc == CKR_FUNCTION_NOT_SUPPORTED) {
rc = ep11tok_verify_single(tokdata, sess, &sess->verify_ctx.mech,
sess->verify_ctx.key, pData, ulDataLen,
pSignature, ulSignatureLen);

View File

@ -0,0 +1,36 @@
commit 4fefcf517133260a7b63049d3a02c9249fe7776c
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Apr 15 09:31:12 2024 +0200
EP11: Fix compile error with NO_PKEY defined
Function signature of ep11tok_pkey_usage_ok() has changed, also change the
code inside the #ifdef NO_PKEY block.
Fixes: cf978b111205b206c7b3c53f424f7085913c00d0
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index b5d788bf..e9007a16 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1460,15 +1460,15 @@ done:
}
#ifdef NO_PKEY
-CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
- CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech)
+CK_RV ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
+ CK_OBJECT_HANDLE hkey, CK_MECHANISM *mech)
{
UNUSED(tokdata);
UNUSED(session);
UNUSED(hkey);
UNUSED(mech);
- return CK_FALSE;
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
#endif /* NO_PKEY */

View File

@ -1,153 +0,0 @@
commit f931d6e47bf2fb26aa9cf52e231d13edc1c837a1
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Dec 12 17:16:56 2023 +0100
COMMON: Update rsa_parse_block_type_2() to not leak the message length
Take the implementation of OpenSSL function RSA_padding_check_PKCS1_type_2()
in crypto/rsa/rsa_pk1.c instead of ossl_rsa_padding_check_PKCS1_type_2(), since
the latter leaks the message size.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
index 326c5795..7bab1a84 100644
--- a/usr/lib/common/mech_rsa.c
+++ b/usr/lib/common/mech_rsa.c
@@ -29,6 +29,7 @@
#include "constant_time.h"
#include <openssl/crypto.h>
+#include <openssl/rsa.h>
CK_BBOOL is_rsa_mechanism(CK_MECHANISM_TYPE mech)
{
@@ -293,13 +294,16 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
CK_BYTE *out_data,
CK_ULONG *out_data_len)
{
- unsigned int ok = 0, found, zero;
- size_t zero_index = 0, msg_index, mlen;
- size_t i, j;
+ int i;
+ unsigned char *em = NULL;
+ unsigned int good, found_zero_byte, mask, equals0;
+ int zero_index = 0, msg_index, mlen = -1;
+ int out_len = *out_data_len;
+ int rsa_size = in_data_len;
/*
* The implementation of this function is copied from OpenSSL's function
- * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
+ * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
*
* The OpenSSL code is licensed under the Apache License 2.0.
@@ -324,55 +328,86 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
* section 7.2.2.
*/
- if (in_data_len < 11) {
+ if (rsa_size < RSA_PKCS1_PADDING_SIZE) {
TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
- ok = constant_time_is_zero(in_data[0]);
- ok &= constant_time_eq(in_data[1], 2);
+ em = malloc(rsa_size);
+ if (em == NULL) {
+ TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY));
+ return CKR_HOST_MEMORY;
+ }
+
+ /* in_data_len is always equal to rsa_size */
+ memcpy(em, in_data, rsa_size);
+
+ good = constant_time_is_zero(em[0]);
+ good &= constant_time_eq(em[1], 2);
/* scan over padding data */
- found = 0;
- for (i = 2; i < in_data_len; i++) {
- zero = constant_time_is_zero(in_data[i]);
+ found_zero_byte = 0;
+ for (i = 2; i < rsa_size; i++) {
+ equals0 = constant_time_is_zero(em[i]);
- zero_index = constant_time_select_int(~found & zero, i, zero_index);
- found |= zero;
+ zero_index = constant_time_select_int(~found_zero_byte & equals0,
+ i, zero_index);
+ found_zero_byte |= equals0;
}
/*
- * PS must be at least 8 bytes long, and it starts two bytes into |enc_msg|.
+ * PS must be at least 8 bytes long, and it starts two bytes into |em|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
- ok &= constant_time_ge(zero_index, 2 + 8);
+ good &= constant_time_ge(zero_index, 2 + 8);
/*
* Skip the zero byte. This is incorrect if we never found a zero-byte
* but in this case we also do not copy the message out.
*/
msg_index = zero_index + 1;
- mlen = in_data_len - msg_index;
+ mlen = rsa_size - msg_index;
/*
* For good measure, do this check in constant time as well.
*/
- ok &= constant_time_ge(*out_data_len, mlen);
+ good &= constant_time_ge(out_len, mlen);
/*
- * since at this point the |msg_index| does not provide the signal
- * indicating if the padding check failed or not, we don't have to worry
- * about leaking the length of returned message, we still need to ensure
- * that we read contents of both buffers so that cache accesses don't leak
- * the value of |good|
+ * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen|
+ * bytes to the left.
+ * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to
+ * |out_data|. Otherwise leave |out_data| unchanged.
+ * Copy the memory back in a way that does not reveal the size of
+ * the data being copied via a timing side channel. This requires copying
+ * parts of the buffer multiple times based on the bits set in the real
+ * length. Clear bits do a non-copy with identical access pattern.
+ * The loop below has overall complexity of O(N*log(N)).
*/
- for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len; i++, j++)
- out_data[j] = constant_time_select_8(ok, in_data[i], out_data[j]);
+ out_len = constant_time_select_int(
+ constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len),
+ rsa_size - RSA_PKCS1_PADDING_SIZE,
+ out_len);
+ for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE;
+ msg_index <<= 1) {
+ mask = ~constant_time_eq(
+ msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0);
+ for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++)
+ em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]);
+ }
+ for (i = 0; i < out_len; i++) {
+ mask = good & constant_time_lt(i, mlen);
+ out_data[i] = constant_time_select_8(
+ mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]);
+ }
+
+ OPENSSL_cleanse(em, rsa_size);
+ free(em);
- *out_data_len = j;
+ *out_data_len = constant_time_select_int(good, mlen, 0);
- return constant_time_select_int(ok, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
+ return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
}
CK_RV rsa_parse_block(CK_BYTE *in_data,

View File

@ -1,737 +0,0 @@
commit 5f1a4f8641306ee192b70c8a32c9ee8a0fe9be5f
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jan 15 12:53:37 2024 +0100
common: Add support for implicit rejection for RSA PKCS#1 v1.5 de-padding
Implicit rejection returns a pseudo random message in case the RSA PKCS#1 v1.5
padding is incorrect, but returns no error. The pseudo random message is based
on static secret data (the private exponent) and the provided ciphertext, so
that the attacker cannot determine that the returned value is randomly generated
instead of the result of decryption and de-padding.
The implicit rejection algorithm is the same as used by OpenSSL.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/COPYRIGHTS b/COPYRIGHTS
index 2bb3dffe..21b6b702 100644
--- a/COPYRIGHTS
+++ b/COPYRIGHTS
@@ -12,19 +12,29 @@ For code originating from OpenSSL:
* Note that in OpenSSL the file crypto/bn/rsa_sup_mul.c does no longer
* exist, it was removed with commit https://github.com/openssl/openssl/commit/4209ce68d8fe8b1506494efa03d378d05baf9ff8
* - usr/lib/common/constant_time.h: Copied unchanged from OpenSSL from
- include/internal/constant_time.h
+ * include/internal/constant_time.h
* - The implementation of function rsa_parse_block_type_2() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
* See comment in function rsa_parse_block_type_2() for a list of changes.
+ * - The implementation of function openssl_specific_rsa_derive_kdk() in
+ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function
+ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to
+ * the OpenCryptoki environment. See comment in function
+ * openssl_specific_rsa_derive_kdk() for a list of changes.
+ * - The implementation of function openssl_specific_rsa_prf() in
+ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function
+ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to
+ * the OpenCryptoki environment. See comment in function
+ * openssl_specific_rsa_prf() for a list of changes.
* - The implementation of function decode_eme_oaep() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* RSA_padding_check_PKCS1_OAEP_mgf1() in crypto/rsa/rsa_oaep.c and is
* slightly modified to fit to the OpenCryptoki environment. See comment in
* function decode_eme_oaep() for a list of changes.
*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* The OpenSSL code is licensed under the Apache License 2.0 (the "License").
* You can obtain a copy in the file LICENSE in the OpenSSL source distribution
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index a88b57d0..29496d99 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -731,7 +731,8 @@ CK_RV rsa_format_block(STDLL_TokData_t *tokdata,
CK_RV rsa_parse_block(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len, CK_ULONG type);
+ CK_ULONG *out_data_len, CK_ULONG type,
+ CK_BYTE *kdk, CK_ULONG kdklen);
CK_RV get_mgf_mech(CK_RSA_PKCS_MGF_TYPE mgf, CK_MECHANISM_TYPE *mech);
@@ -3179,6 +3180,14 @@ CK_RV openssl_specific_hmac_update(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data,
CK_RV openssl_specific_hmac_final(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *signature,
CK_ULONG *sig_len, CK_BBOOL sign);
+CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ const CK_BYTE *in, CK_ULONG inlen,
+ CK_BYTE *kdk, CK_ULONG kdklen);
+CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen,
+ const char *label, CK_ULONG labellen,
+ const CK_BYTE *kdk, CK_ULONG kdklen,
+ uint16_t bitlen);
+
#include "tok_spec_struct.h"
extern token_spec_t token_specific;
diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c
index 9983fcb3..da515289 100644
--- a/usr/lib/common/mech_openssl.c
+++ b/usr/lib/common/mech_openssl.c
@@ -1154,6 +1154,7 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata,
CK_RV rc;
CK_BYTE out[MAX_RSA_KEYLEN];
CK_ULONG modulus_bytes;
+ unsigned char kdk[SHA256_HASH_SIZE] = { 0 };
modulus_bytes = in_data_len;
@@ -1163,7 +1164,16 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata,
goto done;
}
- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2);
+ rc = openssl_specific_rsa_derive_kdk(tokdata, key_obj,
+ in_data, in_data_len,
+ kdk, sizeof(kdk));
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("openssl_specific_rsa_derive_kdk failed\n");
+ goto done;
+ }
+
+ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2,
+ kdk, sizeof(kdk));
done:
OPENSSL_cleanse(out, sizeof(out));
@@ -1254,7 +1264,7 @@ CK_RV openssl_specific_rsa_pkcs_verify(STDLL_TokData_t *tokdata, SESSION *sess,
}
rc = rsa_parse_block(out, modulus_bytes, out_data, &out_data_len,
- PKCS_BT_1);
+ PKCS_BT_1, NULL, 0);
if (rc == CKR_ENCRYPTED_DATA_INVALID) {
TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID));
return CKR_SIGNATURE_INVALID;
@@ -1318,7 +1328,8 @@ CK_RV openssl_specific_rsa_pkcs_verify_recover(STDLL_TokData_t *tokdata,
return rc;
}
- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1);
+ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1,
+ NULL, 0);
if (rc == CKR_ENCRYPTED_DATA_INVALID) {
TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID));
return CKR_SIGNATURE_INVALID;
@@ -4983,3 +4994,388 @@ done:
ctx->context = NULL;
return rv;
}
+
+static CK_RV calc_rsa_priv_exp(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ CK_BYTE *priv_exp, CK_ULONG priv_exp_len)
+{
+ CK_ATTRIBUTE *modulus = NULL, *pub_exp = NULL;
+ CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL;
+ BN_CTX *bn_ctx;
+ BIGNUM *n, *e, *p, *q, *d;
+ CK_RV rc;
+
+ UNUSED(tokdata);
+
+ bn_ctx = BN_CTX_secure_new();
+ if (bn_ctx == NULL) {
+ TRACE_ERROR("BN_CTX_secure_new failed\n");
+ return CKR_FUNCTION_FAILED;
+ }
+
+ /* Get modulus a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
+ &modulus);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_MODULUS\n");
+ goto done;
+ }
+
+ n = BN_CTX_get(bn_ctx);
+ if (n == NULL ||
+ BN_bin2bn(modulus->pValue, modulus->ulValueLen, n) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for modulus\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(n, BN_FLG_CONSTTIME);
+
+ /* Get public exponent a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template,
+ CKA_PUBLIC_EXPONENT, &pub_exp);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PUBLIC_EXPONENT\n");
+ goto done;
+ }
+
+ e = BN_CTX_get(bn_ctx);
+ if (e == NULL ||
+ BN_bin2bn(pub_exp->pValue, pub_exp->ulValueLen, e) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for public exponent\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(e, BN_FLG_CONSTTIME);
+
+ /* Get prime1 a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_1,
+ &prime1);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PRIME_1\n");
+ goto done;
+ }
+
+ p = BN_CTX_get(bn_ctx);
+ if (p == NULL ||
+ BN_bin2bn(prime1->pValue, prime1->ulValueLen, p) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime1\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(p, BN_FLG_CONSTTIME);
+
+ /* Get prime2 a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_2,
+ &prime2);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PRIME_2\n");
+ goto done;
+ }
+
+ q = BN_CTX_get(bn_ctx);
+ if (q == NULL ||
+ BN_bin2bn(prime2->pValue, prime2->ulValueLen, q) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime2\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(q, BN_FLG_CONSTTIME);
+
+ d = BN_CTX_get(bn_ctx);
+ if (d == NULL) {
+ TRACE_ERROR("BN_CTX_get failed to get d\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(d, BN_FLG_CONSTTIME);
+
+ /*
+ * phi(n) = (p - 1 )(q - 1) = n - p - q + 1
+ * d = e ^{-1} mod phi(n).
+ */
+ if (BN_copy(d, n) == NULL ||
+ BN_sub(d, d, p) == 0 ||
+ BN_sub(d, d, q) == 0 ||
+ BN_add_word(d, 1) == 0 ||
+ BN_mod_inverse(d, e, d, bn_ctx) == NULL) {
+ TRACE_ERROR("Failed to calculate private key part d\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+
+ if (BN_bn2binpad(d, priv_exp, priv_exp_len) <= 0) {
+ TRACE_ERROR("BN_bn2binpad failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+
+done:
+ BN_CTX_free(bn_ctx);
+
+ return rc;
+}
+
+CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ const CK_BYTE *in, CK_ULONG inlen,
+ CK_BYTE *kdk, CK_ULONG kdklen)
+{
+ CK_ATTRIBUTE *priv_exp_attr = NULL, *modulus = NULL;
+ CK_BYTE *priv_exp = NULL, *buf = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *mdctx = NULL;
+ const EVP_MD *md = NULL;
+ size_t md_len;
+ unsigned char d_hash[SHA256_HASH_SIZE] = { 0 };
+ CK_RV rc;
+
+ /*
+ * The implementation of this function is copied from OpenSSL's function
+ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to
+ * the OpenCryptoki environment.
+ * Changes include:
+ * - Different variable and define names.
+ * - Usage of TRACE_ERROR to report errors and issue debug messages.
+ * - Different return codes.
+ * - Different code to get the private key component 'd'.
+ * - Use of the EVP APIs instead of the internal APIs for Digest and HMAC
+ * operations.
+ */
+
+ if (kdklen != SHA256_HASH_SIZE) {
+ TRACE_ERROR("KDK length is wrong\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
+ &modulus);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_MODULUS\n");
+ return rc;
+ }
+
+ buf = calloc(1, modulus->ulValueLen);
+ if (buf == NULL) {
+ TRACE_ERROR("Failed to allocate a buffer for private exponent\n");
+ return CKR_HOST_MEMORY;
+ }
+
+ rc = template_attribute_get_non_empty(key_obj->template,
+ CKA_PRIVATE_EXPONENT, &priv_exp_attr);
+ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) {
+ TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n");
+ goto out;
+ }
+
+ if (priv_exp_attr == NULL) {
+ rc = calc_rsa_priv_exp(tokdata, key_obj, buf, modulus->ulValueLen);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("calc_rsa_priv_exp failed\n");
+ goto out;
+ }
+ priv_exp = buf;
+ } else {
+ if (priv_exp_attr->ulValueLen < modulus->ulValueLen) {
+ memcpy(buf + modulus->ulValueLen - priv_exp_attr->ulValueLen,
+ priv_exp_attr->pValue, priv_exp_attr->ulValueLen);
+ priv_exp = buf;
+ } else {
+ priv_exp = (CK_BYTE *)priv_exp_attr->pValue +
+ priv_exp_attr->ulValueLen - modulus->ulValueLen;
+ }
+ }
+
+ /*
+ * we use hardcoded hash so that migrating between versions that use
+ * different hash doesn't provide a Bleichenbacher oracle:
+ * if the attacker can see that different versions return different
+ * messages for the same ciphertext, they'll know that the message is
+ * synthetically generated, which means that the padding check failed
+ */
+ md = EVP_sha256();
+ if (md == NULL) {
+ TRACE_ERROR("EVP_sha256 failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (EVP_Digest(priv_exp, modulus->ulValueLen, d_hash, NULL,
+ md, NULL) <= 0) {
+ TRACE_ERROR("EVP_Digest failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, d_hash, sizeof(d_hash));
+ if (pkey == NULL) {
+ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ mdctx = EVP_MD_CTX_create();
+ if (mdctx == NULL) {
+ TRACE_ERROR("EVP_MD_CTX_create() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey) != 1) {
+ TRACE_ERROR("EVP_DigestSignInit failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (inlen < modulus->ulValueLen) {
+ memset(buf, 0, modulus->ulValueLen - inlen);
+ if (EVP_DigestSignUpdate(mdctx, buf, modulus->ulValueLen - inlen)!= 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ }
+ if (EVP_DigestSignUpdate(mdctx, in, inlen) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ md_len = kdklen;
+ if (EVP_DigestSignFinal(mdctx, kdk, &md_len) != 1 ||
+ md_len != kdklen) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ rc = CKR_OK;
+
+out:
+ if (buf != NULL)
+ free(buf);
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ if (mdctx != NULL)
+ EVP_MD_CTX_free(mdctx);
+
+ return rc;
+}
+
+CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen,
+ const char *label, CK_ULONG labellen,
+ const CK_BYTE *kdk, CK_ULONG kdklen,
+ uint16_t bitlen)
+{
+ CK_RV rc;
+ CK_ULONG pos;
+ uint16_t iter = 0;
+ unsigned char be_iter[sizeof(iter)];
+ unsigned char be_bitlen[sizeof(bitlen)];
+ EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *mdctx = NULL;
+ unsigned char hmac_out[SHA256_HASH_SIZE];
+ size_t md_len;
+
+ /*
+ * The implementation of this function is copied from OpenSSL's function
+ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to
+ * the providers environment.
+ * Changes include:
+ * - Different variable and define names.
+ * - Usage of TRACE_ERROR report errors and issue debug messages.
+ * - Different return codes.
+ * - Use of the EVP API instead of the internal APIs for HMAC operations.
+ */
+
+ if (kdklen != SHA256_HASH_SIZE) {
+ TRACE_ERROR("invalid kdklen\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+ if (outlen * 8 != bitlen) {
+ TRACE_ERROR("invalid outlen\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ be_bitlen[0] = (bitlen >> 8) & 0xff;
+ be_bitlen[1] = bitlen & 0xff;
+
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, kdk, kdklen);
+ if (pkey == NULL) {
+ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ mdctx = EVP_MD_CTX_create();
+ if (mdctx == NULL) {
+ TRACE_ERROR("EVP_MD_CTX_create() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ /*
+ * we use hardcoded hash so that migrating between versions that use
+ * different hash doesn't provide a Bleichenbacher oracle:
+ * if the attacker can see that different versions return different
+ * messages for the same ciphertext, they'll know that the message is
+ * synthetically generated, which means that the padding check failed
+ */
+ for (pos = 0; pos < outlen; pos += SHA256_HASH_SIZE, iter++) {
+ if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
+ TRACE_ERROR("EVP_DigestSignInit failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ be_iter[0] = (iter >> 8) & 0xff;
+ be_iter[1] = iter & 0xff;
+
+ if (EVP_DigestSignUpdate(mdctx, be_iter, sizeof(be_iter)) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ if (EVP_DigestSignUpdate(mdctx, (unsigned char *)label, labellen) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ if (EVP_DigestSignUpdate(mdctx, be_bitlen, sizeof(be_bitlen)) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ /*
+ * HMAC_Final requires the output buffer to fit the whole MAC
+ * value, so we need to use the intermediate buffer for the last
+ * unaligned block
+ */
+ md_len = SHA256_HASH_SIZE;
+ if (pos + SHA256_HASH_SIZE > outlen) {
+ md_len = sizeof(hmac_out);
+ if (EVP_DigestSignFinal(mdctx, hmac_out, &md_len) != 1) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ memcpy(out + pos, hmac_out, outlen - pos);
+ } else {
+ md_len = outlen - pos;
+ if (EVP_DigestSignFinal(mdctx, out + pos, &md_len) != 1) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ }
+ }
+
+ rc = CKR_OK;
+
+out:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ if (mdctx != NULL)
+ EVP_MD_CTX_free(mdctx);
+
+ return rc;
+}
+
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
index 7bab1a84..7dc9589a 100644
--- a/usr/lib/common/mech_rsa.c
+++ b/usr/lib/common/mech_rsa.c
@@ -289,21 +289,34 @@ static CK_RV rsa_parse_block_type_1(CK_BYTE *in_data,
return rc;
}
+#define MAX_LEN_GEN_TRIES 128
+
static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len)
+ CK_ULONG *out_data_len,
+ CK_BYTE *kdk, CK_ULONG kdklen)
{
- int i;
- unsigned char *em = NULL;
- unsigned int good, found_zero_byte, mask, equals0;
- int zero_index = 0, msg_index, mlen = -1;
- int out_len = *out_data_len;
- int rsa_size = in_data_len;
+ unsigned int good = 0, found_zero_byte, equals0;
+ size_t zero_index = 0, msg_index;
+ unsigned char *synthetic = NULL;
+ int synthetic_length;
+ uint16_t len_candidate;
+ unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)];
+ uint16_t len_mask;
+ uint16_t max_sep_offset;
+ int synth_msg_index = 0;
+ size_t i, j;
+ CK_RV rc;
+
+ if (kdk == NULL || kdklen == 0) {
+ TRACE_DEVEL("%s\n", ock_err(ERR_ARGUMENTS_BAD));
+ return CKR_ARGUMENTS_BAD;
+ }
/*
* The implementation of this function is copied from OpenSSL's function
- * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
+ * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
*
* The OpenSSL code is licensed under the Apache License 2.0.
@@ -328,27 +341,67 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
* section 7.2.2.
*/
- if (rsa_size < RSA_PKCS1_PADDING_SIZE) {
+ if (in_data_len < RSA_PKCS1_PADDING_SIZE) {
TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
- em = malloc(rsa_size);
- if (em == NULL) {
- TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY));
+ /* Generate a random message to return in case the padding checks fail. */
+ synthetic = calloc(1, in_data_len);
+ if (synthetic == NULL) {
+ TRACE_ERROR("Failed to allocate synthetic buffer");
return CKR_HOST_MEMORY;
}
- /* in_data_len is always equal to rsa_size */
- memcpy(em, in_data, rsa_size);
+ rc = openssl_specific_rsa_prf(synthetic, in_data_len, "message", 7,
+ kdk, kdklen, in_data_len * 8);
+ if (rc != CKR_OK)
+ goto out;
+
+ /* decide how long the random message should be */
+ rc = openssl_specific_rsa_prf(candidate_lengths,
+ sizeof(candidate_lengths),
+ "length", 6, kdk, kdklen,
+ MAX_LEN_GEN_TRIES *
+ sizeof(len_candidate) * 8);
+ if (rc != CKR_OK)
+ goto out;
- good = constant_time_is_zero(em[0]);
- good &= constant_time_eq(em[1], 2);
+ /*
+ * max message size is the size of the modulus size minus 2 bytes for
+ * version and padding type and a minimum of 8 bytes padding
+ */
+ len_mask = max_sep_offset = in_data_len - 2 - 8;
+ /*
+ * we want a mask so let's propagate the high bit to all positions less
+ * significant than it
+ */
+ len_mask |= len_mask >> 1;
+ len_mask |= len_mask >> 2;
+ len_mask |= len_mask >> 4;
+ len_mask |= len_mask >> 8;
+
+ synthetic_length = 0;
+ for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate);
+ i += sizeof(len_candidate)) {
+ len_candidate = (candidate_lengths[i] << 8) |
+ candidate_lengths[i + 1];
+ len_candidate &= len_mask;
+
+ synthetic_length = constant_time_select_int(
+ constant_time_lt(len_candidate, max_sep_offset),
+ len_candidate, synthetic_length);
+ }
+
+ synth_msg_index = in_data_len - synthetic_length;
+
+ good = constant_time_is_zero(in_data[0]);
+ good &= constant_time_eq(in_data[1], 2);
/* scan over padding data */
found_zero_byte = 0;
- for (i = 2; i < rsa_size; i++) {
- equals0 = constant_time_is_zero(em[i]);
+ for (i = 2; i < in_data_len; i++) {
+ equals0 = constant_time_is_zero(in_data[i]);
zero_index = constant_time_select_int(~found_zero_byte & equals0,
i, zero_index);
@@ -356,7 +409,7 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
}
/*
- * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+ * PS must be at least 8 bytes long, and it starts two bytes into |in_data|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
@@ -367,53 +420,41 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* but in this case we also do not copy the message out.
*/
msg_index = zero_index + 1;
- mlen = rsa_size - msg_index;
/*
- * For good measure, do this check in constant time as well.
+ * old code returned an error in case the decrypted message wouldn't fit
+ * into the |out_data|, since that would leak information, return the
+ * synthetic message instead
*/
- good &= constant_time_ge(out_len, mlen);
+ good &= constant_time_ge(*out_data_len, in_data_len - msg_index);
+
+ msg_index = constant_time_select_int(good, msg_index, synth_msg_index);
/*
- * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen|
- * bytes to the left.
- * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to
- * |out_data|. Otherwise leave |out_data| unchanged.
- * Copy the memory back in a way that does not reveal the size of
- * the data being copied via a timing side channel. This requires copying
- * parts of the buffer multiple times based on the bits set in the real
- * length. Clear bits do a non-copy with identical access pattern.
- * The loop below has overall complexity of O(N*log(N)).
+ * since at this point the |msg_index| does not provide the signal
+ * indicating if the padding check failed or not, we don't have to worry
+ * about leaking the length of returned message, we still need to ensure
+ * that we read contents of both buffers so that cache accesses don't leak
+ * the value of |good|
*/
- out_len = constant_time_select_int(
- constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len),
- rsa_size - RSA_PKCS1_PADDING_SIZE,
- out_len);
- for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE;
- msg_index <<= 1) {
- mask = ~constant_time_eq(
- msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0);
- for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++)
- em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]);
- }
- for (i = 0; i < out_len; i++) {
- mask = good & constant_time_lt(i, mlen);
- out_data[i] = constant_time_select_8(
- mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]);
- }
+ for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len;
+ i++, j++)
+ out_data[j] = constant_time_select_8(good, in_data[i], synthetic[i]);
- OPENSSL_cleanse(em, rsa_size);
- free(em);
+ *out_data_len = j;
- *out_data_len = constant_time_select_int(good, mlen, 0);
+out:
+ if (synthetic != NULL)
+ free(synthetic);
- return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
+ return rc;
}
CK_RV rsa_parse_block(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len, CK_ULONG type)
+ CK_ULONG *out_data_len, CK_ULONG type,
+ CK_BYTE *kdk, CK_ULONG kdklen)
{
switch (type) {
case PKCS_BT_1:
@@ -421,7 +462,7 @@ CK_RV rsa_parse_block(CK_BYTE *in_data,
out_data, out_data_len);
case PKCS_BT_2:
return rsa_parse_block_type_2(in_data, in_data_len,
- out_data, out_data_len);
+ out_data, out_data_len, kdk, kdklen);
}
return CKR_ARGUMENTS_BAD;

View File

@ -1,387 +0,0 @@
commit e2b496f58a84c2f537667655fe08a0d4923f0c70
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Jan 12 09:36:27 2024 +0100
Constant time fixes for C_Decrypt return code handling
Return code handling of C_Decrypt, C_DecryptUpdate, and C_DecryptFinal must
be performed in a constant time manner for RSA mechanisms. Otherwise it
may cause a timing side channel that may be used to perform a Bleichenbacher
style attack.
Handling of error situations with CKR_BUFFER_TOO_SMALL or size-query calls,
where the output buffer is NULL and the required size of the output buffer
is to be returned, do not need to be performed in constant time, since
these cases are shortcut anyway, and the result is only dependent on the
modulus size of the RSA key (which is public information anyway).
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c
index 8a1e8723..bbb0f601 100644
--- a/usr/lib/common/new_host.c
+++ b/usr/lib/common/new_host.c
@@ -47,6 +47,7 @@
#include "trace.h"
#include "slotmgr.h"
#include "attributes.h"
+#include "constant_time.h"
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -2345,6 +2346,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2377,11 +2379,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt(tokdata, sess, length_only, &sess->decr_ctx,
pEncryptedData, ulEncryptedDataLen, pData,
pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2404,6 +2414,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2436,11 +2447,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt_update(tokdata, sess, length_only,
&sess->decr_ctx, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2462,6 +2480,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2493,11 +2512,19 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt_final(tokdata, sess, length_only, &sess->decr_ctx,
pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 073b349f..6d08b95e 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -9552,10 +9552,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
@@ -9611,10 +9613,12 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
@@ -9676,10 +9680,12 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c
index 55e34c18..299a1d3c 100644
--- a/usr/lib/ep11_stdll/new_host.c
+++ b/usr/lib/ep11_stdll/new_host.c
@@ -38,6 +38,7 @@
#include "slotmgr.h"
#include "attributes.h"
#include "ep11_specific.h"
+#include "constant_time.h"
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -2466,6 +2467,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2513,17 +2515,29 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
length_only, sess->decr_ctx.key,
pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_single() failed.\n");
} else {
rc = ep11tok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt() failed.\n");
}
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2545,6 +2559,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
{
SESSION *sess = NULL;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2596,11 +2611,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = ep11tok_decrypt_update(tokdata, sess, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2622,6 +2644,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2670,10 +2693,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
}
rc = ep11tok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c
index 6c419750..d8064559 100644
--- a/usr/lib/icsf_stdll/new_host.c
+++ b/usr/lib/icsf_stdll/new_host.c
@@ -35,6 +35,8 @@
#include "slotmgr.h"
#include "attributes.h"
#include "icsf_specific.h"
+#include "constant_time.h"
+
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -1768,6 +1770,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1801,11 +1804,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = icsftok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -1827,6 +1838,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
{
SESSION *sess = NULL;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1857,11 +1869,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = icsftok_decrypt_update(tokdata, sess, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -1883,6 +1902,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1915,10 +1935,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
length_only = TRUE;
rc = icsftok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
commit d756ba1ec270a289950e66398c7e8be59c4a594d
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Feb 9 14:07:34 2024 +0100
COMMON: Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT
An RSA key object that has no CKA_PRIVATE_EXPONENT may either don't have that
attribute at all, or may have an empty CKA_PRIVATE_EXPONENT attribute.
Both situations should be handed the same, and the private exponent of the
key needs to be calculated from the other key components.
Note that RSA key objects generated with a current soft or ICA token will
always have a valid CKA_PRIVATE_EXPONENT attribute, since this is provided
during key generation.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c
index da515289..14c82e2d 100644
--- a/usr/lib/common/mech_openssl.c
+++ b/usr/lib/common/mech_openssl.c
@@ -5160,7 +5160,8 @@ CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
rc = template_attribute_get_non_empty(key_obj->template,
CKA_PRIVATE_EXPONENT, &priv_exp_attr);
- if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) {
+ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE &&
+ rc != CKR_ATTRIBUTE_VALUE_INVALID) {
TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n");
goto out;
}

View File

@ -1,49 +1,51 @@
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0
Version: 3.22.0
Release: 3%{?dist}
License: CPL
Group: System Environment/Base
URL: https://github.com/opencryptoki/opencryptoki
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0
Version: 3.23.0
Release: 1%{?dist}
License: CPL
URL: https://github.com/opencryptoki/opencryptoki
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
# bz#1373833, change tmpfiles snippets from /var/lock/* to /run/lock/*
Patch1: opencryptoki-3.11.0-lockdir.patch
# add missing p11sak_defined_attrs.conf
Patch2: opencryptoki-3.21.0-p11sak.patch
# comment some unsupported sandbox options and add /run to ReadWritePaths to exclude
# /run directory from being made read-only on rhel8
Patch3: opencryptoki-3.21-sandboxing.patch
Patch1: opencryptoki-3.11.0-lockdir.patch
# add missing p11sak_defined_attrs.conf, strength.conf
Patch2: opencryptoki-3.21.0-p11sak.patch
# upstream patches
# CVE-2024-0914 opencryptoki: timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts
Patch20: opencryptoki-CVE-2024-0914-part1.patch
Patch21: opencryptoki-CVE-2024-0914-part2.patch
Patch22: opencryptoki-CVE-2024-0914-part3.patch
Patch23: opencryptoki-CVE-2024-0914-part4.patch
Patch24: opencryptoki-CVE-2024-0914-part5.patch
# SEC2356-backport
Patch100: opencryptoki-3.23-SEC2356-backport-01.patch
Patch101: opencryptoki-3.23-SEC2356-backport-02.patch
Patch102: opencryptoki-3.23-SEC2356-backport-03.patch
Patch103: opencryptoki-3.23-SEC2356-backport-04.patch
Patch104: opencryptoki-3.23-SEC2356-backport-05.patch
Patch105: opencryptoki-3.23-SEC2356-backport-06.patch
Patch106: opencryptoki-3.23-SEC2356-backport-07.patch
Patch107: opencryptoki-3.23-SEC2356-backport-08.patch
Patch108: opencryptoki-3.23-SEC2356-backport-09.patch
Requires(pre): coreutils diffutils
Requires: (selinux-policy >= 3.14.3-121 if selinux-policy-targeted)
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: openssl-devel >= 1.1.1
BuildRequires: trousers-devel
BuildRequires: openldap-devel
BuildRequires: autoconf automake libtool
BuildRequires: bison flex
BuildRequires: systemd-devel
BuildRequires: libcap-devel
BuildRequires: expect
BuildRequires: make
%ifarch s390 s390x
BuildRequires: libica-devel >= 3.3
Requires(pre): coreutils diffutils
Requires: (selinux-policy >= 38.1.14-1 if selinux-policy-targeted)
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: openssl-devel >= 1.1.1
%if 0%{?tmptok}
BuildRequires: trousers-devel
%endif
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}(token)
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
BuildRequires: openldap-devel
BuildRequires: autoconf automake libtool
BuildRequires: bison flex
BuildRequires: systemd-devel
BuildRequires: libcap-devel
BuildRequires: expect
BuildRequires: make
%ifarch s390 s390x
BuildRequires: libica-devel >= 3.3
%endif
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}(token)
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
%description
@ -56,7 +58,6 @@ This package contains the Slot Daemon (pkcsslotd) and general utilities.
%package libs
Group: System Environment/Libraries
Summary: The run-time libraries for opencryptoki package
Requires(pre): shadow-utils
@ -72,7 +73,6 @@ functional.
%package devel
Group: Development/Libraries
Summary: Development files for openCryptoki
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -82,7 +82,6 @@ opencryptoki and PKCS#11 based applications
%package swtok
Group: System Environment/Libraries
Summary: The software token implementation for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -99,7 +98,6 @@ without any specific cryptographic hardware.
%package tpmtok
Group: System Environment/Libraries
Summary: Trusted Platform Module (TPM) device support for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -116,7 +114,6 @@ Trusted Platform Module (TPM) devices in the opencryptoki stack.
%package icsftok
Group: System Environment/Libraries
Summary: ICSF token support for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -134,7 +131,6 @@ ICSF token in the opencryptoki stack.
%ifarch s390 s390x
%package icatok
Group: System Environment/Libraries
Summary: ICA cryptographic devices (clear-key) support for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -152,7 +148,6 @@ cryptographic hardware such as IBM 4764 or 4765 that uses the
"accelerator" or "clear-key" path.
%package ccatok
Group: System Environment/Libraries
Summary: CCA cryptographic devices (secure-key) support for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -170,7 +165,6 @@ cryptographic hardware such as IBM 4764 or 4765 that uses the
"co-processor" or "secure-key" path.
%package ep11tok
Group: System Environment/Libraries
Summary: CCA cryptographic devices (secure-key) support for opencryptoki
Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release}
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
@ -196,44 +190,24 @@ configured with Enterprise PKCS#11 (EP11) firmware.
%build
./bootstrap.sh
%configure --with-systemd=%{_unitdir} \
%configure --with-systemd=%{_unitdir} --enable-testcases \
--with-pkcsslotd-user=pkcsslotd --with-pkcs-group=pkcs11 \
%if 0%{?tpmtok}
--enable-tpmtok \
%else
--disable-tpmtok \
%endif
%ifarch s390 s390x
--enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate
%else
--disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --disable-pkcscca_migrate
--disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate
%endif
make %{?_smp_mflags} CHGRP=/bin/true
%make_build CHGRP=/bin/true
%install
make install DESTDIR=$RPM_BUILD_ROOT CHGRP=/bin/true
# Remove unwanted cruft
rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/*.la
rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/stdll/*.la
%post libs -p /sbin/ldconfig
%post swtok -p /sbin/ldconfig
%post tpmtok -p /sbin/ldconfig
%post icsftok -p /sbin/ldconfig
%ifarch s390 s390x
%post icatok -p /sbin/ldconfig
%post ccatok -p /sbin/ldconfig
%post ep11tok -p /sbin/ldconfig
%endif
%postun libs -p /sbin/ldconfig
%postun swtok -p /sbin/ldconfig
%postun tpmtok -p /sbin/ldconfig
%postun icsftok -p /sbin/ldconfig
%ifarch s390 s390x
%postun icatok -p /sbin/ldconfig
%postun ccatok -p /sbin/ldconfig
%postun ep11tok -p /sbin/ldconfig
%endif
%make_install CHGRP=/bin/true
%pre
# don't touch opencryptoki.conf even if it is unchanged due to new tokversion
@ -260,7 +234,7 @@ fi
%systemd_post pkcsslotd.service
if test $1 -eq 1; then
%tmpfiles_create
%tmpfiles_create %{name}.conf
fi
%preun
@ -269,8 +243,6 @@ fi
%postun
%systemd_postun_with_restart pkcsslotd.service
%triggerun -- opencryptoki < 3.21.0-1
/usr/bin/systemctl daemon-reload
%files
%doc ChangeLog FAQ README.md
@ -334,11 +306,13 @@ fi
%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/swtok/
%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/swtok/TOK_OBJ/
%if 0%{?tmptok}
%files tpmtok
%doc doc/README.tpm_stdll
%{_libdir}/opencryptoki/stdll/libpkcs11_tpm.*
%{_libdir}/opencryptoki/stdll/PKCS11_TPM.so
%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/tpm/
%endif
%files icsftok
%doc doc/README.icsf_stdll
@ -381,196 +355,212 @@ fi
%changelog
* Wed May 22 2024 Than Ngo <than@redhat.com> - 3.23.0-1
- Resolves: RHEL-23671, ep11 token: support protected keys for extractable keys
- Resolves: RHEL-23672, ep11 token support for FIPS 2021-session bound EP11 keys
- Resolves: RHEL-23673, update to 3.23.0
* Fri Feb 16 2024 Than Ngo <than@redhat.com> - 3.22.0-3
- Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT
Related: RHEL-22791
Related: RHEL-22792
* Thu Feb 08 2024 Than Ngo <than@redhat.com> - 3.22.0-2
- timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts (Marvin)
Resolves: RHEL-22791
Resolves: RHEL-22792
* Thu Nov 23 2023 Than Ngo <than@redhat.com> - 3.22.0-1
- Resolves: RHEL-11413, update to 3.22.0
* Tue Nov 21 2023 Than Ngo <than@redhat.com> - 3.22.0-1
- Resolves: RHEL-11412, rebase to 3.22.0
- Resolves: RHEL-10569, openCryptoki for PKCS #11 3.0
* Tue Jul 18 2023 Than Ngo <than@redhat.com> - 3.21.0-9
- Resolves: #2223588, FTBFS
* Tue Jul 18 2023 Than Ngo <than@redhat.com> - 3.21.0-8
- Related: #2222595, add triggerun to reload daemon
* Fri Jul 14 2023 Than Ngo <than@redhat.com> - 3.21.0-7
- Resolves: #2222595, p11sak tool: slot option does not accept argument 0 for slot index 0
- Resolves: #2222594, p11sak fails as soon as there reside non-key objects
* Tue Jul 04 2023 Than Ngo <than@redhat.com> - 3.21.0-6
- add workaround for segfault in PEM_write_bio() on OpenSSL 1.1.1
Related: #2159741
* Fri Jul 14 2023 Than Ngo <than@redhat.com> - 3.21.0-8
- Resolves: #2222592, p11sak tool: slot option does not accept argument 0 for slot index 0
- Resolves: #2222596, p11sak fails as soon as there reside non-key objects
* Tue Jun 13 2023 Than Ngo <than@redhat.com> - 3.21.0-5
- add requirement on selinux-policy >= 3.14.3-121 for pkcsslotd policy sandboxing
Related: #2159697
- add requirement on selinux-policy >= 38.1.14-1 for pkcsslotd policy sandboxing
Related: #2160061
* Thu May 25 2023 Than Ngo <than@redhat.com> - 3.21.0-4
* Fri May 26 2023 Than Ngo <than@redhat.com> - 3.21.0-4
- add verify attributes for opencryptoki.conf to ignore the verification
Related: #2159697
Related: #2160061
* Mon May 22 2023 Than Ngo <than@redhat.com> - 3.21.0-3
- pkcsstats: Fix handling of user name
- p11sak: Fix user confirmation prompt behavior when stdin is closed
Related: #2159697
* Tue May 16 2023 Than Ngo <than@redhat.com> - 3.21.0-2
- add missing /var/lib/opencryptoki/HSM_MK_CHANGE
- disable unsupported sandbox options and add /run to ReadWritePaths to exclude
/run directory from being made read-only on rhel8
Related: #2159697
* Mon May 15 2023 Than Ngo <than@redhat.com> - 3.21.0-1
- Resolves: #1984865, ep11 and cca: support concurrent HSM master key changes
- Resolves: #2110500, ep11 token: PKCS #11 3.0 - support AES_XTS
- Resolves: #2111011, cca token: protected key support
- Resolves: #2159697, update to 3.21.0
- Resolves: #2159740, pkcsslotd hardening
- Resolves: #2159741, p11sak support Dilithium and Kyber keys
- Resolves: #2159742, ica and soft tokens: PKCS #11 3.0 - support AES_XTS
- Resolves: #2110497, concurrent MK rotation for cca token
- Resolves: #2110498, concurrent MK rotation for ep11 token
- Resolves: #2110499, ep11 token: PKCS #11 3.0 - support AES_XTS
- Resolves: #2111010, cca token: protected key support
- Resolves: #2160061, rebase to 3.21.0
- Resolves: #2160105, pkcsslotd hardening
- Resolves: #2160107, p11sak support Dilithium and Kyber keys
- Resolves: #2160109, ica and soft tokens: PKCS #11 3.0 - support AES_XTS
* Mon Jan 30 2023 Than Ngo <than@redhat.com> - 3.19.0-2
- Resolves: #2043856, Support of ep11 token for new IBM Z Hardware (IBM z16)
- Resolves: #2044182, Support of ep11 token for new IBM Z Hardware (IBM z16)
* Tue Nov 01 2022 Than Ngo <than@redhat.com> - 3.19.0-1
- Resolves: #2126612, opencryptoki fails after generating > 500 RSA keys
- Resolves: #2110315, rebase to 3.19.0
- Resolves: #2110990, openCryptoki key generation with expected MKVP only on CCA and EP11 tokens
- Resolves: #2110477, openCryptoki ep11 token: master key consistency
- Resolves: #1984871, openCryptoki ep11 token: vendor specific key derivation
* Tue Oct 11 2022 Than Ngo <than@redhat.com> - 3.19.0-1
- Resolves: #2126294, opencryptoki fails after generating > 500 RSA keys
- Resolves: #2110314, rebase to 3.19.0
- Resolves: #2110989, openCryptoki key generation with expected MKVP only on CCA and EP11 tokens
- Resolves: #2110476, openCryptoki ep11 token: master key consistency
- Resolves: #2018458, openCryptoki ep11 token: vendor specific key derivation
* Mon Aug 01 2022 Than Ngo <than@redhat.com> - 3.18.0-3
- Related: #2043854, do not touch opencryptoki.conf if it is in place already and even if it is unchanged
- Resolves: #2112785, EP11: Fix C_GetMechanismList returning CKR_BUFFER_TOO_SMALL
* Fri Jul 29 2022 Than Ngo <than@redhat.com> - 3.18.0-4
- Related: #2044179, do not touch opencryptoki.conf if it is in place already and even if it is unchanged
* Tue Jun 07 2022 Than Ngo <than@redhat.com> - 3.18.0-2
- Related: #2043854, fix json output
* Tue Jun 07 2022 Than Ngo <than@redhat.com> - 3.18.0-3
- Related: #2044179, fix json output
* Tue May 24 2022 Than Ngo <than@redhat.com> - 3.18.0-1
- Resolves: #2043845, rebase to 3.18.0
- Resolves: #2043854, add crypto counters
- Resolves: #2043855, support crypto profiles
* Mon May 09 2022 Than Ngo <than@redhat.com> - 3.18.0-2
- Related: #2044179, add missing strength.conf
* Fri Apr 15 2022 Than Ngo <than@redhat.com> - 3.17.0-4
- Resolves: #2066762, Dilithium support not available
* Mon May 09 2022 Than Ngo <than@redhat.com> - 3.18.0-1
- Resolves: #2044179, rebase to 3.18.0
- Resolves: #2068091, pkcsconf -t failed with Segmentation fault in FIPS mode
- Resolves: #2066763, Dilithium support not available
- Resolves: #2064697, OpenSSL 3.0 Compatibility for IBM Security Libraries and Tools
- Resolves: #2044181, support crypto profiles
- Resolves: #2044180, add crypto counters
* Mon Jan 17 2022 Than Ngo <than@redhat.com> - 3.17.0-3
- Resolves: #2040677, API: Unlock GlobMutex if user and group check fails
* Tue May 03 2022 Than Ngo <than@redhat.com> - 3.17.0-6
- Resolves: #2066763, Dilithium support not available
* Tue Nov 09 2021 Than Ngo <than@redhat.com> - 3.17.0-2
- Related: #1984993, add missing p11sak_defined_attrs.conf
* Mon Mar 14 2022 Than Ngo <than@redhat.com> - 3.17.0-5
- Resolves: #2064697, ICA/EP11: Support libica version 4
* Tue Oct 19 2021 Than Ngo <than@redhat.com> - 3.17.0-1
- Resolves: #1984993, rebase to 3.17.0
- Resolves: #1984870, openCryptoki key management tool
* Mon Jan 17 2022 Than Ngo <than@redhat.com> - 3.17.0-4
- Resolves: #2040678, API: Unlock GlobMutex if user and group check fails
* Mon Sep 13 2021 Than Ngo <than@redhat.com> - 3.16.0-6
- Fix: Could not open /run/lock/opencryptoki/LCK..APIlock
* Sat Dec 04 2021 Than Ngo <than@redhat.com> - 3.17.0-3
- Related: #2015888, added missing patch pkcsslotd-pidfile
* Thu Aug 19 2021 Than Ngo <than@redhat.com> - 3.16.0-5
- Resolves: #1987256, pkcstok_migrate leaves options with multiple strings in opencryptoki.conf options without double-quotes
* Wed Nov 24 2021 Than Ngo <than@redhat.com> - 3.17.0-2
- Related: #2015888, add missing p11sak_defined_attrs.conf
* Fri Jul 16 2021 Than Ngo <than@redhat.com> - 3.16.0-4
- Resolves: #1964304, Fix detection if pkcsslotd is still running
* Wed Nov 03 2021 Than Ngo <than@redhat.com> - 3.17.0-1
- Resolves: #2015888, rebase to 3.17.0
- Resolves: #2017720, openCryptoki key management tool
* Tue Jun 15 2021 Than Ngo <than@redhat.com> - 3.16.0-3
- Related: #1919223, add conditional requirement
* Thu Aug 26 2021 Than Ngo <than@redhat.com> - 3.16.0-12
- Related: #1989138, Support for OpenSSL 3.0
* Fri Jun 11 2021 Than Ngo <than@redhat.com> - 3.16.0-2
- Related: #1919223, add requirement on selinux-policy >= 3.14.3-70 for using ipsec
* Mon Aug 23 2021 Than Ngo <than@redhat.com> - 3.16.0-11
- Resolves: #1989138, Support for OpenSSL 3.0
* Tue Jun 01 2021 Than Ngo <than@redhat.com> - 3.16.0-1
- Resolves: #1919223, rebase to 3.16.0
- Resolves: #1922195, Event Notification Support
- Resolves: #1959936, Soft token does not check if an EC key is valid
- Resolves: #1851104, import and export of secure key objects
- Resolves: #1851106, openCryptoki ep11 token: protected key support
- Resolves: #1851107, openCryptoki ep11 token: support attribute bound keys
* Thu Aug 19 2021 Than Ngo <than@redhat.com> - 3.16.0-10
- Resolves: #1987186, pkcstok_migrate leaves options with multiple strings in opencryptoki.conf options without double-quotes
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.16.0-9
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jul 28 2021 Florian Weimer <fweimer@redhat.com> - 3.16.0-8
- Rebuild to pick up OpenSSL 3.0 Beta ABI (#1984097)
* Fri Jul 16 2021 Than Ngo <than@redhat.com> - 3.16.0-7
- Resolves: #1974365, Fix detection if pkcsslotd is still running
* Fri Jun 25 2021 Than Ngo <than@redhat.com> - 3.16.0-6
- Resolves: #1974693, pkcsslotd PIDfile below legacy directory /var/run/
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.16.0-5
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Tue Jun 15 2021 Than Ngo <than@redhat.com> - 3.16.0-4
- Related: #1924120, add conditional requirement on new selinux-policy
* Mon May 17 2021 Than Ngo <than@redhat.com> - 3.16.0-3
- Resolves: #1959894, Soft token does not check if an EC key is valid
- Resolves: #1924120, Event Notification Support
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.16.0-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Wed Mar 31 2021 Dan Horák <dan[at]danny.cz> - 3.16.0-1
- Rebase to 3.16.0
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 3.15.1-6
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Fri Feb 12 2021 Than Ngo <than@redhat.com> - 3.15.1-5
- Resolves: #1928120, Fix problem with C_Get/SetOperationState and digest contexts
- Added upstream patch, a slot ID has nothing to do with the number of slots
* Fri Feb 12 2021 Than Ngo <than@redhat.com> - 3.15.1-4
- Resolves: #1927745, pkcscca migration fails with usr/sb2 is not a valid slot ID
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.15.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Thu Nov 26 2020 Than Ngo <than@redhat.com> - 3.15.1-3
- Resolves: #1902022
Fix compiling with c++
Added error message handling for p11sak remove-key command
* Tue Dec 22 2020 Than Ngo <than@redhat.com> - 3.15.1-3
- Drop tpm1.2 support by default
* Thu Nov 26 2020 Than Ngo <than@redhat.com> - 3.15.1-2
- Related: #1847433, Added error message handling for p11sak remove-key command
* Tue Dec 22 2020 Than Ngo <than@redhat.com> - 3.15.1-2
- Fix compiling with c++
- Added error message handling for p11sak remove-key command
- Add BR on make
* Mon Nov 02 2020 Than Ngo <than@redhat.com> - 3.15.1-1
- Related: #1847433
upstream fixes:
- Free generated key in all error cases
- CCA: Zeroize key buffer to avoid CCA 8/32 error
- Do not delete the map-btree entry if destroying an object is not allowed
- Remove now unused header timeb.h
- TESTCASES: Use FIPS conforming keys for 3DES CBC-MAC test vectors
- Fix buffer overrun in C_CopyObject
- TPM: Fix double free in openssl_gen_key
- Rebase to 3.15.1
* Mon Oct 19 2020 Than Ngo <than@redhat.com> - 3.15.0-1
- Resolves: #1847433, rebase to 3.15.0
- Resolves: #1851105, PKCS #11 3.0 - baseline provider support
- Resolves: #1851108, openCryptoki ep11 token: enhanced functionality
- Resolves: #1851109, openCryptoki key management tool: key deletion function
* Mon Oct 19 2020 Dan Horák <dan[at]danny.cz> - 3.15.0-1
- Rebase to 3.15.0
* Mon Jul 06 2020 Than Ngo <than@redhat.com> - 3.14.0-5
- Related: #1853420, more fixes
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.14.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jul 03 2020 Than Ngo <than@redhat.com> - 3.14.0-4
- Resolves: #1853420, endian issue
* Tue Jul 14 2020 Tom Stellard <tstellar@redhat.com> - 3.14.0-5
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Mon Jun 15 2020 Than Ngo <than@redhat.com> - 3.14.0-3
- Resolves: #1780294, PIN conversion tool
* Wed Jul 08 2020 Than Ngo <than@redhat.com> - 3.14.0-4
- added PIN conversion tool
* Tue May 26 2020 Than Ngo <than@redhat.com> - 3.14.0-2
- Related: #1780293, fix regression, segfault in C_SetPin
* Wed Jul 01 2020 Than Ngo <than@redhat.com> - 3.14.0-3
- upstream fix - handle early error cases in C_Initialize
* Tue May 19 2020 Than Ngo <than@redhat.com> - 3.14.0-1
- Resolves: #1723863 - ep11 token: Enhanced Support
- Resolves: #1780285 - ep11 token: Support for new IBM Z hardware z15
- Resolves: #1780293 - rebase to 3.14.0
- Resolves: #1800549 - key management tool: list keys function
-Resolves: #1800555 - key management tool: random key generation function
* Wed May 27 2020 Than Ngo <than@redhat.com> - 3.14.0-2
- fix regression, segfault in C_SetPin
* Fri Dec 13 2019 Than Ngo <than@redhat.com> - 3.12.1-2
- Resolves: #1782445, EP11: Fix EC-uncompress buffer length
* Fri May 15 2020 Dan Horák <dan[at]danny.cz> - 3.14.0-1
- Rebase to 3.14.0
* Thu Nov 28 2019 Than Ngo <than@redhat.com> - 3.12.1-1
- Resolves: #1777313, rebase to 3.12.1
* Fri Mar 06 2020 Dan Horák <dan[at]danny.cz> - 3.13.0-1
- Rebase to 3.13.0
* Tue Nov 12 2019 Than Ngo <than@redhat.com> - 3.12.0-1
- Resolves: #1726243, rebase to 3.12.0
* Mon Feb 03 2020 Dan Horák <dan[at]danny.cz> - 3.12.1-3
- fix build with gcc 10
* Mon Aug 26 2019 Dan Horák <dhorak@redhat.com> - 3.11.1-2
- Resolves: #1739433, ICA HW token missing after the package update
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.12.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon May 06 2019 Than Ngo <than@redhat.com> - 3.11.1-1
- Resolves: #1706140, rebase to 3.11.1
* Wed Nov 27 2019 Dan Horák <dan[at]danny.cz> - 3.12.1-1
- Rebase to 3.12.1
* Tue Mar 26 2019 Than Ngo <than@redhat.com> - 3.11.0-3
- Resolves: #1667941, 3des tests failures due to FIPS incompatible test scenarios
- Resolves: #1651731, ep11 token: enhanced IBM z14 functions
- Resolves: #1651732, ep11 token: support m_*Single functions from ep11 lib
- Resolves: #1525407, use CPACF hashes in ep11 token
- Resolves: #1651238, rebase to 3.11.0
- Resolves: #1682530, gating
* Wed Nov 13 2019 Dan Horák <dan[at]danny.cz> - 3.12.0-1
- Rebase to 3.12.0
* Fri Dec 14 2018 Than Ngo <than@redhat.com> - 3.10.0-3
- Resolves: #1657683, can't establish libica token in FIPS mode
- Resolves: #1652856, EP11 token fails when using Strict-Session mode or VHSM-Mode
* Sun Sep 22 2019 Dan Horák <dan[at]danny.cz> - 3.11.1-1
- Rebase to 3.11.1
* Thu Oct 25 2018 Than Ngo <than@redhat.com> - 3.10.0-2
- Resolves: #1602641, covscan
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.11.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Thu Mar 28 2019 Than Ngo <than@redhat.com> - 3.11.0-4
- enable testcase by default
- fix URL
* Tue Feb 19 2019 Than Ngo <than@redhat.com> - 3.11.0-3
- Resolved #1063763 - opencryptoki tools should inform the user that he is not in pkcs11 group
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.11.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Thu Jan 31 2019 Than Ngo <than@redhat.com> - 3.11.0-1
- Updated to 3.11.0
- Resolved #1341079 - Failed to create directory or subvolume "/var/lock/opencryptoki"
- Ported root's group membership's patch for 3.11.0
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.10.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jun 12 2018 Dan Horák <dan[at]danny.cz> - 3.10.0-1
- Rebase to 3.10.0