• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - PS3 Linux wireless extension driver interface
3  * Copyright 2007, 2008 Sony Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 #include <sys/ioctl.h>
17 #include "wireless_copy.h"
18 #include "common.h"
19 #include "wpa_common.h"
20 #include "driver.h"
21 #include "eloop.h"
22 #include "driver_wext.h"
23 #include "ieee802_11_defs.h"
24 
wpa_driver_ps3_set_wpa_key(struct wpa_driver_wext_data * drv,struct wpa_driver_associate_params * params)25 static int wpa_driver_ps3_set_wpa_key(struct wpa_driver_wext_data *drv,
26 				struct wpa_driver_associate_params *params)
27 {
28 	int ret, i;
29 	struct iwreq iwr;
30 	char *buf, *str;
31 
32 	if (!params->psk && !params->passphrase) {
33 		wpa_printf(MSG_INFO, "%s:no PSK error", __func__);
34 		return -EINVAL;
35 	}
36 
37 	os_memset(&iwr, 0, sizeof(iwr));
38 	if (params->psk) {
39 		/* includes null */
40 		iwr.u.data.length = PMK_LEN * 2 + 1;
41 		buf = os_malloc(iwr.u.data.length);
42 		if (!buf)
43 			return -ENOMEM;
44 		str = buf;
45 		for (i = 0; i < PMK_LEN; i++) {
46 			str += snprintf(str, iwr.u.data.length - (str - buf),
47 					"%02x", params->psk[i]);
48 		}
49 	} else if (params->passphrase) {
50 		/* including quotations and null */
51 		iwr.u.data.length = strlen(params->passphrase) + 3;
52 		buf = os_malloc(iwr.u.data.length);
53 		if (!buf)
54 			return -ENOMEM;
55 		buf[0] = '"';
56 		os_memcpy(buf + 1, params->passphrase, iwr.u.data.length - 3);
57 		buf[iwr.u.data.length - 2] = '"';
58 		buf[iwr.u.data.length - 1] = '\0';
59 	} else
60 		return -EINVAL;
61 	iwr.u.data.pointer = (caddr_t) buf;
62 	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
63 	ret = ioctl(drv->ioctl_sock, SIOCIWFIRSTPRIV, &iwr);
64 	os_free(buf);
65 
66 	return ret;
67 }
68 
wpa_driver_ps3_set_wep_keys(struct wpa_driver_wext_data * drv,struct wpa_driver_associate_params * params)69 static int wpa_driver_ps3_set_wep_keys(struct wpa_driver_wext_data *drv,
70 				struct wpa_driver_associate_params *params)
71 {
72 	int ret, i;
73 	struct iwreq iwr;
74 
75 	for (i = 0; i < 4; i++) {
76 		os_memset(&iwr, 0, sizeof(iwr));
77 		os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
78 		iwr.u.encoding.flags = i + 1;
79 		if (params->wep_key_len[i]) {
80 			iwr.u.encoding.pointer = (caddr_t) params->wep_key[i];
81 			iwr.u.encoding.length = params->wep_key_len[i];
82 		} else
83 			iwr.u.encoding.flags = IW_ENCODE_NOKEY |
84 				IW_ENCODE_DISABLED;
85 
86 		if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
87 			perror("ioctl[SIOCSIWENCODE]");
88 			ret = -1;
89 		}
90 	}
91 	return ret;
92 }
93 
wpa_driver_ps3_associate(void * priv,struct wpa_driver_associate_params * params)94 static int wpa_driver_ps3_associate(void *priv,
95 				    struct wpa_driver_associate_params *params)
96 {
97 	struct wpa_driver_wext_data *drv = priv;
98 	int ret, value;
99 
100 	wpa_printf(MSG_DEBUG, "%s: <-", __func__);
101 
102 	/* clear BSSID */
103 	if (!params->bssid &&
104 	    wpa_driver_wext_set_bssid(drv, NULL) < 0)
105 		ret = -1;
106 
107 	if (wpa_driver_wext_set_mode(drv, params->mode) < 0)
108 		ret = -1;
109 
110 	if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
111 		value = IW_AUTH_WPA_VERSION_DISABLED;
112 	else if (params->wpa_ie[0] == WLAN_EID_RSN)
113 		value = IW_AUTH_WPA_VERSION_WPA2;
114 	else
115 		value = IW_AUTH_WPA_VERSION_WPA;
116 	if (wpa_driver_wext_set_auth_param(drv,
117 					   IW_AUTH_WPA_VERSION, value) < 0)
118 		ret = -1;
119 	value = wpa_driver_wext_cipher2wext(params->pairwise_suite);
120 	if (wpa_driver_wext_set_auth_param(drv,
121 					   IW_AUTH_CIPHER_PAIRWISE, value) < 0)
122 		ret = -1;
123 	value = wpa_driver_wext_cipher2wext(params->group_suite);
124 	if (wpa_driver_wext_set_auth_param(drv,
125 					   IW_AUTH_CIPHER_GROUP, value) < 0)
126 		ret = -1;
127 	value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite);
128 	if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_KEY_MGMT, value) < 0)
129 		ret = -1;
130 
131 	/* set selected BSSID */
132 	if (params->bssid &&
133 	    wpa_driver_wext_set_bssid(drv, params->bssid) < 0)
134 		ret = -1;
135 
136 	switch (params->group_suite) {
137 	case CIPHER_NONE:
138 		ret = 0;
139 		break;
140 	case CIPHER_WEP40:
141 	case CIPHER_WEP104:
142 		ret = wpa_driver_ps3_set_wep_keys(drv, params);
143 		break;
144 	case CIPHER_TKIP:
145 	case CIPHER_CCMP:
146 		ret = wpa_driver_ps3_set_wpa_key(drv, params);
147 		break;
148 	}
149 
150 	/* start to associate */
151 	ret = wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len);
152 
153 	wpa_printf(MSG_DEBUG, "%s: ->", __func__);
154 
155 	return ret;
156 }
157 
wpa_driver_ps3_get_capa(void * priv,struct wpa_driver_capa * capa)158 static int wpa_driver_ps3_get_capa(void *priv, struct wpa_driver_capa *capa)
159 {
160 	int ret;
161 	wpa_printf(MSG_DEBUG, "%s:<-", __func__);
162 
163 	ret = wpa_driver_wext_get_capa(priv, capa);
164 	if (ret) {
165 		wpa_printf(MSG_INFO, "%s: base wext returns error %d",
166 			   __func__, ret);
167 		return ret;
168 	}
169 	/* PS3 hypervisor does association and 4way handshake by itself */
170 	capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
171 	wpa_printf(MSG_DEBUG, "%s:->", __func__);
172 	return 0;
173 }
174 
175 const struct wpa_driver_ops wpa_driver_ps3_ops = {
176 	.name = "ps3",
177 	.desc = "PLAYSTATION3 Linux wireless extension driver",
178 	.get_bssid = wpa_driver_wext_get_bssid,
179 	.get_ssid = wpa_driver_wext_get_ssid,
180 	.scan = wpa_driver_wext_scan,
181 	.get_scan_results2 = wpa_driver_wext_get_scan_results,
182 	.associate = wpa_driver_ps3_associate, /* PS3 */
183 	.init = wpa_driver_wext_init,
184 	.deinit = wpa_driver_wext_deinit,
185 	.get_capa = wpa_driver_ps3_get_capa, /* PS3 */
186 };
187