mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
wlan: set_key and del_key
This commit is contained in:
@@ -4,6 +4,27 @@
|
||||
#include <u80211_drv/kernel_interface.h>
|
||||
#include <kernel/net.h>
|
||||
|
||||
#define WLAN_CIPHER_CCMP 0
|
||||
#define WLAN_CIPHER_TKIP 1
|
||||
#define WLAN_CIPHER_WEP40 2
|
||||
#define WLAN_CIPHER_WEP104 3
|
||||
|
||||
#define WLAN_KEY_PAIRWISE 1
|
||||
#define WLAN_KEY_GROUP 2
|
||||
#define WLAN_KEY_RX 4
|
||||
#define WLAN_KEY_TX 8
|
||||
|
||||
typedef struct {
|
||||
uint8_t cipher;
|
||||
uint8_t index;
|
||||
uint8_t peer[6];
|
||||
uint8_t *key;
|
||||
size_t key_len;
|
||||
uint8_t *rx_seq;
|
||||
size_t rx_seq_len;
|
||||
uint32_t flags;
|
||||
} wlan_key_t;
|
||||
|
||||
int wlan_register(void *handle, const u80211_drv_device_metadata_t *metadata, const u80211_drv_device_ops_t *ops, u80211_drv_network_device_handle_t *network_device);
|
||||
void wlan_process_packet(u80211_drv_network_device_handle_t handle, void *packet, size_t packet_size);
|
||||
|
||||
@@ -16,4 +37,7 @@ int wlan_associate(netdev_t *netdev, uint8_t bssid[6], void *ie, size_t ie_size)
|
||||
int wlan_associate_wait(netdev_t *netdev);
|
||||
int wlan_disassociate(netdev_t *netdev);
|
||||
|
||||
int wlan_set_key(netdev_t *netdev, wlan_key_t *key);
|
||||
int wlan_del_key(netdev_t *netdev, uint8_t index, uint8_t peer[6], uint32_t flags);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,14 @@ typedef struct {
|
||||
size_t ie_size;
|
||||
} wlan_association_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t peer[6];
|
||||
uint8_t index;
|
||||
uint32_t flags;
|
||||
} wlan_del_key_request_t;
|
||||
|
||||
#define MAX_KEY_SIZE 128
|
||||
#define MAX_SEQ_SIZE 16
|
||||
#define MAX_IE_SIZE 1024
|
||||
|
||||
#define NETDEV_IOCTL_GET_INFO 0x1337631
|
||||
@@ -96,12 +104,71 @@ int handle_wlan_ioctl(netdev_t *netdev, unsigned long request, void *arg, int *r
|
||||
return wlan_associate_wait(netdev);
|
||||
case NETDEV_IOCTL_WLAN_DISASSOCIATE:
|
||||
return wlan_disassociate(netdev);
|
||||
case NETDEV_IOCTL_WLAN_SET_KEY:
|
||||
case NETDEV_IOCTL_WLAN_SET_KEY: {
|
||||
wlan_key_t req;
|
||||
int error = USERCOPY_POSSIBLY_FROM_USER(&req, arg, sizeof(req));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
break;
|
||||
case NETDEV_IOCTL_WLAN_DEL_KEY:
|
||||
if (req.rx_seq_len > MAX_SEQ_SIZE)
|
||||
return EINVAL;
|
||||
|
||||
break;
|
||||
if (req.key_len > MAX_KEY_SIZE)
|
||||
return EINVAL;
|
||||
|
||||
void *key = NULL;
|
||||
void *seq = NULL;
|
||||
|
||||
if (req.key_len) {
|
||||
if (IS_USER_ADDRESS(arg) && !IS_USER_ADDRESS(req.key))
|
||||
return EFAULT;
|
||||
|
||||
key = alloc(req.key_len);
|
||||
if (key == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
error = USERCOPY_POSSIBLY_FROM_USER(key, req.key, req.key_len);
|
||||
if (error)
|
||||
goto wlan_set_key_done;
|
||||
}
|
||||
|
||||
if (req.rx_seq_len) {
|
||||
if (IS_USER_ADDRESS(arg) && !IS_USER_ADDRESS(req.rx_seq)) {
|
||||
error = EFAULT;
|
||||
goto wlan_set_key_done;
|
||||
}
|
||||
|
||||
seq = alloc(req.rx_seq_len);
|
||||
if (seq == NULL) {
|
||||
error = ENOMEM;
|
||||
goto wlan_set_key_done;
|
||||
}
|
||||
|
||||
error = USERCOPY_POSSIBLY_FROM_USER(seq, req.rx_seq, req.rx_seq_len);
|
||||
if (error)
|
||||
goto wlan_set_key_done;
|
||||
}
|
||||
|
||||
req.key = key;
|
||||
req.rx_seq = seq;
|
||||
|
||||
error = wlan_set_key(netdev, &req);
|
||||
|
||||
wlan_set_key_done:
|
||||
if (key)
|
||||
free(key);
|
||||
if (seq)
|
||||
free(seq);
|
||||
return error;
|
||||
}
|
||||
case NETDEV_IOCTL_WLAN_DEL_KEY: {
|
||||
wlan_del_key_request_t req;
|
||||
int error = USERCOPY_POSSIBLY_FROM_USER(&req, arg, sizeof(req));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return wlan_del_key(netdev, req.index, req.peer, req.flags);
|
||||
}
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
@@ -363,3 +363,70 @@ int wlan_disassociate(netdev_t *netdev) {
|
||||
|
||||
return u80211_disassociate(wlan->u80211_device) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
static bool wlan_cipher_to_u80211_cipher(uint8_t cipher, u80211_cipher_t *out) {
|
||||
switch (cipher) {
|
||||
case WLAN_CIPHER_CCMP:
|
||||
*out = U80211_CIPHER_CCMP;
|
||||
break;
|
||||
case WLAN_CIPHER_TKIP:
|
||||
*out = U80211_CIPHER_TKIP;
|
||||
break;
|
||||
case WLAN_CIPHER_WEP40:
|
||||
*out = U80211_CIPHER_WEP40;
|
||||
break;
|
||||
case WLAN_CIPHER_WEP104:
|
||||
*out = U80211_CIPHER_WEP104;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t wlan_flags_to_u80211_flags(uint32_t flags) {
|
||||
uint32_t out = 0;
|
||||
|
||||
if (flags & WLAN_KEY_PAIRWISE)
|
||||
out |= U80211_KEY_PAIRWISE;
|
||||
|
||||
if (flags & WLAN_KEY_GROUP)
|
||||
out |= U80211_KEY_GROUP;
|
||||
|
||||
if (flags & WLAN_KEY_RX)
|
||||
out |= U80211_KEY_RX;
|
||||
|
||||
if (flags & WLAN_KEY_TX)
|
||||
out |= U80211_KEY_TX;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int wlan_set_key(netdev_t *netdev, wlan_key_t *key) {
|
||||
wlan_device_t *wlan = (wlan_device_t *)netdev;
|
||||
|
||||
u80211_key_t u80211_key = {
|
||||
.index = key->index,
|
||||
.key = key->key,
|
||||
.key_len = key->key_len,
|
||||
.rx_seq = key->rx_seq,
|
||||
.rx_seq_len = key->rx_seq_len,
|
||||
.flags = wlan_flags_to_u80211_flags(key->flags)
|
||||
};
|
||||
memcpy(&u80211_key.peer, key->peer, 6);
|
||||
|
||||
if (!wlan_cipher_to_u80211_cipher(key->cipher, &u80211_key.cipher))
|
||||
return EINVAL;
|
||||
|
||||
return u80211_set_key(wlan->u80211_device, &u80211_key) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int wlan_del_key(netdev_t *netdev, uint8_t index, uint8_t peer[6], uint32_t flags) {
|
||||
wlan_device_t *wlan = (wlan_device_t *)netdev;
|
||||
|
||||
u80211_mac_address_t mac;
|
||||
memcpy(&mac, peer, 6);
|
||||
|
||||
return u80211_del_key(wlan->u80211_device, index, &mac, flags) == U80211_STATUS_SUCCESS ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user