opencryptoki/opencryptoki-3.23-SEC2356-b...

223 lines
9.2 KiB
Diff

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];