Skip to content

Commit 1c5e45a

Browse files
Antoine LochetAntoine Lochet
authored andcommitted
Pulled PR softhsm#583 for more RSA OAEP algorithms support
1 parent 5d72ff4 commit 1c5e45a

File tree

9 files changed

+346
-92
lines changed

9 files changed

+346
-92
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ SoftHSM depends on a cryptographic library, Botan or OpenSSL.
3737
Minimum required versions:
3838

3939
- Botan 2.0.0
40-
- OpenSSL 1.0.0
40+
- OpenSSL 1.0.2
4141

4242
If you are using Botan, use at least version 2.6.0. This will improve
4343
the performance when doing public key operations.

m4/acx_crypto_backend.m4

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ AC_DEFUN([ACX_CRYPTO_BACKEND],[
7575
AC_MSG_RESULT(OpenSSL)
7676
7777
if test "x${enable_fips}" = "xyes"; then
78-
ACX_OPENSSL(1,0,1)
78+
# needed for FIPS compliance, so change only when FIPS requirements change
79+
ACX_OPENSSL(1,0,2)
7980
else
80-
ACX_OPENSSL(1,0,0)
81+
# increase this as features from newer versions needed
82+
ACX_OPENSSL(1,0,2)
8183
fi
8284
8385
CRYPTO_INCLUDES=$OPENSSL_INCLUDES

src/lib/SoftHSM.cpp

Lines changed: 156 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,6 +2670,7 @@ CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
26702670

26712671
// Get the asymmetric algorithm matching the mechanism
26722672
AsymMech::Type mechanism;
2673+
unsigned long expectedMgf;
26732674
bool isRSA = false;
26742675
switch(pMechanism->mechanism) {
26752676
case CKM_RSA_PKCS:
@@ -2691,7 +2692,37 @@ CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
26912692
if (rv != CKR_OK)
26922693
return rv;
26932694

2694-
mechanism = AsymMech::RSA_PKCS_OAEP;
2695+
switch(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
2696+
case CKM_SHA_1:
2697+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA1;
2698+
expectedMgf = CKG_MGF1_SHA1;
2699+
break;
2700+
case CKM_SHA224:
2701+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA224;
2702+
expectedMgf = CKG_MGF1_SHA224;
2703+
break;
2704+
case CKM_SHA256:
2705+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA256;
2706+
expectedMgf = CKG_MGF1_SHA256;
2707+
break;
2708+
case CKM_SHA384:
2709+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA384;
2710+
expectedMgf = CKG_MGF1_SHA384;
2711+
break;
2712+
case CKM_SHA512:
2713+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA512;
2714+
expectedMgf = CKG_MGF1_SHA512;
2715+
break;
2716+
default:
2717+
DEBUG_MSG("hashAlg must be one of: CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512");
2718+
return CKR_ARGUMENTS_BAD;
2719+
}
2720+
2721+
if(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != expectedMgf) {
2722+
ERROR_MSG("Hash and MGF don't match");
2723+
return CKR_ARGUMENTS_BAD;
2724+
}
2725+
26952726
isRSA = true;
26962727
break;
26972728
default:
@@ -3457,6 +3488,7 @@ CK_RV SoftHSM::AsymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
34573488

34583489
// Get the asymmetric algorithm matching the mechanism
34593490
AsymMech::Type mechanism = AsymMech::Unknown;
3491+
unsigned long expectedMgf;
34603492
bool isRSA = false;
34613493
switch(pMechanism->mechanism) {
34623494
case CKM_RSA_PKCS:
@@ -3480,18 +3512,38 @@ CK_RV SoftHSM::AsymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMec
34803512
DEBUG_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS");
34813513
return CKR_ARGUMENTS_BAD;
34823514
}
3483-
if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1)
3484-
{
3485-
DEBUG_MSG("hashAlg must be CKM_SHA_1");
3486-
return CKR_ARGUMENTS_BAD;
3515+
3516+
switch(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
3517+
case CKM_SHA_1:
3518+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA1;
3519+
expectedMgf = CKG_MGF1_SHA1;
3520+
break;
3521+
case CKM_SHA224:
3522+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA224;
3523+
expectedMgf = CKG_MGF1_SHA224;
3524+
break;
3525+
case CKM_SHA256:
3526+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA256;
3527+
expectedMgf = CKG_MGF1_SHA256;
3528+
break;
3529+
case CKM_SHA384:
3530+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA384;
3531+
expectedMgf = CKG_MGF1_SHA384;
3532+
break;
3533+
case CKM_SHA512:
3534+
mechanism = AsymMech::RSA_PKCS_OAEP_SHA512;
3535+
expectedMgf = CKG_MGF1_SHA512;
3536+
break;
3537+
default:
3538+
DEBUG_MSG("hashAlg must be one of: CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512");
3539+
return CKR_ARGUMENTS_BAD;
34873540
}
3488-
if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1)
3489-
{
3490-
DEBUG_MSG("mgf must be CKG_MGF1_SHA1");
3541+
3542+
if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != expectedMgf) {
3543+
ERROR_MSG("Hash and MGF don't match");
34913544
return CKR_ARGUMENTS_BAD;
34923545
}
34933546

3494-
mechanism = AsymMech::RSA_PKCS_OAEP;
34953547
isRSA = true;
34963548
break;
34973549
default:
@@ -4424,7 +4476,7 @@ CK_RV SoftHSM::MacSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechani
44244476

44254477
CK_RV SoftHSM::GmacSignInit(Token* token, Session* session, CK_MECHANISM_PTR pMechanism, OSObject *key)
44264478
{
4427-
4479+
44284480
// Get key info
44294481
CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
44304482

@@ -4477,7 +4529,7 @@ CK_RV SoftHSM::GmacSignInit(Token* token, Session* session, CK_MECHANISM_PTR pMe
44774529
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
44784530
return CKR_MECHANISM_INVALID;
44794531
}
4480-
4532+
44814533
session->setOpType(SESSION_OP_SIGN);
44824534
session->setSymmetricCryptoOp(cipher);
44834535
session->setAllowMultiPartOp(false);
@@ -4539,7 +4591,7 @@ CK_RV SoftHSM::GmacVerifyInit(Token* token, Session* session, CK_MECHANISM_PTR p
45394591
CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
45404592
return CKR_MECHANISM_INVALID;
45414593
}
4542-
4594+
45434595
session->setOpType(SESSION_OP_VERIFY);
45444596
session->setSymmetricCryptoOp(cipher);
45454597
session->setAllowMultiPartOp(false);
@@ -5102,7 +5154,7 @@ static CK_RV GmacSign(Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pul
51025154
*pulSignatureLen = maxSize;
51035155
return CKR_BUFFER_TOO_SMALL;
51045156
}
5105-
5157+
51065158
// Finalize encryption
51075159
ByteString encryptedData;
51085160
if (!cipher->encryptFinal(encryptedData))
@@ -5205,7 +5257,7 @@ CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ul
52055257
if (mockReturnCode != CKR_OK) {
52065258
return mockErrorCode;
52075259
}
5208-
5260+
52095261
// Get the session
52105262
Session* session = (Session*)handleManager->getSession(hSession);
52115263
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
@@ -5215,7 +5267,7 @@ CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ul
52155267
if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
52165268
if (pulSignatureLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
52175269
}
5218-
5270+
52195271
// Check if we are doing the correct operation
52205272
if (session->getOpType() != SESSION_OP_SIGN)
52215273
return CKR_OPERATION_NOT_INITIALIZED;
@@ -6245,7 +6297,7 @@ CK_RV SoftHSM::C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG
62456297
return mockErrorCode;
62466298
}
62476299

6248-
6300+
62496301
// Get the session
62506302
Session* session = (Session*)handleManager->getSession(hSession);
62516303
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
@@ -7085,6 +7137,7 @@ CK_RV SoftHSM::WrapKeyAsym
70857137
const size_t bb = 8;
70867138
AsymAlgo::Type algo = AsymAlgo::Unknown;
70877139
AsymMech::Type mech = AsymMech::Unknown;
7140+
unsigned long expectedMgf;
70887141

70897142
CK_ULONG modulus_length;
70907143
switch(pMechanism->mechanism) {
@@ -7111,11 +7164,51 @@ CK_RV SoftHSM::WrapKeyAsym
71117164
break;
71127165

71137166
case CKM_RSA_PKCS_OAEP:
7114-
mech = AsymMech::RSA_PKCS_OAEP;
7115-
// SHA-1 is the only supported option
7116-
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7117-
if (keydata.size() > modulus_length - 2 - 2 * 160 / 8)
7118-
return CKR_KEY_SIZE_RANGE;
7167+
switch(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
7168+
case CKM_SHA_1:
7169+
mech = AsymMech::RSA_PKCS_OAEP_SHA1;
7170+
expectedMgf = CKG_MGF1_SHA1;
7171+
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7172+
if (keydata.size() > modulus_length - 2 - 2 * 160 / 8)
7173+
return CKR_KEY_SIZE_RANGE;
7174+
break;
7175+
case CKM_SHA224:
7176+
mech = AsymMech::RSA_PKCS_OAEP_SHA224;
7177+
expectedMgf = CKG_MGF1_SHA224;
7178+
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7179+
if (keydata.size() > modulus_length - 2 - 2 * 224 / 8)
7180+
return CKR_KEY_SIZE_RANGE;
7181+
break;
7182+
case CKM_SHA256:
7183+
mech = AsymMech::RSA_PKCS_OAEP_SHA256;
7184+
expectedMgf = CKG_MGF1_SHA256;
7185+
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7186+
if (keydata.size() > modulus_length - 2 - 2 * 256 / 8)
7187+
return CKR_KEY_SIZE_RANGE;
7188+
break;
7189+
case CKM_SHA384:
7190+
mech = AsymMech::RSA_PKCS_OAEP_SHA384;
7191+
expectedMgf = CKG_MGF1_SHA384;
7192+
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7193+
if (keydata.size() > modulus_length - 2 - 2 * 384 / 8)
7194+
return CKR_KEY_SIZE_RANGE;
7195+
break;
7196+
case CKM_SHA512:
7197+
mech = AsymMech::RSA_PKCS_OAEP_SHA512;
7198+
expectedMgf = CKG_MGF1_SHA512;
7199+
// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
7200+
if (keydata.size() > modulus_length - 2 - 2 * 512 / 8)
7201+
return CKR_KEY_SIZE_RANGE;
7202+
break;
7203+
default:
7204+
return CKR_MECHANISM_INVALID;
7205+
}
7206+
7207+
if(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != expectedMgf) {
7208+
ERROR_MSG("Hash and MGF don't match");
7209+
return CKR_ARGUMENTS_BAD;
7210+
}
7211+
71197212
break;
71207213

71217214
default:
@@ -7678,6 +7771,7 @@ CK_RV SoftHSM::UnwrapKeyAsym
76787771
// Get the symmetric algorithm matching the mechanism
76797772
AsymAlgo::Type algo = AsymAlgo::Unknown;
76807773
AsymMech::Type mode = AsymMech::Unknown;
7774+
unsigned long expectedMgf;
76817775
switch(pMechanism->mechanism) {
76827776
case CKM_RSA_PKCS:
76837777
algo = AsymAlgo::RSA;
@@ -7686,7 +7780,35 @@ CK_RV SoftHSM::UnwrapKeyAsym
76867780

76877781
case CKM_RSA_PKCS_OAEP:
76887782
algo = AsymAlgo::RSA;
7689-
mode = AsymMech::RSA_PKCS_OAEP;
7783+
switch(CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
7784+
case CKM_SHA_1:
7785+
mode = AsymMech::RSA_PKCS_OAEP_SHA1;
7786+
expectedMgf = CKG_MGF1_SHA1;
7787+
break;
7788+
case CKM_SHA224:
7789+
mode = AsymMech::RSA_PKCS_OAEP_SHA224;
7790+
expectedMgf = CKG_MGF1_SHA224;
7791+
break;
7792+
case CKM_SHA256:
7793+
mode = AsymMech::RSA_PKCS_OAEP_SHA256;
7794+
expectedMgf = CKG_MGF1_SHA256;
7795+
break;
7796+
case CKM_SHA384:
7797+
mode = AsymMech::RSA_PKCS_OAEP_SHA384;
7798+
expectedMgf = CKG_MGF1_SHA384;
7799+
break;
7800+
case CKM_SHA512:
7801+
mode = AsymMech::RSA_PKCS_OAEP_SHA512;
7802+
expectedMgf = CKG_MGF1_SHA512;
7803+
break;
7804+
default:
7805+
return CKR_MECHANISM_INVALID;
7806+
}
7807+
7808+
if (CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != expectedMgf) {
7809+
ERROR_MSG("Hash and MGF don't match");
7810+
return CKR_ARGUMENTS_BAD;
7811+
}
76907812
break;
76917813

76927814
default:
@@ -13994,14 +14116,22 @@ CK_RV SoftHSM::MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism)
1399414116
}
1399514117

1399614118
CK_RSA_PKCS_OAEP_PARAMS_PTR params = (CK_RSA_PKCS_OAEP_PARAMS_PTR)pMechanism->pParameter;
13997-
if (params->hashAlg != CKM_SHA_1)
14119+
if (params->hashAlg != CKM_SHA_1 &&
14120+
params->hashAlg != CKM_SHA224 &&
14121+
params->hashAlg != CKM_SHA256 &&
14122+
params->hashAlg != CKM_SHA384 &&
14123+
params->hashAlg != CKM_SHA512)
1399814124
{
13999-
ERROR_MSG("hashAlg must be CKM_SHA_1");
14125+
ERROR_MSG("hashAlg must be one of: CKM_SHA_1, CKM_SHA224, CKM_SHA256, CKM_SHA384, CKM_SHA512");
1400014126
return CKR_ARGUMENTS_BAD;
1400114127
}
14002-
if (params->mgf != CKG_MGF1_SHA1)
14128+
if (params->mgf != CKG_MGF1_SHA1 &&
14129+
params->mgf != CKG_MGF1_SHA224 &&
14130+
params->mgf != CKG_MGF1_SHA256 &&
14131+
params->mgf != CKG_MGF1_SHA384 &&
14132+
params->mgf != CKG_MGF1_SHA512)
1400314133
{
14004-
ERROR_MSG("mgf must be CKG_MGF1_SHA1");
14134+
ERROR_MSG("mgf must be onf of: CKG_MGF1_SHA1, CKM_MGF1_SHA224, CKM_MGF1_SHA256, CKM_MGF1_SHA384, CKM_MGF1_SHA512");
1400514135
return CKR_ARGUMENTS_BAD;
1400614136
}
1400714137
if (params->source != CKZ_DATA_SPECIFIED)

src/lib/crypto/AsymmetricAlgorithm.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ bool AsymmetricAlgorithm::isWrappingMech(AsymMech::Type padding)
152152
{
153153
case AsymMech::RSA:
154154
case AsymMech::RSA_PKCS:
155-
case AsymMech::RSA_PKCS_OAEP:
155+
case AsymMech::RSA_PKCS_OAEP_SHA1:
156+
case AsymMech::RSA_PKCS_OAEP_SHA224:
157+
case AsymMech::RSA_PKCS_OAEP_SHA256:
158+
case AsymMech::RSA_PKCS_OAEP_SHA384:
159+
case AsymMech::RSA_PKCS_OAEP_SHA512:
156160
return true;
157161

158162
default:

src/lib/crypto/AsymmetricAlgorithm.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ struct AsymMech
6565
RSA,
6666
RSA_MD5_PKCS,
6767
RSA_PKCS,
68-
RSA_PKCS_OAEP,
68+
RSA_PKCS_OAEP_SHA1,
69+
RSA_PKCS_OAEP_SHA224,
70+
RSA_PKCS_OAEP_SHA256,
71+
RSA_PKCS_OAEP_SHA384,
72+
RSA_PKCS_OAEP_SHA512,
6973
RSA_SHA1_PKCS,
7074
RSA_SHA224_PKCS,
7175
RSA_SHA256_PKCS,

src/lib/crypto/BotanRSA.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,20 @@ bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data,
761761
case AsymMech::RSA_PKCS:
762762
eme = "PKCS1v15";
763763
break;
764-
case AsymMech::RSA_PKCS_OAEP:
765-
eme = "EME1(SHA-160)";
764+
case AsymMech::RSA_PKCS_OAEP_SHA1:
765+
eme = "EME1(SHA-1)";
766+
break;
767+
case AsymMech::RSA_PKCS_OAEP_SHA224:
768+
eme = "EME1(SHA-224)";
769+
break;
770+
case AsymMech::RSA_PKCS_OAEP_SHA256:
771+
eme = "EME1(SHA-256)";
772+
break;
773+
case AsymMech::RSA_PKCS_OAEP_SHA384:
774+
eme = "EME1(SHA-384)";
775+
break;
776+
case AsymMech::RSA_PKCS_OAEP_SHA512:
777+
eme = "EME1(SHA-512)";
766778
break;
767779
case AsymMech::RSA:
768780
eme = "Raw";
@@ -855,8 +867,20 @@ bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
855867
case AsymMech::RSA_PKCS:
856868
eme = "PKCS1v15";
857869
break;
858-
case AsymMech::RSA_PKCS_OAEP:
859-
eme = "EME1(SHA-160)";
870+
case AsymMech::RSA_PKCS_OAEP_SHA1:
871+
eme = "EME1(SHA-1)";
872+
break;
873+
case AsymMech::RSA_PKCS_OAEP_SHA224:
874+
eme = "EME1(SHA-224)";
875+
break;
876+
case AsymMech::RSA_PKCS_OAEP_SHA256:
877+
eme = "EME1(SHA-256)";
878+
break;
879+
case AsymMech::RSA_PKCS_OAEP_SHA384:
880+
eme = "EME1(SHA-384)";
881+
break;
882+
case AsymMech::RSA_PKCS_OAEP_SHA512:
883+
eme = "EME1(SHA-512)";
860884
break;
861885
case AsymMech::RSA:
862886
eme = "Raw";

0 commit comments

Comments
 (0)