#include <array>
#include <memory>
-#include <crypto-backend.h>
-#ifdef SE_BACKEND_ENABLED
-#include <se-backend/internals.h>
-#endif
+
using namespace CKM;
namespace {
}
typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
+
// derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
-KeyData makePKEK1(const KeyComponentsInfoDKEK& keyInfo, const Password &password)
+KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password)
{
std::string concatPasswordClient(password.c_str());
concatPasswordClient += std::string(keyInfo.client);
- KeyData key;
- if (keyInfo.version != KEYCOMPONENT_VERSION)
- ThrowErr(Exc::InternalError, "It's not expected version");
-
-#if SE_BACKEND_ENABLED
- RawBuffer salt;
- if (keyInfo.backend == (int)CryptoBackend::SecureElement) {
- RawBuffer salt = Crypto::SE::Internals::encryptWithDbpKey((unsigned char*)keyInfo.salt, MAX_SALT_SIZE,
- (unsigned char*)keyInfo.iv, MAX_IV_SIZE);
- } else {
- salt = RawBuffer(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
- }
-#else
- if (keyInfo.backend != (int)CryptoBackend::OpenSSL)
- ThrowErr(Exc::InternalError, "It's not expected backend");
- RawBuffer salt(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
-#endif
+ KeyData key;
if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
concatPasswordClient.size(),
- salt.data(),
- salt.size(),
+ keyInfo.salt,
+ MAX_SALT_SIZE,
PBKDF2_ITERATIONS,
key.size(),
key.data())) {
const Password &password,
KeyAndInfoContainer &domainKEK)
{
- WrappedKeyAndInfoContainer wrappedDomainKEK;
- wrappedDomainKEK.setWrappedDKEKAndInfo(wrappedDomainKEKbuffer.data());
- KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo, password);
+ WrappedKeyAndInfoContainer wrappedDomainKEK(wrappedDomainKEKbuffer.data());
+
+ KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo, password);
int keyLength;
- if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
- wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.keyLength,
- wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.tag,
+ if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
+ wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
+ wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag,
PKEK1.data(),
- wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.iv,
- domainKEK.getDKEKAndInfo().key)))
+ wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.iv,
+ domainKEK.getKeyAndInfo().key)))
ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
- domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo));
- domainKEK.setDKEKInfo(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.version,
- wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.backend);
+ domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo));
domainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
}
RawBuffer wrapDomainKEK(KeyAndInfoContainer &domainKEK, const Password &password)
{
- KeyData PKEK1 = makePKEK1(domainKEK.getDKEKAndInfo().keyInfo, password);
+ KeyData PKEK1 = makePKEK1(domainKEK.getKeyAndInfo().keyInfo, password);
WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer();
- wrappedDomainKEK.setKeyInfo(&(domainKEK.getDKEKAndInfo().keyInfo));
- wrappedDomainKEK.setDKEKInfo(domainKEK.getDKEKAndInfo().keyInfo.version,
- domainKEK.getDKEKAndInfo().keyInfo.backend);
+ wrappedDomainKEK.setKeyInfo(&(domainKEK.getKeyAndInfo().keyInfo));
int wrappedLength;
- if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getDKEKAndInfo().key,
- domainKEK.getDKEKAndInfo().keyInfo.keyLength,
+ if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getKeyAndInfo().key,
+ domainKEK.getKeyAndInfo().keyInfo.keyLength,
PKEK1.data(),
- domainKEK.getDKEKAndInfo().keyInfo.iv,
- wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
- wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.tag)))
+ domainKEK.getKeyAndInfo().keyInfo.iv,
+ wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey,
+ wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag)))
ThrowErr(Exc::InternalError, "DomainKEK encryption failed");
wrappedDomainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(wrappedLength));
- return toRawBuffer(wrappedDomainKEK.getWrappedDKEKAndInfo());
+ return toRawBuffer(wrappedDomainKEK.getWrappedKeyAndInfo());
}
template <size_t N>
WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
{
memset(&wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
- memset(&wrappedDKEKAndInfo, 0, sizeof(WrappedKeyAndInfoDKEK));
}
-WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
-{
- return wrappedKeyAndInfo;
-}
-
-WrappedKeyAndInfoDKEK &WrappedKeyAndInfoContainer::getWrappedDKEKAndInfo()
-{
- return wrappedDKEKAndInfo;
-}
-
-void WrappedKeyAndInfoContainer::setWrappedKeyAndInfo(
- const unsigned char *data)
+WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char
+ *data)
{
memcpy(&wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
}
}
-void WrappedKeyAndInfoContainer::setWrappedDKEKAndInfo(
- const unsigned char *data)
+WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
{
- memcpy(&wrappedDKEKAndInfo, data, sizeof(WrappedKeyAndInfoDKEK));
-
- if (wrappedDKEKAndInfo.keyInfo.keyLength > sizeof(wrappedDKEKAndInfo.wrappedKey)) {
- ThrowErr(Exc::InternalError,
- "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
- }
-
- size_t maxlen = sizeof(wrappedDKEKAndInfo.keyInfo.client);
- if (strnlen(wrappedDKEKAndInfo.keyInfo.client, maxlen) == maxlen) {
- ThrowErr(Exc::InternalError,
- "Wrapped key info is corrupted. Client id is not NULL terminated.");
- }
+ return wrappedKeyAndInfo;
}
-void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
+void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length)
{
wrappedKeyAndInfo.keyInfo.keyLength = length;
- wrappedDKEKAndInfo.keyInfo.keyLength = length;
}
void WrappedKeyAndInfoContainer::setKeyInfoClient(const std::string resized_client)
}
strncpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
- strncpy(wrappedDKEKAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
}
void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
const int size)
{
memcpy(wrappedKeyAndInfo.keyInfo.salt, salt, size);
- memcpy(wrappedDKEKAndInfo.keyInfo.salt, salt, size);
}
void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
{
memcpy(&(wrappedKeyAndInfo.keyInfo), keyComponentsInfo,
sizeof(KeyComponentsInfo));
- wrappedDKEKAndInfo.keyInfo.set(wrappedKeyAndInfo.keyInfo);
-}
-
-void WrappedKeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
-{
- wrappedDKEKAndInfo.keyInfo.version = version;
- wrappedDKEKAndInfo.keyInfo.backend = backend;
}
WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
KeyAndInfoContainer::KeyAndInfoContainer()
{
memset(&keyAndInfo, 0, sizeof(KeyAndInfo));
- memset(&DKEKAndInfo, 0, sizeof(KeyAndInfoDKEK));
-}
-
-KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
-{
- return keyAndInfo;
-}
-
-KeyAndInfoDKEK &KeyAndInfoContainer::getDKEKAndInfo()
-{
- return DKEKAndInfo;
}
-void KeyAndInfoContainer::setKeyAndInfo(const unsigned char *data)
+KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
{
memcpy(&keyAndInfo, data, sizeof(KeyAndInfo));
}
-void KeyAndInfoContainer::setDKEKAndInfo(const unsigned char *data)
+KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
{
- memcpy(&DKEKAndInfo, data, sizeof(KeyAndInfoDKEK));
+ return keyAndInfo;
}
-void KeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
+void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length)
{
keyAndInfo.keyInfo.keyLength = length;
- DKEKAndInfo.keyInfo.keyLength = length;
}
void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
{
memcpy(&(keyAndInfo.keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
- DKEKAndInfo.keyInfo.set(keyAndInfo.keyInfo);
-}
-
-void KeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
-{
- DKEKAndInfo.keyInfo.version = version;
- DKEKAndInfo.keyInfo.backend = backend;
}
KeyAndInfoContainer::~KeyAndInfoContainer()
{
// overwrite key
ZeroMemory(reinterpret_cast<unsigned char*>(&keyAndInfo), sizeof(KeyAndInfo));
- ZeroMemory(reinterpret_cast<unsigned char*>(&DKEKAndInfo), sizeof(KeyAndInfoDKEK));
}
KeyProvider::KeyProvider() :
if (!m_isInitialized)
ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
- if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfoDKEK)) {
- LogWarning("input size:" << domainKEKInWrapForm.size()
- << " Expected: " << sizeof(WrappedKeyAndInfoDKEK));
- LogWarning("buffer doesn't have proper size to store WrappedKeyAndInfoDKEK in KeyProvider Constructor");
- m_isInitialized = false;
- return;
+ if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
+ LogError("input size:" << domainKEKInWrapForm.size()
+ << " Expected: " << sizeof(WrappedKeyAndInfo));
+ ThrowErr(Exc::InternalError,
+ "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
}
unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK);
ThrowErr(Exc::InternalError, "Object not initialized!");
// TODO secure
- return RawBuffer(m_domainKEK->getDKEKAndInfo().key,
- (m_domainKEK->getDKEKAndInfo().key) +
- m_domainKEK->getDKEKAndInfo().keyInfo.keyLength);
+ return RawBuffer(m_domainKEK->getKeyAndInfo().key,
+ (m_domainKEK->getKeyAndInfo().key) +
+ m_domainKEK->getKeyAndInfo().keyInfo.keyLength);
}
RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
LogError("input size:" << DEKInWrapForm.size()
<< " Expected: " << sizeof(WrappedKeyAndInfo));
-
ThrowErr(Exc::InternalError,
"buffer doesn't have proper size to store "
"WrappedKeyAndInfo in KeyProvider::getPureDEK");
}
KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
- WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
- wkmcDEK.setWrappedKeyAndInfo(DEKInWrapForm.data());
+ WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
+ DEKInWrapForm.data());
- KeyData PKEK2 = makePKEK2(m_domainKEK->getDKEKAndInfo().key,
+ KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key,
wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
int keyLength;
if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
- KeyData PKEK2 = makePKEK2(m_domainKEK->getDKEKAndInfo().key, resized_client);
+ KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, resized_client);
int wrappedKeyLength;
if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
- m_domainKEK->getDKEKAndInfo().keyInfo.keyLength,
+ m_domainKEK->getKeyAndInfo().keyInfo.keyLength,
PKEK2.data(),
wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
}
-void KeyProvider::migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
- const Password &password)
-{
- WrappedKeyAndInfo wrappedInfo;
- if (wrappedDomainKEKbuffer.size() != sizeof(WrappedKeyAndInfo)) {
- LogError("[migrateDKEK] Input size:" << wrappedDomainKEKbuffer.size() <<
- " Expected: " << sizeof(WrappedKeyAndInfo));
- ThrowErr(Exc::InternalError,
- "buffer doesn't have proper size to store ");
- }
- memcpy(&wrappedInfo, wrappedDomainKEKbuffer.data(), sizeof(WrappedKeyAndInfo));
-
- size_t maxlen = sizeof(wrappedInfo.keyInfo.client);
- if (strnlen(wrappedInfo.keyInfo.client, maxlen) == maxlen) {
- ThrowErr(Exc::InternalError,
- "Wrapped key info is corrupted. Client id is not NULL terminated.");
- }
-
- KeyComponentsInfo keyInfo = wrappedInfo.keyInfo;
- std::string concatPasswordClient(password.c_str());
- concatPasswordClient += std::string(keyInfo.client);
-
- KeyData PKEK1;
- if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
- concatPasswordClient.size(),
- keyInfo.salt,
- MAX_SALT_SIZE,
- PBKDF2_ITERATIONS,
- PKEK1.size(),
- PKEK1.data())) {
- ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
- }
-
- int keyLength;
- if (0 > (keyLength = decryptAes256Gcm(wrappedInfo.wrappedKey,
- keyInfo.keyLength,
- keyInfo.tag,
- PKEK1.data(),
- keyInfo.iv,
- m_domainKEK->getDKEKAndInfo().key)))
- ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
-
- m_domainKEK->getDKEKAndInfo().keyInfo.set(keyInfo);
- m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
-#ifdef SE_BACKEND_ENABLED
- m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
-#endif
- m_domainKEK->setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
- m_isInitialized = true;
- LogDebug("Migrate DKEK Success");
-}
-
RawBuffer KeyProvider::reencrypt(
const RawBuffer &domainKEKInWrapForm,
const Password &oldPass,
const std::string &user,
const Password &userPassword)
{
+ WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
+
KeyAndInfoContainer domainKEK;
- if (!randomize(domainKEK.getDKEKAndInfo().keyInfo.salt) ||
- !randomize(domainKEK.getDKEKAndInfo().key) ||
- !randomize(domainKEK.getDKEKAndInfo().keyInfo.iv)) {
+ if (!randomize(domainKEK.getKeyAndInfo().keyInfo.salt) ||
+ !randomize(domainKEK.getKeyAndInfo().key) ||
+ !randomize(domainKEK.getKeyAndInfo().keyInfo.iv)) {
ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
}
- domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
-#ifdef SE_BACKEND_ENABLED
- domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
-#endif
- domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getDKEKAndInfo().key));
- if (user.size() >= sizeof(domainKEK.getDKEKAndInfo().keyInfo.client)) {
+ domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getKeyAndInfo().key));
+
+ if (user.size() >= sizeof(domainKEK.getKeyAndInfo().keyInfo.client)) {
ThrowErr(Exc::InternalError, "Client name too long");
}
- strncpy(domainKEK.getDKEKAndInfo().keyInfo.client, user.c_str(), user.size());
+ strncpy(domainKEK.getKeyAndInfo().keyInfo.client, user.c_str(), user.size());
return wrapDomainKEK(domainKEK, userPassword);
}