2 #include <key-provider.h>
3 #include <dpl/log/log.h>
8 CKM::RawBuffer toRawBuffer(const T &data)
10 CKM::RawBuffer output;
11 const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&data);
12 output.assign(ptr, ptr + sizeof(T));
16 // You cannot use toRawBuffer template with pointers
18 CKM::RawBuffer toRawBuffer(T *)
20 class NoPointerAllowed {
24 return CKM::RawBuffer();
27 } // anonymous namespace
31 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
33 wrappedKeyAndInfo = new WrappedKeyAndInfo;
34 memset(wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
37 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char
40 wrappedKeyAndInfo = new WrappedKeyAndInfo;
41 memcpy(wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
44 WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
46 return *wrappedKeyAndInfo;
49 void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length)
51 wrappedKeyAndInfo->keyInfo.keyLength = length;
54 void WrappedKeyAndInfoContainer::setKeyInfoLabel(const std::string label)
57 wrappedKeyAndInfo->keyInfo.label,
62 void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
65 memcpy(wrappedKeyAndInfo->keyInfo.salt, salt, size);
68 void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
71 memcpy(&(wrappedKeyAndInfo->keyInfo), keyComponentsInfo,
72 sizeof(KeyComponentsInfo));
75 WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
77 delete wrappedKeyAndInfo;
80 KeyAndInfoContainer::KeyAndInfoContainer()
82 keyAndInfo = new KeyAndInfo;
83 memset(keyAndInfo, 0, sizeof(KeyAndInfo));
86 KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
88 keyAndInfo = new KeyAndInfo;
89 memcpy(keyAndInfo, data, sizeof(KeyAndInfo));
92 KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
97 void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length)
99 keyAndInfo->keyInfo.keyLength = length;
102 void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
104 memcpy(&(keyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
107 KeyAndInfoContainer::~KeyAndInfoContainer()
110 char *ptr = reinterpret_cast<char *>(keyAndInfo);
111 memset(ptr, 0, sizeof(KeyAndInfo));
114 for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) {
116 LogError("Write momory error! Memory used by key was not owerwritten.");
122 KeyProvider::KeyProvider() :
124 m_isInitialized(false)
126 LogDebug("Created empty KeyProvider");
129 KeyProvider::KeyProvider(
130 const RawBuffer &domainKEKInWrapForm,
131 const Password &password) :
132 m_kmcDKEK(new KeyAndInfoContainer()),
133 m_isInitialized(true)
135 if (!m_isInitialized)
136 ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
138 if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
139 LogError("input size:" << domainKEKInWrapForm.size()
140 << " Expected: " << sizeof(WrappedKeyAndInfo));
141 ThrowErr(Exc::InternalError,
142 "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
145 WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(
146 domainKEKInWrapForm.data());
148 char *concat_user_pass = NULL;
149 uint8_t PKEK1[MAX_KEY_SIZE];
151 concat_user_pass = concat_password_user(
152 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.label,
155 if (!PKCS5_PBKDF2_HMAC_SHA1(
157 strlen(concat_user_pass),
158 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
163 delete[] concat_user_pass;
164 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
167 delete[] concat_user_pass;
171 if (0 > (keyLength = decryptAes256Gcm(
172 wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
173 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
174 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag,
176 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
177 m_kmcDKEK->getKeyAndInfo().key))) {
178 ThrowErr(Exc::AuthenticationFailed,
179 "VerifyDomainKEK failed in KeyProvider Constructor");
182 m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo));
183 m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength);
186 KeyProvider &KeyProvider::operator=(KeyProvider &&second)
188 LogDebug("Moving KeyProvider");
193 m_isInitialized = second.m_isInitialized;
194 m_kmcDKEK = second.m_kmcDKEK;
195 second.m_isInitialized = false;
196 second.m_kmcDKEK = NULL;
200 KeyProvider::KeyProvider(KeyProvider &&second)
202 LogDebug("Moving KeyProvider");
203 m_isInitialized = second.m_isInitialized;
204 m_kmcDKEK = second.m_kmcDKEK;
205 second.m_isInitialized = false;
206 second.m_kmcDKEK = NULL;
209 bool KeyProvider::isInitialized()
211 return m_isInitialized;
214 RawBuffer KeyProvider::getPureDomainKEK()
216 if (!m_isInitialized)
217 ThrowErr(Exc::InternalError, "Object not initialized!");
220 return RawBuffer(m_kmcDKEK->getKeyAndInfo().key,
221 (m_kmcDKEK->getKeyAndInfo().key) +
222 m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength);
225 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
227 if (!m_isInitialized)
228 ThrowErr(Exc::InternalError, "Object not initialized!");
230 WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
232 char *concat_user_pass = NULL;
233 uint8_t PKEK1[MAX_KEY_SIZE];
235 concat_user_pass = concat_password_user(
236 m_kmcDKEK->getKeyAndInfo().keyInfo.label,
239 if (!PKCS5_PBKDF2_HMAC_SHA1(
241 strlen(concat_user_pass),
242 m_kmcDKEK->getKeyAndInfo().keyInfo.salt,
247 delete[] concat_user_pass;
248 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
251 delete[] concat_user_pass;
253 wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo));
255 int wrappedKeyLength;
257 if (0 > (wrappedKeyLength = encryptAes256Gcm(
258 m_kmcDKEK->getKeyAndInfo().key,
259 m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
261 m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
262 wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
263 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
264 ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK");
266 wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
268 LogDebug("getDomainKEK(password) Success");
269 return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
273 RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
275 if (!m_isInitialized)
276 ThrowErr(Exc::InternalError, "Object not initialized!");
278 if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
279 LogError("input size:" << DEKInWrapForm.size()
280 << " Expected: " << sizeof(WrappedKeyAndInfo));
281 ThrowErr(Exc::InternalError,
282 "buffer doesn't have proper size to store "
283 "WrappedKeyAndInfo in KeyProvider::getPureDEK");
286 KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
287 WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
288 DEKInWrapForm.data());
290 uint8_t PKEK2[MAX_KEY_SIZE];
293 if (!PKCS5_PBKDF2_HMAC_SHA1(
294 wkmcDEK.getWrappedKeyAndInfo().keyInfo.label,
295 strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.label),
296 m_kmcDKEK->getKeyAndInfo().key,
301 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
303 if (0 > (keyLength = decryptAes256Gcm(
304 wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
305 wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
306 wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
308 wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
309 kmcDEK.getKeyAndInfo().key)))
310 ThrowErr(Exc::InternalError,
311 "UnwrapDEK Failed in KeyProvider::getPureDEK");
313 kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
315 LogDebug("getPureDEK SUCCESS");
317 kmcDEK.getKeyAndInfo().key,
318 (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
321 RawBuffer KeyProvider::generateDEK(const std::string &smackLabel)
323 if (!m_isInitialized)
324 ThrowErr(Exc::InternalError, "Object not initialized!");
326 WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
327 std::string resized_smackLabel;
329 if (smackLabel.length() < APP_LABEL_SIZE)
330 resized_smackLabel = smackLabel;
332 resized_smackLabel = smackLabel.substr(0, APP_LABEL_SIZE - 1);
334 uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE];
336 if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) ||
337 !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE))
338 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
340 if (!PKCS5_PBKDF2_HMAC_SHA1(
341 resized_smackLabel.c_str(),
342 strlen(resized_smackLabel.c_str()),
343 m_kmcDKEK->getKeyAndInfo().key,
348 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
350 int wrappedKeyLength;
352 if (0 > (wrappedKeyLength = encryptAes256Gcm(
354 m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
356 wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
357 wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
358 wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
359 ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
361 wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
362 wkmcDEK.setKeyInfoLabel(resized_smackLabel);
364 LogDebug("GenerateDEK Success");
365 return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
368 RawBuffer KeyProvider::reencrypt(
369 const RawBuffer &domainKEKInWrapForm,
370 const Password &oldPass,
371 const Password &newPass)
373 if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
374 LogError("input size:" << domainKEKInWrapForm.size()
375 << " Expected: " << sizeof(WrappedKeyAndInfo));
376 ThrowErr(Exc::InternalError,
377 "buffer doesn't have proper size to store "
378 "WrappedKeyAndInfo in KeyProvider::reencrypt");
381 WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer(
382 domainKEKInWrapForm.data());
383 WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer();
384 KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer();
386 char *concat_user_pass = NULL;
387 uint8_t PKEK1[MAX_KEY_SIZE];
391 concat_user_pass = concat_password_user(
392 wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.label,
395 if (!PKCS5_PBKDF2_HMAC_SHA1(
397 strlen(concat_user_pass),
398 wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt,
403 delete[] concat_user_pass;
404 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
407 delete[] concat_user_pass;
409 if (0 > (keyLength = decryptAes256Gcm(
410 wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey,
411 wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
412 wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag,
414 wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
415 kmcDKEK.getKeyAndInfo().key)))
416 ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password ");
418 kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
419 kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
421 concat_user_pass = concat_password_user(
422 kmcDKEK.getKeyAndInfo().keyInfo.label,
425 if (!PKCS5_PBKDF2_HMAC_SHA1(
427 strlen(concat_user_pass),
428 kmcDKEK.getKeyAndInfo().keyInfo.salt,
433 delete[] concat_user_pass;
434 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
437 delete[] concat_user_pass;
439 int wrappedKeyLength = 0;
440 wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
442 if (0 > (wrappedKeyLength = encryptAes256Gcm(
443 kmcDKEK.getKeyAndInfo().key,
444 kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
446 kmcDKEK.getKeyAndInfo().keyInfo.iv,
447 wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
448 wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
449 ThrowErr(Exc::InternalError,
450 "UpdateDomainKEK in KeyProvider::reencrypt Failed");
452 wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
454 LogDebug("reencrypt SUCCESS");
455 return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo());
459 RawBuffer KeyProvider::generateDomainKEK(
460 const std::string &user,
461 const Password &userPassword)
463 WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
464 uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE];
466 if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) ||
467 !RAND_bytes(key, MAX_KEY_SIZE) ||
468 !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE))
469 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
471 int wrappedKeyLength;
472 char *concat_user_pass = NULL;
473 concat_user_pass = concat_password_user(user.c_str(), userPassword.c_str());
475 if (!PKCS5_PBKDF2_HMAC_SHA1(
477 strlen(concat_user_pass),
478 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
483 delete[] concat_user_pass;
484 ThrowErr(Exc::InternalError, "OPENSSL_ENGINED_ERROR");
487 delete[] concat_user_pass;
489 if (0 > (wrappedKeyLength = encryptAes256Gcm(
493 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
494 wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
495 wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
496 ThrowErr(Exc::InternalError,
497 "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK");
499 wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
500 wkmcDKEK.setKeyInfoLabel(user);
502 LogDebug("generateDomainKEK Success");
503 return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
506 int KeyProvider::initializeLibrary()
508 LogDebug("initializeLibrary Success");
512 int KeyProvider::closeLibrary()
514 LogDebug("closeLibrary Success");
518 KeyProvider::~KeyProvider()
520 LogDebug("KeyProvider Destructor");
523 int KeyProvider::encryptAes256Gcm(const unsigned char *plaintext,
524 int plaintext_len, const unsigned char *key, const unsigned char *iv,
525 unsigned char *ciphertext, unsigned char *tag)
529 int ciphertext_len = 0;
531 if (!(ctx = EVP_CIPHER_CTX_new()))
532 return OPENSSL_ENGINE_ERROR;
534 if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
535 return OPENSSL_ENGINE_ERROR;
537 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
538 return OPENSSL_ENGINE_ERROR;
540 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
541 return OPENSSL_ENGINE_ERROR;
543 if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
544 return OPENSSL_ENGINE_ERROR;
546 ciphertext_len = len;
548 if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
549 return OPENSSL_ENGINE_ERROR;
551 ciphertext_len += len;
553 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag))
554 return OPENSSL_ENGINE_ERROR;
556 EVP_CIPHER_CTX_free(ctx);
558 return ciphertext_len;
561 int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext,
562 int ciphertext_len, unsigned char *tag, const unsigned char *key,
563 const unsigned char *iv, unsigned char *plaintext)
570 if (!(ctx = EVP_CIPHER_CTX_new()))
571 return OPENSSL_ENGINE_ERROR;
573 if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
574 return OPENSSL_ENGINE_ERROR;
576 if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
577 return OPENSSL_ENGINE_ERROR;
579 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
580 return OPENSSL_ENGINE_ERROR;
582 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag))
583 return OPENSSL_ENGINE_ERROR;
585 if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
586 return OPENSSL_ENGINE_ERROR;
590 if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len)))
591 return OPENSSL_ENGINE_ERROR;
593 EVP_CIPHER_CTX_free(ctx);
596 plaintext_len += len;
597 return plaintext_len;
603 char *KeyProvider::concat_password_user(const char *user, const char *password)
605 std::string result(password);
608 if (strlen(user) > MAX_LABEL_SIZE - 1)
609 result.resize(strlen(password) + MAX_LABEL_SIZE - 1);
611 char *ret = new char[result.size() + 1];
612 memcpy(ret, result.c_str(), result.size() + 1);