Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GOST 2012 256 with botan #616

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ endif(NOT CMAKE_BUILD_TYPE)

message(STATUS "Build Configuration: ${CMAKE_BUILD_TYPE}")

add_definitions(-DDEFAULT_UMASK=0077)

# Build Modules Path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
${CMAKE_SOURCE_DIR}/modules
Expand Down
2 changes: 1 addition & 1 deletion src/bin/keyconv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ endif(WITH_BOTAN)

include_directories(${INCLUDE_DIRS})
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} ${CRYPTO_LIBS})
target_link_libraries(${PROJECT_NAME} ${CRYPTO_LIBS} pthread)

install(TARGETS ${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_BINDIR}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ endif()
# Static Library Config
###############################################################################
add_library(${PROJECT_NAME}-static STATIC ${SOURCES})
target_link_libraries(${PROJECT_NAME}-static ${STATIC_FILES})
target_link_libraries(${PROJECT_NAME}-static ${STATIC_FILES} pthread)
set_target_properties(${PROJECT_NAME}-static
PROPERTIES OUTPUT_NAME ${PROJECT_NAME}
)
Expand Down
97 changes: 85 additions & 12 deletions src/lib/SoftHSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERT
*p11object = new P11DHPublicKeyObj();
else if (keyType == CKK_GOSTR3410)
*p11object = new P11GOSTPublicKeyObj();
else if (keyType == CKK_GOSTR3410_512)
*p11object = new P11GOSTPublicKeyObj();
else if (keyType == CKK_EC_EDWARDS)
*p11object = new P11EDPublicKeyObj();
else
Expand Down Expand Up @@ -811,8 +813,12 @@ void SoftHSM::prepareSupportedMecahnisms(std::map<std::string, CK_MECHANISM_TYPE
t["CKM_GOSTR3411"] = CKM_GOSTR3411;
t["CKM_GOSTR3411_HMAC"] = CKM_GOSTR3411_HMAC;
t["CKM_GOSTR3410_KEY_PAIR_GEN"] = CKM_GOSTR3410_KEY_PAIR_GEN;
t["CKM_GOSTR3410_512_KEY_PAIR_GEN"] = CKM_GOSTR3410_512_KEY_PAIR_GEN;
t["CKM_GOSTR3410"] = CKM_GOSTR3410;
t["CKM_GOSTR3410_512"] = CKM_GOSTR3410_512;
t["CKM_GOSTR3410_WITH_GOSTR3411"] = CKM_GOSTR3410_WITH_GOSTR3411;
t["CKM_GOSTR3410_WITH_GOSTR3411_12_256"] = CKM_GOSTR3410_WITH_GOSTR3411_12_256;
t["CKM_GOSTR3410_WITH_GOSTR3411_12_512"] = CKM_GOSTR3410_WITH_GOSTR3411_12_512;
#endif
#ifdef WITH_EDDSA
t["CKM_EC_EDWARDS_KEY_PAIR_GEN"] = CKM_EC_EDWARDS_KEY_PAIR_GEN;
Expand Down Expand Up @@ -3637,6 +3643,12 @@ CK_RV SoftHSM::C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
case CKM_GOSTR3411:
algo = HashAlgo::GOST;
break;
case CKM_GOSTR3411_12_256:
algo = HashAlgo::GOST2012_256;
break;
case CKM_GOSTR3411_12_512:
algo = HashAlgo::GOST2012_512;
break;
#endif
default:
return CKR_MECHANISM_INVALID;
Expand Down Expand Up @@ -4339,6 +4351,14 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
mechanism = AsymMech::GOST_GOST;
bAllowMultiPartOp = true;
break;
case CKM_GOSTR3410_WITH_GOSTR3411_12_256:
mechanism = AsymMech::GOST_GOST_256;
bAllowMultiPartOp = true;
break;
case CKM_GOSTR3410_WITH_GOSTR3411_12_512:
mechanism = AsymMech::GOST_GOST_512;
bAllowMultiPartOp = true;
break;
#endif
#ifdef WITH_EDDSA
case CKM_EDDSA:
Expand Down Expand Up @@ -4436,7 +4456,25 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
else
{
#ifdef WITH_GOST
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
ByteString param;
if (isKeyPrivate)
{
if(!token->decrypt(key->getByteStringValue(CKA_GOSTR3411_PARAMS), param))
return CKR_PUBLIC_KEY_INVALID;
}
else
{
param = key->getByteStringValue(CKA_GOSTR3411_PARAMS);
}
AsymAlgo::Type type = CryptoFactory::i()->getGOSTType(param);
if(type == AsymAlgo::Unknown)
{
ERROR_MSG("Cannot parse GOST key type");
return CKR_PUBLIC_KEY_INVALID;
}
asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(type);
if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;

privateKey = asymCrypto->newPrivateKey();
Expand Down Expand Up @@ -6013,6 +6051,9 @@ CK_RV SoftHSM::C_GenerateKeyPair
case CKM_GOSTR3410_KEY_PAIR_GEN:
keyType = CKK_GOSTR3410;
break;
case CKM_GOSTR3410_512_KEY_PAIR_GEN:
keyType = CKK_GOSTR3410_512;
break;
#endif
#ifdef WITH_EDDSA
case CKM_EC_EDWARDS_KEY_PAIR_GEN:
Expand Down Expand Up @@ -6044,6 +6085,8 @@ CK_RV SoftHSM::C_GenerateKeyPair
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410)
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_GOSTR3410_512_KEY_PAIR_GEN && keyType != CKK_GOSTR3410_512)
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS)
return CKR_TEMPLATE_INCONSISTENT;

