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

307 lines
14 KiB
Diff

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