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