From d3ae3b9936d6487108d5129c8da0e2d7535eb3d1 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 | 14 +++++++++++++- src/interface.c | 18 ++++++++++++++++++ src/interface.h | 5 +++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/asymmetric_cipher.c b/src/asymmetric_cipher.c index a4f33083..c0243e3b 100644 --- a/src/asymmetric_cipher.c +++ b/src/asymmetric_cipher.c @@ -296,12 +296,24 @@ 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 + * no conditionals here. Setting outlen is fine because out_size is + * initialized to the value of outlen itself, and the value should + * not matter in an error condition anyway */ + *outlen = out_size; + result = ret; + 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..cd4e9891 100644 --- a/src/interface.c +++ b/src/interface.c @@ -450,3 +450,21 @@ 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..0d0b52bc 100644 --- a/src/interface.h +++ b/src/interface.h @@ -127,4 +127,9 @@ 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 */