add the se-backend for db encryption
[platform/core/security/key-manager.git] / src / manager / service / key-provider.h
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 #pragma once
18
19 #include <string.h>
20 #include <stdint.h>
21 #include <openssl/rand.h>
22 #include <openssl/err.h>
23 #include <openssl/evp.h>
24 #include <openssl/sha.h>
25 #include <memory>
26
27 #include <ckm/ckm-type.h>
28
29 #ifndef SUCCESS
30 #define SUCCESS               0
31 #endif
32 #ifndef ERROR
33 #define ERROR                -1
34 #endif
35 #ifndef INVALID_ARGUMENTS
36 #define INVALID_ARGUMENTS    -2
37 #endif
38 #ifndef VERIFY_DATA_ERROR
39 #define VERIFY_DATA_ERROR    -3
40 #endif
41 #ifndef OPENSSL_ENGINE_ERROR
42 #define OPENSSL_ENGINE_ERROR -4
43 #endif
44 #ifndef UNKNOWN_ERROR
45 #define UNKNOWN_ERROR        -5
46 #endif
47
48 #define AES256_KEY_LEN_BITS   256
49 #define AES256_KEY_LEN_BYTSE  (AES256_KEY_LEN_BITS / 8)
50 // Unused
51 //#define AES_GCM_TAG_SIZE      32
52
53 #define PBKDF2_SALT_LEN       16
54 #define PBKDF2_ITERATIONS     4096
55
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
62
63 namespace CKM {
64
65 const uint32_t KEYCOMPONENT_VERSION = 2;
66
67 typedef struct KeyComponentsInfo_ {
68         uint32_t keyLength;
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];
73 } KeyComponentsInfo;
74
75 typedef struct KeyAndInfo_ {
76         KeyComponentsInfo keyInfo;
77         uint8_t key[MAX_KEY_SIZE];
78 } KeyAndInfo;
79
80 typedef struct WrappedKeyAndInfo_ {
81         KeyComponentsInfo keyInfo;
82         uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
83 } WrappedKeyAndInfo;
84
85 typedef struct KeyComponentsInfoDKEK_ : KeyComponentsInfo{
86         uint32_t version;
87         uint32_t backend;
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);
94         }
95 } KeyComponentsInfoDKEK;
96
97 typedef struct KeyAndInfoDKEK_ {
98         KeyComponentsInfoDKEK keyInfo;
99         uint8_t key[MAX_KEY_SIZE];
100 } KeyAndInfoDKEK;
101
102 typedef struct WrappedKeyAndInfoDKEK_ {
103         KeyComponentsInfoDKEK keyInfo;
104         uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
105 } WrappedKeyAndInfoDKEK;
106
107 class WrappedKeyAndInfoContainer {
108 public:
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();
120
121 private:
122         WrappedKeyAndInfo wrappedKeyAndInfo;
123         WrappedKeyAndInfoDKEK wrappedDKEKAndInfo;
124 };
125
126 class KeyAndInfoContainer {
127 public:
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();
137
138 private:
139         KeyAndInfo keyAndInfo;
140         KeyAndInfoDKEK DKEKAndInfo;
141 };
142
143
144 // This is internal api so all functions should throw exception on errors.
145 class KeyProvider {
146 public:
147         // To store in std containers
148         KeyProvider();
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);
155
156         KeyProvider(KeyProvider &&);
157         KeyProvider(const KeyProvider &) = delete;
158         KeyProvider &operator=(const KeyProvider &) = delete;
159         KeyProvider &operator=(KeyProvider &&);
160
161         bool isInitialized();
162
163         // Returns Key used to decrypt database.
164         RawBuffer getPureDomainKEK();
165
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);
170
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);
174
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
178         // application keys.
179         RawBuffer generateDEK(const std::string &client);
180
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);
186
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);
191
192         void migrateDKEK(const RawBuffer &wrappedDomainKEKbuffer,
193                                                 const Password &password);
194         RawBuffer migrateDBDEK(const RawBuffer &DEKInWrapForm);
195
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();
200
201         virtual ~KeyProvider();
202
203 private:
204         // KeyAndInfoContainer class
205         std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
206         bool m_isInitialized;
207 };
208
209 } // namespace CKM