Use new exception types in KeyProvider class.
[platform/core/security/key-manager.git] / src / manager / service / key-provider.h
1 #pragma once
2
3 #include <string.h>
4 #include <stdint.h>
5 #include <openssl/rand.h>
6 #include <openssl/err.h>
7 #include <openssl/evp.h>
8 #include <openssl/sha.h>
9 #include <memory>
10
11 #include <ckm/ckm-type.h>
12
13 #ifndef SUCCESS
14 #define SUCCESS               0
15 #endif
16 #ifndef ERROR
17 #define ERROR                -1
18 #endif
19 #ifndef INVALID_ARGUMENTS
20 #define INVALID_ARGUMENTS    -2
21 #endif
22 #ifndef VERIFY_DATA_ERROR
23 #define VERIFY_DATA_ERROR    -3
24 #endif
25 #ifndef OPENSSL_ENGINE_ERROR
26 #define OPENSSL_ENGINE_ERROR -4
27 #endif
28 #ifndef UNKNOWN_ERROR
29 #define UNKNOWN_ERROR        -5
30 #endif
31
32 #define AES256_KEY_LEN_BITS   256
33 #define AES256_KEY_LEN_BYTSE  (AES256_KEY_LEN_BITS / 8)
34 // Unused
35 //#define AES_GCM_TAG_SIZE      32
36
37 #define PBKDF2_SALT_LEN       16
38 #define PBKDF2_ITERATIONS     4096
39
40 #define MAX_IV_SIZE           16
41 #define MAX_SALT_SIZE         16
42 #define MAX_KEY_SIZE          32
43 #define MAX_WRAPPED_KEY_SIZE  32
44 #define MAX_LABEL_SIZE        32
45 #define DOMAIN_NAME_SIZE      32
46 #define APP_LABEL_SIZE        32
47
48 namespace CKM {
49
50 typedef struct KeyComponentsInfo_ {
51     uint32_t keyLength;
52     char label[MAX_LABEL_SIZE];
53     uint8_t salt[MAX_SALT_SIZE];
54     uint8_t iv[MAX_IV_SIZE];
55     uint8_t tag[MAX_IV_SIZE];
56 } KeyComponentsInfo;
57
58 typedef struct KeyAndInfo_ {
59     KeyComponentsInfo keyInfo;
60     uint8_t key[MAX_KEY_SIZE];
61 } KeyAndInfo;
62
63 typedef struct WrappedKeyAndInfo_ {
64     KeyComponentsInfo keyInfo;
65     uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE];
66 } WrappedKeyAndInfo;
67
68 class WrappedKeyAndInfoContainer{
69 public:
70     WrappedKeyAndInfoContainer();
71     WrappedKeyAndInfoContainer(const unsigned char*);
72     WrappedKeyAndInfo& getWrappedKeyAndInfo();
73     void setKeyInfoKeyLength(const unsigned int);
74     void setKeyInfoLabel(const std::string);
75     void setKeyInfoSalt(const unsigned char*, const int);
76     void setKeyInfo(const KeyComponentsInfo*);
77     ~WrappedKeyAndInfoContainer();
78 private:
79     WrappedKeyAndInfo *wrappedKeyAndInfo;
80 };
81
82 class KeyAndInfoContainer{
83 public:
84     KeyAndInfoContainer();
85     KeyAndInfoContainer(const unsigned char*);
86     KeyAndInfo& getKeyAndInfo();
87     void setKeyInfoKeyLength(const unsigned int);
88     void setKeyInfo(const KeyComponentsInfo*);
89     ~KeyAndInfoContainer();
90 private:
91     KeyAndInfo *keyAndInfo;
92 };
93
94
95 // This is internal api so all functions should throw exception on errors.
96 class KeyProvider {
97 public:
98     // To store in std containers
99     KeyProvider();
100     // In constructor you must check if SKMM is initialized. On error -> exception
101     // keyInWrapForm should be used like this:
102     // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo))
103     //     throw exception; // buffer does not have proper size to store WrappedKeyAndInfo
104     // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data());
105     KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password);
106
107     KeyProvider(KeyProvider &&);
108     KeyProvider(const KeyProvider &) = delete;
109     KeyProvider& operator=(const KeyProvider &) = delete;
110     KeyProvider& operator=(KeyProvider &&);
111
112     bool isInitialized();
113
114     // Returns Key used to decrypt database.
115     RawBuffer getPureDomainKEK();
116
117     // Returns Key in form used to store key in file
118     // Requied by Control::resetPassword(const RawBuffer &newPassword);
119     // This api should be used only on Tizen 2.2.1
120     RawBuffer getWrappedDomainKEK(const Password &password);
121
122     // EncryptedKey key extracted from database. Used to encrypt application data.
123     // This key will be used to decrypt/encrypt data in ROW
124     RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm);
125
126     // Returns WRAPPED DEK. This will be written to datbase.
127     // This key will be used to encrypt all application information.
128     // All application are identified by smackLabel.
129     RawBuffer generateDEK(const std::string &smackLabel);
130
131     // used by change user password. On error -> exception
132     static RawBuffer reencrypt(
133         const RawBuffer &domainKEKInWrapForm,
134         const Password &oldPass,
135         const Password &newPass);
136
137     // First run of application for some user. DomainKEK was not created yet. We must create one.
138     // This key will be used to encrypt user database.
139     static RawBuffer generateDomainKEK(const std::string &user, const Password &userPassword);
140
141     // This will be called by framework at the begin of the program
142     static int initializeLibrary();
143     // This will be called by framework at the end of the program
144     static int closeLibrary();
145
146     virtual ~KeyProvider();
147 private:
148     // KeyAndInfoContainer class
149     std::shared_ptr<KeyAndInfoContainer> m_kmcDKEK;
150     bool m_isInitialized;
151
152     static int encryptAes256Gcm(
153         const unsigned char *plaintext,
154         int plaintext_len,
155         const unsigned char *key,
156         const unsigned char *iv,
157         unsigned char *ciphertext,
158         unsigned char *tag);
159
160     static int decryptAes256Gcm(
161         const unsigned char *ciphertext,
162         int ciphertext_len,
163         unsigned char *tag,
164         const unsigned char *key,
165         const unsigned char *iv,
166         unsigned char *plaintext);
167
168     static char * concat_password_user(
169         const char *user,
170         const char *password);
171
172 };
173
174 } // namespace CKM