713e95269a9f5bfdbb09f9c856c5ff6f78ed53ba
[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 typedef struct KeyComponentsInfo_ {
66         uint32_t keyLength;
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];
71 } KeyComponentsInfo;
72
73 typedef struct KeyAndInfo_ {
74         KeyComponentsInfo keyInfo;
75         uint8_t key[MAX_KEY_SIZE];
76 } KeyAndInfo;
77
78 typedef struct WrappedKeyAndInfo_ {
79         KeyComponentsInfo keyInfo;
80         uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
81 } WrappedKeyAndInfo;
82
83 class WrappedKeyAndInfoContainer {
84 public:
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();
93
94 private:
95         WrappedKeyAndInfo wrappedKeyAndInfo;
96 };
97
98 class KeyAndInfoContainer {
99 public:
100         KeyAndInfoContainer();
101         explicit KeyAndInfoContainer(const unsigned char *);
102         KeyAndInfo &getKeyAndInfo();
103         void setKeyInfoKeyLength(const unsigned int);
104         void setKeyInfo(const KeyComponentsInfo *);
105         ~KeyAndInfoContainer();
106
107 private:
108         KeyAndInfo keyAndInfo;
109 };
110
111
112 // This is internal api so all functions should throw exception on errors.
113 class KeyProvider {
114 public:
115         // To store in std containers
116         KeyProvider();
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);
123
124         KeyProvider(KeyProvider &&);
125         KeyProvider(const KeyProvider &) = delete;
126         KeyProvider &operator=(const KeyProvider &) = delete;
127         KeyProvider &operator=(KeyProvider &&);
128
129         bool isInitialized();
130
131         // Returns Key used to decrypt database.
132         RawBuffer getPureDomainKEK();
133
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);
138
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);
142
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
146         // application keys.
147         RawBuffer generateDEK(const std::string &client);
148
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);
154
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);
159
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();
164
165         virtual ~KeyProvider();
166
167 private:
168         // KeyAndInfoContainer class
169         std::shared_ptr<KeyAndInfoContainer> m_domainKEK;
170         bool m_isInitialized;
171 };
172
173 } // namespace CKM