From 5e3b7607fa9ecbb685a8d7bbc9c7de10d2cdd3b8 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 29 Jan 2019 15:58:55 +0100 Subject: Add helpers for domain KEK encryption/decryption Change-Id: I048649f8a9a3450f6cefcbd9d2d75c8445f46277 --- src/manager/service/key-provider.cpp | 189 +++++++++++++---------------------- src/manager/service/key-provider.h | 2 +- 2 files changed, 73 insertions(+), 118 deletions(-) (limited to 'src') diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp index aea5c9b5..8168fda1 100644 --- a/src/manager/service/key-provider.cpp +++ b/src/manager/service/key-provider.cpp @@ -162,6 +162,46 @@ KeyData makePKEK2(const uint8_t *domainKEK, const std::string &user) return key; } +void unwrapDomainKEK(const RawBuffer &wrappedDomainKEKbuffer, + const Password &password, + KeyAndInfoContainer &domainKEK) +{ + WrappedKeyAndInfoContainer wrappedDomainKEK(wrappedDomainKEKbuffer.data()); + + KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo, password); + + int keyLength; + if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey, + wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.keyLength, + wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag, + PKEK1.data(), + wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.iv, + domainKEK.getKeyAndInfo().key))) + ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed"); + + domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo)); + domainKEK.setKeyInfoKeyLength(static_cast(keyLength)); +} + +RawBuffer wrapDomainKEK(KeyAndInfoContainer &domainKEK, const Password &password) +{ + KeyData PKEK1 = makePKEK1(domainKEK.getKeyAndInfo().keyInfo, password); + + WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer(); + wrappedDomainKEK.setKeyInfo(&(domainKEK.getKeyAndInfo().keyInfo)); + + int wrappedLength; + if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getKeyAndInfo().key, + domainKEK.getKeyAndInfo().keyInfo.keyLength, + PKEK1.data(), + domainKEK.getKeyAndInfo().keyInfo.iv, + wrappedDomainKEK.getWrappedKeyAndInfo().wrappedKey, + wrappedDomainKEK.getWrappedKeyAndInfo().keyInfo.tag))) + ThrowErr(Exc::InternalError, "DomainKEK encryption failed"); + + wrappedDomainKEK.setKeyInfoKeyLength(static_cast(wrappedLength)); + return toRawBuffer(wrappedDomainKEK.getWrappedKeyAndInfo()); +} template bool randomize(uint8_t (&array)[N]) @@ -268,7 +308,7 @@ KeyAndInfoContainer::~KeyAndInfoContainer() } KeyProvider::KeyProvider() : - m_kmcDKEK(NULL), + m_domainKEK(NULL), m_isInitialized(false) { LogDebug("Created empty KeyProvider"); @@ -277,7 +317,7 @@ KeyProvider::KeyProvider() : KeyProvider::KeyProvider( const RawBuffer &domainKEKInWrapForm, const Password &password) : - m_kmcDKEK(new KeyAndInfoContainer()), + m_domainKEK(new KeyAndInfoContainer()), m_isInitialized(true) { if (!m_isInitialized) @@ -290,25 +330,7 @@ KeyProvider::KeyProvider( "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor"); } - WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer( - domainKEKInWrapForm.data()); - - KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password); - - int keyLength; - if (0 > (keyLength = decryptAes256Gcm( - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1.data(), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, - m_kmcDKEK->getKeyAndInfo().key))) { - ThrowErr(Exc::AuthenticationFailed, - "VerifyDomainKEK failed in KeyProvider Constructor"); - } - - m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo)); - m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength); + unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK); } KeyProvider &KeyProvider::operator=(KeyProvider &&second) @@ -319,9 +341,9 @@ KeyProvider &KeyProvider::operator=(KeyProvider &&second) return *this; m_isInitialized = second.m_isInitialized; - m_kmcDKEK = second.m_kmcDKEK; + m_domainKEK = second.m_domainKEK; second.m_isInitialized = false; - second.m_kmcDKEK = NULL; + second.m_domainKEK = NULL; return *this; } @@ -329,9 +351,9 @@ KeyProvider::KeyProvider(KeyProvider &&second) { LogDebug("Moving KeyProvider"); m_isInitialized = second.m_isInitialized; - m_kmcDKEK = second.m_kmcDKEK; + m_domainKEK = second.m_domainKEK; second.m_isInitialized = false; - second.m_kmcDKEK = NULL; + second.m_domainKEK = NULL; } bool KeyProvider::isInitialized() @@ -345,9 +367,9 @@ RawBuffer KeyProvider::getPureDomainKEK() ThrowErr(Exc::InternalError, "Object not initialized!"); // TODO secure - return RawBuffer(m_kmcDKEK->getKeyAndInfo().key, - (m_kmcDKEK->getKeyAndInfo().key) + - m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength); + return RawBuffer(m_domainKEK->getKeyAndInfo().key, + (m_domainKEK->getKeyAndInfo().key) + + m_domainKEK->getKeyAndInfo().keyInfo.keyLength); } RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password) @@ -355,26 +377,7 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password) if (!m_isInitialized) ThrowErr(Exc::InternalError, "Object not initialized!"); - WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo)); - - KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password); - - int wrappedKeyLength; - - if (0 > (wrappedKeyLength = encryptAes256Gcm( - m_kmcDKEK->getKeyAndInfo().key, - m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK1.data(), - m_kmcDKEK->getKeyAndInfo().keyInfo.iv, - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK"); - - wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - - LogDebug("getDomainKEK(password) Success"); - return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); + return wrapDomainKEK(*m_domainKEK, password); } @@ -395,7 +398,7 @@ RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm) WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer( DEKInWrapForm.data()); - KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, + KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, wkmcDEK.getWrappedKeyAndInfo().keyInfo.client); int keyLength; @@ -435,16 +438,15 @@ RawBuffer KeyProvider::generateDEK(const ClientId &client) if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv)) ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, resized_client); + KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, resized_client); int wrappedKeyLength; - if (0 > (wrappedKeyLength = encryptAes256Gcm( - key, - m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK2.data(), - wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, - wkmcDEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) + if (0 > (wrappedKeyLength = encryptAes256Gcm(key, + m_domainKEK->getKeyAndInfo().keyInfo.keyLength, + PKEK2.data(), + wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, + wkmcDEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK"); wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); @@ -467,45 +469,9 @@ RawBuffer KeyProvider::reencrypt( "WrappedKeyAndInfo in KeyProvider::reencrypt"); } - WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer( - domainKEKInWrapForm.data()); - WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer(); - KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer(); - - KeyData PKEK1 = makePKEK1(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo, oldPass); - - int keyLength = 0; - if (0 > (keyLength = decryptAes256Gcm( - wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1.data(), - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv, - kmcDKEK.getKeyAndInfo().key))) - ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password "); - - kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo)); - kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength); - - PKEK1 = makePKEK1(wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo, newPass); - - wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo)); - - int wrappedKeyLength = 0; - if (0 > (wrappedKeyLength = encryptAes256Gcm( - kmcDKEK.getKeyAndInfo().key, - kmcDKEK.getKeyAndInfo().keyInfo.keyLength, - PKEK1.data(), - kmcDKEK.getKeyAndInfo().keyInfo.iv, - wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, - "UpdateDomainKEK in KeyProvider::reencrypt Failed"); - - wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - - LogDebug("reencrypt SUCCESS"); - return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo()); + KeyAndInfoContainer domainKEK; + unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK); + return wrapDomainKEK(domainKEK, newPass); } RawBuffer KeyProvider::generateDomainKEK( @@ -513,34 +479,23 @@ RawBuffer KeyProvider::generateDomainKEK( const Password &userPassword) { WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - uint8_t key[MAX_KEY_SIZE]; - int wrappedKeyLength; - wkmcDKEK.setKeyInfoClient(user); + KeyAndInfoContainer domainKEK; - if (!randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt) || - !randomize(key) || - !randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv)) { + if (!randomize(domainKEK.getKeyAndInfo().keyInfo.salt) || + !randomize(domainKEK.getKeyAndInfo().key) || + !randomize(domainKEK.getKeyAndInfo().keyInfo.iv)) { ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); } - KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, userPassword); + domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getKeyAndInfo().key)); - if (0 > (wrappedKeyLength = encryptAes256Gcm( - key, - sizeof(key), - PKEK1.data(), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, - "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK"); - - wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - wkmcDKEK.setKeyInfoClient(user); + if (user.size() >= sizeof(domainKEK.getKeyAndInfo().keyInfo.client)) { + ThrowErr(Exc::InternalError, "Client name too long"); + } + strcpy(domainKEK.getKeyAndInfo().keyInfo.client, user.c_str()); - LogDebug("generateDomainKEK Success"); - return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); + return wrapDomainKEK(domainKEK, userPassword); } int KeyProvider::initializeLibrary() diff --git a/src/manager/service/key-provider.h b/src/manager/service/key-provider.h index ed47b586..23523fae 100644 --- a/src/manager/service/key-provider.h +++ b/src/manager/service/key-provider.h @@ -165,7 +165,7 @@ public: private: // KeyAndInfoContainer class - std::shared_ptr m_kmcDKEK; + std::shared_ptr m_domainKEK; bool m_isInitialized; }; -- cgit v1.2.3