Skip to content

Commit 6f0d417

Browse files
antoinelochetAntoine Lochet
authored andcommitted
Added sign/verify tests with test vectors
Added ML-DSA hedge support
1 parent 24a8aae commit 6f0d417

20 files changed

Lines changed: 1147 additions & 91 deletions

.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
}
@@ -4195,6 +4195,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
41954195
#endif
41964196
#ifdef WITH_ML_DSA
41974197
bool isMLDSA = false;
4198+
SIGN_ADDITIONAL_CONTEXT additionalContext = {};
41984199
#endif
41994200
switch(pMechanism->mechanism) {
42004201
case CKM_RSA_PKCS:
@@ -4467,6 +4468,51 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
44674468
mechanism = AsymMech::MLDSA;
44684469
bAllowMultiPartOp = false;
44694470
isMLDSA = true;
4471+
if (pMechanism->pParameter != NULL_PTR) {
4472+
if(pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT))
4473+
{
4474+
ERROR_MSG("Invalid parameters");
4475+
return CKR_ARGUMENTS_BAD;
4476+
}
4477+
else
4478+
{
4479+
const CK_SIGN_ADDITIONAL_CONTEXT* ckSignAdditionalContext = (const CK_SIGN_ADDITIONAL_CONTEXT*) pMechanism->pParameter;
4480+
if (ckSignAdditionalContext->ulContextLen > 255)
4481+
{
4482+
ERROR_MSG("ML-DSA: Invalid parameters, context length > 255");
4483+
return CKR_ARGUMENTS_BAD;
4484+
}
4485+
4486+
// Always initialize context fields
4487+
additionalContext.contextAsChar = NULL;
4488+
additionalContext.contextLength = 0;
4489+
if (ckSignAdditionalContext->ulContextLen > 0)
4490+
{
4491+
if (ckSignAdditionalContext->pContext == NULL)
4492+
{
4493+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
4494+
return CKR_ARGUMENTS_BAD;
4495+
}
4496+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
4497+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
4498+
}
4499+
switch (ckSignAdditionalContext->hedgeVariant) {
4500+
case CKH_HEDGE_REQUIRED:
4501+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
4502+
break;
4503+
case CKH_DETERMINISTIC_REQUIRED:
4504+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
4505+
break;
4506+
case CKH_HEDGE_PREFERRED:
4507+
// Per PKCS11v3.2 section 6.67.5
4508+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
4509+
default:
4510+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
4511+
}
4512+
param = &additionalContext;
4513+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
4514+
}
4515+
}
44704516
break;
44714517
#endif
44724518
default:
@@ -5229,6 +5275,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
52295275
#endif
52305276
#ifdef WITH_ML_DSA
52315277
bool isMLDSA = false;
5278+
SIGN_ADDITIONAL_CONTEXT additionalContext = {};
52325279
#endif
52335280
switch(pMechanism->mechanism) {
52345281
case CKM_RSA_PKCS:
@@ -5499,6 +5546,49 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
54995546
mechanism = AsymMech::MLDSA;
55005547
bAllowMultiPartOp = false;
55015548
isMLDSA = true;
5549+
if (pMechanism->pParameter != NULL_PTR) {
5550+
if(pMechanism->ulParameterLen != sizeof(CK_SIGN_ADDITIONAL_CONTEXT))
5551+
{
5552+
ERROR_MSG("Invalid parameters");
5553+
return CKR_ARGUMENTS_BAD;
5554+
}
5555+
else
5556+
{
5557+
const CK_SIGN_ADDITIONAL_CONTEXT* ckSignAdditionalContext = (const CK_SIGN_ADDITIONAL_CONTEXT*) pMechanism->pParameter;
5558+
if (ckSignAdditionalContext->ulContextLen > 255) {
5559+
ERROR_MSG("ML-DSA: Invalid parameters, context length > 255");
5560+
return CKR_ARGUMENTS_BAD;
5561+
}
5562+
// Always initialize context fields
5563+
additionalContext.contextAsChar = NULL;
5564+
additionalContext.contextLength = 0;
5565+
if (ckSignAdditionalContext->ulContextLen > 0) {
5566+
if (ckSignAdditionalContext->pContext == NULL)
5567+
{
5568+
ERROR_MSG("ML-DSA: Invalid parameters, pContext is NULL");
5569+
return CKR_ARGUMENTS_BAD;
5570+
}
5571+
additionalContext.contextAsChar = (unsigned char*) ckSignAdditionalContext->pContext;
5572+
additionalContext.contextLength = ckSignAdditionalContext->ulContextLen;
5573+
}
5574+
5575+
switch (ckSignAdditionalContext->hedgeVariant) {
5576+
case CKH_HEDGE_REQUIRED:
5577+
additionalContext.hedgeType = Hedge::HEDGE_REQUIRED;
5578+
break;
5579+
case CKH_DETERMINISTIC_REQUIRED:
5580+
additionalContext.hedgeType = Hedge::DETERMINISTIC_REQUIRED;
5581+
break;
5582+
// Per PKCS11v3.2 section 6.67.5
5583+
// "If no parameter is supplied the hedgeVariant will be CKH_HEDGE_PREFERRED"
5584+
case CKH_HEDGE_PREFERRED:
5585+
default:
5586+
additionalContext.hedgeType = Hedge::HEDGE_PREFERRED;
5587+
}
5588+
param = &additionalContext;
5589+
paramLen = sizeof(SIGN_ADDITIONAL_CONTEXT);
5590+
}
5591+
}
55025592
break;
55035593
#endif
55045594
default:
@@ -10274,7 +10364,6 @@ CK_RV SoftHSM::generateMLDSA
1027410364
bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
1027510365

1027610366
// MLDSA Private Key Attributes
10277-
ByteString parameterSet;
1027810367
ByteString value;
1027910368
ByteString seed;
1028010369
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)