2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <ckmc/ckmc-type.h>
23 #include <ckmc/ckmc-manager.h>
28 #include "wifi-key-encryption.h"
30 #define KEY_ALIAS "connman_wifi_passphrase"
31 #define IV_ALIAS "connman_wifi_enciv"
32 #define AAD_ALIAS "connman_wifi_gcmaad"
34 #define PASSPHRASE "Passphrase"
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); \
44 DBG(#expression " success");
50 static void __netconfig_generate_random_bytes(unsigned char* bytes, int len)
57 bytes[i++] = (unsigned char)random();
61 static void __netconfig_convert_hexstr_to_bytes(gchar* hexstr, int hlen, gchar* bin)
66 if (*hexstr >= '0' && *hexstr <= '9')
67 *bin = (*hexstr - '0') << 4;
68 else if (*hexstr >= 'a' && *hexstr <= 'f')
69 *bin = (*hexstr - 'a' + 10) << 4;
73 if (*hexstr >= '0' && *hexstr <= '9')
74 *bin |= (*hexstr - '0') & 0x0f;
75 else if (*hexstr >= 'a' && *hexstr <= 'f')
76 *bin |= (*hexstr - 'a' + 10) & 0x0f;
84 static void __netconfig_convert_bytes_to_hexstr(char* bin, int blen, gchar* hexstr)
89 t = (*bin >> 4) & 0x0f;
93 else if (t >= 10 && t <= 16)
94 *hexstr = (t - 10) + 'a';
100 if (t >= 0 && t <= 9)
102 else if (t >= 10 && t <= 16)
103 *hexstr = (t - 10) + 'a';
113 static int __netconfig_generate_aes_key()
116 pol.extractable = false;
120 err = ckmc_create_key_aes(AES_KEY_SIZE, KEY_ALIAS, pol);
122 if (err != CKMC_ERROR_NONE && err != CKMC_ERROR_DB_ALIAS_EXISTS)
125 return CKMC_ERROR_NONE;
128 static void* __netconfig_set_param_list_aes_gcm(ckmc_param_list_h param)
130 ckmc_raw_buffer_s *iv_buf;
131 unsigned char rnd[RND_LENGTH];
132 ckmc_raw_buffer_s *aad_buf;
133 unsigned char aad[RND_LENGTH];
135 err = ckmc_get_data(IV_ALIAS, NULL, &iv_buf);
137 if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
138 ckmc_policy_s policy;
139 policy.extractable = true;
140 policy.password = NULL;
142 __netconfig_generate_random_bytes(rnd, RND_LENGTH);
145 ckmc_buffer_new(rnd, RND_LENGTH, &iv_buf),
149 ckmc_save_data(IV_ALIAS, *iv_buf, policy),
150 ckmc_buffer_free(iv_buf));
153 err = ckmc_get_data(AAD_ALIAS, NULL, &aad_buf);
155 if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
156 ckmc_policy_s policy;
157 policy.extractable = true;
158 policy.password = NULL;
160 __netconfig_generate_random_bytes(aad, RND_LENGTH);
163 ckmc_buffer_new(aad, RND_LENGTH, &aad_buf),
164 ckmc_buffer_free(iv_buf));
167 ckmc_save_data(AAD_ALIAS, *aad_buf, policy),
168 ckmc_buffer_free(iv_buf);\
169 ckmc_buffer_free(aad_buf));
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));
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));
182 return GINT_TO_POINTER(1);
185 gchar* _netconfig_encrypt_passphrase(const gchar *passphrase)
187 gchar* origin_value = NULL;
188 gchar* encrypted_value = NULL;
190 ckmc_param_list_h param;
191 ckmc_raw_buffer_s *ptext;
192 ckmc_raw_buffer_s *ctext;
197 origin_value = g_strdup(passphrase);
200 __netconfig_generate_aes_key(),
201 g_free(origin_value));
204 ckmc_generate_new_params(CKMC_ALGO_AES_GCM, ¶m),
205 g_free(origin_value));
207 if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
208 ckmc_param_list_free(param);
209 g_free(origin_value);
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));
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));
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);
234 __netconfig_convert_bytes_to_hexstr((char*)ctext->data, ctext->size, encrypted_value);
236 g_free(origin_value);
238 ckmc_param_list_free(param);
239 ckmc_buffer_free(ptext);
240 ckmc_buffer_free(ctext);
242 return encrypted_value;
245 static gchar* _netconfig_decrypt_passphrase(const gchar *enc_data)
247 gchar *ehexstr = NULL;
248 gchar *encrypted_value = NULL;
249 gchar *passphrase = NULL;
251 ckmc_param_list_h param = NULL;
252 ckmc_raw_buffer_s *ptext;
253 ckmc_raw_buffer_s *ctext;
258 ehexstr = g_strdup(enc_data);
261 ckmc_generate_new_params(CKMC_ALGO_AES_GCM, ¶m),
264 if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
265 ckmc_param_list_free(param);
270 if ((encrypted_value = g_try_malloc0(strlen((char*)ehexstr)/2)) == NULL) {
271 DBG(" encrypted_value allocation failed");
272 ckmc_param_list_free(param);
277 __netconfig_convert_hexstr_to_bytes(ehexstr, strlen((char*)ehexstr), encrypted_value);
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);\
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));
294 passphrase = g_strdup((const gchar*)ptext->data);
296 ckmc_param_list_free(param);
297 ckmc_buffer_free(ctext);
298 ckmc_buffer_free(ptext);
299 g_free(encrypted_value);
304 gboolean handle_encrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *passphrase)
306 gchar *enc_data = NULL;
308 if ((wifi == NULL) || (passphrase == NULL)) {
309 ERR("Invalid parameter");
310 netconfig_error_invalid_parameter(context);
314 enc_data = _netconfig_encrypt_passphrase(passphrase);
317 ERR("Failed to encrypt the passphrase");
318 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
322 wifi_complete_encrypt_passphrase(wifi, context, enc_data);
328 gboolean handle_decrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *enc_data)
330 gchar *passphrase = NULL;
332 if ((wifi == NULL) || (enc_data == NULL)) {
333 ERR("Invalid parameter");
334 netconfig_error_invalid_parameter(context);
338 passphrase = _netconfig_decrypt_passphrase(enc_data);
341 ERR("Failed to decrypt the passphrase");
342 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
346 wifi_complete_decrypt_passphrase(wifi, context, passphrase);