Projects
Eulaceura:Mainline:GA
opencryptoki
_service:obs_scm:CVE-2024-0914-2.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2024-0914-2.patch of Package opencryptoki
From 7ffc0e135b4d923d686be536aa7bf69405a360a1 Mon Sep 17 00:00:00 2001 From: Ingo Franzki <ifranzki@linux.ibm.com> Date: Fri, 12 Jan 2024 09:36:27 +0100 Subject: [PATCH] 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> --- usr/lib/common/new_host.c | 39 ++++++++++++++++++++++---- usr/lib/ep11_stdll/ep11_specific.c | 30 ++++++++++++-------- usr/lib/ep11_stdll/new_host.c | 45 +++++++++++++++++++++++++----- usr/lib/icsf_stdll/new_host.c | 40 ++++++++++++++++++++++---- 4 files changed, 123 insertions(+), 31 deletions(-) diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c index 8a1e8723b..bbb0f6010 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 723eb3f63..e8543300a 100644 --- a/usr/lib/ep11_stdll/ep11_specific.c +++ b/usr/lib/ep11_stdll/ep11_specific.c @@ -9596,10 +9596,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: @@ -9655,10 +9657,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: @@ -9720,10 +9724,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 55e34c18f..299a1d3c3 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 6c419750d..d8064559d 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); }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2