aea5c9b58eb06352456d4b60e5f45c449fcc06ed
[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 <string.h>
21
22 #include <array>
23
24 using namespace CKM;
25
26 namespace {
27
28 template<typename T>
29 RawBuffer toRawBuffer(const T &data)
30 {
31         RawBuffer output;
32         const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&data);
33         output.assign(ptr, ptr + sizeof(T));
34         return output;
35 }
36
37 // You cannot use toRawBuffer template with pointers
38 template<typename T>
39 RawBuffer toRawBuffer(T *)
40 {
41         class NoPointerAllowed {
42                 NoPointerAllowed() {}
43         };
44         NoPointerAllowed a;
45         return RawBuffer();
46 }
47
48 int encryptAes256Gcm(const unsigned char *plaintext,
49                      int plaintext_len, const unsigned char *key, const unsigned char *iv,
50                      unsigned char *ciphertext, unsigned char *tag)
51 {
52         EVP_CIPHER_CTX *ctx;
53         int len;
54         int ciphertext_len = 0;
55
56         if (!(ctx = EVP_CIPHER_CTX_new()))
57                 return OPENSSL_ENGINE_ERROR;
58
59         if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
60                 return OPENSSL_ENGINE_ERROR;
61
62         if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
63                 return OPENSSL_ENGINE_ERROR;
64
65         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
66                 return OPENSSL_ENGINE_ERROR;
67
68         if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
69                 return OPENSSL_ENGINE_ERROR;
70
71         ciphertext_len = len;
72
73         if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
74                 return OPENSSL_ENGINE_ERROR;
75
76         ciphertext_len += len;
77
78         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag))
79                 return OPENSSL_ENGINE_ERROR;
80
81         EVP_CIPHER_CTX_free(ctx);
82
83         return ciphertext_len;
84 }
85
86 int decryptAes256Gcm(const unsigned char *ciphertext,
87                      int ciphertext_len, unsigned char *tag, const unsigned char *key,
88                      const unsigned char *iv, unsigned char *plaintext)
89 {
90         EVP_CIPHER_CTX *ctx;
91         int len;
92         int plaintext_len;
93         int ret;
94
95         if (!(ctx = EVP_CIPHER_CTX_new()))
96                 return OPENSSL_ENGINE_ERROR;
97
98         if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
99                 return OPENSSL_ENGINE_ERROR;
100
101         if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
102                 return OPENSSL_ENGINE_ERROR;
103
104         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL))
105                 return OPENSSL_ENGINE_ERROR;
106
107         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag))
108                 return OPENSSL_ENGINE_ERROR;
109
110         if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
111                 return OPENSSL_ENGINE_ERROR;
112
113         plaintext_len = len;
114
115         if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len)))
116                 return OPENSSL_ENGINE_ERROR;
117
118         EVP_CIPHER_CTX_free(ctx);
119
120         if (ret > 0) {
121                 plaintext_len += len;
122                 return plaintext_len;
123         } else {
124                 return -1;
125         }
126 }
127
128 typedef std::array<uint8_t, MAX_KEY_SIZE> KeyData;
129
130 // derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password
131 KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password)
132 {
133         std::string concatPasswordClient(password.c_str());
134         concatPasswordClient += std::string(keyInfo.client);
135
136         KeyData key;
137         if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(),
138                                     concatPasswordClient.size(),
139                                     keyInfo.salt,
140                                     MAX_SALT_SIZE,
141                                     PBKDF2_ITERATIONS,
142                                     key.size(),
143                                     key.data())) {
144                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
145         }
146         return key;
147 }
148
149 // derives a key used for DB DEK encryption (aka PKEK2) from DomainKEK and user id
150 KeyData makePKEK2(const uint8_t *domainKEK, const std::string &user)
151 {
152         KeyData key;
153         if (!PKCS5_PBKDF2_HMAC_SHA1(user.c_str(),
154                                     user.size(),
155                                     domainKEK,
156                                     MAX_SALT_SIZE,
157                                     PBKDF2_ITERATIONS,
158                                     key.size(),
159                                     key.data())) {
160                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
161         }
162         return key;
163 }
164
165
166 template <size_t N>
167 bool randomize(uint8_t (&array)[N])
168 {
169         return RAND_bytes(array, N) == 1;
170 }
171
172 } // anonymous namespace
173
174 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer()
175 {
176         memset(&wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo));
177 }
178
179 WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char
180                 *data)
181 {
182         memcpy(&wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo));
183
184         if (wrappedKeyAndInfo.keyInfo.keyLength > sizeof(wrappedKeyAndInfo.wrappedKey)) {
185                 ThrowErr(Exc::InternalError,
186                          "Wrapped key info is corrupted. Key length exceeds the size of the key buffer.");
187         }
188
189         size_t maxlen = sizeof(wrappedKeyAndInfo.keyInfo.client);
190         if (strnlen(wrappedKeyAndInfo.keyInfo.client, maxlen) == maxlen) {
191                 ThrowErr(Exc::InternalError,
192                          "Wrapped key info is corrupted. Client id is not NULL terminated.");
193         }
194 }
195
196 WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo()
197 {
198         return wrappedKeyAndInfo;
199 }
200
201 void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length)
202 {
203         wrappedKeyAndInfo.keyInfo.keyLength = length;
204 }
205
206 void WrappedKeyAndInfoContainer::setKeyInfoClient(const std::string resized_client)
207 {
208         if (resized_client.size() >= sizeof(wrappedKeyAndInfo.keyInfo.client)) {
209                 ThrowErr(Exc::InternalError, "Client name too long");
210         }
211
212         strcpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str());
213 }
214
215 void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt,
216                 const int size)
217 {
218         memcpy(wrappedKeyAndInfo.keyInfo.salt, salt, size);
219 }
220
221 void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo
222                 *keyComponentsInfo)
223 {
224         memcpy(&(wrappedKeyAndInfo.keyInfo), keyComponentsInfo,
225                    sizeof(KeyComponentsInfo));
226 }
227
228 WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer()
229 {
230 }
231
232 KeyAndInfoContainer::KeyAndInfoContainer()
233 {
234         memset(&keyAndInfo, 0, sizeof(KeyAndInfo));
235 }
236
237 KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data)
238 {
239         memcpy(&keyAndInfo, data, sizeof(KeyAndInfo));
240 }
241
242 KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo()
243 {
244         return keyAndInfo;
245 }
246
247 void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length)
248 {
249         keyAndInfo.keyInfo.keyLength = length;
250 }
251
252 void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo)
253 {
254         memcpy(&(keyAndInfo.keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo));
255 }
256
257 KeyAndInfoContainer::~KeyAndInfoContainer()
258 {
259         // overwrite key
260         char *ptr = reinterpret_cast<char *>(&keyAndInfo);
261         memset(ptr, 0, sizeof(KeyAndInfo));
262
263         // verification
264         for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) {
265                 if (ptr[size])
266                         LogError("Write memory error! Memory used by key was not owerwritten.");
267         }
268 }
269
270 KeyProvider::KeyProvider() :
271         m_kmcDKEK(NULL),
272         m_isInitialized(false)
273 {
274         LogDebug("Created empty KeyProvider");
275 }
276
277 KeyProvider::KeyProvider(
278         const RawBuffer &domainKEKInWrapForm,
279         const Password &password) :
280         m_kmcDKEK(new KeyAndInfoContainer()),
281         m_isInitialized(true)
282 {
283         if (!m_isInitialized)
284                 ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
285
286         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
287                 LogError("input size:" << domainKEKInWrapForm.size()
288                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
289                 ThrowErr(Exc::InternalError,
290                                  "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
291         }
292
293         WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(
294                         domainKEKInWrapForm.data());
295
296         KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password);
297
298         int keyLength;
299         if (0 > (keyLength = decryptAes256Gcm(
300                                                          wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
301                                                          wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
302                                                          wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag,
303                                                          PKEK1.data(),
304                                                          wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
305                                                          m_kmcDKEK->getKeyAndInfo().key))) {
306                 ThrowErr(Exc::AuthenticationFailed,
307                                  "VerifyDomainKEK failed in KeyProvider Constructor");
308         }
309
310         m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo));
311         m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength);
312 }
313
314 KeyProvider &KeyProvider::operator=(KeyProvider &&second)
315 {
316         LogDebug("Moving KeyProvider");
317
318         if (this == &second)
319                 return *this;
320
321         m_isInitialized = second.m_isInitialized;
322         m_kmcDKEK = second.m_kmcDKEK;
323         second.m_isInitialized = false;
324         second.m_kmcDKEK = NULL;
325         return *this;
326 }
327
328 KeyProvider::KeyProvider(KeyProvider &&second)
329 {
330         LogDebug("Moving KeyProvider");
331         m_isInitialized = second.m_isInitialized;
332         m_kmcDKEK = second.m_kmcDKEK;
333         second.m_isInitialized = false;
334         second.m_kmcDKEK = NULL;
335 }
336
337 bool KeyProvider::isInitialized()
338 {
339         return m_isInitialized;
340 }
341
342 RawBuffer KeyProvider::getPureDomainKEK()
343 {
344         if (!m_isInitialized)
345                 ThrowErr(Exc::InternalError, "Object not initialized!");
346
347         // TODO secure
348         return RawBuffer(m_kmcDKEK->getKeyAndInfo().key,
349                                          (m_kmcDKEK->getKeyAndInfo().key) +
350                                          m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength);
351 }
352
353 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
354 {
355         if (!m_isInitialized)
356                 ThrowErr(Exc::InternalError, "Object not initialized!");
357
358         WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
359         wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo));
360
361         KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password);
362
363         int wrappedKeyLength;
364
365         if (0 > (wrappedKeyLength = encryptAes256Gcm(
366                                                                         m_kmcDKEK->getKeyAndInfo().key,
367                                                                         m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
368                                                                         PKEK1.data(),
369                                                                         m_kmcDKEK->getKeyAndInfo().keyInfo.iv,
370                                                                         wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
371                                                                         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
372                 ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK");
373
374         wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
375
376         LogDebug("getDomainKEK(password) Success");
377         return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
378 }
379
380
381 RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
382 {
383         if (!m_isInitialized)
384                 ThrowErr(Exc::InternalError, "Object not initialized!");
385
386         if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
387                 LogError("input size:" << DEKInWrapForm.size()
388                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
389                 ThrowErr(Exc::InternalError,
390                                  "buffer doesn't have proper size to store "
391                                  "WrappedKeyAndInfo in KeyProvider::getPureDEK");
392         }
393
394         KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
395         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
396                         DEKInWrapForm.data());
397
398         KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key,
399                                   wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
400
401         int keyLength;
402         if (0 > (keyLength = decryptAes256Gcm(
403                                                          wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
404                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
405                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
406                                                          PKEK2.data(),
407                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
408                                                          kmcDEK.getKeyAndInfo().key)))
409                 ThrowErr(Exc::InternalError,
410                                  "UnwrapDEK Failed in KeyProvider::getPureDEK");
411
412         kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
413
414         LogDebug("getPureDEK SUCCESS");
415         return RawBuffer(
416                            kmcDEK.getKeyAndInfo().key,
417                            (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
418 }
419
420 RawBuffer KeyProvider::generateDEK(const ClientId &client)
421 {
422         if (!m_isInitialized)
423                 ThrowErr(Exc::InternalError, "Object not initialized!");
424
425         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
426         std::string resized_client;
427
428         if (client.length() < MAX_CLIENT_ID_SIZE)
429                 resized_client = client;
430         else
431                 resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1);
432
433         uint8_t key[MAX_KEY_SIZE];
434
435         if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
436                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
437
438         KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, resized_client);
439
440         int wrappedKeyLength;
441         if (0 > (wrappedKeyLength = encryptAes256Gcm(
442                                                                         key,
443                                                                         m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength,
444                                                                         PKEK2.data(),
445                                                                         wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
446                                                                         wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
447                                                                         wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
448                 ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
449
450         wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
451         wkmcDEK.setKeyInfoClient(resized_client);
452
453         LogDebug("GenerateDEK Success");
454         return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
455 }
456
457 RawBuffer KeyProvider::reencrypt(
458         const RawBuffer &domainKEKInWrapForm,
459         const Password &oldPass,
460         const Password &newPass)
461 {
462         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
463                 LogError("input size:" << domainKEKInWrapForm.size()
464                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
465                 ThrowErr(Exc::InternalError,
466                                  "buffer doesn't have proper size to store "
467                                  "WrappedKeyAndInfo in KeyProvider::reencrypt");
468         }
469
470         WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer(
471                                 domainKEKInWrapForm.data());
472         WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer();
473         KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer();
474
475         KeyData PKEK1 = makePKEK1(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo, oldPass);
476
477         int keyLength = 0;
478         if (0 > (keyLength = decryptAes256Gcm(
479                                                          wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey,
480                                                          wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength,
481                                                          wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag,
482                                                          PKEK1.data(),
483                                                          wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv,
484                                                          kmcDKEK.getKeyAndInfo().key)))
485                 ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password ");
486
487         kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo));
488         kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength);
489
490         PKEK1 = makePKEK1(wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo, newPass);
491
492         wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo));
493
494         int wrappedKeyLength = 0;
495         if (0 > (wrappedKeyLength = encryptAes256Gcm(
496                                                                         kmcDKEK.getKeyAndInfo().key,
497                                                                         kmcDKEK.getKeyAndInfo().keyInfo.keyLength,
498                                                                         PKEK1.data(),
499                                                                         kmcDKEK.getKeyAndInfo().keyInfo.iv,
500                                                                         wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey,
501                                                                         wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
502                 ThrowErr(Exc::InternalError,
503                                  "UpdateDomainKEK in KeyProvider::reencrypt Failed");
504
505         wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
506
507         LogDebug("reencrypt SUCCESS");
508         return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo());
509 }
510
511 RawBuffer KeyProvider::generateDomainKEK(
512         const std::string &user,
513         const Password &userPassword)
514 {
515         WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
516         uint8_t key[MAX_KEY_SIZE];
517         int wrappedKeyLength;
518
519         wkmcDKEK.setKeyInfoClient(user);
520
521         if (!randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt) ||
522             !randomize(key) ||
523             !randomize(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv)) {
524                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
525         }
526
527         KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, userPassword);
528
529         if (0 > (wrappedKeyLength = encryptAes256Gcm(
530                                                                         key,
531                                                                         sizeof(key),
532                                                                         PKEK1.data(),
533                                                                         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv,
534                                                                         wkmcDKEK.getWrappedKeyAndInfo().wrappedKey,
535                                                                         wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag)))
536                 ThrowErr(Exc::InternalError,
537                                  "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK");
538
539         wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
540         wkmcDKEK.setKeyInfoClient(user);
541
542         LogDebug("generateDomainKEK Success");
543         return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo());
544 }
545
546 int KeyProvider::initializeLibrary()
547 {
548         LogDebug("initializeLibrary Success");
549         return SUCCESS;
550 }
551
552 int KeyProvider::closeLibrary()
553 {
554         LogDebug("closeLibrary Success");
555         return SUCCESS;
556 }
557
558 KeyProvider::~KeyProvider()
559 {
560         LogDebug("KeyProvider Destructor");
561 }