Expand All @@ -6067,6 +6110,8 @@ CK_RV SoftHSM::C_GenerateKeyPair
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410)
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_GOSTR3410_512_KEY_PAIR_GEN && keyType != CKK_GOSTR3410_512)
return CKR_TEMPLATE_INCONSISTENT;
if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS)
return CKR_TEMPLATE_INCONSISTENT;

Expand Down Expand Up @@ -6123,13 +6168,14 @@ CK_RV SoftHSM::C_GenerateKeyPair
}

// Generate GOST keys
if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN)
if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN || pMechanism->mechanism == CKM_GOSTR3410_512_KEY_PAIR_GEN)
{
return this->generateGOST(hSession,
pPublicKeyTemplate, ulPublicKeyAttributeCount,
pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
phPublicKey, phPrivateKey,
ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate,
keyType);
}

// Generate EDDSA keys
Expand Down Expand Up @@ -9844,7 +9890,8 @@ CK_RV SoftHSM::generateGOST
CK_BBOOL isPublicKeyOnToken,
CK_BBOOL isPublicKeyPrivate,
CK_BBOOL isPrivateKeyOnToken,
CK_BBOOL isPrivateKeyPrivate)
CK_BBOOL isPrivateKeyPrivate,
CK_KEY_TYPE keyType)
{
*phPublicKey = CK_INVALID_HANDLE;
*phPrivateKey = CK_INVALID_HANDLE;
Expand Down Expand Up @@ -9881,10 +9928,25 @@ CK_RV SoftHSM::generateGOST
}
}

AsymAlgo::Type algo = AsymAlgo::GOST;
// The parameters must be specified to be able to generate a key pair.
if (param_3410.size() == 0 || param_3411.size() == 0) {
INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
return CKR_TEMPLATE_INCOMPLETE;
if (keyType != CKK_GOSTR3410_512)
{
if(param_3411.size() == 0)
{
param_3411 = ByteString("06082a85030701010202");
algo = AsymAlgo::GOST2012;
}
else if (param_3410.size() == 0)
{
INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
return CKR_TEMPLATE_INCOMPLETE;
}
}
else
{
param_3411 = ByteString("06082a85030701010203");
algo = AsymAlgo::GOST2012_512;
}

// Set the parameters
Expand All @@ -9893,7 +9955,7 @@ CK_RV SoftHSM::generateGOST

// Generate key pair
AsymmetricKeyPair* kp = NULL;
AsymmetricAlgorithm* gost = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
AsymmetricAlgorithm* gost = CryptoFactory::i()->getAsymmetricAlgorithm(algo);
if (gost == NULL) return CKR_GENERAL_ERROR;
if (!gost->generateKeyPair(&kp, &p))
{
Expand All @@ -9912,12 +9974,11 @@ CK_RV SoftHSM::generateGOST
{
const CK_ULONG maxAttribs = 32;
CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
CK_KEY_TYPE publicKeyType = CKK_GOSTR3410;
CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
};
CK_ULONG publicKeyAttribsCount = 4;

Expand All @@ -9937,6 +9998,19 @@ CK_RV SoftHSM::generateGOST
publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
}
}
if (param_3410.size() == 0)
{
const ByteString &str = p.getEC();
publicKeyAttribs[publicKeyAttribsCount].type = CKA_GOSTR3410_PARAMS;
publicKeyAttribs[publicKeyAttribsCount].pValue = const_cast<u_char*>(str.const_byte_str());
publicKeyAttribs[publicKeyAttribsCount++].ulValueLen = str.size();
}
if(algo == AsymAlgo::GOST2012 || algo == AsymAlgo::GOST2012_512)
{
publicKeyAttribs[publicKeyAttribsCount].type = CKA_GOSTR3411_PARAMS;
publicKeyAttribs[publicKeyAttribsCount].pValue = const_cast<u_char*>(param_3411.const_byte_str());
publicKeyAttribs[publicKeyAttribsCount++].ulValueLen = param_3411.size();
}

