Using updated clatd's Dbus interface and Path values
[platform/core/connectivity/net-config.git] / src / wifi-key-encryption.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdlib.h>
21 #include <glib.h>
22 #include <ckmc/ckmc-type.h>
23 #include <ckmc/ckmc-manager.h>
24 #include <tizen.h>
25
26 #include "log.h"
27 #include "util.h"
28 #include "wifi-key-encryption.h"
29
30 #define KEY_ALIAS       "connman_wifi_passphrase"
31 #define IV_ALIAS        "connman_wifi_enciv"
32 #define AAD_ALIAS       "connman_wifi_gcmaad"
33
34 #define PASSPHRASE      "Passphrase"
35 #define RND_LENGTH      32
36 #define AES_KEY_SIZE    256
37 #define CKMC_ERROR_HANDLING(expression, release) err = expression; \
38         if (CKMC_ERROR_NONE != err) { \
39                 err_str = get_error_message(err); \
40                 ERR(#expression " : %s", err_str); \
41                 release; \
42                 return NULL; \
43         } \
44         DBG(#expression " success");
45
46 static char* err_str;
47 static int err;
48
49
50 static void __netconfig_generate_random_bytes(unsigned char* bytes, int len)
51 {
52         int i = 0;
53
54         srandom(time(NULL));
55
56         while (len--)
57                 bytes[i++] = (unsigned char)random();
58
59 }
60
61 static void __netconfig_convert_hexstr_to_bytes(gchar* hexstr, int hlen, gchar* bin)
62 {
63         hlen = hlen / 2;
64
65         while (hlen) {
66                 if (*hexstr >= '0' && *hexstr <= '9')
67                         *bin = (*hexstr - '0') << 4;
68                 else if (*hexstr >= 'a' && *hexstr <= 'f')
69                         *bin = (*hexstr - 'a' + 10) << 4;
70
71                 hexstr++;
72
73                 if (*hexstr >= '0' && *hexstr <= '9')
74                         *bin |= (*hexstr - '0') & 0x0f;
75                 else if (*hexstr >= 'a' && *hexstr <= 'f')
76                         *bin |= (*hexstr - 'a' + 10) & 0x0f;
77
78                 hexstr++;
79                 bin++;
80                 hlen--;
81         }
82 }
83
84 static void __netconfig_convert_bytes_to_hexstr(char* bin, int blen, gchar* hexstr)
85 {
86         char t;
87
88         while (blen) {
89                 t = (*bin >> 4) & 0x0f;
90
91                 if (t >= 0 && t <= 9)
92                         *hexstr = t + '0';
93                 else if (t >= 10 && t <= 16)
94                         *hexstr = (t - 10) + 'a';
95
96                 hexstr++;
97
98                 t = *bin & 0x0f;
99
100                 if (t >= 0 && t <= 9)
101                         *hexstr = t + '0';
102                 else if (t >= 10 && t <= 16)
103                         *hexstr = (t - 10) + 'a';
104
105                 hexstr++;
106                 bin++;
107                 blen--;
108         }
109
110         *hexstr = '\0';
111 }
112
113 static int __netconfig_generate_aes_key()
114 {
115         ckmc_policy_s pol;
116         pol.extractable = false;
117         pol.password = NULL;
118         int err;
119
120         err = ckmc_create_key_aes(AES_KEY_SIZE, KEY_ALIAS, pol);
121
122         if (err != CKMC_ERROR_NONE && err != CKMC_ERROR_DB_ALIAS_EXISTS)
123                 return err;
124
125         return CKMC_ERROR_NONE;
126 }
127
128 static void*  __netconfig_set_param_list_aes_gcm(ckmc_param_list_h param)
129 {
130         ckmc_raw_buffer_s *iv_buf = NULL;
131         unsigned char rnd[RND_LENGTH];
132         ckmc_raw_buffer_s *aad_buf = NULL;
133         unsigned char aad[RND_LENGTH];
134
135         err = ckmc_get_data(IV_ALIAS, NULL, &iv_buf);
136
137         if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
138                 ckmc_policy_s policy;
139                 policy.extractable = true;
140                 policy.password = NULL;
141
142                 __netconfig_generate_random_bytes(rnd, RND_LENGTH);
143
144                 CKMC_ERROR_HANDLING(
145                                 ckmc_buffer_new(rnd, RND_LENGTH, &iv_buf),
146                                 NULL);
147
148                 CKMC_ERROR_HANDLING(
149                                 ckmc_save_data(IV_ALIAS, *iv_buf, policy),
150                                 ckmc_buffer_free(iv_buf));
151         }
152
153         err = ckmc_get_data(AAD_ALIAS, NULL, &aad_buf);
154
155         if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
156                 ckmc_policy_s policy;
157                 policy.extractable = true;
158                 policy.password = NULL;
159
160                 __netconfig_generate_random_bytes(aad, RND_LENGTH);
161
162                 CKMC_ERROR_HANDLING(
163                                 ckmc_buffer_new(aad, RND_LENGTH, &aad_buf),
164                                 ckmc_buffer_free(iv_buf));
165
166                 CKMC_ERROR_HANDLING(
167                                 ckmc_save_data(AAD_ALIAS, *aad_buf, policy),
168                                 ckmc_buffer_free(iv_buf);\
169                                 ckmc_buffer_free(aad_buf));
170         }
171
172         CKMC_ERROR_HANDLING(
173                         ckmc_param_list_set_buffer(param, CKMC_PARAM_ED_IV, iv_buf),
174                         ckmc_buffer_free(iv_buf);\
175                         ckmc_buffer_free(aad_buf));
176
177         CKMC_ERROR_HANDLING(
178                         ckmc_param_list_set_buffer(param, CKMC_PARAM_ED_AAD, aad_buf),
179                         ckmc_buffer_free(iv_buf);\
180                         ckmc_buffer_free(aad_buf));
181
182         return GINT_TO_POINTER(1);
183 }
184
185 gchar* _netconfig_encrypt_passphrase(const gchar *passphrase)
186 {
187         gchar* origin_value = NULL;
188         gchar* encrypted_value = NULL;
189
190         ckmc_param_list_h param;
191         ckmc_raw_buffer_s *ptext;
192         ckmc_raw_buffer_s *ctext;
193
194         if (!passphrase)
195                 return NULL;
196
197         origin_value = g_strdup(passphrase);
198
199         CKMC_ERROR_HANDLING(
200                         __netconfig_generate_aes_key(),
201                         g_free(origin_value));
202
203         CKMC_ERROR_HANDLING(
204                         ckmc_generate_new_params(CKMC_ALGO_AES_GCM, &param),
205                         g_free(origin_value));
206
207         if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
208                 ckmc_param_list_free(param);
209                 g_free(origin_value);
210                 return NULL;
211         }
212
213         CKMC_ERROR_HANDLING(
214                         ckmc_buffer_new((unsigned char*)origin_value,
215                                 strlen((char*)origin_value) + 1, &ptext),
216                         ckmc_param_list_free(param);\
217                         g_free(origin_value));
218
219         CKMC_ERROR_HANDLING(
220                         ckmc_encrypt_data(param, KEY_ALIAS, NULL, *ptext, &ctext),
221                         ckmc_param_list_free(param);\
222                         ckmc_buffer_free(ptext);\
223                         g_free(origin_value));
224
225         if ((encrypted_value = g_try_malloc0(ctext->size * 2 + 1)) == NULL) {
226                 DBG(" encrypted_value allocation failed");
227                 ckmc_param_list_free(param);
228                 ckmc_buffer_free(ptext);
229                 ckmc_buffer_free(ctext);
230                 g_free(origin_value);
231                 return NULL;
232         }
233
234         __netconfig_convert_bytes_to_hexstr((char*)ctext->data, ctext->size, encrypted_value);
235
236         g_free(origin_value);
237
238         ckmc_param_list_free(param);
239         ckmc_buffer_free(ptext);
240         ckmc_buffer_free(ctext);
241
242         return encrypted_value;
243 }
244
245 static gchar* _netconfig_decrypt_passphrase(const gchar *enc_data)
246 {
247         gchar *ehexstr = NULL;
248         gchar *encrypted_value = NULL;
249         gchar *passphrase = NULL;
250
251         ckmc_param_list_h param = NULL;
252         ckmc_raw_buffer_s *ptext;
253         ckmc_raw_buffer_s *ctext;
254
255         if (!enc_data)
256                 return NULL;
257
258         ehexstr = g_strdup(enc_data);
259
260         CKMC_ERROR_HANDLING(
261                         ckmc_generate_new_params(CKMC_ALGO_AES_GCM, &param),
262                         g_free(ehexstr));
263
264         if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
265                 ckmc_param_list_free(param);
266                 g_free(ehexstr);
267                 return NULL;
268         }
269
270         if ((encrypted_value = g_try_malloc0(strlen((char*)ehexstr)/2)) == NULL) {
271                 DBG(" encrypted_value allocation failed");
272                 ckmc_param_list_free(param);
273                 g_free(ehexstr);
274                 return NULL;
275         }
276
277         __netconfig_convert_hexstr_to_bytes(ehexstr, strlen((char*)ehexstr), encrypted_value);
278
279         CKMC_ERROR_HANDLING(
280                         ckmc_buffer_new((unsigned char*)encrypted_value,
281                                         strlen((char*)ehexstr)/2, &ctext),
282                         ckmc_param_list_free(param);\
283                         g_free(encrypted_value);\
284                         g_free(ehexstr));
285
286         g_free(ehexstr);
287
288         CKMC_ERROR_HANDLING(
289                         ckmc_decrypt_data(param, KEY_ALIAS, NULL, *ctext, &ptext),
290                         ckmc_param_list_free(param);\
291                         ckmc_buffer_free(ctext);\
292                         g_free(encrypted_value));
293
294         passphrase = g_strdup((const gchar*)ptext->data);
295
296         ckmc_param_list_free(param);
297         ckmc_buffer_free(ctext);
298         ckmc_buffer_free(ptext);
299         g_free(encrypted_value);
300
301         return passphrase;
302 }
303
304 gboolean handle_encrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *passphrase)
305 {
306         gchar *enc_data = NULL;
307
308         if ((wifi == NULL) || (passphrase == NULL)) {
309                 ERR("Invalid parameter");
310                 netconfig_error_invalid_parameter(context);
311                 return TRUE;
312         }
313
314         enc_data = _netconfig_encrypt_passphrase(passphrase);
315
316         if (!enc_data) {
317                 ERR("Failed to encrypt the passphrase");
318                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
319                 return TRUE;
320         }
321
322         wifi_complete_encrypt_passphrase(wifi, context, enc_data);
323         g_free(enc_data);
324
325         return TRUE;
326 }
327
328 gboolean handle_decrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *enc_data)
329 {
330         gchar *passphrase = NULL;
331
332         if ((wifi == NULL) || (enc_data == NULL)) {
333                 ERR("Invalid parameter");
334                 netconfig_error_invalid_parameter(context);
335                 return TRUE;
336         }
337
338         passphrase = _netconfig_decrypt_passphrase(enc_data);
339
340         if (!passphrase) {
341                 ERR("Failed to decrypt the passphrase");
342                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
343                 return TRUE;
344         }
345
346         wifi_complete_decrypt_passphrase(wifi, context, passphrase);
347         g_free(passphrase);
348
349         return TRUE;
350 }
351