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 int __netconfig_generate_aes_key()
87 pol.extractable = false;
91 err = ckmc_create_key_aes(AES_KEY_SIZE, KEY_ALIAS, pol);
93 if (err != CKMC_ERROR_NONE && err != CKMC_ERROR_DB_ALIAS_EXISTS)
96 return CKMC_ERROR_NONE;
99 static void* __netconfig_set_param_list_aes_gcm(ckmc_param_list_h param)
101 ckmc_raw_buffer_s *iv_buf = NULL;
102 unsigned char rnd[RND_LENGTH];
103 ckmc_raw_buffer_s *aad_buf = NULL;
104 unsigned char aad[RND_LENGTH];
106 err = ckmc_get_data(IV_ALIAS, NULL, &iv_buf);
108 if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
109 ckmc_policy_s policy;
110 policy.extractable = true;
111 policy.password = NULL;
113 __netconfig_generate_random_bytes(rnd, RND_LENGTH);
116 ckmc_buffer_new(rnd, RND_LENGTH, &iv_buf),
120 ckmc_save_data(IV_ALIAS, *iv_buf, policy),
121 ckmc_buffer_free(iv_buf));
124 err = ckmc_get_data(AAD_ALIAS, NULL, &aad_buf);
126 if (err == CKMC_ERROR_DB_ALIAS_UNKNOWN) {
127 ckmc_policy_s policy;
128 policy.extractable = true;
129 policy.password = NULL;
131 __netconfig_generate_random_bytes(aad, RND_LENGTH);
134 ckmc_buffer_new(aad, RND_LENGTH, &aad_buf),
135 ckmc_buffer_free(iv_buf));
138 ckmc_save_data(AAD_ALIAS, *aad_buf, policy),
139 ckmc_buffer_free(iv_buf);\
140 ckmc_buffer_free(aad_buf));
144 ckmc_param_list_set_buffer(param, CKMC_PARAM_ED_IV, iv_buf),
145 ckmc_buffer_free(iv_buf);\
146 ckmc_buffer_free(aad_buf));
149 ckmc_param_list_set_buffer(param, CKMC_PARAM_ED_AAD, aad_buf),
150 ckmc_buffer_free(iv_buf);\
151 ckmc_buffer_free(aad_buf));
153 return GINT_TO_POINTER(1);
156 gchar* _netconfig_encrypt_passphrase(const gchar *passphrase)
158 gchar* origin_value = NULL;
159 gchar* encrypted_value = NULL;
161 ckmc_param_list_h param;
162 ckmc_raw_buffer_s *ptext;
163 ckmc_raw_buffer_s *ctext;
168 origin_value = g_strdup(passphrase);
171 __netconfig_generate_aes_key(),
172 g_free(origin_value));
175 ckmc_generate_new_params(CKMC_ALGO_AES_GCM, ¶m),
176 g_free(origin_value));
178 if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
179 ckmc_param_list_free(param);
180 g_free(origin_value);
185 ckmc_buffer_new((unsigned char*)origin_value,
186 strlen((char*)origin_value) + 1, &ptext),
187 ckmc_param_list_free(param);\
188 g_free(origin_value));
191 ckmc_encrypt_data(param, KEY_ALIAS, NULL, *ptext, &ctext),
192 ckmc_param_list_free(param);\
193 ckmc_buffer_free(ptext);\
194 g_free(origin_value));
196 if ((encrypted_value = g_try_malloc0(ctext->size * 2 + 1)) == NULL) {
197 DBG(" encrypted_value allocation failed");
198 ckmc_param_list_free(param);
199 ckmc_buffer_free(ptext);
200 ckmc_buffer_free(ctext);
201 g_free(origin_value);
205 netconfig_convert_bytes_to_hexstr((const char *)ctext->data, ctext->size, encrypted_value);
207 g_free(origin_value);
209 ckmc_param_list_free(param);
210 ckmc_buffer_free(ptext);
211 ckmc_buffer_free(ctext);
213 return encrypted_value;
216 static gchar* _netconfig_decrypt_passphrase(const gchar *enc_data)
218 gchar *ehexstr = NULL;
219 gchar *encrypted_value = NULL;
220 gchar *passphrase = NULL;
222 ckmc_param_list_h param = NULL;
223 ckmc_raw_buffer_s *ptext;
224 ckmc_raw_buffer_s *ctext;
229 ehexstr = g_strdup(enc_data);
232 ckmc_generate_new_params(CKMC_ALGO_AES_GCM, ¶m),
235 if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
236 ckmc_param_list_free(param);
241 if ((encrypted_value = g_try_malloc0(strlen((char*)ehexstr)/2)) == NULL) {
242 DBG(" encrypted_value allocation failed");
243 ckmc_param_list_free(param);
248 __netconfig_convert_hexstr_to_bytes(ehexstr, strlen((char*)ehexstr), encrypted_value);
251 ckmc_buffer_new((unsigned char*)encrypted_value,
252 strlen((char*)ehexstr)/2, &ctext),
253 ckmc_param_list_free(param);\
254 g_free(encrypted_value);\
260 ckmc_decrypt_data(param, KEY_ALIAS, NULL, *ctext, &ptext),
261 ckmc_param_list_free(param);\
262 ckmc_buffer_free(ctext);\
263 g_free(encrypted_value));
265 passphrase = g_strdup((const gchar*)ptext->data);
267 ckmc_param_list_free(param);
268 ckmc_buffer_free(ctext);
269 ckmc_buffer_free(ptext);
270 g_free(encrypted_value);
275 gboolean handle_encrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *passphrase)
277 gchar *enc_data = NULL;
279 if ((wifi == NULL) || (passphrase == NULL)) {
280 ERR("Invalid parameter");
281 netconfig_error_invalid_parameter(context);
285 enc_data = _netconfig_encrypt_passphrase(passphrase);
288 ERR("Failed to encrypt the passphrase");
289 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
293 wifi_complete_encrypt_passphrase(wifi, context, enc_data);
299 gboolean handle_decrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *enc_data)
301 gchar *passphrase = NULL;
303 if ((wifi == NULL) || (enc_data == NULL)) {
304 ERR("Invalid parameter");
305 netconfig_error_invalid_parameter(context);
309 passphrase = _netconfig_decrypt_passphrase(enc_data);
312 ERR("Failed to decrypt the passphrase");
313 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
317 wifi_complete_decrypt_passphrase(wifi, context, passphrase);
323 gboolean handle_decrypt_conf_obj(Wifi *wifi, GDBusMethodInvocation *context,
324 const gchar *enc_connector,
325 const gchar *enc_c_sign_key,
326 const gchar *enc_net_access_key)
328 GVariantBuilder *builder = NULL;
329 gchar *connector = NULL;
330 gchar *c_sign_key = NULL;
331 gchar *net_access_key = NULL;
334 if (!wifi || !enc_connector || !enc_c_sign_key || !enc_net_access_key) {
335 ERR("Invalid parameter");
336 netconfig_error_invalid_parameter(context);
340 connector = _netconfig_decrypt_passphrase(enc_connector);
341 c_sign_key = _netconfig_decrypt_passphrase(enc_c_sign_key);
342 net_access_key = _netconfig_decrypt_passphrase(enc_net_access_key);
344 if (!connector || !c_sign_key || !net_access_key) {
345 ERR("Failed to decrypt the configuration object");
346 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
349 g_free(net_access_key);
353 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
354 g_variant_builder_add(builder, "{sv}", "connector",
355 g_variant_new_string(connector));
356 g_variant_builder_add(builder, "{sv}", "c_sign_key",
357 g_variant_new_string(c_sign_key));
358 g_variant_builder_add(builder, "{sv}", "net_access_key",
359 g_variant_new_string(net_access_key));
361 wifi_complete_decrypt_conf_obj(wifi, context, g_variant_builder_end(builder));
362 g_variant_builder_unref(builder);
365 g_free(net_access_key);