const Policy &policy,
RawBuffer &data);
+ int encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &publicKeyAlias,
+ const Password &publicKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ RawBuffer &ciphertext);
+
+ int decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &privateKeyAlias,
+ const Password &privateKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ const RawBuffer &ciphertext);
+
int initializeCipher(const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
const Password &keyPassword,
const ckmc_policy_s shared_secret_policy,
ckmc_raw_buffer_s **ppciphertext)
{
- (void) params;
- (void) public_key_alias;
- (void) public_key_password;
- (void) shared_secret_alias;
- (void) shared_secret_policy;
- (void) ppciphertext;
+ EXCEPTION_GUARD_START_CAPI
- return CKMC_ERROR_NONE;
+ if (params == nullptr || public_key_alias == nullptr ||
+ shared_secret_alias == nullptr || ppciphertext == nullptr)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+ (params);
+
+ int ret = 0;
+ CKM::RawBuffer ciphertextBuffer;
+ auto mgr = CKM::Manager::create();
+
+ ret = to_ckmc_error(
+ mgr->encapsulateKey(*ca,
+ CKM::Alias(public_key_alias),
+ _tostring(public_key_password),
+ CKM::Alias(shared_secret_alias),
+ _toCkmPolicy(shared_secret_policy),
+ ciphertextBuffer));
+
+ if (ret == CKMC_ERROR_NONE) {
+ ret = ckmc_buffer_new(ciphertextBuffer.data(),
+ ciphertextBuffer.size(),
+ ppciphertext);
+ }
+
+ return ret;
+ EXCEPTION_GUARD_END
}
KEY_MANAGER_CAPI
const ckmc_policy_s shared_secret_policy,
const ckmc_raw_buffer_s *ciphertext)
{
- (void) params;
- (void) private_key_alias;
- (void) private_key_password;
- (void) shared_secret_alias;
- (void) shared_secret_policy;
- (void) ciphertext;
+ EXCEPTION_GUARD_START_CAPI
- return CKMC_ERROR_NONE;
+ if (params == nullptr || private_key_alias == nullptr ||
+ shared_secret_alias == nullptr || ciphertext == nullptr)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+ (params);
+
+ int ret = 0;
+ auto mgr = CKM::Manager::create();
+
+ ret = to_ckmc_error(
+ mgr->decapsulateKey(*ca,
+ CKM::Alias(private_key_alias),
+ _tostring(private_key_password),
+ CKM::Alias(shared_secret_alias),
+ _toCkmPolicy(shared_secret_policy),
+ CKM::RawBuffer(ciphertext->data, ciphertext->data + ciphertext->size)));
+
+ return ret;
+ EXCEPTION_GUARD_END
}
KEY_MANAGER_CAPI
case CKMC_ALGO_KBKDF:
case CKMC_ALGO_ECDH:
+ case CKMC_ALGO_KEM:
break;
default:
EXCEPTION_GUARD_END
}
+int Manager::Impl::encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &publicKeyAlias,
+ const Password &publicKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ RawBuffer &ciphertext)
+{
+ EXCEPTION_GUARD_START_CPPAPI
+
+ AliasSupport keyAliasHelper(publicKeyAlias);
+ AliasSupport secretAliasHelper(sharedSecretAlias);
+
+ return Request(*this,
+ LogicCommand::ENCAPSULATE_KEY,
+ m_extendedConnection,
+ CryptoAlgorithmSerializable(params),
+ keyAliasHelper.getName(),
+ keyAliasHelper.getOwner(),
+ publicKeyPassword,
+ secretAliasHelper.getName(),
+ secretAliasHelper.getOwner(),
+ PolicySerializable(sharedSecretPolicy)
+ ).maybeDeserialize(ciphertext);
+
+ EXCEPTION_GUARD_END
+}
+
+int Manager::Impl::decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &privateKeyAlias,
+ const Password &privateKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ const RawBuffer &ciphertext)
+{
+ EXCEPTION_GUARD_START_CPPAPI
+
+ AliasSupport keyAliasHelper(privateKeyAlias);
+ AliasSupport secretAliasHelper(sharedSecretAlias);
+
+ return Request(*this,
+ LogicCommand::DECAPSULATE_KEY,
+ m_extendedConnection,
+ CryptoAlgorithmSerializable(params),
+ keyAliasHelper.getName(),
+ keyAliasHelper.getOwner(),
+ privateKeyPassword,
+ secretAliasHelper.getName(),
+ secretAliasHelper.getOwner(),
+ PolicySerializable(sharedSecretPolicy),
+ ciphertext
+ ).maybeDeserialize();
+
+ EXCEPTION_GUARD_END
+}
+
int Manager::Impl::initializeCipher(
const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
const Policy &policy,
RawBuffer &data);
+ int encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &publicKeyAlias,
+ const Password &publicKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ RawBuffer &ciphertext);
+
+ int decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &privateKeyAlias,
+ const Password &privateKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ const RawBuffer &ciphertext);
+
int initializeCipher(const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
const Password &keyPassword,
);
}
+int Manager::encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &publicKeyAlias,
+ const Password &publicKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ RawBuffer &ciphertext)
+{
+ return m_impl->encapsulateKey(
+ params,
+ publicKeyAlias,
+ publicKeyPassword,
+ sharedSecretAlias,
+ sharedSecretPolicy,
+ ciphertext
+ );
+}
+
+int Manager::decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Alias &privateKeyAlias,
+ const Password &privateKeyPassword,
+ const Alias &sharedSecretAlias,
+ const Policy &sharedSecretPolicy,
+ const RawBuffer &ciphertext)
+{
+ return m_impl->decapsulateKey(
+ params,
+ privateKeyAlias,
+ privateKeyPassword,
+ sharedSecretAlias,
+ sharedSecretPolicy,
+ ciphertext
+ );
+}
+
int Manager::initializeCipher(
const CryptoAlgorithm ¶ms,
const Alias &keyAlias,
EXPORT_WRAPPED_KEY,
WRAP_CONCATENATED_DATA,
UNWRAP_CONCATENATED_DATA,
- GET_BACKEND_INFO
+ GET_BACKEND_INFO,
+ ENCAPSULATE_KEY,
+ DECAPSULATE_KEY
};
enum class EncryptionCommand : int {
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+ virtual std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
+ virtual Token decapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
// onward = true for encryption/signing, false for decryption/verification
virtual GCtxShPtr initContext(const CryptoAlgorithm &, bool /*onward*/)
{
#include <utils.h>
#include <generic-backend/exception.h>
+#include <generic-backend/algo-validation.h>
#include <sw-backend/obj.h>
#include <sw-backend/store.h>
#include <sw-backend/internals.h>
#include <sw-backend/ctx.h>
#include <ckm/ckm-key.h>
+#include <ckm/ckm-type.h>
namespace CKM {
namespace Crypto {
namespace {
+
AlgoType key2algo(DataType type)
{
switch (type) {
return std::make_tuple(Token(backendId(), wrappedKey.type, Store::pack(key, pass)), data);
}
+std::tuple<Token, RawBuffer> AKey::encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Token &pubKey,
+ const Password &pubKeyPass,
+ const Password &sharedSecretPass,
+ const RawBuffer &)
+{
+ KemType kemType = unpack<KemType>(params, ParamName::GEN_KEM_TYPE);
+ Internals::OqsKemPtr kem = Internals::createNewKem(kemType);
+
+ RawBuffer ciphertext(kem->length_ciphertext, 0x00);
+ RawBuffer sharedSecret(kem->length_shared_secret, 0x00);
+ RawBuffer pubKeyBuffer = Store::unpack(pubKey.data, pubKeyPass);
+
+ if (pubKeyBuffer.size() != kem->length_public_key) {
+ ThrowErr(Exc::Crypto::InputParam, "KEM type differs from public key KEM type");
+ }
+
+ OQS_STATUS rc = OQS_KEM_encaps(kem.get(), ciphertext.data(), sharedSecret.data(), pubKeyBuffer.data());
+ if (rc != OQS_SUCCESS) {
+ ThrowErr(Exc::Crypto::InternalError, "Error in KEM key encapsulation");
+ }
+
+ KeyShPtr outputKey = CKM::Key::createAES(sharedSecret);
+ if (!outputKey) {
+ ThrowErr(Exc::Crypto::InputParam, "Encapsulated key is not a valid AES key");
+ }
+
+ return std::make_tuple(Token(backendId(), DataType::KEY_AES,
+ Store::pack(outputKey.get()->getDER(), sharedSecretPass)), ciphertext);
+}
+
+Token AKey::decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Token &privKey,
+ const Password &privKeyPass,
+ const Password &sharedSecretPass,
+ const RawBuffer &ciphertext,
+ const RawBuffer &)
+{
+ KemType kemType = unpack<KemType>(params, ParamName::GEN_KEM_TYPE);
+ Internals::OqsKemPtr kem = Internals::createNewKem(kemType);
+
+ RawBuffer privKeyBuffer = Store::unpack(privKey.data, privKeyPass);
+ RawBuffer sharedSecret(kem->length_shared_secret, 0x00);
+
+ if (privKeyBuffer.size() != kem->length_secret_key) {
+ ThrowErr(Exc::Crypto::InputParam, "KEM type differs from private key KEM type");
+ }
+
+ OQS_STATUS rc = OQS_KEM_decaps(kem.get(), sharedSecret.data(), ciphertext.data(), privKeyBuffer.data());
+ if (rc != OQS_SUCCESS) {
+ ThrowErr(Exc::Crypto::InternalError, "Error in KEM key decapsulation");
+ }
+
+ KeyShPtr outputKey = CKM::Key::createAES(sharedSecret);
+ if (!outputKey) {
+ ThrowErr(Exc::Crypto::InputParam, "Decapsulated key is not a valid AES key");
+ }
+
+ return Token(backendId(), DataType::KEY_AES, Store::pack(outputKey.get()->getDER(), sharedSecretPass));
+}
+
EvpShPtr Cert::getEvpShPtr()
{
if (m_evp)
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+std::tuple<Token, RawBuffer> Cert::encapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
+Token Cert::decapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &)
+{
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+}
+
} // namespace SW
} // namespace Crypto
} // namespace CKM
size_t size,
const RawBuffer &data) override;
+ std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm ¶ms,
+ const Token &pubKey,
+ const Password &pubKeyPass,
+ const Password &sharedSecretPass,
+ const RawBuffer &) override;
+
+ Token decapsulateKey(const CryptoAlgorithm ¶ms,
+ const Token &privKey,
+ const Password &privKeyPass,
+ const Password &sharedSecretPass,
+ const RawBuffer &ciphertext,
+ const RawBuffer &) override;
+
protected:
virtual EvpShPtr getEvpShPtr();
size_t,
const RawBuffer &) override;
+ std::tuple<Token, RawBuffer> encapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &) override;
+
+ Token decapsulateKey(const CryptoAlgorithm &,
+ const Token &,
+ const Password &,
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &) override;
+
protected:
EvpShPtr getEvpShPtr() override;
};
return SerializeMessage(msgID, retCode, data);
}
+RawBuffer CKMLogic::encapsulateKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &publicKeyAlias,
+ const ClientId &publicKeyOwner,
+ const Password &publicKeyPassword,
+ const Name &sharedSecretAlias,
+ const ClientId &sharedSecretOwner,
+ const PolicySerializable &sharedSecretPolicy)
+{
+ DB::Row publicKeyRow;
+ DataType publicKeyType;
+ RawBuffer ciphertext;
+ Password sharedSecretPassword = sharedSecretPolicy.password;
+
+ auto retCode = tryRet([&] {
+ Crypto::GObjUPtr key;
+
+ auto [dbOp, digest, retCode2] = beginSaveAndGetHash(cred, sharedSecretAlias, sharedSecretOwner);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ retCode2 = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyAlias,
+ publicKeyOwner, publicKeyPassword, key);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ retCode2 = readRowHelper(false, cred, DataType::KEY_KEM_PUBLIC, publicKeyAlias, publicKeyOwner,
+ publicKeyPassword, publicKeyRow, publicKeyType);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ if (!publicKeyType.isKemPublicKey()) {
+ LogError("Only public KEM key should be used!");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ std::tuple<Token, RawBuffer> tokenWithData =
+ key->encapsulateKey(params, publicKeyRow, publicKeyPassword, sharedSecretPassword, digest);
+
+ ciphertext = std::get<1>(tokenWithData);
+
+ dbOp.finalize(std::move(std::get<0>(tokenWithData)), sharedSecretPolicy);
+
+ return retCode2;
+ });
+
+ return SerializeMessage(msgID, retCode, ciphertext);
+}
+
+RawBuffer CKMLogic::decapsulateKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &privateKeyAlias,
+ const ClientId &privateKeyOwner,
+ const Password &privateKeyPassword,
+ const Name &sharedSecretAlias,
+ const ClientId &sharedSecretOwner,
+ const PolicySerializable &sharedSecretPolicy,
+ const RawBuffer &ciphertext)
+{
+ DB::Row privateKeyRow;
+ DataType privateKeyType;
+ Password sharedSecretPassword = sharedSecretPolicy.password;
+
+ auto retCode = tryRet([&] {
+ Crypto::GObjUPtr key;
+ auto [dbOp, digest, retCode2] = beginSaveAndGetHash(cred, sharedSecretAlias, sharedSecretOwner);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ retCode2 = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyAlias,
+ privateKeyOwner, privateKeyPassword, key);
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ retCode2 = readRowHelper(false, cred, DataType::KEY_KEM_PRIVATE, privateKeyAlias, privateKeyOwner,
+ privateKeyPassword, privateKeyRow, privateKeyType);
+
+ if (retCode2 != CKM_API_SUCCESS)
+ return retCode2;
+
+ if (!privateKeyType.isKemPrivateKey()) {
+ LogError("Only private KEM key should be used!");
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ Token token = key->decapsulateKey(params, privateKeyRow, privateKeyPassword,
+ sharedSecretPassword, ciphertext, digest);
+
+ dbOp.finalize(std::move(token), sharedSecretPolicy);
+ return retCode2;
+ });
+
+ return SerializeMessage(msgID, retCode);
+}
+
RawBuffer CKMLogic::getBackendInfo(const int msgID, BackendId backend)
{
BackendInfo info;
size_t size,
const PolicySerializable &policy);
+ RawBuffer encapsulateKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &publicKeyAlias,
+ const ClientId &publicKeyOwner,
+ const Password &publicKeyPassword,
+ const Name &sharedSecretAlias,
+ const ClientId &sharedSecretOwner,
+ const PolicySerializable &sharedSecretPolicy);
+
+ RawBuffer decapsulateKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &privateKeyAlias,
+ const ClientId &privateKeyOwner,
+ const Password &privateKeyPassword,
+ const Name &sharedSecretAlias,
+ const ClientId &sharedSecretOwner,
+ const PolicySerializable &sharedSecretPolicy,
+ const RawBuffer &ciphertext);
+
RawBuffer getBackendInfo(
const int msgID,
BackendId backend);
break;
}
+ case LogicCommand::ENCAPSULATE_KEY: {
+ CryptoAlgorithmSerializable params;
+ Name publicKeyAlias;
+ ClientId publicKeyOwner;
+ Password publicKeyPassword;
+ Name sharedSecretAlias;
+ ClientId sharedSecretOwner;
+ PolicySerializable sharedSecretPolicy;
+
+ buffer.Deserialize(params,
+ publicKeyAlias,
+ publicKeyOwner,
+ publicKeyPassword,
+ sharedSecretAlias,
+ sharedSecretOwner,
+ sharedSecretPolicy);
+
+ logicFunc = [&, params, publicKeyAlias, publicKeyOwner, publicKeyPassword, sharedSecretAlias,
+ sharedSecretOwner, sharedSecretPolicy]() {
+ return m_logic->encapsulateKey(
+ cred,
+ msgId,
+ params,
+ publicKeyAlias,
+ cred.effectiveOwner(publicKeyOwner),
+ publicKeyPassword,
+ sharedSecretAlias,
+ cred.effectiveOwner(sharedSecretOwner),
+ sharedSecretPolicy);
+ };
+ break;
+ }
+
+ case LogicCommand::DECAPSULATE_KEY: {
+ CryptoAlgorithmSerializable params;
+ Name privateKeyAlias;
+ ClientId privateKeyOwner;
+ Password privateKeyPassword;
+ Name sharedSecretAlias;
+ ClientId sharedSecretOwner;
+ PolicySerializable sharedSecretPolicy;
+ RawBuffer ciphertext;
+
+ buffer.Deserialize(params,
+ privateKeyAlias,
+ privateKeyOwner,
+ privateKeyPassword,
+ sharedSecretAlias,
+ sharedSecretOwner,
+ sharedSecretPolicy,
+ ciphertext);
+
+ logicFunc = [&, params, privateKeyAlias, privateKeyOwner, privateKeyPassword, sharedSecretAlias,
+ sharedSecretOwner, sharedSecretPolicy, ciphertext]() {
+ return m_logic->decapsulateKey(
+ cred,
+ msgId,
+ params,
+ privateKeyAlias,
+ cred.effectiveOwner(privateKeyOwner),
+ privateKeyPassword,
+ sharedSecretAlias,
+ cred.effectiveOwner(sharedSecretOwner),
+ sharedSecretPolicy,
+ ciphertext);
+ };
+ break;
+ }
+
default:
Throw(Exception::BrokenProtocol);
}