if (rv == CKR_OK)
rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
Expand Down Expand Up @@ -9984,12 +10058,11 @@ CK_RV SoftHSM::generateGOST
{
const CK_ULONG maxAttribs = 32;
CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
CK_KEY_TYPE privateKeyType = CKK_GOSTR3410;
CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
};
CK_ULONG privateKeyAttribsCount = 4;
if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
Expand Down
6 changes: 3 additions & 3 deletions src/lib/SoftHSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,7 @@ class SoftHSM
CK_BBOOL isPrivate
);
CK_RV generateGOST
(
CK_SESSION_HANDLE hSession,
(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pPublicKeyTemplate,
CK_ULONG ulPublicKeyAttributeCount,
CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
Expand All @@ -348,7 +347,8 @@ class SoftHSM
CK_BBOOL isPublicKeyOnToken,
CK_BBOOL isPublicKeyPrivate,
CK_BBOOL isPrivateKeyOnToken,
CK_BBOOL isPrivateKeyPrivate
CK_BBOOL isPrivateKeyPrivate,
CK_KEY_TYPE keyType
);
CK_RV generateGeneric
(
Expand Down
4 changes: 4 additions & 0 deletions src/lib/crypto/AsymmetricAlgorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ struct AsymAlgo
ECDH,
ECDSA,
GOST,
GOST2012,
GOST2012_512,
EDDSA
};
};
Expand Down Expand Up @@ -87,6 +89,8 @@ struct AsymMech
ECDSA,
GOST,
GOST_GOST,
GOST_GOST_256,
GOST_GOST_512,
EDDSA
};
};
Expand Down
51 changes: 51 additions & 0 deletions src/lib/crypto/BotanCryptoFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,20 @@
#include "BotanSHA512.h"
#ifdef WITH_GOST
#include "BotanGOST.h"
#include "BotanGOST2012.h"
#include "BotanGOST2012_512.h"
#include "BotanGOSTR3411.h"
#include "BotanGOSTR3411_12_256.h"
#include "BotanGOSTR3411_12_512.h"
//#include "../object_store/OSObject.h"
//#include "../slot_mgr/Token.h"
#include <botan/ber_dec.h>
#endif
#include "BotanMAC.h"
#ifdef WITH_EDDSA
#include "BotanEDDSA.h"

#include <botan/ber_dec.h>
#endif

// Constructor
Expand Down Expand Up @@ -144,6 +153,10 @@ AsymmetricAlgorithm* BotanCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type a
#ifdef WITH_GOST
case AsymAlgo::GOST:
return new BotanGOST();
case AsymAlgo::GOST2012:
return new BotanGOST2012();
case AsymAlgo::GOST2012_512:
return new BotanGOST2012_512();
#endif
#ifdef WITH_EDDSA
case AsymAlgo::EDDSA:
Expand Down Expand Up @@ -180,6 +193,10 @@ HashAlgorithm* BotanCryptoFactory::getHashAlgorithm(HashAlgo::Type algorithm)
#ifdef WITH_GOST
case HashAlgo::GOST:
return new BotanGOSTR3411();
case HashAlgo::GOST2012_256:
return new BotanGOSTR3411_12_256();
case HashAlgo::GOST2012_512:
return new BotanGOSTR3411_12_512();
#endif
default:
// No algorithm implementation is available
Expand Down Expand Up @@ -279,3 +296,37 @@ RNG* BotanCryptoFactory::getRNG(RNGImpl::Type name /* = RNGImpl::Default */)
return NULL;
}
}

AsymAlgo::Type BotanCryptoFactory::getGOSTType(const ByteString &param)
{/*
// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
ByteString param;
if (isKeyPrivate)
{
if(!token->decrypt(key->getByteStringValue(CKA_GOSTR3411_PARAMS), param))
return AsymAlgo::Unknown;
}
else
{
param = key->getByteStringValue(CKA_GOSTR3411_PARAMS);
}*/
if(param.size() == 0)
return AsymAlgo::Unknown;
Botan::BER_Decoder dec(param.const_byte_str(), param.size());
Botan::OID oid;
Botan::OID gost_256({1,2,643,7,1,1,2,2}), gost_512({1,2,643,7,1,1,2,3});
try {
oid.decode_from(dec);

} catch (Botan::Exception except) {
ERROR_MSG(except.what());
return AsymAlgo::Unknown;
}
if(oid == gost_256)
return AsymAlgo::GOST2012;
else if(oid == gost_512)
return AsymAlgo::GOST2012_512;
else
return AsymAlgo::GOST;
}
5 changes: 5 additions & 0 deletions src/lib/crypto/BotanCryptoFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ class BotanCryptoFactory : public CryptoFactory
// Get the global RNG (may be an unique RNG per thread)
RNG* getRNG(RNGImpl::Type name = RNGImpl::Default);

#ifdef WITH_GOST
// Parse GOST key type
AsymAlgo::Type getGOSTType(const ByteString& param);
#endif

// Destructor
~BotanCryptoFactory();

Expand Down
2 changes: 1 addition & 1 deletion src/lib/crypto/BotanGOST.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class BotanGOST : public AsymmetricAlgorithm
virtual PrivateKey* newPrivateKey();
virtual AsymmetricParameters* newParameters();

private:
protected:
Botan::PK_Signer* signer;
Botan::PK_Verifier* verifier;
};
Expand Down
Loading