add the se-backend for db encryption
[platform/core/security/key-manager.git] / src / manager / service / key-provider.cpp
1 /*
2  *  Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16
17 #include <exception.h>
18 #include <key-provider.h>
19 #include <dpl/log/log.h>
20 #include <ckm/ckm-zero-memory.h>
21 #include <string.h>
22
23 #include <array>
24 #include <memory>
25 #include <crypto-backend.h>
26 #ifdef SE_BACKEND_ENABLED
27 #include <se-backend/internals.h>
28 #endif
29 using namespace CKM;
30
31 namespace {
32
33 template<typename T>
34 RawBuffer toRawBuffer(const T &data)
35 {
36         RawBuffer output;
37         const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&data);
38         output.assign(ptr, ptr + sizeof(T));
39         return output;
40 }
41
42 // You cannot use toRawBuffer template with pointers
43 template<typename T>
44 RawBuffer toRawBuffer(T *)
45 {
46         class NoPointerAllowed {
47                 NoPointerAllowed() {}
48         };
49         NoPointerAllowed a;
50         return RawBuffer();
51 }
52
53 typedef std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)> CipherCtxPtr;
54
55 int encryptAes256Gcm(const unsigned char *plaintext,
56                      int plaintext_len, const unsigned char *key, const unsigned char *iv,
57                      unsigned char *ciphertext, unsigned char *tag)
58 {
59         int len;
60         int ciphertext_len = 0;
61
62         CipherCtxPtr ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
63         if (!ctx)
64                 return OPENSSL_ENGINE_ERROR;
65
66         if (!EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_gcm(), NULL, NULL, NULL))
67                 return OPENSSL_ENGINE_ERROR;
68
69         if (!EVP_EncryptInit_ex(ctx.get(), NULL, NULL, key, iv))
70                 return OPENSSL_ENGINE_ERROR;
71
72         if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
73                 return OPENSSL_ENGINE_ERROR;
74
75         if (!EVP_EncryptUpdate(ctx.get(), ciphertext, &len, plaintext, plaintext_len))
76                 return OPENSSL_ENGINE_ERROR;
77
78         ciphertext_len = len;
79
80         if (!EVP_EncryptFinal_ex(ctx.get(), ciphertext + len, &len))
81                 return OPENSSL_ENGINE_ERROR;
82
83         ciphertext_len += len;
84
85         if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag))
86                 return OPENSSL_ENGINE_ERROR;
87
88         return ciphertext_len;
89 }
90
91 int decryptAes256Gcm(const unsigned char *ciphertext,
92                      int ciphertext_len, unsigned char *tag, const unsigned char *key,
93                      const unsigned char *iv, unsigned char *plaintext)
94 {
95         int len;
96         int plaintext_len;
97         int ret;
98
99         CipherCtxPtr ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
100         if (!ctx)
101                 return OPENSSL_ENGINE_ERROR;
102
103         if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_gcm(), NULL, NULL, NULL))
104                 return OPENSSL_ENGINE_ERROR;
105
106         if (!EVP_DecryptInit_ex(ctx.get(), NULL, NULL, key, iv))
107                 return OPENSSL_ENGINE_ERROR;
108
109         if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
110                 return OPENSSL_ENGINE_ERROR;
111
112         if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag))
113                 return OPENSSL_ENGINE_ERROR;
114
115         if (!EVP_DecryptUpdate(ctx.get(), plaintext, &len, ciphertext, ciphertext_len))
116                 return OPENSSL_ENGINE_ERROR;
117
118         plaintext_len = len;
119
120         if (!(ret = EVP_DecryptFinal_ex(ctx.get(), plaintext + len, &len)))
121                 return OPENSSL_ENGINE_ERROR;
122
123         if (ret > 0) {
124                 plaintext_len += len;
125                 return plaintext_len;
126         } else {
127                 return -1;
128         }
129 }
130
131 typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
132 // derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
133 KeyData makePKEK1(const KeyComponentsInfoDKEK& keyInfo, const Password &password)
134 {
135         std::string concatPasswordClient(password.c_str());
136         concatPasswordClient += std::string(keyInfo.client);
137         KeyData key;
138         if (keyInfo.version != KEYCOMPONENT_VERSION)
139                 ThrowErr(Exc::InternalError, "It's not expected version");
140
141 #if SE_BACKEND_ENABLED
142         RawBuffer salt;
143         if (keyInfo.backend == (int)CryptoBackend::SecureElement) {
144                 RawBuffer salt = Crypto::SE::Internals::encryptWithDbpKey((unsigned char*)keyInfo.salt, MAX_SALT_SIZE,
145                                                                                 (unsigned char*)keyInfo.iv, MAX_IV_SIZE);
146         } else {
147                 salt = RawBuffer(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
148         }
149 #else
150         if (keyInfo.backend != (int)CryptoBackend::OpenSSL)
151                 ThrowErr(Exc::InternalError, "It's not expected backend");
152
153         RawBuffer salt(keyInfo.salt, keyInfo.salt + MAX_SALT_SIZE);
154 #endif
155         if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
156                                     concatPasswordClient.size(),
157                                     salt.data(),
158                                     salt.size(),
159                                     PBKDF2_ITERATIONS,
160                                     key.size(),
161                                     key.data())) {
162                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
163         }
164         return key;
165 }
166
167 // derives a key (PKEK2) from DomainKEK and custom client string (may be a client id or uid)
168 KeyData makePKEK2(const uint8_t *domainKEK, const std::string &client)
169 {
170         KeyData key;
171         if (!PKCS5_PBKDF2_HMAC_SHA1(client.c_str(),
172                                     client.size(),
173                                     domainKEK,
174                                     MAX_SALT_SIZE,
175                                     PBKDF2_ITERATIONS,
176                                     key.size(),
177                                     key.data())) {
178                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
179         }
180         return key;
181 }
182
183 void unwrapDomainKEK(const RawBuffer &wrappedDomainKEKbuffer,
184                      const Password &password,
185                      KeyAndInfoContainer &domainKEK)
186 {
187         WrappedKeyAndInfoContainer wrappedDomainKEK;
188         wrappedDomainKEK.setWrappedDKEKAndInfo(wrappedDomainKEKbuffer.data());
189         KeyData PKEK1 = makePKEK1(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo, password);
190
191         int keyLength;
192         if (0 > (keyLength = decryptAes256Gcm(wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
193                                               wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.keyLength,
194                                               wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.tag,
195                                               PKEK1.data(),
196                                               wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.iv,
197                                               domainKEK.getDKEKAndInfo().key)))
198                 ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
199
200         domainKEK.setKeyInfo(&(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo));
201         domainKEK.setDKEKInfo(wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.version,
202                                                 wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.backend);
203         domainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
204 }
205
206 RawBuffer wrapDomainKEK(KeyAndInfoContainer &domainKEK, const Password &password)
207 {
208         KeyData PKEK1 = makePKEK1(domainKEK.getDKEKAndInfo().keyInfo, password);
209
210         WrappedKeyAndInfoContainer wrappedDomainKEK = WrappedKeyAndInfoContainer();
211         wrappedDomainKEK.setKeyInfo(&(domainKEK.getDKEKAndInfo().keyInfo));
212         wrappedDomainKEK.setDKEKInfo(domainKEK.getDKEKAndInfo().keyInfo.version,
213                                                                 domainKEK.getDKEKAndInfo().keyInfo.backend);
214
215         int wrappedLength;
216         if (0 > (wrappedLength = encryptAes256Gcm(domainKEK.getDKEKAndInfo().key,
217                                                   domainKEK.getDKEKAndInfo().keyInfo.keyLength,
218                                                   PKEK1.data(),
219                                                   domainKEK.getDKEKAndInfo().keyInfo.iv,
220                                                   wrappedDomainKEK.getWrappedDKEKAndInfo().wrappedKey,
221                                                   wrappedDomainKEK.getWrappedDKEKAndInfo().keyInfo.tag)))
222                 ThrowErr(Exc::InternalError, "DomainKEK encryption failed");
223
224         wrappedDomainKEK.setKeyInfoKeyLength(static_cast<unsigned int>(wrappedLength));
225         return toRawBuffer(wrappedDomainKEK.getWrappedDKEKAndInfo());
226 }
227
228 template <size_t N>
229 bool randomize(uint8_t (&array)[N])
230 {
231         return RAND_bytes(array, N) == 1;
232 }
233
234 } // anonymous namespace
235
236 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
237 {
238         memset(&wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
239         memset(&wrappedDKEKAndInfo, 0, sizeof(WrappedKeyAndInfoDKEK));
240 }
241
242 WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
243 {
244         return wrappedKeyAndInfo;
245 }
246
247 WrappedKeyAndInfoDKEK &WrappedKeyAndInfoContainer::getWrappedDKEKAndInfo()
248 {
249         return wrappedDKEKAndInfo;
250 }
251
252 void WrappedKeyAndInfoContainer::setWrappedKeyAndInfo(
253                 const unsigned char *data)
254 {
255         memcpy(&wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
256
257         if (wrappedKeyAndInfo.keyInfo.keyLength > sizeof(wrappedKeyAndInfo.wrappedKey)) {
258                 ThrowErr(Exc::InternalError,
259                          "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
260         }
261
262         size_t maxlen = sizeof(wrappedKeyAndInfo.keyInfo.client);
263         if (strnlen(wrappedKeyAndInfo.keyInfo.client, maxlen) == maxlen) {
264                 ThrowErr(Exc::InternalError,
265                          "Wrapped key info is corrupted. Client id is not NULL terminated.");
266         }
267 }
268
269 void WrappedKeyAndInfoContainer::setWrappedDKEKAndInfo(
270                 const unsigned char *data)
271 {
272         memcpy(&wrappedDKEKAndInfo, data, sizeof(WrappedKeyAndInfoDKEK));
273
274         if (wrappedDKEKAndInfo.keyInfo.keyLength > sizeof(wrappedDKEKAndInfo.wrappedKey)) {
275                 ThrowErr(Exc::InternalError,
276                          "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
277         }
278
279         size_t maxlen = sizeof(wrappedDKEKAndInfo.keyInfo.client);
280         if (strnlen(wrappedDKEKAndInfo.keyInfo.client, maxlen) == maxlen) {
281                 ThrowErr(Exc::InternalError,
282                          "Wrapped key info is corrupted. Client id is not NULL terminated.");
283         }
284 }
285
286 void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
287 {
288         wrappedKeyAndInfo.keyInfo.keyLength = length;
289         wrappedDKEKAndInfo.keyInfo.keyLength = length;
290 }
291
292 void WrappedKeyAndInfoContainer::setKeyInfoClient(const std::string resized_client)
293 {
294         if (resized_client.size() >= sizeof(wrappedKeyAndInfo.keyInfo.client)) {
295                 ThrowErr(Exc::InternalError, "Client name too long");
296         }
297
298         strncpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
299         strncpy(wrappedDKEKAndInfo.keyInfo.client, resized_client.c_str(), resized_client.size());
300 }
301
302 void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
303                 const int size)
304 {
305         memcpy(wrappedKeyAndInfo.keyInfo.salt, salt, size);
306         memcpy(wrappedDKEKAndInfo.keyInfo.salt, salt, size);
307 }
308
309 void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
310                 *keyComponentsInfo)
311 {
312         memcpy(&(wrappedKeyAndInfo.keyInfo), keyComponentsInfo,
313                    sizeof(KeyComponentsInfo));
314         wrappedDKEKAndInfo.keyInfo.set(wrappedKeyAndInfo.keyInfo);
315 }
316
317 void WrappedKeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
318 {
319         wrappedDKEKAndInfo.keyInfo.version = version;
320         wrappedDKEKAndInfo.keyInfo.backend = backend;
321 }
322
323 WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
324 {
325 }
326
327 KeyAndInfoContainer::KeyAndInfoContainer()
328 {
329         memset(&keyAndInfo, 0, sizeof(KeyAndInfo));
330         memset(&DKEKAndInfo, 0, sizeof(KeyAndInfoDKEK));
331 }
332
333 KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
334 {
335         return keyAndInfo;
336 }
337
338 KeyAndInfoDKEK &KeyAndInfoContainer::getDKEKAndInfo()
339 {
340         return DKEKAndInfo;
341 }
342
343 void KeyAndInfoContainer::setKeyAndInfo(const unsigned char *data)
344 {
345         memcpy(&keyAndInfo, data, sizeof(KeyAndInfo));
346 }
347
348 void KeyAndInfoContainer::setDKEKAndInfo(const unsigned char *data)
349 {
350         memcpy(&DKEKAndInfo, data, sizeof(KeyAndInfoDKEK));
351 }
352
353 void KeyAndInfoContainer::setKeyInfoKeyLength(const uint32_t length)
354 {
355         keyAndInfo.keyInfo.keyLength = length;
356         DKEKAndInfo.keyInfo.keyLength = length;
357 }
358
359 void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
360 {
361         memcpy(&(keyAndInfo.keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
362         DKEKAndInfo.keyInfo.set(keyAndInfo.keyInfo);
363 }
364
365 void KeyAndInfoContainer::setDKEKInfo(const uint32_t version, const uint32_t backend)
366 {
367         DKEKAndInfo.keyInfo.version = version;
368         DKEKAndInfo.keyInfo.backend = backend;
369 }
370
371 KeyAndInfoContainer::~KeyAndInfoContainer()
372 {
373         // overwrite key
374         ZeroMemory(reinterpret_cast<unsigned char*>(&keyAndInfo), sizeof(KeyAndInfo));
375         ZeroMemory(reinterpret_cast<unsigned char*>(&DKEKAndInfo), sizeof(KeyAndInfoDKEK));
376 }
377
378 KeyProvider::KeyProvider() :
379         m_domainKEK(NULL),
380         m_isInitialized(false)
381 {
382         LogDebug("Created empty KeyProvider");
383 }
384
385 KeyProvider::KeyProvider(
386         const RawBuffer &domainKEKInWrapForm,
387         const Password &password) :
388         m_domainKEK(new KeyAndInfoContainer()),
389         m_isInitialized(true)
390 {
391         if (!m_isInitialized)
392                 ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
393
394         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfoDKEK)) {
395                 LogWarning("input size:" << domainKEKInWrapForm.size()
396                                  << " Expected: " << sizeof(WrappedKeyAndInfoDKEK));
397                 LogWarning("buffer doesn't have proper size to store WrappedKeyAndInfoDKEK in KeyProvider Constructor");
398                 m_isInitialized = false;
399                 return;
400         }
401
402         unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK);
403 }
404
405 KeyProvider &KeyProvider::operator=(KeyProvider &&second)
406 {
407         LogDebug("Moving KeyProvider");
408
409         if (this == &second)
410                 return *this;
411
412         m_isInitialized = second.m_isInitialized;
413         m_domainKEK = second.m_domainKEK;
414         second.m_isInitialized = false;
415         second.m_domainKEK = NULL;
416         return *this;
417 }
418
419 KeyProvider::KeyProvider(KeyProvider &&second)
420 {
421         LogDebug("Moving KeyProvider");
422         m_isInitialized = second.m_isInitialized;
423         m_domainKEK = second.m_domainKEK;
424         second.m_isInitialized = false;
425         second.m_domainKEK = NULL;
426 }
427
428 bool KeyProvider::isInitialized()
429 {
430         return m_isInitialized;
431 }
432
433 RawBuffer KeyProvider::getPureDomainKEK()
434 {
435         if (!m_isInitialized)
436                 ThrowErr(Exc::InternalError, "Object not initialized!");
437
438         // TODO secure
439         return RawBuffer(m_domainKEK->getDKEKAndInfo().key,
440                                          (m_domainKEK->getDKEKAndInfo().key) +
441                                          m_domainKEK->getDKEKAndInfo().keyInfo.keyLength);
442 }
443
444 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
445 {
446         if (!m_isInitialized)
447                 ThrowErr(Exc::InternalError, "Object not initialized!");
448
449         return wrapDomainKEK(*m_domainKEK, password);
450 }
451
452
453 RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
454 {
455         if (!m_isInitialized)
456                 ThrowErr(Exc::InternalError, "Object not initialized!");
457
458         if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
459                 LogError("input size:" << DEKInWrapForm.size()
460                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
461
462                 ThrowErr(Exc::InternalError,
463                                  "buffer doesn't have proper size to store "
464                                  "WrappedKeyAndInfo in KeyProvider::getPureDEK");
465         }
466
467         KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
468         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
469         wkmcDEK.setWrappedKeyAndInfo(DEKInWrapForm.data());
470
471         KeyData PKEK2 = makePKEK2(m_domainKEK->getDKEKAndInfo().key,
472                                   wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
473
474         int keyLength;
475         if (0 > (keyLength = decryptAes256Gcm(
476                                                          wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
477                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
478                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
479                                                          PKEK2.data(),
480                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
481                                                          kmcDEK.getKeyAndInfo().key)))
482                 ThrowErr(Exc::InternalError,
483                                  "UnwrapDEK Failed in KeyProvider::getPureDEK");
484
485         kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
486
487         LogDebug("getPureDEK SUCCESS");
488         return RawBuffer(
489                            kmcDEK.getKeyAndInfo().key,
490                            (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
491 }
492
493 RawBuffer KeyProvider::generateDEK(const std::string &client)
494 {
495         if (!m_isInitialized)
496                 ThrowErr(Exc::InternalError, "Object not initialized!");
497
498         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
499         std::string resized_client;
500
501         if (client.length() < MAX_CLIENT_ID_SIZE)
502                 resized_client = client;
503         else
504                 resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1);
505
506         uint8_t key[MAX_KEY_SIZE];
507
508         if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
509                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
510
511         KeyData PKEK2 = makePKEK2(m_domainKEK->getDKEKAndInfo().key, resized_client);
512
513         int wrappedKeyLength;
514         if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
515                                                      m_domainKEK->getDKEKAndInfo().keyInfo.keyLength,
516                                                      PKEK2.data(),
517                                                      wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
518                                                      wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
519                                                      wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
520                 ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
521
522         wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
523         wkmcDEK.setKeyInfoClient(resized_client);
524
525         LogDebug("GenerateDEK Success");
526         return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
527 }
528
529 void KeyProvider::migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
530                                                                 const Password &password)
531 {
532         WrappedKeyAndInfo wrappedInfo;
533         if (wrappedDomainKEKbuffer.size() != sizeof(WrappedKeyAndInfo)) {
534                 LogError("[migrateDKEK] Input size:" << wrappedDomainKEKbuffer.size() <<
535                                  " Expected: " << sizeof(WrappedKeyAndInfo));
536                 ThrowErr(Exc::InternalError,
537                                  "buffer doesn't have proper size to store ");
538         }
539         memcpy(&wrappedInfo, wrappedDomainKEKbuffer.data(), sizeof(WrappedKeyAndInfo));
540
541         size_t maxlen = sizeof(wrappedInfo.keyInfo.client);
542         if (strnlen(wrappedInfo.keyInfo.client, maxlen) == maxlen) {
543                 ThrowErr(Exc::InternalError,
544                          "Wrapped key info is corrupted. Client id is not NULL terminated.");
545         }
546
547         KeyComponentsInfo keyInfo = wrappedInfo.keyInfo;
548         std::string concatPasswordClient(password.c_str());
549         concatPasswordClient += std::string(keyInfo.client);
550
551         KeyData PKEK1;
552         if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
553                                     concatPasswordClient.size(),
554                                     keyInfo.salt,
555                                     MAX_SALT_SIZE,
556                                     PBKDF2_ITERATIONS,
557                                     PKEK1.size(),
558                                     PKEK1.data())) {
559                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
560         }
561
562         int keyLength;
563         if (0 > (keyLength = decryptAes256Gcm(wrappedInfo.wrappedKey,
564                                               keyInfo.keyLength,
565                                               keyInfo.tag,
566                                               PKEK1.data(),
567                                               keyInfo.iv,
568                                               m_domainKEK->getDKEKAndInfo().key)))
569                 ThrowErr(Exc::AuthenticationFailed, "DomainKEK decryption failed");
570
571         m_domainKEK->getDKEKAndInfo().keyInfo.set(keyInfo);
572         m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
573 #ifdef SE_BACKEND_ENABLED
574         m_domainKEK->setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
575 #endif
576         m_domainKEK->setKeyInfoKeyLength(static_cast<unsigned int>(keyLength));
577         m_isInitialized = true;
578         LogDebug("Migrate DKEK Success");
579 }
580
581 RawBuffer KeyProvider::reencrypt(
582         const RawBuffer &domainKEKInWrapForm,
583         const Password &oldPass,
584         const Password &newPass)
585 {
586         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
587                 LogError("input size:" << domainKEKInWrapForm.size()
588                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
589                 ThrowErr(Exc::InternalError,
590                                  "buffer doesn't have proper size to store "
591                                  "WrappedKeyAndInfo in KeyProvider::reencrypt");
592         }
593
594         KeyAndInfoContainer domainKEK;
595         unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK);
596         return wrapDomainKEK(domainKEK, newPass);
597 }
598
599 RawBuffer KeyProvider::generateDomainKEK(
600         const std::string &user,
601         const Password &userPassword)
602 {
603         KeyAndInfoContainer domainKEK;
604
605         if (!randomize(domainKEK.getDKEKAndInfo().keyInfo.salt) ||
606                 !randomize(domainKEK.getDKEKAndInfo().key) ||
607             !randomize(domainKEK.getDKEKAndInfo().keyInfo.iv)) {
608                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
609         }
610
611         domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::OpenSSL);
612 #ifdef SE_BACKEND_ENABLED
613         domainKEK.setDKEKInfo(KEYCOMPONENT_VERSION, (uint32_t)CryptoBackend::SecureElement);
614 #endif
615         domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getDKEKAndInfo().key));
616         if (user.size() >= sizeof(domainKEK.getDKEKAndInfo().keyInfo.client)) {
617                 ThrowErr(Exc::InternalError, "Client name too long");
618         }
619         strncpy(domainKEK.getDKEKAndInfo().keyInfo.client, user.c_str(), user.size());
620
621         return wrapDomainKEK(domainKEK, userPassword);
622 }
623
624 int KeyProvider::initializeLibrary()
625 {
626         LogDebug("initializeLibrary Success");
627         return SUCCESS;
628 }
629
630 int KeyProvider::closeLibrary()
631 {
632         LogDebug("closeLibrary Success");
633         return SUCCESS;
634 }
635
636 KeyProvider::~KeyProvider()
637 {
638         LogDebug("KeyProvider Destructor");
639 }