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 typedef struct KeyComponentsInfo_ {
67 char client[MAX_CLIENT_ID_SIZE];
68 uint8_t salt[MAX_SALT_SIZE];
69 uint8_t iv[MAX_IV_SIZE];
70 uint8_t tag[MAX_IV_SIZE];
73 typedef struct KeyAndInfo_ {
74 KeyComponentsInfo keyInfo;
75 uint8_t key[MAX_KEY_SIZE];
78 typedef struct WrappedKeyAndInfo_ {
79 KeyComponentsInfo keyInfo;
80 uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
83 class WrappedKeyAndInfoContainer {
85 WrappedKeyAndInfoContainer();
86 WrappedKeyAndInfoContainer(const unsigned char *);
87 WrappedKeyAndInfo &getWrappedKeyAndInfo();
88 void setKeyInfoKeyLength(const unsigned int);
89 void setKeyInfoClient(const std::string);
90 void setKeyInfoSalt(const unsigned char *, const int);
91 void setKeyInfo(const KeyComponentsInfo *);
92 ~WrappedKeyAndInfoContainer();
95 WrappedKeyAndInfo wrappedKeyAndInfo;
98 class KeyAndInfoContainer {
100 KeyAndInfoContainer();
101 explicit KeyAndInfoContainer(const unsigned char *);
102 KeyAndInfo &getKeyAndInfo();
103 void setKeyInfoKeyLength(const unsigned int);
104 void setKeyInfo(const KeyComponentsInfo *);
105 ~KeyAndInfoContainer();
108 KeyAndInfo keyAndInfo;
112 // This is internal api so all functions should throw exception on errors.
115 // To store in std containers
117 // In constructor you must check if SKMM is initialized. On error -> exception
118 // keyInWrapForm should be used like this:
119 // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo))
120 // throw exception; // buffer does not have proper size to store WrappedKeyAndInfo
121 // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data());
122 KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password);
124 KeyProvider(KeyProvider &&);
125 KeyProvider(const KeyProvider &) = delete;
126 KeyProvider &operator=(const KeyProvider &) = delete;
127 KeyProvider &operator=(KeyProvider &&);
129 bool isInitialized();
131 // Returns Key used to decrypt database.
132 RawBuffer getPureDomainKEK();
134 // Returns Key in form used to store key in file
135 // Requied by Control::resetPassword(const RawBuffer &newPassword);
136 // This api should be used only on Tizen 2.2.1
137 RawBuffer getWrappedDomainKEK(const Password &password);
139 // Unwraps (decrypts) a DEK using a key derived from DomainKEK and data stored in wrapped key
140 // info. It returns the DEK in unencrypted form.
141 RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
143 // Generates a random DEK and encrypts it using a key derived from DomainKEK and custom client
144 // string (not to be confused with ClientId). The function returns the DEK in wrapped
145 // (encrypted) form. The function is used to produce a key for database encryption as well as
147 RawBuffer generateDEK(const std::string &client);
149 // used by change user password. On error -> exception
150 static RawBuffer reencrypt(
151 const RawBuffer &domainKEKInWrapForm,
152 const Password &oldPass,
153 const Password &newPass);
155 // First run of application for some user. DomainKEK was not created yet. We must create one.
156 // This key will be used to encrypt user database.
157 static RawBuffer generateDomainKEK(const std::string &user,
158 const Password &userPassword);
160 // This will be called by framework at the begin of the program
161 static int initializeLibrary();
162 // This will be called by framework at the end of the program
163 static int closeLibrary();
165 virtual ~KeyProvider();
168 // KeyAndInfoContainer class
169 std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
170 bool m_isInitialized;