Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/bin/util/softhsm2-util-botan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ eddsa_key_material_t* crypto_malloc_eddsa
return NULL;
}

eddsa_key_material_t* keyMat = (eddsa_key_material_t*)malloc(sizeof(eddsa_key_material_t));
eddsa_key_material_t* keyMat = (eddsa_key_material_t*)calloc(1, sizeof(eddsa_key_material_t));
if (keyMat == NULL)
{
return NULL;
Expand All @@ -848,13 +848,13 @@ eddsa_key_material_t* crypto_malloc_eddsa
if (ed25519) oid = Botan::OIDS::lookup("Ed25519");
if (oid.empty())
{
crypto_free_eddsa(keyMat);
return NULL;
}

Botan::secure_vector<Botan::byte> derOID;
derOID = Botan::DER_Encoder().encode(oid).get_contents();

memset(keyMat, 0, sizeof(*keyMat));
keyMat->sizeOID = derOID.size();
keyMat->derOID = (CK_VOID_PTR)malloc(keyMat->sizeOID);

Expand Down
20 changes: 20 additions & 0 deletions src/lib/SoftHSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
#include "ECParameters.h"
#include "EDPublicKey.h"
#include "EDPrivateKey.h"
#ifdef WITH_EDDSA
#include "EDDSAMechanismParam.h"
#include "EDDSAUtil.h"
#endif
#include "DHParameters.h"
#include "DHPublicKey.h"
#include "DHPrivateKey.h"
Expand Down Expand Up @@ -4320,6 +4324,7 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
#endif
#ifdef WITH_EDDSA
bool isEDDSA = false;
EDDSAMechanismParam eddsaParam;
#endif
#ifdef WITH_ML_DSA
bool isMLDSA = false;
Expand Down Expand Up @@ -4582,10 +4587,17 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
#endif
#ifdef WITH_EDDSA
case CKM_EDDSA:
{
mechanism = AsymMech::EDDSA;
bAllowMultiPartOp = false;
isEDDSA = true;
CK_RV eddsaRv = EDDSAUtil::getEddsaParam(pMechanism, eddsaParam, &mechanismParam);
if (eddsaRv != CKR_OK)
{
return eddsaRv;
}
break;
}
#endif
#ifdef WITH_ML_DSA
case CKM_ML_DSA:
Expand Down Expand Up @@ -5410,6 +5422,7 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
#endif
#ifdef WITH_EDDSA
bool isEDDSA = false;
EDDSAMechanismParam eddsaParam;
#endif
#ifdef WITH_ML_DSA
bool isMLDSA = false;
Expand Down Expand Up @@ -5671,10 +5684,17 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
#endif
#ifdef WITH_EDDSA
case CKM_EDDSA:
{
mechanism = AsymMech::EDDSA;
bAllowMultiPartOp = false;
isEDDSA = true;
CK_RV eddsaRv = EDDSAUtil::getEddsaParam(pMechanism, eddsaParam, &mechanismParam);
if (eddsaRv != CKR_OK)
{
return eddsaRv;
}
break;
}
#endif
#ifdef WITH_ML_DSA
case CKM_ML_DSA:
Expand Down
89 changes: 66 additions & 23 deletions src/lib/crypto/BotanEDDSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "CryptoFactory.h"
#include "BotanCryptoFactory.h"
#include "ECParameters.h"
#include "EDDSAMechanismParam.h"
#include "BotanEDKeyPair.h"
#include "BotanUtil.h"
#include <algorithm>
Expand All @@ -62,22 +63,56 @@ BotanEDDSA::~BotanEDDSA()
delete verifier;
}

// Select the Botan EMSA for the requested EdDSA instance
bool BotanEDDSA::selectEmsa(std::string& emsa, size_t orderLength, const MechanismParam* mechanismParam)
{
emsa = "Pure";

if (mechanismParam == NULL || !mechanismParam->isOfType(EDDSAMechanismParam::type))
{
return true;
}

const EDDSAMechanismParam* eddsaParam = (const EDDSAMechanismParam*) mechanismParam;

if (eddsaParam->contextData.size() > 0)
{
ERROR_MSG("EDDSA: Context data is not supported in the Botan 2 EDDSA implementation");
return false;
}

if (!eddsaParam->flag)
{
return true;
}

// Ed25519: orderLength = 32, Ed448: orderLength = 57
if (orderLength == 32)
{
emsa = "Ed25519ph";
return true;
}
Comment thread
antoinelochet marked this conversation as resolved.

if (orderLength == 57)
{
ERROR_MSG("EDDSA: Ed448 is not supported in the Botan 2 EDDSA implementation");
return false;
}

ERROR_MSG("EDDSA: Unknown EdDSA key size: %lu", (unsigned long) orderLength);
return false;
}

// Signing functions
bool BotanEDDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
ByteString& signature, const AsymMech::Type mechanism,
const MechanismParam* /* mechanismParam */)
const MechanismParam* mechanismParam)
{
std::string emsa;

if (mechanism == AsymMech::EDDSA)
if (mechanism != AsymMech::EDDSA)
{
emsa = "Pure";
}
else
{
ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
return false;
}
}

// Check if the private key is the right type
if (!privateKey->isOfType(BotanEDPrivateKey::type))
Expand All @@ -87,24 +122,31 @@ bool BotanEDDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
return false;
}

