const RawBuffer &encrypted,
RawBuffer &decrypted);
+ int deriveKey(const CryptoAlgorithm &algo,
+ const Alias &secretAlias,
+ const Password &secretPassword,
+ const Alias &newKeyAlias,
+ const Policy &newKeyPolicy);
+
static ManagerShPtr create();
private:
// keep in sync with ckmc_permission_e !
};
+enum class KdfPrf : int {
+ HMAC_SHA256 = 1,
+ HMAC_SHA384,
+ HMAC_SHA512
+ // keep in sync with ckmc_kdf_prf_e !
+};
+
+enum class KbkdfMode : int {
+ COUNTER = 1,
+ // keep in sync with ckmc_kbkdf_mode_e !
+};
+
+enum class KbkdfCounterLocation : int {
+ BEFORE_FIXED = 1,
+ AFTER_FIXED,
+ MIDDLE_FIXED
+ // keep in sync with ckmc_kbkdf_counter_location_e !
+};
+
// algorithm parameters
enum class ParamName : int {
ALGO_TYPE = 1, // If there's no such param, the service will try to deduce the algorithm
SV_HASH_ALGO = 301, // hash algorithm (HashAlgorithm)
SV_RSA_PADDING, // RSA padding (RSAPaddingAlgorithm)
+ KDF_PRF = 401, // KdfPrf
+ KDF_LEN,
+ KBKDF_MODE, // KbkdfMode
+ KBKDF_LABEL,
+ KBKDF_CONTEXT,
+ KBKDF_FIXED_INPUT,
+ KBKDF_COUNTER_LOCATION, // KbkdfCounterLocation
+ KBKDF_RLEN,
+ KBKDF_LLEN,
+ KBKDF_NO_SEPARATOR,
+ ECDH_PUBKEY,
+
// special values marking valid values range
FIRST = ALGO_TYPE,
- LAST = SV_RSA_PADDING
+ LAST = ECDH_PUBKEY
};
// algorithm types (ALGO_TYPE param)
AES_GCM,
AES_CFB,
RSA_OAEP,
+ KBKDF,
+ ECDH,
+ // keep in sync with ckmc_algo_type_e !
+
RSA_SV,
DSA_SV,
ECDSA_SV,
const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
(params);
- // password
- CKM::Password pass;
-
- if (password)
- pass = password;
-
// buffers
CKM::RawBuffer inBuffer(in.data, in.data + in.size);
CKM::RawBuffer outBuffer;
auto mgr = CKM::Manager::create();
- int ret = ((*mgr).*operation)(*ca, key_alias, pass, inBuffer, outBuffer);
+ int ret = ((*mgr).*operation)(*ca, key_alias, _tostring(password), inBuffer, outBuffer);
if (ret != CKM_API_SUCCESS)
return to_ckmc_error(ret);
EXCEPTION_GUARD_END
}
+
+KEY_MANAGER_CAPI
+int ckmc_key_derive(const ckmc_param_list_h params,
+ const char *secret_alias,
+ const char *secret_password,
+ const char *new_key_alias,
+ ckmc_policy_s new_key_policy)
+{
+ if (secret_alias == nullptr || new_key_alias == nullptr || params == nullptr)
+ return CKMC_ERROR_INVALID_PARAMETER;
+
+ EXCEPTION_GUARD_START_CAPI
+
+ // params
+ const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *>
+ (params);
+
+ auto mgr = CKM::Manager::create();
+ return to_ckmc_error(mgr->deriveKey(*ca,
+ CKM::Alias(secret_alias),
+ _tostring(secret_password),
+ CKM::Alias(new_key_alias),
+ _toCkmPolicy(new_key_policy)));
+
+ EXCEPTION_GUARD_END
+}
decrypted);
}
+int Manager::Impl::deriveKey(const CryptoAlgorithm &algo,
+ const Alias &secretAlias,
+ const Password &secretPassword,
+ const Alias &newKeyAlias,
+ const Policy &newKeyPolicy)
+{
+ EXCEPTION_GUARD_START_CPPAPI
+
+ AliasSupport secret(secretAlias);
+ AliasSupport newKey(newKeyAlias);
+ CryptoAlgorithmSerializable cas(algo);
+
+ return Request(*this, LogicCommand::DERIVE, m_storageConnection,
+ cas, secret.getName(), secret.getOwner(), secretPassword,
+ newKey.getName(), newKey.getOwner(), PolicySerializable(newKeyPolicy)
+ ).maybeDeserialize();
+
+ EXCEPTION_GUARD_END
+}
+
} // namespace CKM
const RawBuffer &encrypted,
RawBuffer &decrypted);
+ int deriveKey(const CryptoAlgorithm &algo,
+ const Alias &secretAlias,
+ const Password &secretPassword,
+ const Alias &newKeyAlias,
+ const Policy &newKeyPolicy);
+
+
private:
int saveBinaryData(
const Alias &alias,
return m_impl->decrypt(algo, keyAlias, password, encrypted, decrypted);
}
+int Manager::deriveKey(const CryptoAlgorithm &algo,
+ const Alias &secretAlias,
+ const Password &secretPassword,
+ const Alias &newKeyAlias,
+ const Policy &newKeyPolicy)
+{
+ return m_impl->deriveKey(algo, secretAlias, secretPassword, newKeyAlias, newKeyPolicy);
+}
+
ManagerShPtr Manager::create()
{
try {
case ParamName::ED_IV:
case ParamName::ED_AAD:
case ParamName::ED_LABEL:
+ case ParamName::KBKDF_LABEL:
+ case ParamName::KBKDF_CONTEXT:
+ case ParamName::KBKDF_FIXED_INPUT:
+ case ParamName::ECDH_PUBKEY:
Deserializer<RawBuffer>::Deserialize(stream, buffer);
setParam(name, buffer);
break;
case ParamName::GEN_EC:
case ParamName::SV_HASH_ALGO:
case ParamName::SV_RSA_PADDING:
+ case ParamName::KDF_LEN:
+ case ParamName::KDF_PRF:
+ case ParamName::KBKDF_MODE:
+ case ParamName::KBKDF_RLEN:
+ case ParamName::KBKDF_LLEN:
+ case ParamName::KBKDF_COUNTER_LOCATION:
+ case ParamName::KBKDF_NO_SEPARATOR:
Deserializer<uint64_t>::Deserialize(stream, integer);
setParam(name, integer);
break;
SET_PERMISSION,
SAVE_PKCS12,
GET_PKCS12,
- GET_PROTECTION_STATUS
+ GET_PROTECTION_STATUS,
+ DERIVE
};
enum class EncryptionCommand : int {
#include <generic-backend/exception.h>
#include <crypto-backend.h>
+#include <token.h>
namespace CKM {
namespace Crypto {
ThrowErr(Exc::Crypto::OperationNotSupported);
}
+ virtual Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &)
+ {
+ ThrowErr(Exc::Crypto::OperationNotSupported);
+ }
+
virtual ~GObj()
{
}
} // namespace anonymous
+Token BData::derive(const CryptoAlgorithm &, const Password &, const RawBuffer &)
+{
+ return Token();
+}
+
RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data)
{
return Internals::symmetricEncrypt(getBinary(), alg, data);
return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data);
}
+Token AKey::derive(const CryptoAlgorithm &, const Password &, const RawBuffer &)
+{
+ return Token();
+}
+
EvpShPtr AKey::getEvpShPtr()
{
if (m_evp)
{
return m_raw;
}
+ Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
protected:
RawBuffer m_raw;
const RawBuffer &sign) override;
RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) override;
RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) override;
+ Token derive(const CryptoAlgorithm &, const Password &, const RawBuffer &) override;
protected:
virtual EvpShPtr getEvpShPtr();
}));
}
+RawBuffer CKMLogic::deriveKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &secretName,
+ const ClientId &secretOwner,
+ const Password &secretPassword,
+ const Name &newKeyName,
+ const ClientId &newKeyOwner,
+ const Policy &newKeyPolicy)
+{
+ return SerializeMessage(msgID, tryRet([&] {
+ // Get key/secret for internal service use. It won't be exported to the client
+ Crypto::GObjUPtr obj;
+ int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST,
+ secretName, secretOwner, secretPassword, obj);
+ if (retCode != CKM_API_SUCCESS) {
+ if (retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
+ return retCode;
+
+ retCode = readDataHelper(false, cred, DataType::BINARY_DATA,
+ secretName, secretOwner, secretPassword, obj);
+ if (retCode != CKM_API_SUCCESS)
+ return retCode;
+ }
+
+ auto [dbOp, digest, ret] = beginSaveAndGetHash(cred, newKeyName, newKeyOwner);
+ if (ret != CKM_API_SUCCESS)
+ return ret;
+
+ // derive
+ Token derived = obj->derive(params, newKeyPolicy.password, digest);
+
+ dbOp.finalize(std::move(derived), newKeyPolicy);
+
+ return CKM_API_SUCCESS;
+ }));
+}
+
} // namespace CKM
const ClientId &accessor,
const PermissionMask permissionMask);
+ RawBuffer deriveKey(
+ const Credentials &cred,
+ const int msgID,
+ const CryptoAlgorithm ¶ms,
+ const Name &secretName,
+ const ClientId &secretOwner,
+ const Password &secretPassword,
+ const Name &newKeyName,
+ const ClientId &newKeyOwner,
+ const Policy &newKeyPolicy);
+
int setPermissionHelper(
const Credentials &cred,
const Name &name,
permissionMask);
}
+ case LogicCommand::DERIVE: {
+ CryptoAlgorithmSerializable keyDerivationAlgorithm;
+ Name secretName;
+ ClientId secretExplicitOwner;
+ Password secretPassword;
+ Name newKeyName;
+ ClientId newKeyExplicitOwner;
+ PolicySerializable newKeyPolicy;
+ buffer.Deserialize(keyDerivationAlgorithm,
+ secretName,
+ secretExplicitOwner,
+ secretPassword,
+ newKeyName,
+ newKeyExplicitOwner,
+ newKeyPolicy);
+ return m_logic->deriveKey(
+ cred,
+ msgId,
+ keyDerivationAlgorithm,
+ secretName,
+ cred.effectiveOwner(secretExplicitOwner),
+ secretPassword,
+ newKeyName,
+ cred.effectiveOwner(newKeyExplicitOwner),
+ newKeyPolicy);
+ }
+
default:
Throw(Exception::BrokenProtocol);
}