Merge pull request #618 from marceloaqno/dev-rpi-signing

RPi: Add support for signing messages
This commit is contained in:
Henrik Ekblad
2016-10-19 08:02:53 +02:00
committed by GitHub
7 changed files with 312 additions and 4 deletions
+3
View File
@@ -131,6 +131,9 @@
#if defined(MY_SIGNING_ATSHA204) && defined(MY_SIGNING_SOFT)
#error Only one signing engine can be activated
#endif
#if defined(MY_SIGNING_ATSHA204) && defined(__linux__)
#error No support for ATSHA204 on this platform
#endif
#if defined(MY_SIGNING_ATSHA204)
#include "core/MySigningAtsha204.cpp"
+262 -4
View File
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>
#include <getopt.h>
#include "log.h"
#include "MySensorsCore.h"
@@ -103,20 +104,247 @@ void print_usage()
{
printf("Usage: mysGateway [options]\n\n" \
"Options:\n" \
" -h Display a short summary of all program options.\n" \
" -d Enable debug.\n" \
" -b Become a daemon.\n");
" -h, --help Display a short summary of all program options.\n" \
" -d, --debug Enable debug.\n" \
" -b, --background Run as a background process.\n"
" --gen-soft-hmac-key Generate and print a soft hmac key.\n"
" --gen-soft-serial-key Generate and print a soft serial key.\n"
" --gen-aes-key Generate and print an aes encryption key.\n"
" --print-soft-hmac-key Print the soft hmac key from the config file.\n"
" --print-soft-serial-key Print the soft serial key from the config file.\n"
" --print-aes-key Print the aes encryption key from the config file.\n"
" --set-soft-hmac-key Write a soft hmac key to the config file.\n"
" --set-soft-serial-key Write a soft serial key to the config file.\n"
" --set-aes-key Write an aes encryption key to the config file.\n");
}
void print_soft_sign_hmac_key()
{
uint8_t key[32];
hwReadConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
printf("SOFT_HMAC_KEY | ");
for (int i = 0; i < 32; i++) {
printf("%02X", key[i]);
}
printf("\n");
printf("The next line is intended to be used in SecurityPersonalizer.ino:\n");
printf("#define MY_SOFT_HMAC_KEY ");
for (int i=0; i<32; i++) {
printf("%#02X", key[i]);
if (i < 31) printf(",");
}
printf("\n");
}
void generate_soft_sign_hmac_key()
{
uint8_t key[32];
for (int i = 0; i < 32; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
printf("SOFT_HMAC_KEY | ");
for (int i = 0; i < 32; i++) {
printf("%02X", key[i]);
}
printf("\n");
}
void set_soft_sign_hmac_key(char *key_str)
{
uint8_t key[32];
int n;
if (strlen(key_str) != 64) {
printf("invalid key!\n");
} else {
for (int i = 0; i < 64; ++i) {
char c = key_str[i];
if (c <= '9')
n = c - '0';
else if (c >= 'a')
n = c - 'a' + 10;
else
n = c - 'A' + 10;
if ((i & 0x1) == 0) {
key[i/2] = n * 16;
} else {
key[i/2] += n;
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
print_soft_sign_hmac_key();
}
}
void print_soft_sign_serial_key()
{
uint8_t key[9];
hwReadConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
printf("SOFT_SERIAL | ");
for (int i = 0; i < 9; i++) {
printf("%02X", key[i]);
}
printf("\n");
printf("The next line is intended to be used in SecurityPersonalizer.ino:\n");
printf("#define MY_SOFT_SERIAL ");
for (int i=0; i<9; i++) {
printf("%#02X", key[i]);
if (i < 8) printf(",");
}
printf("\n");
}
void generate_soft_sign_serial_key()
{
uint8_t key[9];
for (int i = 0; i < 9; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
printf("SOFT_SERIAL | ");
for (int i = 0; i < 9; i++) {
printf("%02X", key[i]);
}
printf("\n");
}
void set_soft_sign_serial_key(char *key_str)
{
uint8_t key[9];
int n;
if (strlen(key_str) != 18) {
printf("invalid key!\n");
} else {
for (int i = 0; i < 18; ++i) {
char c = key_str[i];
if (c <= '9')
n = c - '0';
else if (c >= 'a')
n = c - 'a' + 10;
else
n = c - 'A' + 10;
if ((i & 0x1) == 0) {
key[i/2] = n * 16;
} else {
key[i/2] += n;
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
print_soft_sign_serial_key();
}
}
void print_aes_key()
{
uint8_t key[16];
hwReadConfigBlock(&key, reinterpret_cast<void*>EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
printf("AES_KEY | ");
for (int i = 0; i < 16; i++) {
printf("%02X", key[i]);
}
printf("\n");
printf("The next line is intended to be used in SecurityPersonalizer.ino:\n");
printf("#define MY_AES_KEY ");
for (int i=0; i<16; i++) {
printf("%#02X", key[i]);
if (i < 15) printf(",");
}
printf("\n");
}
void generate_aes_key()
{
uint8_t key[16];
for (int i = 0; i < 16; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
printf("AES_KEY | ");
for (int i = 0; i < 16; i++) {
printf("%02X", key[i]);
}
printf("\n");
}
void set_aes_key(char *key_str)
{
uint8_t key[16];
int n;
if (strlen(key_str) != 32) {
printf("invalid key!\n");
} else {
for (int i = 0; i < 32; ++i) {
char c = key_str[i];
if (c <= '9')
n = c - '0';
else if (c >= 'a')
n = c - 'a' + 10;
else
n = c - 'A' + 10;
if ((i & 0x1) == 0) {
key[i/2] = n * 16;
} else {
key[i/2] += n;
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
print_aes_key();
}
}
int main(int argc, char *argv[])
{
int opt, log_opts, debug = 0, foreground = 1;
char *key = NULL;
/* register the signal handler */
signal(SIGINT, handle_sigint);
signal(SIGTERM, handle_sigint);
while ((opt = getopt(argc, argv, "hdb")) != -1) {
hwRandomNumberInit();
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"debug", no_argument, 0, 'd'},
{"background", no_argument, 0, 'b'},
{"gen-soft-hmac-key", no_argument, 0, 'A'},
{"gen-soft-serial-key", no_argument, 0, 'B'},
{"gen-aes-key", no_argument, 0, 'C'},
{"print-soft-hmac-key", no_argument, 0, 'D'},
{"print-soft-serial-key", no_argument, 0, 'E'},
{"print-aes-key", no_argument, 0, 'F'},
{"set-soft-hmac-key", required_argument, 0, 'G'},
{"set-soft-serial-key", required_argument, 0, 'H'},
{"set-aes-key", required_argument, 0, 'I'},
{0, 0, 0, 0}
};
int long_index = 0;
while ((opt = getopt_long(argc, argv,"hdbABCDEFGHI", long_options, &long_index )) != -1) {
switch (opt) {
case 'h':
print_usage();
@@ -127,6 +355,36 @@ int main(int argc, char *argv[])
case 'b':
foreground = 0;
break;
case 'A':
generate_soft_sign_hmac_key();
exit(0);
case 'B':
generate_soft_sign_serial_key();
exit(0);
case 'C':
generate_aes_key();
exit(0);
case 'D':
print_soft_sign_hmac_key();
exit(0);
case 'E':
print_soft_sign_serial_key();
exit(0);
case 'F':
print_aes_key();
exit(0);
case 'G':
key = strdup(optarg);
set_soft_sign_hmac_key(key);
exit(0);
case 'H':
key = strdup(optarg);
set_soft_sign_serial_key(key);
exit(0);
case 'I':
key = strdup(optarg);
set_aes_key(key);
exit(0);
default:
print_usage();
exit(0);
+5
View File
@@ -19,6 +19,11 @@
#include "MySensorsCore.h"
#if defined(__linux__)
#include <stdlib.h>
#include <unistd.h>
#endif
ControllerConfig _cc; // Configuration coming from controller
NodeConfig _nc; // Essential settings for node to work
MyMessage _msg; // Buffer for incoming messages
+18
View File
@@ -64,6 +64,23 @@ static char i2h(uint8_t i)
}
}
#ifdef __linux__
static void DEBUG_SIGNING_PRINTBUF(const char *str, uint8_t* buf, uint8_t sz) {
static char printBuffer[300];
for (int i=0; i<sz; i++)
{
printBuffer[i * 2] = i2h(buf[i] >> 4);
printBuffer[(i * 2) + 1] = i2h(buf[i]);
}
printBuffer[sz * 2] = '\0';
debug(str);
if (sz > 0)
{
debug(printBuffer);
}
}
#else
static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz) {
static char printBuffer[300];
#ifdef MY_GATEWAY_FEATURE
@@ -88,6 +105,7 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf,
}
MY_SERIALDEVICE.println("");
}
#endif /* __linux__ */
#else
#define DEBUG_SIGNING_PRINTBUF(str, buf, sz)
#endif
+1
View File
@@ -71,6 +71,7 @@ typedef string String;
void yield(void);
unsigned long millis(void);
unsigned long micros(void);
void _delay_ms(unsigned int millis);
void randomSeed(unsigned long seed);
long randMax(long howbig);
+13
View File
@@ -21,6 +21,19 @@ unsigned long millis(void)
return ((curTime.tv_sec - millis_at_start) * 1000) + (curTime.tv_usec / 1000);
}
unsigned long micros()
{
timeval curTime;
if (millis_at_start == 0) {
gettimeofday(&curTime, NULL);
millis_at_start = curTime.tv_sec;
}
gettimeofday(&curTime, NULL);
return ((curTime.tv_sec - millis_at_start) * 1000000) + (curTime.tv_usec);
}
void _delay_ms(unsigned int millis)
{
struct timespec sleeper;
+10
View File
@@ -57,6 +57,16 @@
// Inverse the blinking feature
//#define MY_WITH_LEDS_BLINKING_INVERSE
// Enable software signing
//#define MY_SIGNING_SOFT
// Enable signing related debug
//#define MY_DEBUG_VERBOSE_SIGNING
// Enable this to request signatures from nodes that in turn request signatures from gateway
//#define MY_SIGNING_REQUEST_SIGNATURES
// Enable this to have gateway require all nodes in the network to sign messages sent to it
// Note: MY_SIGNING_REQUEST_SIGNATURES must also be set
//#define MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL
#include <MySensors.h>
void setup() {