Skip to content

Commit 16cffe0

Browse files
committed
Added ML-DSA hedge support
1 parent 38ef579 commit 16cffe0

20 files changed

+861
-91
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ jobs:
7676
make check || (find . -name test-suite.log -exec cat {} \; && false)
7777
7878
linux_ossl_35:
79-
name: Linux with OpenSSL 3.5.2
79+
name: Linux with OpenSSL 3.5.4
8080
runs-on: ubuntu-24.04
8181
steps:
8282
- uses: actions/checkout@v4
8383
- name: Prepare
8484
env:
85-
OPENSSL_VERSION: 3.5.2
85+
OPENSSL_VERSION: 3.5.4
8686
OPENSSL_INSTALL_DIR: /usr/local/openssl-3.5
8787
LDFLAGS: "-Wl,-rpath,/usr/local/openssl-3.5/lib64 -L/usr/local/openssl-3.5/lib64"
8888
PKG_CONFIG_PATH: "/usr/local/openssl-3.5/lib64/pkgconfig"
@@ -97,7 +97,7 @@ jobs:
9797
make -j$(nproc) > build.log
9898
sudo make install > install.log
9999
cd ${{ env.OPENSSL_INSTALL_DIR }}
100-
sudo ln -s lib64 lib
100+
sudo ln -sf lib64 lib
101101
- name: Build
102102
env:
103103
# Once all OpenSSL deprecations fixed, uncomment this

src/lib/SoftHSM.cpp

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ void SoftHSM::prepareSupportedMechanisms(std::map<std::string, CK_MECHANISM_TYPE
884884
else
885885
supportedMechanisms.remove(mechanism);
886886
}
887-
catch (const std::out_of_range& e)
887+
catch (const std::out_of_range&)
888888
{
889889
WARNING_MSG("Unknown mechanism provided: %s", token.c_str());
890890
}
@@ -4204,6 +4204,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
42044204
#endif
42054205
#ifdef WITH_ML_DSA
42064206
bool isMLDSA = false;
4207+
SIGN_ADDITIONAL_CONTEXT additionalContext = {};
42074208
#endif
42084209
switch(pMechanism->mechanism) {
42094210
case CKM_RSA_PKCS:
@@ -4476,6 +4477,51 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
44764477
mechanism = AsymMech::MLDSA;
44774478
bAllowMultiPartOp = false;
44784479
isMLDSA = true;
4480+
if (pMechanism->pParameter != NULL_PTR) {
4481+
if(pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT))
4482+
{
4483+
ERROR_MSG("Invalid parameters");
4484+
return CKR_ARGUMENTS_BAD;
4485+
}
4486+
else
4487+
{
4488+
const CK_SIGN_ADDITIONAL_CONTEXT* ckSignAdditionalContext = (const CK_SIGN_ADDITIONAL_CONTEXT*) pMechanism->pParameter;
4489+
if (ckSignAdditionalContext->ulContextLen > 255)
4490+
{
4491+
ERROR_MSG("ML-DSA: Invalid parameters, context length > 255");
4492+
return CKR_ARGUMENTS_BAD;
4493+
}
4494+
4495+
// Always initialize context fields
4496+
additionalContext.contextAsChar = NULL;
4497+
additionalContext.contextLength = 0;
4498+
if (ckSignAdditionalContext->ulContextLen > 0)
4499+
{
4500+
if (ckSignAdditionalContext->pContext == NULL)
4501+
{
4502+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
4503+
return CKR_ARGUMENTS_BAD;
4504+
}
4505+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
4506+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
4507+
}
4508+
switch (ckSignAdditionalContext->hedgeVariant) {
4509+
case CKH_HEDGE_REQUIRED:
4510+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
4511+
break;
4512+
case CKH_DETERMINISTIC_REQUIRED:
4513+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
4514+
break;
4515+
case CKH_HEDGE_PREFERRED:
4516+
// Per PKCS11v3.2 section 6.67.5
4517+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
4518+
default:
4519+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
4520+
}
4521+
param = &additionalContext;
4522+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
4523+
}
4524+
}
44794525
break;
44804526
#endif
44814527
default:
@@ -5238,6 +5284,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
52385284
#endif
52395285
#ifdef WITH_ML_DSA
52405286
bool isMLDSA = false;
5287+
SIGN_ADDITIONAL_CONTEXT additionalContext = {};
52415288
#endif
52425289
switch(pMechanism->mechanism) {
52435290
case CKM_RSA_PKCS:
@@ -5508,6 +5555,49 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
55085555
mechanism = AsymMech::MLDSA;
55095556
bAllowMultiPartOp = false;
55105557
isMLDSA = true;
5558+
if (pMechanism->pParameter != NULL_PTR) {
5559+
if(pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT))
5560+
{
5561+
ERROR_MSG("Invalid parameters");
5562+
return CKR_ARGUMENTS_BAD;
5563+
}
5564+
else
5565+
{
5566+
const CK_SIGN_ADDITIONAL_CONTEXT* ckSignAdditionalContext = (const CK_SIGN_ADDITIONAL_CONTEXT*) pMechanism->pParameter;
5567+
if (ckSignAdditionalContext->ulContextLen > 255) {
5568+
ERROR_MSG("ML-DSA: Invalid parameters, context length > 255");
5569+
return CKR_ARGUMENTS_BAD;
5570+
}
5571+
// Always initialize context fields
5572+
additionalContext.contextAsChar = NULL;
5573+
additionalContext.contextLength = 0;
5574+
if (ckSignAdditionalContext->ulContextLen > 0) {
5575+
if (ckSignAdditionalContext->pContext == NULL)
5576+
{
5577+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
5578+
return CKR_ARGUMENTS_BAD;
5579+
}
5580+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
5581+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
5582+
}
5583+
5584+
switch (ckSignAdditionalContext->hedgeVariant) {
5585+
case CKH_HEDGE_REQUIRED:
5586+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
5587+
break;
5588+
case CKH_DETERMINISTIC_REQUIRED:
5589+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
5590+
break;
5591+
// Per PKCS11v3.2 section 6.67.5
5592+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
5593+
case CKH_HEDGE_PREFERRED:
5594+
default:
5595+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
5596+
}
5597+
param = &additionalContext;
5598+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
5599+
}
5600+
}
55115601
break;
55125602
#endif
55135603
default:
@@ -10283,7 +10373,6 @@ CK_RV SoftHSM::generateMLDSA
1028310373
bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
1028410374

