hostapd: add support for rxkh_file

Initial support for dynamic reload of RxKHs.

In order to check if RxKHs need reloading.
RxKHs defined in the rxkh_file first has to be parsed and formated,
the same way as hostapd will read from the file and also output,
with the command GET_RXKHS.
Then each list of RxKHs can be hashed and compared.

Ucode implementation of hostapds rkh_derive_key() function.
Hostapd converts hex keys with 128-bits or more when less than 256-bits
to 256-bits, and truncates those that are more than 256-bits.
See: https://w1.fi/cgit/hostap/commit/hostapd/config_file.c?id=245fc96e5f4b1c566b7eaa19180c774307ebed79

Signed-off-by: Sybil127 <sybil127@outlook.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Sybil127
2024-05-23 18:49:54 +02:00
committed by Felix Fietkau
parent 97c8a94ec5
commit 7306ae401c
4 changed files with 104 additions and 2 deletions

View File

@@ -823,6 +823,7 @@ int hostapd_ucode_init(struct hapd_interfaces *ifaces)
{ "printf", uc_wpa_printf },
{ "getpid", uc_wpa_getpid },
{ "sha1", uc_wpa_sha1 },
{ "rkh_derive_key", uc_wpa_rkh_derive_key },
{ "freq_info", uc_wpa_freq_info },
{ "add_iface", uc_hostapd_add_iface },
{ "remove_iface", uc_hostapd_remove_iface },

View File

@@ -3,6 +3,7 @@
#include "utils/eloop.h"
#include "crypto/crypto.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "common/ieee802_11_common.h"
#include <linux/netlink.h>
#include <linux/genetlink.h>
@@ -236,6 +237,40 @@ uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs)
return ucv_string_new_length(hash_hex, 2 * ARRAY_SIZE(hash));
}
uc_value_t *uc_wpa_rkh_derive_key(uc_vm_t *vm, size_t nargs)
{
u8 oldkey[16];
char *oldkey_hex;
u8 key[SHA256_MAC_LEN];
size_t key_len = sizeof(key);
char key_hex[2 * ARRAY_SIZE(key) + 1];
uc_value_t *val = uc_fn_arg(0);
int i;
if (ucv_type(val) != UC_STRING)
return NULL;
oldkey_hex = ucv_string_get(val);
if (!hexstr2bin(oldkey_hex, key, key_len))
return ucv_string_new_length(oldkey_hex, 2 * ARRAY_SIZE(key));
if (hexstr2bin(oldkey_hex, oldkey, sizeof(oldkey))) {
wpa_printf(MSG_ERROR, "Invalid RxKH key: '%s'", oldkey_hex);
return NULL;
}
if (hmac_sha256_kdf(oldkey, sizeof(oldkey), "FT OLDKEY", NULL, 0, key, key_len) < 0) {
wpa_printf(MSG_ERROR, "Invalid RxKH key: '%s'", oldkey_hex);
return NULL;
}
for (i = 0; i < ARRAY_SIZE(key); i++)
sprintf(key_hex + 2 * i, "%02x", key[i]);
return ucv_string_new_length(key_hex, 2 * ARRAY_SIZE(key));
}
uc_vm_t *wpa_ucode_create_vm(void)
{
static uc_parse_config_t config = {

View File

@@ -25,6 +25,7 @@ uc_value_t *uc_wpa_udebug_set(uc_vm_t *vm, size_t nargs);
uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs);
uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs);
uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs);
uc_value_t *uc_wpa_rkh_derive_key(uc_vm_t *vm, size_t nargs);
uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs);
#endif