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 = NULL;
162 ckmc_raw_buffer_s *ptext = NULL;
163 ckmc_raw_buffer_s *ctext = NULL;
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));
197 (encrypted_value = g_try_malloc0(ctext->size * 2 + 1)) == NULL) {
198 DBG(" encrypted_value allocation failed");
199 ckmc_param_list_free(param);
200 ckmc_buffer_free(ptext);
201 ckmc_buffer_free(ctext);
202 g_free(origin_value);
206 netconfig_convert_bytes_to_hexstr((const char *)ctext->data, ctext->size, encrypted_value);
208 g_free(origin_value);
210 ckmc_param_list_free(param);
211 ckmc_buffer_free(ptext);
212 ckmc_buffer_free(ctext);
214 return encrypted_value;
217 static gchar* _netconfig_decrypt_passphrase(const gchar *enc_data)
219 gchar *ehexstr = NULL;
220 gchar *encrypted_value = NULL;
221 gchar *passphrase = NULL;
223 ckmc_param_list_h param = NULL;
224 ckmc_raw_buffer_s *ptext = NULL;
225 ckmc_raw_buffer_s *ctext = NULL;
230 ehexstr = g_strdup(enc_data);
233 ckmc_generate_new_params(CKMC_ALGO_AES_GCM, ¶m),
236 if (__netconfig_set_param_list_aes_gcm(param) == NULL) {
237 ckmc_param_list_free(param);
242 if ((encrypted_value = g_try_malloc0(strlen((char*)ehexstr)/2)) == NULL) {
243 DBG(" encrypted_value allocation failed");
244 ckmc_param_list_free(param);
249 __netconfig_convert_hexstr_to_bytes(ehexstr, strlen((char*)ehexstr), encrypted_value);
252 ckmc_buffer_new((unsigned char*)encrypted_value,
253 strlen((char*)ehexstr)/2, &ctext),
254 ckmc_param_list_free(param);\
255 g_free(encrypted_value);\
261 ckmc_decrypt_data(param, KEY_ALIAS, NULL, *ctext, &ptext),
262 ckmc_param_list_free(param);\
263 ckmc_buffer_free(ctext);\
264 g_free(encrypted_value));
267 passphrase = g_strdup((const gchar*)ptext->data);
269 ckmc_param_list_free(param);
270 ckmc_buffer_free(ctext);
271 ckmc_buffer_free(ptext);
272 g_free(encrypted_value);
277 gboolean handle_encrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *passphrase)
279 gchar *enc_data = NULL;
281 if ((wifi == NULL) || (passphrase == NULL)) {
282 ERR("Invalid parameter");
283 netconfig_error_invalid_parameter(context);
287 enc_data = _netconfig_encrypt_passphrase(passphrase);
290 ERR("Failed to encrypt the passphrase");
291 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
295 wifi_complete_encrypt_passphrase(wifi, context, enc_data);
301 gboolean handle_decrypt_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *enc_data)
303 gchar *passphrase = NULL;
305 if ((wifi == NULL) || (enc_data == NULL)) {
306 ERR("Invalid parameter");
307 netconfig_error_invalid_parameter(context);
311 passphrase = _netconfig_decrypt_passphrase(enc_data);
314 ERR("Failed to decrypt the passphrase");
315 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
319 wifi_complete_decrypt_passphrase(wifi, context, passphrase);
325 gboolean handle_decrypt_conf_obj(Wifi *wifi, GDBusMethodInvocation *context,
326 const gchar *enc_connector,
327 const gchar *enc_c_sign_key,
328 const gchar *enc_net_access_key)
330 GVariantBuilder *builder = NULL;
331 gchar *connector = NULL;
332 gchar *c_sign_key = NULL;
333 gchar *net_access_key = NULL;
336 if (!wifi || !enc_connector || !enc_c_sign_key || !enc_net_access_key) {
337 ERR("Invalid parameter");
338 netconfig_error_invalid_parameter(context);
342 connector = _netconfig_decrypt_passphrase(enc_connector);
343 c_sign_key = _netconfig_decrypt_passphrase(enc_c_sign_key);
344 net_access_key = _netconfig_decrypt_passphrase(enc_net_access_key);
346 if (!connector || !c_sign_key || !net_access_key) {
347 ERR("Failed to decrypt the configuration object");
348 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
351 g_free(net_access_key);
355 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
356 g_variant_builder_add(builder, "{sv}", "connector",
357 g_variant_new_string(connector));
358 g_variant_builder_add(builder, "{sv}", "c_sign_key",
359 g_variant_new_string(c_sign_key));
360 g_variant_builder_add(builder, "{sv}", "net_access_key",
361 g_variant_new_string(net_access_key));
363 wifi_complete_decrypt_conf_obj(wifi, context, g_variant_builder_end(builder));
364 g_variant_builder_unref(builder);
367 g_free(net_access_key);