Skip to content

Commit e5810ba

Browse files
antoinelochetAntoine Lochet
authored andcommitted
Added ML-DSA hedge support
1 parent 7759bb1 commit e5810ba

File tree

14 files changed

+807
-69
lines changed

14 files changed

+807
-69
lines changed

.github/workflows/ci.yml

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

src/lib/SoftHSM.cpp

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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,48 @@ 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+
if (ckSignAdditionalContext->ulContextLen > 0)
4496+
{
4497+
if (ckSignAdditionalContext->pContext == NULL)
4498+
{
4499+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
4500+
return CKR_ARGUMENTS_BAD;
4501+
}
4502+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
4503+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
4504+
}
4505+
switch (ckSignAdditionalContext->hedgeVariant) {
4506+
case CKH_HEDGE_REQUIRED:
4507+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
4508+
break;
4509+
case CKH_DETERMINISTIC_REQUIRED:
4510+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
4511+
break;
4512+
case CKH_HEDGE_PREFERRED:
4513+
// Per PKCS11v3.2 section 6.67.5
4514+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
4515+
default:
4516+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
4517+
}
4518+
param = &additionalContext;
4519+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
4520+
}
4521+
}
44794522
break;
44804523
#endif
44814524
default:
@@ -5238,6 +5281,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
52385281
#endif
52395282
#ifdef WITH_ML_DSA
52405283
bool isMLDSA = false;
5284+
SIGN_ADDITIONAL_CONTEXT additionalContext;
52415285
#endif
52425286
switch(pMechanism->mechanism) {
52435287
case CKM_RSA_PKCS:
@@ -5508,6 +5552,46 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
55085552
mechanism = AsymMech::MLDSA;
55095553
bAllowMultiPartOp = false;
55105554
isMLDSA = true;
5555+
if (pMechanism->pParameter != NULL_PTR) {
5556+
if(pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT))
5557+
{
5558+
ERROR_MSG("Invalid parameters");
5559+
return CKR_ARGUMENTS_BAD;
5560+
}
5561+
else
5562+
{
5563+
const CK_SIGN_ADDITIONAL_CONTEXT* ckSignAdditionalContext = (const CK_SIGN_ADDITIONAL_CONTEXT*) pMechanism->pParameter;
5564+
if (ckSignAdditionalContext->ulContextLen > 255) {
5565+
ERROR_MSG("ML-DSA: Invalid parameters, context length > 255");
5566+
return CKR_ARGUMENTS_BAD;
5567+
}
5568+
5569+
if (ckSignAdditionalContext->ulContextLen > 0) {
5570+
if (ckSignAdditionalContext->pContext == NULL)
5571+
{
5572+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
5573+
return CKR_ARGUMENTS_BAD;
5574+
}
5575+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
5576+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
5577+
}
5578+
switch (ckSignAdditionalContext->hedgeVariant) {
5579+
case CKH_HEDGE_REQUIRED:
5580+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
5581+
break;
5582+
case CKH_DETERMINISTIC_REQUIRED:
5583+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
5584+
break;
5585+
// Per PKCS11v3.2 section 6.67.5
5586+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
5587+
case CKH_HEDGE_PREFERRED:
5588+
default:
5589+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
5590+
}
5591+
param = &additionalContext;
5592+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
5593+
}
5594+
}
55115595
break;
55125596
#endif
55135597
default:
@@ -10283,7 +10367,6 @@ CK_RV SoftHSM::generateMLDSA
1028310367
bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
1028410368

1028510369
// MLDSA Private Key Attributes
10286-
ByteString parameterSet;
1028710370
ByteString value;
1028810371
ByteString seed;
1028910372
if (isPrivateKeyPrivate)

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: 1 addition & 1 deletion
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()) {

0 commit comments

Comments
 (0)