Add helpers for domain KEK encryption/decryption
[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 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         strcpy(wrappedKeyAndInfo.keyInfo.client, resized_client.c_str());
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         char *ptr = reinterpret_cast<char *>(&keyAndInfo);
301         memset(ptr, 0, sizeof(KeyAndInfo));
302
303         // verification
304         for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) {
305                 if (ptr[size])
306                         LogError("Write memory error! Memory used by key was not owerwritten.");
307         }
308 }
309
310 KeyProvider::KeyProvider() :
311         m_domainKEK(NULL),
312         m_isInitialized(false)
313 {
314         LogDebug("Created empty KeyProvider");
315 }
316
317 KeyProvider::KeyProvider(
318         const RawBuffer &domainKEKInWrapForm,
319         const Password &password) :
320         m_domainKEK(new KeyAndInfoContainer()),
321         m_isInitialized(true)
322 {
323         if (!m_isInitialized)
324                 ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened");
325
326         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
327                 LogError("input size:" << domainKEKInWrapForm.size()
328                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
329                 ThrowErr(Exc::InternalError,
330                                  "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor");
331         }
332
333         unwrapDomainKEK(domainKEKInWrapForm, password, *m_domainKEK);
334 }
335
336 KeyProvider &KeyProvider::operator=(KeyProvider &&second)
337 {
338         LogDebug("Moving KeyProvider");
339
340         if (this == &second)
341                 return *this;
342
343         m_isInitialized = second.m_isInitialized;
344         m_domainKEK = second.m_domainKEK;
345         second.m_isInitialized = false;
346         second.m_domainKEK = NULL;
347         return *this;
348 }
349
350 KeyProvider::KeyProvider(KeyProvider &&second)
351 {
352         LogDebug("Moving KeyProvider");
353         m_isInitialized = second.m_isInitialized;
354         m_domainKEK = second.m_domainKEK;
355         second.m_isInitialized = false;
356         second.m_domainKEK = NULL;
357 }
358
359 bool KeyProvider::isInitialized()
360 {
361         return m_isInitialized;
362 }
363
364 RawBuffer KeyProvider::getPureDomainKEK()
365 {
366         if (!m_isInitialized)
367                 ThrowErr(Exc::InternalError, "Object not initialized!");
368
369         // TODO secure
370         return RawBuffer(m_domainKEK->getKeyAndInfo().key,
371                                          (m_domainKEK->getKeyAndInfo().key) +
372                                          m_domainKEK->getKeyAndInfo().keyInfo.keyLength);
373 }
374
375 RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password)
376 {
377         if (!m_isInitialized)
378                 ThrowErr(Exc::InternalError, "Object not initialized!");
379
380         return wrapDomainKEK(*m_domainKEK, password);
381 }
382
383
384 RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm)
385 {
386         if (!m_isInitialized)
387                 ThrowErr(Exc::InternalError, "Object not initialized!");
388
389         if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
390                 LogError("input size:" << DEKInWrapForm.size()
391                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
392                 ThrowErr(Exc::InternalError,
393                                  "buffer doesn't have proper size to store "
394                                  "WrappedKeyAndInfo in KeyProvider::getPureDEK");
395         }
396
397         KeyAndInfoContainer kmcDEK = KeyAndInfoContainer();
398         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(
399                         DEKInWrapForm.data());
400
401         KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key,
402                                   wkmcDEK.getWrappedKeyAndInfo().keyInfo.client);
403
404         int keyLength;
405         if (0 > (keyLength = decryptAes256Gcm(
406                                                          wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
407                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength,
408                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag,
409                                                          PKEK2.data(),
410                                                          wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
411                                                          kmcDEK.getKeyAndInfo().key)))
412                 ThrowErr(Exc::InternalError,
413                                  "UnwrapDEK Failed in KeyProvider::getPureDEK");
414
415         kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength);
416
417         LogDebug("getPureDEK SUCCESS");
418         return RawBuffer(
419                            kmcDEK.getKeyAndInfo().key,
420                            (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength);
421 }
422
423 RawBuffer KeyProvider::generateDEK(const ClientId &client)
424 {
425         if (!m_isInitialized)
426                 ThrowErr(Exc::InternalError, "Object not initialized!");
427
428         WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer();
429         std::string resized_client;
430
431         if (client.length() < MAX_CLIENT_ID_SIZE)
432                 resized_client = client;
433         else
434                 resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1);
435
436         uint8_t key[MAX_KEY_SIZE];
437
438         if (!randomize(key) || !randomize(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv))
439                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
440
441         KeyData PKEK2 = makePKEK2(m_domainKEK->getKeyAndInfo().key, resized_client);
442
443         int wrappedKeyLength;
444         if (0 > (wrappedKeyLength = encryptAes256Gcm(key,
445                                                      m_domainKEK->getKeyAndInfo().keyInfo.keyLength,
446                                                      PKEK2.data(),
447                                                      wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv,
448                                                      wkmcDEK.getWrappedKeyAndInfo().wrappedKey,
449                                                      wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag)))
450                 ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK");
451
452         wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength);
453         wkmcDEK.setKeyInfoClient(resized_client);
454
455         LogDebug("GenerateDEK Success");
456         return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo());
457 }
458
459 RawBuffer KeyProvider::reencrypt(
460         const RawBuffer &domainKEKInWrapForm,
461         const Password &oldPass,
462         const Password &newPass)
463 {
464         if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) {
465                 LogError("input size:" << domainKEKInWrapForm.size()
466                                  << " Expected: " << sizeof(WrappedKeyAndInfo));
467                 ThrowErr(Exc::InternalError,
468                                  "buffer doesn't have proper size to store "
469                                  "WrappedKeyAndInfo in KeyProvider::reencrypt");
470         }
471
472         KeyAndInfoContainer domainKEK;
473         unwrapDomainKEK(domainKEKInWrapForm, oldPass, domainKEK);
474         return wrapDomainKEK(domainKEK, newPass);
475 }
476
477 RawBuffer KeyProvider::generateDomainKEK(
478         const std::string &user,
479         const Password &userPassword)
480 {
481         WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer();
482
483         KeyAndInfoContainer domainKEK;
484
485         if (!randomize(domainKEK.getKeyAndInfo().keyInfo.salt) ||
486                 !randomize(domainKEK.getKeyAndInfo().key) ||
487             !randomize(domainKEK.getKeyAndInfo().keyInfo.iv)) {
488                 ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR");
489         }
490
491         domainKEK.setKeyInfoKeyLength(sizeof(domainKEK.getKeyAndInfo().key));
492
493         if (user.size() >= sizeof(domainKEK.getKeyAndInfo().keyInfo.client)) {
494                 ThrowErr(Exc::InternalError, "Client name too long");
495         }
496         strcpy(domainKEK.getKeyAndInfo().keyInfo.client, user.c_str());
497
498         return wrapDomainKEK(domainKEK, userPassword);
499 }
500
501 int KeyProvider::initializeLibrary()
502 {
503         LogDebug("initializeLibrary Success");
504         return SUCCESS;
505 }
506
507 int KeyProvider::closeLibrary()
508 {
509         LogDebug("closeLibrary Success");
510         return SUCCESS;
511 }
512
513 KeyProvider::~KeyProvider()
514 {
515         LogDebug("KeyProvider Destructor");
516 }