ADD_DEFINITIONS("-DTZ_BACKEND_ENABLED")
ENDIF()
-IF (SE_BACKEND_ENABLED)
- ADD_DEFINITIONS("-DSE_BACKEND_ENABLED")
-ENDIF()
-
IF (DEFINED WATCHDOG_ENABLED)
MESSAGE("WATCHDOG ENABELD!")
ADD_DEFINITIONS("-DWATCHDOG_ENABLED")
%global watchdog_timeout_sec 60
%global watchdog_notify_sec 20
%global tz_backend_enabled %{?tz_backend:%tz_backend}%{!?tz_backend:OFF}
-%global se_backend_enabled %{?se_backend:%se_backend}%{!?se_backend:OFF}
Name: key-manager
Summary: Central Key Manager and utilities
BuildRequires: key-manager-ta-serialization-devel
BuildRequires: pkgconfig(tef-libteec)
%endif
-%if %{se_backend_enabled} == ON
-BuildRequires: pkgconfig(key-manager-se-backend)
-%endif
Requires: libkey-manager-common = %{version}-%{release}
%{?systemd_requires}
%else
-DTZ_BACKEND_ENABLED=OFF \
%endif
-%if %{se_backend_enabled} == ON
- -DSE_BACKEND_ENABLED=ON \
-%else
- -DSE_BACKEND_ENABLED=OFF \
-%endif
-DTEST_DIR=%{test_dir} \
-DDUMP_LEGACY_DB_LIBNAME=%{dump_legacy_db_libname}
)
ENDIF()
-IF(SE_BACKEND_ENABLED)
-SET(KEY_MANAGER_SOURCES
- ${KEY_MANAGER_SOURCES}
- ${KEY_MANAGER_PATH}/crypto/se-backend/internals.cpp
- )
-SET(KM_LINK_EXTRA_DEPS ${KM_LINK_EXTRA_DEPS} key-manager-se-backend)
-ENDIF()
-
SET_SOURCE_FILES_PROPERTIES(
${KEY_MANAGER_SOURCES}
PROPERTIES
+++ /dev/null
-/*
- * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd. All rights reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file internals.cpp
- * @author isaac2.lee (isaac2.lee@samsung.com)
- * @version 1.0
- */
-
-#include <functional>
-#include <unistd.h>
-#include <generic-backend/exception.h>
-#include <generic-backend/algo-validation.h>
-#include <generic-backend/crypto-params.h>
-#include <dpl/log/log.h>
-#include <ckm/ckm-type.h>
-
-#include <se-backend/internals.h>
-#include <key-manager-se-backend.h>
-#include <key-provider.h>
-
-#ifndef UNUSED_PARAMETER
-#define UNUSED_PARAMETER(x) (void)(x)
-#endif
-
-namespace CKM {
-namespace Crypto {
-namespace SE {
-namespace Internals {
-
-RawBuffer toRawBuffer(unsigned char* buf, uint32_t buf_len)
-{
- RawBuffer output;
- output.assign(buf, buf + buf_len);
- return output;
-}
-
-kmsb_hash_algo_e getHashType(const CryptoAlgorithm &alg)
-{
- HashAlgorithm hash = unpack<HashAlgorithm>(alg, ParamName::SV_HASH_ALGO);
- switch (hash)
- {
- case HashAlgorithm::SHA1:
- return KMSB_HASH_SHA1;
- case HashAlgorithm::SHA256:
- return KMSB_HASH_SHA256;
- case HashAlgorithm::SHA384:
- return KMSB_HASH_SHA384;
- case HashAlgorithm::SHA512:
- return KMSB_HASH_SHA512;
- default:
- break;
- }
- return KMSB_HASH_SHA256;
-}
-
-kmsb_ec_type_e getEcType(const ElipticCurve ecType)
-{
- if (ecType == ElipticCurve::prime192v1)
- return KMSB_EC_PRIME192V1;
- else if (ecType == ElipticCurve::prime256v1)
- return KMSB_EC_PRIME256V1;
- else if (ecType == ElipticCurve::secp384r1)
- return KMSB_EC_SECP384R1;
- return KMSB_EC_PRIME256V1;
-}
-
-int kmsb_failure_retry(std::function<int()> func)
-{
- int result = KMSB_ERROR_NONE;
- for (size_t attempt = 0; attempt < 3; ++attempt) {
- result = func();
- if (result == KMSB_ERROR_NONE || result == KMSB_ERROR_NO_KEY)
- break;
- LogError("occured err inside SE(errcode:" << result << ")");
- usleep(100000);
- }
- return result;
-}
-
-void generateSKey(const CryptoAlgorithm &alg,
- const uint32_t key_idx)
-{
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(key_idx);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported");
-}
-
-void generateAKey(const CryptoAlgorithm &alg,
- const uint32_t key_idx)
-{
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(key_idx);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported");
-}
-
-/// @brief encrypt key data using SE api for DB metadata
-/// @param key: target data for encryption
-/// @param key_len: target data length
-/// @param iv: iv data
-/// @param iv_len: iv data length
-/// @return Rawbuffer encrypted output
-RawBuffer encryptWithDbpKey(const unsigned char* key, const uint32_t key_len,
- const unsigned char* iv, const uint32_t iv_len)
-{
-
- unsigned char* output_data;
- uint32_t output_len;
-
- int ret = kmsb_failure_retry(std::bind(kmsb_encrypt_with_dbp_key,
- SE_BACKEND_DBP_SCHEME_VERSION,
- key, key_len,
- iv, iv_len,
- &output_data, &output_len));
- if (ret == KMSB_ERROR_NO_KEY) {
- ret = kmsb_failure_retry(std::bind(kmsb_generate_dbp_key,
- false));
- if (ret != KMSB_ERROR_NONE) {
- LogError("Generate Key: SE Internal error: " << ret);
- ThrowErr(Exc::Crypto::InternalError, "Generate Key: SE Internal error");
- }
- ret = kmsb_failure_retry(std::bind(kmsb_encrypt_with_dbp_key,
- SE_BACKEND_DBP_SCHEME_VERSION,
- key, key_len,
- iv, iv_len,
- &output_data, &output_len));
- }
- if (ret != KMSB_ERROR_NONE) {
- LogError("Encrypt Key: SE Internal error: " << ret);
- ThrowErr(Exc::Crypto::InternalError, "Encrypt key: SE Internal error");
- }
- return toRawBuffer(output_data, output_len);
-}
-
-RawBuffer halAES(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data,
- const bool isEncrypt)
-{
- UNUSED_PARAMETER(key_idx);
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(data);
- UNUSED_PARAMETER(isEncrypt);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported AES yet");
-}
-
-RawBuffer symmetricEncrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data)
-{
- return halAES(key_idx, alg, data, true);
-}
-
-RawBuffer symmetricDecrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data)
-{
- return halAES(key_idx, alg, data, false);
-}
-
-RawBuffer asymmetricEncrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data)
-{
- UNUSED_PARAMETER(key_idx);
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(data);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported RSA");
-}
-
-RawBuffer asymmetricDecrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data)
-{
- UNUSED_PARAMETER(key_idx);
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(data);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported RSA");
-}
-
-RawBuffer sign(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &message)
-{
- UNUSED_PARAMETER(key_idx);
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(message);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported signing yet");
-}
-
-int verify(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &hash,
- RawBuffer &signature)
-{
- UNUSED_PARAMETER(key_idx);
- UNUSED_PARAMETER(alg);
- UNUSED_PARAMETER(hash);
- UNUSED_PARAMETER(signature);
-
- ThrowErr(Exc::Crypto::OperationNotSupported, "SE Backend not supported verifying yet");
-}
-
-} // namespace Internals
-} // namespace SE
-} // namespace Crypto
-} // namespace CKM
+++ /dev/null
-/*
- * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-/*
- * @file internals.h
- * @author isaac2.lee (isaac2.lee@samsung.com)
- * @version 1.0
- */
-#pragma once
-
-#include <ckm/ckm-type.h>
-#include <data-type.h>
-#include <generic-backend/gstore.h>
-
-namespace CKM {
-namespace Crypto {
-namespace SE {
-namespace Internals {
-
-void generateSKey(const CryptoAlgorithm &alg, const uint32_t key_idx);
-
-void generateAKey(const CryptoAlgorithm &alg, const uint32_t key_idx);
-
-// encrypt key data using SE api
-RawBuffer encryptWithDbpKey(const unsigned char* key, const uint32_t key_len,
- const unsigned char* iv, const uint32_t iv_len);
-
-RawBuffer symmetricEncrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data);
-RawBuffer symmetricDecrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data);
-
-RawBuffer asymmetricEncrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data);
-
-RawBuffer asymmetricDecrypt(const uint32_t key_idx,
- const CryptoAlgorithm &alg,
- RawBuffer &data);
-
-RawBuffer sign(const uint32_t key_idx, const CryptoAlgorithm &alg,
- RawBuffer &message);
-
-int verify(const uint32_t key_idx, const CryptoAlgorithm &alg,
- RawBuffer &hash, RawBuffer &signature);
-
-} // namespace Internals
-} // namespace SE
-} // namespace Crypto
-} // namespace CKM
}
handle.keyProvider = KeyProvider(wrappedDKEK, password);
- if (!handle.keyProvider.isInitialized()) {
- handle.keyProvider.migrateDKEK(wrappedDKEK, password);
- fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
- LogInfo("DKEK migrated");
- }
}
void CKMLogic::saveDKEKFile(uid_t user, const Password &password)
enum class CryptoBackend {
None = 0,
OpenSSL = 1,
- TrustZone = 2,
- SecureElement = 3
+ TrustZone = 2
};
} // namespace CKM
const std::string CKM_DB_PREFIX = "db0-";
const std::string CKM_REMOVED_APP_PREFIX = "removed-app-";
const std::string CKM_LOCK_FILE = RUN_DIR "/" SERVICE_NAME "/key-manager.pid";
-const std::string CKM_TEMP_POSTFIX = ".tmp";
wur std::string getPath(const std::string &prefix, uid_t uid)
{
void FileSystem::saveFile(const std::string &path,
const RawBuffer &buffer) const
{
- std::ofstream os(path + CKM_TEMP_POSTFIX, std::ios::out |
- std::ofstream::binary | std::ofstream::trunc);
+ std::ofstream os(path, std::ios::out | std::ofstream::binary |
+ std::ofstream::trunc);
if (os.fail())
ThrowErr(Exc::FileSystemFailed, "Can't open file for writing: ", path);
if (os.fail())
ThrowErr(Exc::FileSystemFailed, "Failed to save file: ", path);
-
- if (std::rename((path + CKM_TEMP_POSTFIX).c_str(), path.c_str()))
- ThrowErr(Exc::FileSystemFailed, "Can't rename file: ", path);
}
void FileSystem::saveDKEK(const RawBuffer &buffer) const
{
- std::string path(getDKEKPath());
- saveFile(path, buffer);
+ saveFile(getDKEKPath(), buffer);
}
void FileSystem::saveDBDEK(const RawBuffer &buffer) const
{
- std::string path(getDBDEKPath());
- saveFile(path, buffer);
+ saveFile(getDBDEKPath(), buffer);
}
void FileSystem::addRemovedApp(const ClientId &app) const
#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);
}
namespace CKM {
-const uint32_t KEYCOMPONENT_VERSION = 2;
-
typedef struct KeyComponentsInfo_ {
uint32_t keyLength;
char client[MAX_CLIENT_ID_SIZE];
uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
} WrappedKeyAndInfo;
-typedef struct KeyComponentsInfoDKEK_ : KeyComponentsInfo{
- uint32_t version;
- uint32_t backend;
- void set(const KeyComponentsInfo &src) {
- keyLength = src.keyLength;
- memcpy(&client, &src.client, MAX_CLIENT_ID_SIZE);
- memcpy(&salt, &src.salt, MAX_SALT_SIZE);
- memcpy(&iv, &src.iv, MAX_IV_SIZE);
- memcpy(&tag, &src.tag, MAX_IV_SIZE);
- }
-} KeyComponentsInfoDKEK;
-
-typedef struct KeyAndInfoDKEK_ {
- KeyComponentsInfoDKEK keyInfo;
- uint8_t key[MAX_KEY_SIZE];
-} KeyAndInfoDKEK;
-
-typedef struct WrappedKeyAndInfoDKEK_ {
- KeyComponentsInfoDKEK keyInfo;
- uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
-} WrappedKeyAndInfoDKEK;
-
class WrappedKeyAndInfoContainer {
public:
WrappedKeyAndInfoContainer();
+ WrappedKeyAndInfoContainer(const unsigned char *);
WrappedKeyAndInfo &getWrappedKeyAndInfo();
- WrappedKeyAndInfoDKEK &getWrappedDKEKAndInfo();
- void setWrappedKeyAndInfo(const unsigned char *);
- void setWrappedDKEKAndInfo(const unsigned char *);
- void setKeyInfoKeyLength(const uint32_t);
+ void setKeyInfoKeyLength(const unsigned int);
void setKeyInfoClient(const std::string);
void setKeyInfoSalt(const unsigned char *, const int);
void setKeyInfo(const KeyComponentsInfo *);
- void setDKEKInfo(const uint32_t, const uint32_t);
~WrappedKeyAndInfoContainer();
private:
WrappedKeyAndInfo wrappedKeyAndInfo;
- WrappedKeyAndInfoDKEK wrappedDKEKAndInfo;
};
class KeyAndInfoContainer {
public:
KeyAndInfoContainer();
+ explicit KeyAndInfoContainer(const unsigned char *);
KeyAndInfo &getKeyAndInfo();
- KeyAndInfoDKEK &getDKEKAndInfo();
- void setKeyAndInfo(const unsigned char *);
- void setDKEKAndInfo(const unsigned char *);
- void setKeyInfoKeyLength(const uint32_t);
+ void setKeyInfoKeyLength(const unsigned int);
void setKeyInfo(const KeyComponentsInfo *);
- void setDKEKInfo(const uint32_t, const uint32_t);
~KeyAndInfoContainer();
private:
KeyAndInfo keyAndInfo;
- KeyAndInfoDKEK DKEKAndInfo;
};
static RawBuffer generateDomainKEK(const std::string &user,
const Password &userPassword);
- void migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
- const Password &password);
- RawBuffer migrateDBDEK(const RawBuffer &DEKInWrapForm);
-
// This will be called by framework at the begin of the program
static int initializeLibrary();
// This will be called by framework at the end of the program
${CMAKE_CURRENT_SOURCE_DIR}/encryption-scheme/generate-db.cpp
)
-IF(SE_BACKEND_ENABLED)
-SET(ENCRYPTION_SCHEME_SOURCES
- ${ENCRYPTION_SCHEME_SOURCES}
- ${KEY_MANAGER_PATH}/crypto/se-backend/internals.cpp
- )
-SET(ENCRYPTION_SCHEME_DEP_LIBRARIES ${TEST_LINK_EXTRA_DEPS} key-manager-se-backend)
-ENDIF()
-
ADD_EXECUTABLE(${TARGET_CKM_GENERATOR} ${GENERATOR_SOURCES} ${ENCRYPTION_SCHEME_SOURCES})
SET(SCHEME_TEST_LIBRARIES
)
ENDIF()
-IF(SE_BACKEND_ENABLED)
-SET(TEST_MERGED_SOURCES
- ${TEST_MERGED_SOURCES}
- ${KEY_MANAGER_PATH}/crypto/se-backend/internals.cpp
- )
-SET(TEST_LINK_EXTRA_DEPS ${TEST_LINK_EXTRA_DEPS} key-manager-se-backend)
-ENDIF()
-
LINK_DIRECTORIES(${KEY_MANAGER_DEP_LIBRARY_DIRS})
ADD_EXECUTABLE(${TARGET_TEST_MERGED} ${TEST_MERGED_SOURCES} ${ENCRYPTION_SCHEME_SOURCES})
CKM::WrappedKeyAndInfo wrapped3;
wrapped3.keyInfo.keyLength = MAX_WRAPPED_KEY_SIZE;
- CKM::WrappedKeyAndInfoContainer wrappedContainer3;
- BOOST_REQUIRE_NO_THROW(wrappedContainer3.setWrappedKeyAndInfo(
+ BOOST_REQUIRE_NO_THROW(CKM::WrappedKeyAndInfoContainer wrappedContainer3(
reinterpret_cast<unsigned char*>(&wrapped3)));
}
CKM::WrappedKeyAndInfo wrapped3;
wrapped3.keyInfo.keyLength = MAX_WRAPPED_KEY_SIZE + 1;
- CKM::WrappedKeyAndInfoContainer wrappedContainer3;
- BOOST_REQUIRE_THROW(wrappedContainer3.setWrappedKeyAndInfo(
+ BOOST_REQUIRE_THROW(CKM::WrappedKeyAndInfoContainer wrappedContainer3(
reinterpret_cast<unsigned char*>(&wrapped3)),
CKM::Exc::InternalError);
// missing NULL termination in wrapped4.keyInfo.client
CKM::WrappedKeyAndInfo wrapped4;
memset(&wrapped4, 0x01, sizeof(CKM::WrappedKeyAndInfo));
- CKM::WrappedKeyAndInfoContainer wrappedContainer4;
- BOOST_REQUIRE_THROW(wrappedContainer4.setWrappedKeyAndInfo(
+ BOOST_REQUIRE_THROW(CKM::WrappedKeyAndInfoContainer wrappedContainer3(
reinterpret_cast<unsigned char*>(&wrapped4)),
CKM::Exc::InternalError);
}
)
ENDIF()
-IF(SE_BACKEND_ENABLED)
-SET(CKM_DB_TOOLS_SOURCES
- ${CKM_DB_TOOLS_SOURCES}
- ${KEY_MANAGER_PATH}/crypto/se-backend/internals.cpp
- )
-SET(CKM_DB_TOOL_LINK_EXTRA_DEPS ${CKM_DB_TOOL_LINK_EXTRA_DEPS} key-manager-se-backend)
-ENDIF()
-
LINK_DIRECTORIES(${CKM_DB_TOOL_DEP_LIBRARY_DIRS})
ADD_EXECUTABLE(${CKM_DB_TOOL} ${CKM_DB_TOOLS_SOURCES} ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm_db_tool.cpp)