tizen 2.4 release
[framework/security/key-manager.git] / src / manager / service / key-provider.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 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  * @file        key-provider.cpp
18  * @author      kyungwook tak (k.tak@samsung.com)
19  * @version     1.0
20  * @brief       Provide Domain KEK and Application KEK for key-manager.
21  */
22
23 #include <cstring>
24 #include <openssl/rand.h>
25 #include <openssl/err.h>
26 #include <openssl/evp.h>
27 #include <openssl/sha.h>
28
29 #include <key-provider.h>
30 #include <dpl/log/log.h>
31
32 namespace {
33
34 template<typename T>
35 CKM::RawBuffer toRawBuffer(const T &data)
36 {
37     CKM::RawBuffer output;
38     const unsigned char *ptr = reinterpret_cast<const unsigned char*>(&data);
39     output.assign(ptr, ptr + sizeof(T));
40     return output;
41 }
42
43 // You cannot use toRawBuffer template with pointers
44 template<typename T>
45 CKM::RawBuffer toRawBuffer(T *)
46 {
47     class NoPointerAllowed { NoPointerAllowed(){} };
48     NoPointerAllowed a;
49     return CKM::RawBuffer();
50 }
51
52 int cleanMemory(void *targetPtr, size_t targetSize)
53 {
54     char *ptr = reinterpret_cast<char *>(targetPtr);
55
56     // overwrite ptr
57     for (size_t size = 0; size < targetSize; ++size)
58         ptr[size] = 0;
59
60     // verification
61     for (size_t size = 0; size < targetSize; ++size) {
62         if (0 != ptr[size]) {
63             return -1; // fail
64         }
65     }
66     return 0; // success
67 }
68
69 } // anonymous namespace
70
71 using namespace CKM;
72
73 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
74 {
75     wrappedKeyAndInfo = new WrappedKeyAndInfo;
76     memset(wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
77 }
78
79 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const WrappedKeyAndInfoContainer &second)
80 {
81     wrappedKeyAndInfo = new WrappedKeyAndInfo;
82     memcpy(wrappedKeyAndInfo, second.wrappedKeyAndInfo, sizeof(WrappedKeyAndInfo));
83 }
84
85 WrappedKeyAndInfoContainer &WrappedKeyAndInfoContainer::operator=(const WrappedKeyAndInfoContainer &second)
86 {
87     if (this == &second)
88         return *this;
89
90     if (wrappedKeyAndInfo)
91         delete wrappedKeyAndInfo;
92
93     wrappedKeyAndInfo = new WrappedKeyAndInfo;
94     memcpy(wrappedKeyAndInfo, second.wrappedKeyAndInfo, sizeof(WrappedKeyAndInfo));
95     return *this;
96 }
97
98 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char *data)
99 {
100     wrappedKeyAndInfo = new WrappedKeyAndInfo;
101     memcpy(wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
102 }
103
104 WrappedKeyAndInfo& WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
105 {
106     return *wrappedKeyAndInfo;
107 }
108
109 void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length){
110     wrappedKeyAndInfo->keyInfo.keyLength = length;
111 }
112
113 void WrappedKeyAndInfoContainer::setKeyInfoLabel(const std::string label)
114 {
115     int labelLength = label.length();
116     int copyLength;
117
118     if(labelLength <= (MAX_LABEL_SIZE - 1)) {
119       copyLength = labelLength;
120     }
121     else {
122       copyLength = (MAX_LABEL_SIZE - 1);
123     }
124
125     strncpy(
126       wrappedKeyAndInfo->keyInfo.label,
127       label.c_str(),
128       copyLength);
129 }
130
131 void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt, const int size)
132 {
133     memcpy(wrappedKeyAndInfo->keyInfo.salt, salt, size);
134 }
135
136 void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
137 {
138     memcpy(&(wrappedKeyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
139 }
140
141 WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
142 {
143     delete wrappedKeyAndInfo;
144 }
145
146 KeyAndInfoContainer::KeyAndInfoContainer()
147 {
148     keyAndInfo = new KeyAndInfo;
149     memset(keyAndInfo, 0, sizeof(KeyAndInfo));
150 }
151
152 KeyAndInfoContainer::KeyAndInfoContainer(const KeyAndInfoContainer &second)
153 {
154     keyAndInfo = new KeyAndInfo;
155     memcpy(keyAndInfo, second.keyAndInfo, sizeof(KeyAndInfo));
156 }
157
158 KeyAndInfoContainer &KeyAndInfoContainer::operator=(const KeyAndInfoContainer &second)
159 {
160     if (this == &second)
161         return *this;
162
163     if (keyAndInfo) {
164         if (cleanMemory(keyAndInfo, sizeof(KeyAndInfo))) {
165             delete keyAndInfo;
166             ThrowMsg(Exception::Base,
167                      "KeyAndInfo in KeyAndInfoContainer was not destroyed!");
168         }
169         delete keyAndInfo;
170     }
171
172     keyAndInfo = new KeyAndInfo;
173     memcpy(keyAndInfo, second.keyAndInfo, sizeof(KeyAndInfo));
174     return *this;
175 }
176
177 KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
178 {
179     keyAndInfo = new KeyAndInfo;
180     memcpy(keyAndInfo, data, sizeof(KeyAndInfo));
181 }
182
183 KeyAndInfo& KeyAndInfoContainer::getKeyAndInfo()
184 {
185     return *keyAndInfo;
186 }
187
188 void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length)
189 {
190     keyAndInfo->keyInfo.keyLength = length;
191 }
192
193 void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
194 {
195     memcpy(&(keyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
196 }
197
198 KeyAndInfoContainer::~KeyAndInfoContainer()
199 {
200     if (cleanMemory(keyAndInfo, sizeof(KeyAndInfo))) {
201         // destroy verification failed.
202         delete keyAndInfo;
203         ThrowMsg(Exception::Base,
204                  "KeyAndInfo in KeyAndInfoContainer was not destroyed!");
205     }
206
207     delete keyAndInfo;
208 }
209
210 KeyProvider::KeyProvider()
211     : m_kmcDKEK(NULL)
212     , m_isInitialized(false)
213 {
214     LogDebug("Created empty KeyProvider");
215 }
216
217 KeyProvider::KeyProvider(
218     const RawBuffer &domainKEKInWrapForm,
219     const Password &password)
220     : m_kmcDKEK(new KeyAndInfoContainer())
221     , m_isInitialized(true)
222 {
223     if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
224         ThrowMsg(Exception::InputParamError,
225             "domainKEKInWrapForm "
226             "input size:" << domainKEKInWrapForm.size() <<
227             " Expected:" << sizeof(WrappedKeyAndInfo));
228     }
229
230     WrappedKeyAndInfoContainer wkmcDKEK(domainKEKInWrapForm.data());
231
232     char *concat_user_pass = NULL;
233     uint8_t PKEK1[MAX_KEY_SIZE];
234
235     concat_user_pass = concat_password_user(
236         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.label,
237         getConvertedStr(password));
238
239     if (!PKCS5_PBKDF2_HMAC_SHA1(
240         concat_user_pass,
241         strlen(concat_user_pass),
242         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
243         MAX_SALT_SIZE,
244         PBKDF2_ITERATIONS,
245         MAX_KEY_SIZE,
246         PKEK1)) {
247
248         delete[] concat_user_pass;
249         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
250     }
251
252     delete[] concat_user_pass;
253
254     int keyLength;
255
256     if (0 > (keyLength = decryptAes256Gcm(
257         wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
258         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
259         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag,
260         PKEK1,
261         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
262         m_kmcDKEK->getKeyAndInfo().key))) {
263
264         ThrowMsg(Exception::PassWordError,
265             "VerifyDomainKEK failed in KeyProvider Constructor");
266     }
267
268     m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo));
269     m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength);
270 }
271
272 KeyProvider& KeyProvider::operator=(KeyProvider &&second)
273 {
274     LogDebug("Moving KeyProvider");
275     if (this == &second)
276         return *this;
277     m_isInitialized = second.m_isInitialized;
278     m_kmcDKEK = second.m_kmcDKEK;
279     second.m_isInitialized = false;
280     second.m_kmcDKEK = NULL;
281     return *this;
282 }
283
284 KeyProvider::KeyProvider(KeyProvider &&second)
285 {
286     LogDebug("Moving KeyProvider");
287     m_isInitialized = second.m_isInitialized;
288     m_kmcDKEK = second.m_kmcDKEK;
289     second.m_isInitialized = false;
290     second.m_kmcDKEK = NULL;
291 }
292
293 bool KeyProvider::isInitialized()
294 {
295     return m_isInitialized;
296 }
297
298 RawBuffer KeyProvider::getPureDomainKEK()
299 {
300     if (!m_isInitialized) {
301         ThrowMsg(Exception::InitFailed, "Object not initialized!");
302     }
303
304     return RawBuffer(m_kmcDKEK->getKeyAndInfo().key,
305             (m_kmcDKEK->getKeyAndInfo().key)
306                 + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength);
307 }
308
309 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
310 {
311     if (!m_isInitialized) {
312         ThrowMsg(Exception::InitFailed, "Object not initialized!");
313     }
314
315     WrappedKeyAndInfoContainer wkmcDKEK;
316
317     char *concat_user_pass = NULL;
318     uint8_t PKEK1[MAX_KEY_SIZE];
319
320     concat_user_pass = concat_password_user(
321         m_kmcDKEK->getKeyAndInfo().keyInfo.label,
322         getConvertedStr(password));
323
324     if (!PKCS5_PBKDF2_HMAC_SHA1(
325         concat_user_pass,
326         strlen(concat_user_pass),
327         m_kmcDKEK->getKeyAndInfo().keyInfo.salt,
328         MAX_SALT_SIZE,
329         PBKDF2_ITERATIONS,
330         MAX_KEY_SIZE,
331         PKEK1)) {
332
333         delete[] concat_user_pass;
334         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
335     }
336
337     delete[] concat_user_pass;
338
339     wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo));
340
341     int wrappedKeyLength;
342
343     if (0 > (wrappedKeyLength = encryptAes256Gcm(
344         m_kmcDKEK->getKeyAndInfo().key,
345         m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
346         PKEK1,
347         m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
348         wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
349         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
350
351         ThrowMsg(Exception::InitFailed, "WrapDKEK Failed in KeyProvider::getDomainKEK");
352     }
353
354     wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
355
356     LogDebug("getDomainKEK(password) Success");
357     return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
358 }
359
360
361 RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
362 {
363     if (!m_isInitialized) {
364         ThrowMsg(Exception::InitFailed, "Object not initialized!");
365     }
366
367     if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)){
368         ThrowMsg(Exception::InputParamError,
369             "DEKInWrapForm "
370             "input size:" << DEKInWrapForm.size() <<
371             " Expected:" << sizeof(WrappedKeyAndInfo));
372     }
373
374     KeyAndInfoContainer kmcDEK;
375     WrappedKeyAndInfoContainer wkmcDEK(DEKInWrapForm.data());
376
377     uint8_t PKEK2[MAX_KEY_SIZE];
378     int keyLength;
379
380     if (!PKCS5_PBKDF2_HMAC_SHA1(
381         wkmcDEK.getWrappedKeyAndInfo().keyInfo.label,
382         strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.label),
383         m_kmcDKEK->getKeyAndInfo().key,
384         MAX_SALT_SIZE,
385         PBKDF2_ITERATIONS,
386         MAX_KEY_SIZE,
387         PKEK2)) {
388
389         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
390     }
391
392     if (0 > (keyLength = decryptAes256Gcm(
393         wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
394         wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
395         wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
396         PKEK2,
397         wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
398         kmcDEK.getKeyAndInfo().key))) {
399
400         ThrowMsg(Exception::UnwrapFailed,
401             "UnwrapDEK Failed in KeyProvider::getPureDEK");
402     }
403
404     kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
405
406     LogDebug("getPureDEK SUCCESS");
407     return RawBuffer(
408         kmcDEK.getKeyAndInfo().key,
409         (kmcDEK.getKeyAndInfo().key)
410             + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
411 }
412
413 RawBuffer KeyProvider::generateDEK(const std::string &smackLabel)
414 {
415     if (!m_isInitialized) {
416         ThrowMsg(Exception::InitFailed,
417                 "Object not initialized!");
418     }
419
420     WrappedKeyAndInfoContainer wkmcDEK;
421     std::string resized_smackLabel;
422
423     if (smackLabel.length() < APP_LABEL_SIZE)
424         resized_smackLabel = smackLabel;
425     else
426         resized_smackLabel = smackLabel.substr(0, APP_LABEL_SIZE-1);
427
428     uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE];
429
430     if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) ||
431         !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) {
432
433         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
434     }
435
436     if (!PKCS5_PBKDF2_HMAC_SHA1(
437         resized_smackLabel.c_str(),
438         strlen(resized_smackLabel.c_str()),
439         m_kmcDKEK->getKeyAndInfo().key,
440         MAX_SALT_SIZE,
441         PBKDF2_ITERATIONS,
442         MAX_KEY_SIZE,
443         PKEK2)) {
444
445         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
446     }
447
448     int wrappedKeyLength;
449
450     if (0 > (wrappedKeyLength = encryptAes256Gcm(
451         key,
452         m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
453         PKEK2,
454         wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
455         wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
456         wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) {
457
458         ThrowMsg(Exception::GenFailed,
459             "GenerateDEK Failed in KeyProvider::generateDEK");
460     }
461
462     wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
463     wkmcDEK.setKeyInfoSalt(m_kmcDKEK->getKeyAndInfo().key, MAX_SALT_SIZE);
464     wkmcDEK.setKeyInfoLabel(resized_smackLabel);
465
466     LogDebug("GenerateDEK Success");
467     return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
468 }
469
470 RawBuffer KeyProvider::reencrypt(
471     const RawBuffer &domainKEKInWrapForm,
472     const Password &oldPass,
473     const Password &newPass)
474 {
475     if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
476         ThrowMsg(Exception::InputParamError,
477             "domainKEKInWrapForm "
478             "input size:" << domainKEKInWrapForm.size() <<
479             " Expected:" << sizeof(WrappedKeyAndInfo));
480     }
481
482     WrappedKeyAndInfoContainer wkmcOldDKEK(domainKEKInWrapForm.data());
483     WrappedKeyAndInfoContainer wkmcNewDKEK;
484     KeyAndInfoContainer kmcDKEK;
485
486     char *concat_user_pass = NULL;
487     uint8_t PKEK1[MAX_KEY_SIZE];
488     int keyLength = 0;
489
490
491     concat_user_pass = concat_password_user(
492         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.label,
493         getConvertedStr(oldPass));
494
495     if (!PKCS5_PBKDF2_HMAC_SHA1(
496         concat_user_pass,
497         strlen(concat_user_pass),
498         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt,
499         MAX_SALT_SIZE,
500         PBKDF2_ITERATIONS,
501         MAX_KEY_SIZE,
502         PKEK1)) {
503
504         delete[] concat_user_pass;
505         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
506     }
507     delete[] concat_user_pass;
508
509     if (0 > (keyLength = decryptAes256Gcm(
510         wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey,
511         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
512         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag,
513         PKEK1,
514         wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
515         kmcDKEK.getKeyAndInfo().key))) {
516
517         ThrowMsg(Exception::PassWordError,
518             "Incorrect Old Password ");
519     }
520
521     kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
522     kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
523
524     concat_user_pass = concat_password_user(
525         kmcDKEK.getKeyAndInfo().keyInfo.label,
526         getConvertedStr(newPass));
527
528     if (!PKCS5_PBKDF2_HMAC_SHA1(
529         concat_user_pass,
530         strlen(concat_user_pass),
531         kmcDKEK.getKeyAndInfo().keyInfo.salt,
532         MAX_SALT_SIZE,
533         PBKDF2_ITERATIONS,
534         MAX_KEY_SIZE,
535         PKEK1)) {
536
537         delete[] concat_user_pass;
538         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
539     }
540
541     delete[] concat_user_pass;
542
543     int wrappedKeyLength = 0;
544     wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
545
546     if (0 > (wrappedKeyLength = encryptAes256Gcm(
547         kmcDKEK.getKeyAndInfo().key,
548         kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
549         PKEK1,
550         kmcDKEK.getKeyAndInfo().keyInfo.iv,
551         wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
552         wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
553
554         ThrowMsg(Exception::UnwrapFailed,
555             "UpdateDomainKEK in KeyProvider::reencrypt Failed");
556     }
557
558     wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
559
560     LogDebug("reencrypt SUCCESS");
561     return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo());
562 }
563
564
565 RawBuffer KeyProvider::generateDomainKEK(
566     const std::string &user,
567     const Password &userPassword)
568 {
569     WrappedKeyAndInfoContainer wkmcDKEK;
570     uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE];
571
572     if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) ||
573         !RAND_bytes(key, MAX_KEY_SIZE) ||
574         !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE))
575         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINE_ERROR");
576
577     int wrappedKeyLength;
578     char *concat_user_pass = NULL;
579     concat_user_pass = concat_password_user(user.c_str(), getConvertedStr(userPassword));
580     if (!PKCS5_PBKDF2_HMAC_SHA1(
581         concat_user_pass,
582         strlen(concat_user_pass),
583         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt,
584         MAX_SALT_SIZE,
585         PBKDF2_ITERATIONS,
586         MAX_KEY_SIZE,
587         PKEK1)) {
588
589         delete[] concat_user_pass;
590         ThrowMsg(Exception::OpensslEngineError, "OPENSSL_ENGINED_ERROR");
591     }
592
593     delete[] concat_user_pass;
594
595     if (0 > (wrappedKeyLength = encryptAes256Gcm(
596         key,
597         MAX_KEY_SIZE,
598         PKEK1,
599         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
600         wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
601         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) {
602
603         ThrowMsg(Exception::GenFailed,
604             "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK");
605     }
606
607     wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
608     wkmcDKEK.setKeyInfoLabel(user);
609
610     LogDebug("generateDomainKEK Success");
611     return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
612 }
613
614 int KeyProvider::initializeLibrary()
615 {
616     LogDebug("initializeLibrary Success");
617     return SUCCESS;
618 }
619
620 int KeyProvider::closeLibrary()
621 {
622     LogDebug("closeLibrary Success");
623     return SUCCESS;
624 }
625
626 KeyProvider::~KeyProvider()
627 {
628     LogDebug("KeyProvider Destructor");
629 }
630
631 int KeyProvider::encryptAes256Gcm(const unsigned char *plaintext,
632                                   int plaintext_len,
633                                   const unsigned char *key,
634                                   const unsigned char *iv,
635                                   unsigned char *ciphertext,
636                                   unsigned char *tag)
637 {
638
639     EVP_CIPHER_CTX *ctx;
640     int len;
641     int ciphertext_len = 0;
642
643     if (!(ctx = EVP_CIPHER_CTX_new())) {
644         return OPENSSL_ENGINE_ERROR;
645     }
646
647     if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
648         return OPENSSL_ENGINE_ERROR;
649     }
650
651     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) {
652         return OPENSSL_ENGINE_ERROR;
653     }
654
655     if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) {
656         return OPENSSL_ENGINE_ERROR;
657     }
658
659     if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) {
660         return OPENSSL_ENGINE_ERROR;
661     }
662     ciphertext_len = len;
663
664     if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
665         return OPENSSL_ENGINE_ERROR;
666     }
667     ciphertext_len += len;
668
669     if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag)) {
670         return OPENSSL_ENGINE_ERROR;
671     }
672
673     EVP_CIPHER_CTX_free(ctx);
674
675     return ciphertext_len;
676 }
677
678 int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext,
679                                   int ciphertext_len,
680                                   unsigned char *tag,
681                                   const unsigned char *key,
682                                   const unsigned char *iv,
683                                   unsigned char *plaintext)
684 {
685
686     EVP_CIPHER_CTX *ctx;
687     int len;
688     int plaintext_len;
689     int ret;
690
691     if (!(ctx = EVP_CIPHER_CTX_new())) {
692         return OPENSSL_ENGINE_ERROR;
693     }
694
695     if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) {
696         return OPENSSL_ENGINE_ERROR;
697     }
698     if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) {
699         return OPENSSL_ENGINE_ERROR;
700     }
701
702     if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) {
703         return OPENSSL_ENGINE_ERROR;
704     }
705
706     if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag)) {
707         return OPENSSL_ENGINE_ERROR;
708     }
709
710     if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) {
711         return OPENSSL_ENGINE_ERROR;
712     }
713     plaintext_len = len;
714
715     if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len))) {
716         return OPENSSL_ENGINE_ERROR;
717     }
718
719     EVP_CIPHER_CTX_free(ctx);
720
721     if (ret > 0) {
722         plaintext_len += len;
723         return plaintext_len;
724     }
725     else {
726         return -1;
727     }
728 }
729
730 char * KeyProvider::concat_password_user(const char *user, const char *password)
731 {
732     char *concat_user_pass = NULL;
733     char *resized_user = NULL;
734     int concat_user_pass_len = 0;
735
736     if (strlen(user) > MAX_LABEL_SIZE-1) {
737         resized_user = new char[MAX_LABEL_SIZE];
738         memcpy(resized_user, user, MAX_LABEL_SIZE-1);
739         resized_user[MAX_LABEL_SIZE-1] = '\0';
740     }
741     else {
742         resized_user = new char[strlen(user)+1];
743         memcpy(resized_user, user, strlen(user));
744         resized_user[strlen(user)] = '\0';
745     }
746     concat_user_pass_len = strlen(resized_user) + strlen(password) + 1;
747     concat_user_pass = new char[concat_user_pass_len];
748
749     memset(concat_user_pass, '\0', concat_user_pass_len);
750     memcpy(concat_user_pass, password, strlen(password));
751     memcpy(&(concat_user_pass[strlen(password)]), resized_user, strlen(resized_user));
752     concat_user_pass[strlen(resized_user) + strlen(password)] = '\0';
753
754     delete[] resized_user;
755     return concat_user_pass;
756 }
757
758 const char* KeyProvider::getConvertedStr(const Password &password)
759 {
760     return password.c_str();
761 }