BotanEDPrivateKey* pk = (BotanEDPrivateKey*) privateKey;
Botan::Ed25519_PrivateKey* botanKey = dynamic_cast<Botan::Ed25519_PrivateKey*>(pk->getBotanKey());
BotanEDPrivateKey* pk = (BotanEDPrivateKey*) privateKey;
Botan::Ed25519_PrivateKey* botanKey = dynamic_cast<Botan::Ed25519_PrivateKey*>(pk->getBotanKey());

if (botanKey == NULL)
{
if (botanKey == NULL)
{
ERROR_MSG("Could not get the Botan private key");

return false;
}

std::string emsa;
if (!selectEmsa(emsa, pk->getOrderLength(), mechanismParam))
{
ERROR_MSG("Could not select the EMSA for the Botan 2 EDDSA implementation");
return false;
}

try
{
BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
}
catch (...)
{
ERROR_MSG("Could not create the signer token");
ERROR_MSG("Could not create the signer token. emsa: %s", emsa.c_str());

return false;
}
Expand Down Expand Up @@ -162,16 +204,10 @@ bool BotanEDDSA::signFinal(ByteString& /*signature*/)
// Verification functions
bool BotanEDDSA::verify(PublicKey* publicKey, const ByteString& originalData,
const ByteString& signature, const AsymMech::Type mechanism,
const MechanismParam* /* mechanismParam */)
const MechanismParam* mechanismParam)
{
std::string emsa;

if (mechanism == AsymMech::EDDSA)
if (mechanism != AsymMech::EDDSA)
{
emsa = "Pure";
}
else
{
ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);

return false;
Expand All @@ -195,13 +231,20 @@ bool BotanEDDSA::verify(PublicKey* publicKey, const ByteString& originalData,
return false;
}

std::string emsa;
if (!selectEmsa(emsa, pk->getOrderLength(), mechanismParam))
{
ERROR_MSG("Could not select the EMSA for the Botan 2 EDDSA implementation");
return false;
}

try
{
verifier = new Botan::PK_Verifier(*botanKey, emsa);
}
catch (...)
{
ERROR_MSG("Could not create the verifier token");
ERROR_MSG("Could not create the verifier token. emsa: %s", emsa.c_str());

return false;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/crypto/BotanEDDSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class BotanEDDSA : public AsymmetricAlgorithm
virtual AsymmetricParameters* newParameters();

private:
// Derive the Botan EMSA from the key size and the pre-hash flag; context data is not supported
static bool selectEmsa(std::string& emsa, size_t orderLength, const MechanismParam* mechanismParam);

Botan::PK_Signer* signer;
Botan::PK_Verifier* verifier;
};
Expand Down
4 changes: 3 additions & 1 deletion src/lib/crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ set(SOURCES AESKey.cpp
ECPublicKey.cpp
EDPrivateKey.cpp
EDPublicKey.cpp
EDDSAMechanismParam.cpp
EDDSAUtil.cpp
GOSTPrivateKey.cpp
GOSTPublicKey.cpp
HashAlgorithm.cpp
Expand Down Expand Up @@ -156,7 +158,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
list(APPEND INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/../win32)
ENDIF()

if(WITH_BOTAN)
if(WITH_BOTAN AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# mute botan specific warnings
# https://github.com/randombit/botan/issues/486
list(APPEND COMPILE_OPTIONS "/wd4250;/wd4251;/wd4275;/wd4127;/wd4273")
Expand Down
37 changes: 37 additions & 0 deletions src/lib/crypto/EDDSAMechanismParam.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2026 SoftHSMv2 contributors
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/*****************************************************************************
EDDSAMechanismParam.cpp

EdDSA mechanism parameters used for signing/verifying operations
*****************************************************************************/

#include "config.h"
#ifdef WITH_EDDSA
#include "ByteString.h"
#include "MechanismParam.h"
#include "EDDSAMechanismParam.h"
#include <string.h>

EDDSAMechanismParam::EDDSAMechanismParam()
{
flag = false;
}

// Set the type
/*static*/ const char* EDDSAMechanismParam::type = "EdDSA Signature param";

EDDSAMechanismParam* EDDSAMechanismParam::clone() const
{
return new EDDSAMechanismParam(*this);
}

// Check if the parameter is of the given type
bool EDDSAMechanismParam::isOfType(const char* inType) const
{
return !strcmp(type, inType);
}
#endif
40 changes: 40 additions & 0 deletions src/lib/crypto/EDDSAMechanismParam.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2026 SoftHSMv2 contributors
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/*****************************************************************************
EDDSAMechanismParam.h

EdDSA mechanism parameters used for signing/verifying operations
*****************************************************************************/

#ifndef _SOFTHSM_V2_EDDSAMECHANISMPARAM_H
#define _SOFTHSM_V2_EDDSAMECHANISMPARAM_H

#include "config.h"
#ifdef WITH_EDDSA
#include "ByteString.h"
#include "MechanismParam.h"

class EDDSAMechanismParam : public MechanismParam
{
public:

// EdDSA parameters from ck_eddsa_params
bool flag; // false = no pre-hash (pure), true = with pre-hash (ph)
ByteString contextData;

// The type
static const char* type;

EDDSAMechanismParam();

virtual EDDSAMechanismParam* clone() const;

// Check if the mechanism param is of the given type
virtual bool isOfType(const char* inType) const;
};

#endif // WITH_EDDSA
#endif // !_SOFTHSM_V2_EDDSAMECHANISMPARAM_H
Loading
Loading