2 * Copyright (c) 2014-2019 Samsung Electronics Co., Ltd. All rights reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
21 #include <openssl/rand.h>
22 #include <openssl/err.h>
23 #include <openssl/evp.h>
24 #include <openssl/sha.h>
27 #include <ckm/ckm-type.h>
35 #ifndef INVALID_ARGUMENTS
36 #define INVALID_ARGUMENTS -2
38 #ifndef VERIFY_DATA_ERROR
39 #define VERIFY_DATA_ERROR -3
41 #ifndef OPENSSL_ENGINE_ERROR
42 #define OPENSSL_ENGINE_ERROR -4
45 #define UNKNOWN_ERROR -5
48 #define AES256_KEY_LEN_BITS 256
49 #define AES256_KEY_LEN_BYTSE (AES256_KEY_LEN_BITS / 8)
51 //#define AES_GCM_TAG_SIZE 32
53 #define PBKDF2_SALT_LEN 16
54 #define PBKDF2_ITERATIONS 4096
56 #define MAX_IV_SIZE 16
57 #define MAX_SALT_SIZE 16
58 #define MAX_KEY_SIZE 32
59 #define MAX_WRAPPED_KEY_SIZE 32
60 #define MAX_CLIENT_ID_SIZE 32
61 #define DOMAIN_NAME_SIZE 32
65 const uint32_t KEYCOMPONENT_VERSION = 2;
67 typedef struct KeyComponentsInfo_ {
69 char client[MAX_CLIENT_ID_SIZE];
70 uint8_t salt[MAX_SALT_SIZE];
71 uint8_t iv[MAX_IV_SIZE];
72 uint8_t tag[MAX_IV_SIZE];
75 typedef struct KeyAndInfo_ {
76 KeyComponentsInfo keyInfo;
77 uint8_t key[MAX_KEY_SIZE];
80 typedef struct WrappedKeyAndInfo_ {
81 KeyComponentsInfo keyInfo;
82 uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
85 typedef struct KeyComponentsInfoDKEK_ : KeyComponentsInfo{
88 void set(const KeyComponentsInfo &src) {
89 keyLength = src.keyLength;
90 memcpy(&client, &src.client, MAX_CLIENT_ID_SIZE);
91 memcpy(&salt, &src.salt, MAX_SALT_SIZE);
92 memcpy(&iv, &src.iv, MAX_IV_SIZE);
93 memcpy(&tag, &src.tag, MAX_IV_SIZE);
95 } KeyComponentsInfoDKEK;
97 typedef struct KeyAndInfoDKEK_ {
98 KeyComponentsInfoDKEK keyInfo;
99 uint8_t key[MAX_KEY_SIZE];
102 typedef struct WrappedKeyAndInfoDKEK_ {
103 KeyComponentsInfoDKEK keyInfo;
104 uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
105 } WrappedKeyAndInfoDKEK;
107 class WrappedKeyAndInfoContainer {
109 WrappedKeyAndInfoContainer();
110 WrappedKeyAndInfo &getWrappedKeyAndInfo();
111 WrappedKeyAndInfoDKEK &getWrappedDKEKAndInfo();
112 void setWrappedKeyAndInfo(const unsigned char *);
113 void setWrappedDKEKAndInfo(const unsigned char *);
114 void setKeyInfoKeyLength(const uint32_t);
115 void setKeyInfoClient(const std::string);
116 void setKeyInfoSalt(const unsigned char *, const int);
117 void setKeyInfo(const KeyComponentsInfo *);
118 void setDKEKInfo(const uint32_t, const uint32_t);
119 ~WrappedKeyAndInfoContainer();
122 WrappedKeyAndInfo wrappedKeyAndInfo;
123 WrappedKeyAndInfoDKEK wrappedDKEKAndInfo;
126 class KeyAndInfoContainer {
128 KeyAndInfoContainer();
129 KeyAndInfo &getKeyAndInfo();
130 KeyAndInfoDKEK &getDKEKAndInfo();
131 void setKeyAndInfo(const unsigned char *);
132 void setDKEKAndInfo(const unsigned char *);
133 void setKeyInfoKeyLength(const uint32_t);
134 void setKeyInfo(const KeyComponentsInfo *);
135 void setDKEKInfo(const uint32_t, const uint32_t);
136 ~KeyAndInfoContainer();
139 KeyAndInfo keyAndInfo;
140 KeyAndInfoDKEK DKEKAndInfo;
144 // This is internal api so all functions should throw exception on errors.
147 // To store in std containers
149 // In constructor you must check if SKMM is initialized. On error -> exception
150 // keyInWrapForm should be used like this:
151 // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo))
152 // throw exception; // buffer does not have proper size to store WrappedKeyAndInfo
153 // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data());
154 KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password);
156 KeyProvider(KeyProvider &&);
157 KeyProvider(const KeyProvider &) = delete;
158 KeyProvider &operator=(const KeyProvider &) = delete;
159 KeyProvider &operator=(KeyProvider &&);
161 bool isInitialized();
163 // Returns Key used to decrypt database.
164 RawBuffer getPureDomainKEK();
166 // Returns Key in form used to store key in file
167 // Requied by Control::resetPassword(const RawBuffer &newPassword);
168 // This api should be used only on Tizen 2.2.1
169 RawBuffer getWrappedDomainKEK(const Password &password);
171 // Unwraps (decrypts) a DEK using a key derived from DomainKEK and data stored in wrapped key
172 // info. It returns the DEK in unencrypted form.
173 RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
175 // Generates a random DEK and encrypts it using a key derived from DomainKEK and custom client
176 // string (not to be confused with ClientId). The function returns the DEK in wrapped
177 // (encrypted) form. The function is used to produce a key for database encryption as well as
179 RawBuffer generateDEK(const std::string &client);
181 // used by change user password. On error -> exception
182 static RawBuffer reencrypt(
183 const RawBuffer &domainKEKInWrapForm,
184 const Password &oldPass,
185 const Password &newPass);
187 // First run of application for some user. DomainKEK was not created yet. We must create one.
188 // This key will be used to encrypt user database.
189 static RawBuffer generateDomainKEK(const std::string &user,
190 const Password &userPassword);
192 void migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
193 const Password &password);
194 RawBuffer migrateDBDEK(const RawBuffer &DEKInWrapForm);
196 // This will be called by framework at the begin of the program
197 static int initializeLibrary();
198 // This will be called by framework at the end of the program
199 static int closeLibrary();
201 virtual ~KeyProvider();
204 // KeyAndInfoContainer class
205 std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
206 bool m_isInitialized;