1028510375
// MLDSA Private Key Attributes
10286-
ByteString parameterSet;
1028710376
ByteString value;
1028810377
ByteString seed;
1028910378
if (isPrivateKeyPrivate)

src/lib/SoftHSM.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@
5252
#include "DHPrivateKey.h"
5353
#include "GOSTPublicKey.h"
5454
#include "GOSTPrivateKey.h"
55-
#ifdef WITH_ML_DSA
56-
#include "MLDSAPublicKey.h"
57-
#include "MLDSAPrivateKey.h"
58-
#endif
5955

6056
#include <memory>
6157

src/lib/crypto/AsymmetricAlgorithm.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ struct RSA_PKCS_PSS_PARAMS
118118
size_t sLen;
119119
};
120120

121+
struct Hedge
122+
{
123+
enum Type
124+
{
125+
HEDGE_PREFERRED,
126+
HEDGE_REQUIRED,
127+
DETERMINISTIC_REQUIRED
128+
};
129+
};
130+
131+
struct SIGN_ADDITIONAL_CONTEXT
132+
{
133+
Hedge::Type hedgeType;
134+
const unsigned char* contextAsChar;
135+
size_t contextLength;
136+
137+
// Prevent shallow copies (Session::setParameters handles deep-copy)
138+
SIGN_ADDITIONAL_CONTEXT(const SIGN_ADDITIONAL_CONTEXT&) = delete;
139+
SIGN_ADDITIONAL_CONTEXT& operator=(const SIGN_ADDITIONAL_CONTEXT&) = delete;
140+
141+
SIGN_ADDITIONAL_CONTEXT():
142+
hedgeType(Hedge::Type::HEDGE_PREFERRED),
143+
contextAsChar(NULL),
144+
contextLength(0){}
145+
SIGN_ADDITIONAL_CONTEXT(Hedge::Type hedgeType):
146+
hedgeType(hedgeType),
147+
contextAsChar(NULL),
148+
contextLength(0){}
149+
SIGN_ADDITIONAL_CONTEXT(Hedge::Type hedgeType, const unsigned char* contextAsChar, size_t contextLength):
150+
hedgeType(hedgeType),
151+
contextAsChar(contextAsChar),
152+
contextLength(contextLength){}
153+
};
154+
121155
class AsymmetricAlgorithm
122156
{
123157
public:

src/lib/crypto/MLDSAPrivateKey.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ unsigned long MLDSAPrivateKey::getBitLength() const
2424
return getValue().bits();
2525
}
2626

27-
// Get the bit length
27+
// Get the parameter set
2828
unsigned long MLDSAPrivateKey::getParameterSet() const
2929
{
3030
switch(value.size()) {
@@ -81,17 +81,17 @@ ByteString MLDSAPrivateKey::serialise() const
8181

8282
bool MLDSAPrivateKey::deserialise(ByteString& serialised)
8383
{
84-
ByteString seed = ByteString::chainDeserialise(serialised);
85-
ByteString value = ByteString::chainDeserialise(serialised);
84+
ByteString deserializedSeed = ByteString::chainDeserialise(serialised);
85+
ByteString deserializedValue = ByteString::chainDeserialise(serialised);
8686

87-
if ((seed.size() == 0) ||
88-
(value.size() == 0))
87+
if ((deserializedSeed.size() == 0) ||
88+
(deserializedValue.size() == 0))
8989
{
9090
return false;
9191
}
9292

93-
setSeed(seed);
94-
setValue(value);
93+
setSeed(deserializedSeed);
94+
setValue(deserializedValue);
9595

9696
return true;
9797
}

src/lib/crypto/MLDSAPublicKey.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ ByteString MLDSAPublicKey::serialise() const
7070

7171
bool MLDSAPublicKey::deserialise(ByteString& serialised)
7272
{
73-
ByteString value = ByteString::chainDeserialise(serialised);
73+
ByteString deserializedValue = ByteString::chainDeserialise(serialised);
7474

75-
if ((value.size() == 0))
75+
if ((deserializedValue.size() == 0))
7676
{
7777
return false;
7878
}
7979

80-
setValue(value);
80+
setValue(deserializedValue);
8181

8282
return true;
8383
}

src/lib/crypto/MLDSAPublicKey.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class MLDSAPublicKey : public PublicKey
2020
// Check if the key is of the given type
2121
virtual bool isOfType(const char* inType);
2222

23-
// Get the bit length
23+
// Get the parameter set
2424
virtual unsigned long getParameterSet() const;
2525

2626
// Get the signature length

src/lib/crypto/MLDSAUtil.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ class MLDSAUtil
2626
static bool setMLDSAPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate);
2727
};
2828

29-
#endif // !_SOFTHSM_V2_MLDSAUTIL_H
30-
#endif
29+
#endif // WITH_ML_DSA
30+
#endif // !_SOFTHSM_V2_MLDSAUTIL_H

0 commit comments

Comments
 (0)