mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
Merge pull request #2842 from FrancescoErmini/drivers_xbee_encryption
drivers/xbee: add optional AES encryption support
This commit is contained in:
commit
3e70191aee
@ -39,7 +39,11 @@ extern "C" {
|
||||
/**
|
||||
* @brief Maximum payload length that can be send
|
||||
*/
|
||||
#ifdef MODULE_XBEE_ENCRYPTION
|
||||
#define XBEE_MAX_PAYLOAD_LENGTH (95U)
|
||||
#else
|
||||
#define XBEE_MAX_PAYLOAD_LENGTH (100U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum packet length, including XBee API frame overhead
|
||||
|
||||
@ -456,6 +456,50 @@ static int _set_proto(xbee_t *dev, uint8_t *val, size_t len)
|
||||
return sizeof(gnrc_nettype_t);
|
||||
}
|
||||
|
||||
#ifdef MODULE_XBEE_ENCRYPTION
|
||||
static int _set_encryption(xbee_t *dev, uint8_t *val)
|
||||
{
|
||||
uint8_t cmd[3];
|
||||
resp_t resp;
|
||||
/* get the current state of Encryption */
|
||||
cmd[0] = 'E';
|
||||
cmd[1] = 'E';
|
||||
_api_at_cmd(dev, cmd, 2, &resp);
|
||||
|
||||
/* Prevent writing the same value in EE. */
|
||||
if (val[0] != resp.data[0] ){
|
||||
cmd[0] = 'E';
|
||||
cmd[1] = 'E';
|
||||
cmd[2] = val[0];
|
||||
_api_at_cmd(dev, cmd, 3, &resp);
|
||||
}
|
||||
if (resp.status == 0) {
|
||||
return 2;
|
||||
}
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
static int _set_encryption_key(xbee_t *dev, uint8_t *val, size_t len)
|
||||
{
|
||||
uint8_t cmd[18];
|
||||
resp_t resp;
|
||||
if (len != 16) { /* the AES key is 128bit, 16 byte */
|
||||
return -EINVAL;
|
||||
}
|
||||
cmd[0] = 'K';
|
||||
cmd[1] = 'Y';
|
||||
|
||||
for (int i = 0; i < 16; i++) { /* Append the key to the KY API AT command */
|
||||
cmd[i + 2] = val[i];
|
||||
}
|
||||
_api_at_cmd(dev, cmd, 18, &resp);
|
||||
if (resp.status == 0) {
|
||||
return 2;
|
||||
}
|
||||
return -ECANCELED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Driver's "public" functions
|
||||
*/
|
||||
@ -758,6 +802,12 @@ static int _set(gnrc_netdev_t *netdev, netopt_t opt, void *value, size_t value_l
|
||||
return _set_panid(dev, (uint8_t *)value, value_len);
|
||||
case NETOPT_PROTO:
|
||||
return _set_proto(dev, (uint8_t *)value, value_len);
|
||||
#ifdef MODULE_XBEE_ENCRYPTION
|
||||
case NETOPT_ENCRYPTION:
|
||||
return _set_encryption(dev, (uint8_t *)value);
|
||||
case NETOPT_ENCRYPTION_KEY:
|
||||
return _set_encryption_key(dev, (uint8_t *)value, value_len);
|
||||
#endif
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@ -207,6 +207,12 @@ typedef enum {
|
||||
*/
|
||||
NETOPT_STATS,
|
||||
|
||||
/**
|
||||
* @brief en/disable encryption.
|
||||
*/
|
||||
NETOPT_ENCRYPTION, /**< en/disable encryption */
|
||||
NETOPT_ENCRYPTION_KEY, /**< set encryption key */
|
||||
|
||||
/* add more options if needed */
|
||||
|
||||
/**
|
||||
|
||||
@ -53,6 +53,8 @@ static const char *_netopt_strmap[] = {
|
||||
[NETOPT_CHANNEL_PAGE] = "NETOPT_CHANNEL_PAGE",
|
||||
[NETOPT_CCA_THRESHOLD] = "NETOPT_CCA_THRESHOLD",
|
||||
[NETOPT_STATS] = "NETOPT_STATS",
|
||||
[NETOPT_ENCRYPTION] = "NETOPT_ENCRYPTION",
|
||||
[NETOPT_ENCRYPTION_KEY] = "NETOPT_ENCRYPTION_KEY",
|
||||
[NETOPT_NUMOF] = "NETOPT_NUMOF",
|
||||
};
|
||||
|
||||
|
||||
@ -121,7 +121,9 @@ static void _set_usage(char *cmd_name)
|
||||
" * \"power\" - TX power in dBm\n"
|
||||
" * \"retrans\" - max. number of retransmissions\n"
|
||||
" * \"src_len\" - sets the source address length in byte\n"
|
||||
" * \"state\" - set the device state\n");
|
||||
" * \"state\" - set the device state\n"
|
||||
" * \"encrypt\" - set the encryption on-off\n"
|
||||
" * \"key\" - set the encryption key in hexadecimal format\n");
|
||||
}
|
||||
|
||||
static void _mtu_usage(char *cmd_name)
|
||||
@ -199,6 +201,14 @@ static void _print_netopt(netopt_t opt)
|
||||
printf("CCA threshold [in dBm]");
|
||||
break;
|
||||
|
||||
case NETOPT_ENCRYPTION:
|
||||
printf("encryption");
|
||||
break;
|
||||
|
||||
case NETOPT_ENCRYPTION_KEY:
|
||||
printf("encryption key");
|
||||
break;
|
||||
|
||||
default:
|
||||
/* we don't serve these options here */
|
||||
break;
|
||||
@ -614,6 +624,109 @@ static int _netif_set_state(kernel_pid_t dev, char *state_str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _netif_set_encrypt(kernel_pid_t dev, netopt_t opt, char *encrypt_str)
|
||||
{
|
||||
netopt_enable_t set;
|
||||
size_t size = 1;
|
||||
if ((strcmp("on", encrypt_str) == 0) || (strcmp("ON", encrypt_str) == 0)) {
|
||||
set = NETOPT_ENABLE;
|
||||
}
|
||||
else if ((strcmp("off", encrypt_str) == 0) || (strcmp("OFF", encrypt_str) == 0)) {
|
||||
set = NETOPT_DISABLE;
|
||||
}
|
||||
else {
|
||||
puts("usage: ifconfig <if_id> set encryption [on|off]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gnrc_netapi_set(dev, opt, 0, &set, size) < 0) {
|
||||
printf("error: unable to set ");
|
||||
_print_netopt(opt);
|
||||
puts("");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("success: set ");
|
||||
_print_netopt(opt);
|
||||
printf(" on interface %" PRIkernel_pid " to %s\n", dev, encrypt_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _hex_to_int(char c) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
return c - '0';
|
||||
}
|
||||
else if ('a' <= c && c <= 'f') {
|
||||
return c - 'a';
|
||||
}
|
||||
else if ('A' <= c && c <= 'F') {
|
||||
return c - 'A';
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int _netif_set_encrypt_key(kernel_pid_t dev, netopt_t opt, char *key_str)
|
||||
{
|
||||
size_t str_len = strlen(key_str);
|
||||
size_t key_len = str_len / 2;
|
||||
uint8_t key[key_len];
|
||||
|
||||
if (str_len == 14U) {
|
||||
printf("\nNotice: setting 56 bit key.");
|
||||
}
|
||||
else if (str_len == 16U) {
|
||||
printf("\nNotice: setting 64 bit key.");
|
||||
}
|
||||
else if (str_len == 32U) {
|
||||
printf("\nNotice: setting 128 bit key.");
|
||||
}
|
||||
else if (str_len == 48U) {
|
||||
printf("\nNotice: setting 192 bit key.");
|
||||
}
|
||||
else if (str_len == 64U) {
|
||||
printf("\nNotice: setting 256 bit key.");
|
||||
}
|
||||
else if (str_len == 128U) {
|
||||
printf("\nNotice: setting 512 bit key.");
|
||||
}
|
||||
else {
|
||||
printf("error: invalid key size.\n");
|
||||
return 1;
|
||||
}
|
||||
/* Convert any char from ASCII table in hex format */
|
||||
for (size_t i = 0; i < str_len; i += 2) {
|
||||
int i1 = _hex_to_int(key_str[i]);
|
||||
int i2 = _hex_to_int(key_str[i + 1]);
|
||||
|
||||
if (i1 == -1 || i2 == -1) {
|
||||
puts("error: unable to parse key");
|
||||
return 1;
|
||||
}
|
||||
|
||||
key[i / 2] = (uint8_t)((i1 << 4) + i2);
|
||||
}
|
||||
|
||||
if (gnrc_netapi_set(dev, opt, 0, key, key_len) < 0) {
|
||||
printf("error: unable to set ");
|
||||
_print_netopt(opt);
|
||||
puts("");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("success: set ");
|
||||
_print_netopt(opt);
|
||||
printf(" on interface %" PRIkernel_pid " to \n", dev);
|
||||
for (size_t i = 0; i < key_len; i++) {
|
||||
/* print the hex value of the key */
|
||||
printf("%02x", key[i]);
|
||||
}
|
||||
puts("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _netif_set(char *cmd_name, kernel_pid_t dev, char *key, char *value)
|
||||
{
|
||||
if ((strcmp("addr", key) == 0) || (strcmp("addr_short", key) == 0)) {
|
||||
@ -650,6 +763,12 @@ static int _netif_set(char *cmd_name, kernel_pid_t dev, char *key, char *value)
|
||||
else if (strcmp("cca_threshold", key) == 0) {
|
||||
return _netif_set_u8(dev, NETOPT_CCA_THRESHOLD, value);
|
||||
}
|
||||
else if (strcmp("encrypt", key) == 0) {
|
||||
return _netif_set_encrypt(dev, NETOPT_ENCRYPTION, value);
|
||||
}
|
||||
else if (strcmp("key", key) == 0) {
|
||||
return _netif_set_encrypt_key(dev, NETOPT_ENCRYPTION_KEY, value);
|
||||
}
|
||||
|
||||
_set_usage(cmd_name);
|
||||
return 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user