1
0
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:
Yonezawa-T2 2016-04-21 10:26:06 +09:00
commit 3e70191aee
5 changed files with 182 additions and 1 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 */
/**

View File

@ -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",
};

View File

@ -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;