From a2c4b092dd7575e6c5948265b001372e85598c09 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 14 Nov 2023 12:56:23 -0500 Subject: [PATCH] Side-channel proofing PKCS#1 1.5 paths (Marvin) Signed-off-by: Simo Sorce --- src/asymmetric_cipher.c | 18 +++++++++++++++++- src/interface.c | 19 +++++++++++++++++++ src/interface.h | 6 ++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/asymmetric_cipher.c b/src/asymmetric_cipher.c index a4f33083..76be829c 100644 --- a/src/asymmetric_cipher.c +++ b/src/asymmetric_cipher.c @@ -296,12 +296,28 @@ static int p11prov_rsaenc_decrypt(void *ctx, unsigned char *out, size_t *outlen, goto endsess; } + /* Special handling against PKCS#1 1.5 side channel leaking */ + if (mechanism.mechanism == CKM_RSA_PKCS) { + ret = side_channel_free_Decrypt(encctx->provctx, sess, (void *)in, + inlen, out, &out_size); + /* the error case need to be handled in a side-channel free way, so + * conditionals ineed to be idempotent. Setting outlen unconditionally + * is fine because out_size is initialized to the value of outlen + * itself, and the value should not matter in an error condition */ + *outlen = out_size; + if (ret == CKR_OK) { + result = RET_OSSL_OK; + } else { + result = RET_OSSL_ERR; + } + goto endsess; + } + ret = p11prov_Decrypt(encctx->provctx, sess, (void *)in, inlen, out, &out_size); if (ret != CKR_OK) { goto endsess; } - *outlen = out_size; result = RET_OSSL_OK; diff --git a/src/interface.c b/src/interface.c index 6efa3173..77ef943a 100644 --- a/src/interface.c +++ b/src/interface.c @@ -450,3 +450,22 @@ CK_RV p11prov_module_reinit(P11PROV_MODULE *mctx) /* ------------- LOCKED SECTION */ return ret; } + +/* This is needed to avoid side channels in the PKCS 1.5 decryption case */ +CK_RV side_channel_free_Decrypt(P11PROV_CTX *ctx, CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen) +{ + P11PROV_INTERFACE *intf = p11prov_ctx_get_interface(ctx); + CK_RV ret = CKR_GENERAL_ERROR; + if (!intf) { + P11PROV_raise(ctx, ret, "Can't get module interfaces"); + return ret; + } + P11PROV_debug("Calling C_Decrypt"); + /* Must not add any conditionals based on return value, so we just return + * straight */ + return intf->Decrypt(hSession, pEncryptedData, ulEncryptedDataLen, pData, + pulDataLen); +} diff --git a/src/interface.h b/src/interface.h index 535b885f..37e835cf 100644 --- a/src/interface.h +++ b/src/interface.h @@ -127,4 +127,10 @@ CK_RV p11prov_SeedRandom(P11PROV_CTX *ctx, CK_SESSION_HANDLE hSession, CK_RV p11prov_GenerateRandom(P11PROV_CTX *ctx, CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen); +/* Special side-channel free path against PKCS#1 1.5 side channel leaking */ +CK_RV side_channel_free_Decrypt(P11PROV_CTX *ctx, CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen); + #endif /* _INTERFACE_H */