MySensors Verschlüsselung und Signierung

Begonnen von meddie, 16 Februar 2017, 21:57:07

Vorheriges Thema - Nächstes Thema

meddie

Hallo zusammen,

ich habe eine Frage an all die die Mysensors nutzen. Nutzt Ihr die Verschlüsselung und Signierung und wenn ja wie muss man das einrichten, irgendwie stehe ich voll am Schlauch. Ich denke im Sketch mit einem define wird es nicht getan sein.

Vielen Dank im Voran
Gruß Eddie

SensorMane

Servus Eddie,

ich nutze für die Kommunikation das Signieren. Mir war es wichtig, dass sichergestellt ist, dass die Kommandos auch von mir kommen. Ob jemand die übermittelten Sensorwerte mit liest ist mir egal. Wobei das Verschlüsseln leicht einzurichten wäre wenn man das Signieren erfolgreich geschafft hat.
Wie weit bist du denn in dem Thema? Du kannst auch mal in meinem Wiki nachlesen, da habe ich versucht das ganze ins Deutsche zu übersetzen. Du findest das ganze unter www.hiller-regen.de . Alle Schritte sind eigentlich dort aufgeführt, falls du Fragen hast meld dich einfach.

Gruß -  Markus

meddie

Servus Markus,

vielen dank für Dein Link! Sehr interessant und hilfreich!

Ich bin noch gar nicht weit! :-( Ich hatte zuerst einen Ethernet Gateway zum Testen gebaut, der aber noch in der V1.0 war. Also noch kein Signieren, ich hatte auch ein Node gehabt der als Fensterkontakt fungiert hat. Dann stockte mein PRojekt etwas. Als ich dann weitermachen wollte kam aber auch schon die V1.5 raus, die ja auch signieren konnte, ich fand diese Möglichkeit sehr interessant, und habe mir vorgenommen, wenn schon dann Nodes zu bauen, die signiert kommunizieren. Aber so richtig Zeit hatte ich noch keine dafür, denn zuerst müsste ich ein neues GW basteln, da das alte GW nicht den W5100 verwendet hat und am Arduino Nano mit der neuen FW wahrscheinlich der Speicher gar nicht reichen würde.
Im Dezember habe ich den Sensebender Gateway entdeckt und habe mir diese auch geordert der ist Anfang Februar gekommen und dazu zum testen habe ich mir eine Sensebender Micro bestellt. Nun laufen meine Sketches soweit aber ohne Signieren und verschlüsseln.

Ich fände es schon wichtig dass die Kommunikation verschlüsselt, signiert und auch durch Whitelisten geregelt wird. Denn so hat man ein Maximum an Sicherheit. Heutzutage gibt man viel zu viel an Daten Preis. Und gerade was die Sensoren anbetrifft, wenn der "böse" Mann mitlesen kann welches Fenster geöffnet ist, dann erleichtert es doch den Einstieg oder wenn er lesen kann dass alle Räume auf 17 Grad Temperatur eingestellt sind, dass dann scheinbar niemand daheim ist. (aber das ist eine andere Diskussion)

Ich werde es die nächsten Tage probieren umzustellen, ich war mir mit dieser Data-LOCK Geschichte nicht sicher. Aber ich glaube dank Deiner Übersetzung dass ich schon alles richtig verstanden habe. Man muss den Data Bereich nicht locken, es ist genau so sicher. (angeblich).

Die Vorgehensweise wäre dann am GW diesen Sketch SecurityPersonalizer.ino mit dieser Konfiguration auszuführen:
,,LOCK_CONFIGURATION" aktivieren
,,LOCK_DATA" deaktivieren
,,SKIP_KEY_STORAGE" aktivieren
,,SKIP_UART_CONFIRMATION" deaktivieren
,,USER_KEY" deaktivieren

Dann im Serial Monitor den PSK sowie den AES Key notiren und gut aufbewahren.

Dann am Gateway und auf allen Nodes diesen Sketch mit dieser Konfig ausführen:

LOCK_CONFIGURATION" aktivieren
,,LOCK_DATA" deaktvieren
,,SKIP_KEY_STORAGE" deaktivieren
,,SKIP_UART_CONFIRMATION" aktivieren
,,USER_KEY" aktivieren
Den im ersten Schritt erzeugten PSK in ,,user_key_data" ablegen

Was ich noch nicht ganz verstanden habe, mit dem o.g. Sketch wird der ATSHA204 Chip konfiguriert und behält die Konfig. Auch wenn ich dann einen anderen Sketch lade? Ist das korrekt?

Im Sketch der Nodes muss ich die Anforderung der Signierung aktivieren und auf dem GW die Seriennumern der Nodes in die Whitelist aufnehmen.

Dann sind wir quasi Nachbarn, wenn ich richtig verstehe kommst Du aus Regen?
Vielen Dank für Deine Hilfe
Gruß Eddie

meddie

#3
Wenn ich richtig bin sollten die beiden Sketche dann wie folgt aussehen?


/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*/
/**
* @ingroup MySigninggrp
* @{
* @file SecurityPersonalizer.ino
* @brief Security personalization sketch
*
* REVISION HISTORY
*  - See git log (git log libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino)
*/

/**
* @example SecurityPersonalizer.ino
* This sketch will personalize either none-volatile memory or ATSHA204A for security functions
* available in the MySensors library.
*
* For ATSHA204A:
* It will write factory default settings to the configuration zone
* and then lock it.<br>
* It will then either<br>
* -# Generate a random value to use as a key which will be stored in
* slot 0. The key is printed on UART (115200) in clear text for the user to be
* able to use it as a user-supplied key in other personalization executions
* where the same key is needed.
* -# Use a user-supplied value to use as a key which will be stored in
* slot 0.
* Finally it will lock the data zone.
*
* By default, no locking is performed. User have to manually enable the flags that
* turn on the locking. Furthermore, user have to send a SPACE character on serial
* console when prompted to do any locking. On boards that does not provide UART
* input it is possible to configure the sketch to skip this confirmation.
* Default settings use ATSHA204A on @ref MY_SIGNING_ATSHA204_PIN.
*
* For Soft signing:
* It will<br>
* -# Generate a random value to use as a key which will be stored in EEPROM.
* The key is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied key in other personalization executions where the same
* key is needed.
* -# Use a user-supplied value to use as a key which will be stored in EEPROM.
* -# Generate a random value to use as a serial number which will be stored in EEPROM.
* The serial number is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied serial number in other personalization executions where the
* serial is needed (typically for a whitelist).
* -# Use a user-supplied value to use as a serial which will be stored in EEPROM.
*
* For Encryption support:
* -# Generate a random value to use as a AES key which will be stored in EEPROM.
* The AES key is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied AES key in other personalization executions where the
* AES key is needed (typically for RF encryption).
* -# Use a user-supplied value to use as a AES key which will be stored in EEPROM.
*
* Personalizing EEPROM or ATSHA204A still require the appropriate configuration of the
* library to actually have an effect. There is no problem personalizing EEPROM and
* ATSHA204A at the same time. There is however a security risk with using the same
* data for EEPROM and ATSHA204A so it is recommended to use different serial and HMAC
* keys on the same device for ATSHA204A vs soft signing settings.
*
* Details on personalization procedure is given in @ref personalization.
*/

#include "sha204_library.h"
#include "sha204_lib_return_codes.h"
#define MY_CORE_ONLY
#include <MySensors.h>

// Doxygen specific constructs, not included when built normally
// This is used to enable disabled macros/definitions to be included in the documentation as well.
#if DOXYGEN
#define LOCK_CONFIGURATION
#define LOCK_DATA
#define SKIP_KEY_STORAGE
#define USER_KEY
#define SKIP_UART_CONFIRMATION
#define USE_SOFT_SIGNING
#define STORE_SOFT_KEY
#define USER_SOFT_KEY
#define STORE_SOFT_SERIAL
#define USER_SOFT_SERIAL
#define STORE_AES_KEY
#define USER_AES_KEY
#endif

/**
* @def LOCK_CONFIGURATION
* @brief Uncomment this to enable locking the configuration zone.
*
* It is still possible to change the key, and this also enable random key generation.
* @warning BE AWARE THAT THIS PREVENTS ANY FUTURE CONFIGURATION CHANGE TO THE CHIP
*/
#define LOCK_CONFIGURATION

/**
* @def LOCK_DATA
* @brief Uncomment this to enable locking the data zone.
*
* It is not required to lock data, key cannot be retrieved anyway, but by locking
* data, it can be guaranteed that nobody even with physical access to the chip,
* will be able to change the key.
* @warning BE AWARE THAT THIS PREVENTS THE KEY TO BE CHANGED
*/
//#define LOCK_DATA

/**
* @def SKIP_KEY_STORAGE
* @brief Uncomment this to skip key storage (typically once key has been written once)
*/
#define SKIP_KEY_STORAGE

/**
* @def USER_KEY
* @brief Uncomment this to skip key generation and use @ref user_key_data as key instead.
*/
//#define USER_KEY

/**
* @def SKIP_UART_CONFIRMATION
* @brief Uncomment this for boards that lack UART
*
* @b Important<br> No confirmation will be required for locking any zones with this configuration!
* Also, key generation is not permitted in this mode as there is no way of presenting the generated key.
*/
//#define SKIP_UART_CONFIRMATION

/**
* @def USE_SOFT_SIGNING
* @brief Uncomment this to store data to EEPROM instead of ATSHA204A
*/
//#define USE_SOFT_SIGNING

/**
* @def STORE_SOFT_KEY
* @brief Uncomment this to store soft HMAC key to EEPROM
*/
//#define STORE_SOFT_KEY

/**
* @def USER_SOFT_KEY
* @brief Uncomment this to skip soft HMAC key generation and use @ref user_soft_key_data as HMAC key instead.
*/
//#define USER_SOFT_KEY

/**
* @def STORE_SOFT_SERIAL
* @brief Uncomment this to store soft serial to EEPROM
*/
//#define STORE_SOFT_SERIAL

/**
* @def USER_SOFT_SERIAL
* @brief Uncomment this to skip soft serial generation and use @ref user_soft_serial as serial instead.
*/
//#define USER_SOFT_SERIAL

/**
* @def STORE_AES_KEY
* @brief Uncomment this to store AES key to EEPROM
*/
//#define STORE_AES_KEY

/**
* @def USER_AES_KEY
* @brief Uncomment this to skip AES key generation and use @ref user_aes_key as key instead.
*/
//#define USER_AES_KEY

#if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
#error You have to define USER_KEY for boards that does not have UART
#endif

#ifdef USER_KEY
/** @brief The user-defined HMAC key to use for personalization */
#define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store in key slot 0 */
const uint8_t user_key_data[32] = {MY_HMAC_KEY};
#endif

#ifdef USER_SOFT_KEY
/** @brief The user-defined soft HMAC key to use for EEPROM personalization */
#define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as soft HMAC key in EEPROM */
const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
#endif

#ifdef USER_SOFT_SERIAL
/** @brief The user-defined soft serial to use for EEPROM personalization */
#define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as soft serial in EEPROM */
const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
#endif

#ifdef USER_AES_KEY
/** @brief The user-defined AES key to use for EEPROM personalization */
#define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as AES key in EEPROM */
const uint8_t user_aes_key[16] = {MY_AES_KEY};
#endif

#ifndef USE_SOFT_SIGNING
const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
atsha204Class sha204(sha204Pin);
#endif

/** @brief Print a error notice and halt the execution */
void halt()
{
Serial.println(F("Halting!"));
while(1);
}

#ifndef USE_SOFT_SIGNING
/**
* @brief Write default configuration and return CRC of the configuration bits
* @returns CRC over the configuration bits
*/
uint16_t write_config_and_get_crc()
{
uint16_t crc = 0;
uint8_t config_word[4];
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
bool do_write;

// We will set default settings from datasheet on all slots. This means that we can use slot 0 for the key
// as that slot will not be readable (key will therefore be secure) and slot 8 for the payload digest
// calculationon as that slot can be written in clear text even when the datazone is locked.
// Other settings which are not relevant are kept as is.

for (int i=0; i < 88; i += 4) {
do_write = true;
if (i == 20) {
config_word[0] = 0x8F;
config_word[1] = 0x80;
config_word[2] = 0x80;
config_word[3] = 0xA1;
} else if (i == 24) {
config_word[0] = 0x82;
config_word[1] = 0xE0;
config_word[2] = 0xA3;
config_word[3] = 0x60;
} else if (i == 28) {
config_word[0] = 0x94;
config_word[1] = 0x40;
config_word[2] = 0xA0;
config_word[3] = 0x85;
} else if (i == 32) {
config_word[0] = 0x86;
config_word[1] = 0x40;
config_word[2] = 0x87;
config_word[3] = 0x07;
} else if (i == 36) {
config_word[0] = 0x0F;
config_word[1] = 0x00;
config_word[2] = 0x89;
config_word[3] = 0xF2;
} else if (i == 40) {
config_word[0] = 0x8A;
config_word[1] = 0x7A;
config_word[2] = 0x0B;
config_word[3] = 0x8B;
} else if (i == 44) {
config_word[0] = 0x0C;
config_word[1] = 0x4C;
config_word[2] = 0xDD;
config_word[3] = 0x4D;
} else if (i == 48) {
config_word[0] = 0xC2;
config_word[1] = 0x42;
config_word[2] = 0xAF;
config_word[3] = 0x8F;
} else if (i == 52 || i == 56 || i == 60 || i == 64) {
config_word[0] = 0xFF;
config_word[1] = 0x00;
config_word[2] = 0xFF;
config_word[3] = 0x00;
} else if (i == 68 || i == 72 || i == 76 || i == 80) {
config_word[0] = 0xFF;
config_word[1] = 0xFF;
config_word[2] = 0xFF;
config_word[3] = 0xFF;
} else {
// All other configs are untouched
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to read config. Response: "));
Serial.println(ret_code, HEX);
halt();
}
// Set config_word to the read data
config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
do_write = false;
}

// Update crc with CRC for the current word
crc = sha204.calculateAndUpdateCrc(4, config_word, crc);

// Write config word
if (do_write) {
ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to write config word at address "));
Serial.print(i);
Serial.print(F(". Response: "));
Serial.println(ret_code, HEX);
halt();
}
}
}
return crc;
}

/**
* @brief Write provided key to slot 0
* @param key The key data to write
*/
void write_key(uint8_t* key)
{
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;

// Write key to slot 0
ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to write key to slot 0. Response: "));
Serial.println(ret_code, HEX);
halt();
}
}
#endif // not USE_SOFT_SIGNING

/** @brief Dump current configuration to UART */
void dump_configuration()
{
uint8_t buffer[32];
#ifndef USE_SOFT_SIGNING
Serial.println(F("EEPROM DATA:"));
#endif
hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
Serial.print(F("SOFT_HMAC_KEY | "));
for (int j=0; j<32; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
Serial.print(F("SOFT_SERIAL   | "));
for (int j=0; j<9; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
Serial.print(F("AES_KEY       | "));
for (int j=0; j<16; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
#ifndef USE_SOFT_SIGNING
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
Serial.println(F("ATSHA204A DATA:"));
for (int i=0; i < 88; i += 4) {
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to read config. Response: "));
Serial.println(ret_code, HEX);
halt();
}
if (i == 0x00) {
Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x04) {
Serial.print(F("                          Revnum                         | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x08) {
Serial.print(F("                          SN[4:7]                        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x0C) {
Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x10) {
Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x14) {
Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x18) {
Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x1C) {
Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x20) {
Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x24) {
Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x28) {
Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x2C) {
Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x30) {
Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x34) {
Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x38) {
Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x3C) {
Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x40) {
Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x44) {
Serial.print(F("                      LastKeyUse[0:3]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x48) {
Serial.print(F("                      LastKeyUse[4:7]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x4C) {
Serial.print(F("                      LastKeyUse[8:B]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x50) {
Serial.print(F("                      LastKeyUse[C:F]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x54) {
Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
}
}
#endif // not USE_SOFT_SIGNING
}

/** @brief Sketch setup code */
void setup()
{
// Delay startup a bit for serial consoles to catch up
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)500);
#ifndef USE_SOFT_SIGNING
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
uint8_t lockConfig = 0;
uint8_t lockValue = 0;
uint16_t crc;
(void)crc;
#else
// initialize pseudo-RNG
randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
#endif
uint8_t key[32];
(void)key;

Serial.begin(115200);
hwInit();
Serial.println(F("Personalization sketch for MySensors usage."));
Serial.println(F("-------------------------------------------"));

#ifndef USE_SOFT_SIGNING
// Wake device before starting operations
ret_code = sha204.sha204c_wakeup(rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to wake device. Response: "));
Serial.println(ret_code, HEX);
halt();
}
// Read out lock config bits to determine if locking is possible
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
#endif

#ifdef STORE_SOFT_KEY
#ifdef USER_SOFT_KEY
memcpy(key, user_soft_key_data, 32);
Serial.println(F("Using this user supplied soft HMAC key:"));
#else
// Retrieve random value to use as soft HMAC key
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 32; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_SOFT_KEY
Serial.print("#define MY_SOFT_HMAC_KEY ");
for (int i=0; i<32; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 31) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
#endif // STORE_SOFT_KEY

#ifdef STORE_SOFT_SERIAL
#ifdef USER_SOFT_SERIAL
memcpy(key, user_soft_serial, 9);
Serial.println(F("Using this user supplied soft serial:"));
#else
// Retrieve random value to use as serial
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 9; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This value will be stored in EEPROM as soft serial:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random serial generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
}
if (lockConfig == 0x00) {
Serial.println(F("This value will be stored in EEPROM as soft serial:"));
} else {
Serial.println(F("Serial is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_SOFT_SERIAL
Serial.print("#define MY_SOFT_SERIAL ");
for (int i=0; i<9; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 8) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
#endif // STORE_SOFT_SERIAL

#ifdef STORE_AES_KEY
#ifdef USER_AES_KEY
memcpy(key, user_aes_key, 16);
Serial.println(F("Using this user supplied AES key:"));
#else
// Retrieve random value to use as key
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 16; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This key will be stored in EEPROM as AES key:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("This key will be stored in EEPROM as AES key:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_AES_KEY
Serial.print("#define MY_AES_KEY ");
for (int i=0; i<16; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 15) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
#endif // STORE_AES_KEY

#ifdef USE_SOFT_SIGNING
Serial.println(F("EEPROM configuration:"));
dump_configuration();
#else
// Output device revision on console
ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device revision. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.print(F("Device revision: "));
for (int i=0; i<4; i++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
}
Serial.println();
}

// Output serial number on console
ret_code = sha204.getSerialNumber(rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to obtain device serial number. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.print(F("Device serial:   "));
Serial.print('{');
for (int i=0; i<9; i++) {
Serial.print(F("0x"));
if (rx_buffer[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[i], HEX);
if (i < 8) {
Serial.print(',');
}
}
Serial.print('}');
Serial.println();
for (int i=0; i<9; i++) {
if (rx_buffer[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[i], HEX);
}
Serial.println();
}

if (lockConfig != 0x00) {
// Write config and get CRC for the updated config
crc = write_config_and_get_crc();

// List current configuration before attempting to lock
Serial.println(F("Chip configuration:"));
dump_configuration();

#ifdef LOCK_CONFIGURATION
// Purge serial input buffer
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) {
Serial.read();
}
Serial.println(F("Send SPACE character now to lock the configuration..."));

while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
Serial.println(F("Locking configuration..."));

// Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
Serial.print(F("Resync failed. Response: "));
Serial.println(ret_code, HEX);
halt();
}

// Lock configuration zone
ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                                  crc, 0, NULL, 0, NULL, 0, NULL,
                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Configuration lock failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.println(F("Configuration locked."));

// Update lock flags after locking
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else {
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_CONFIGURATION
Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
#endif
} else {
Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
Serial.println(F("Chip configuration:"));
dump_configuration();
}

#ifdef SKIP_KEY_STORAGE
Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
#else
#ifdef USER_KEY
memcpy(key, user_key_data, 32);
Serial.println(F("Using this user supplied HMAC key:"));
#else
// Retrieve random value to use as key
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("Take note of this key, it will never be the shown again:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif
Serial.print("#define MY_HMAC_KEY ");
for (int i=0; i<32; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 31) {
Serial.print(',');
}
if (i+1 == 16) {
Serial.print("\\\n                    ");
}
}
Serial.println();

// It will not be possible to write the key if the configuration zone is unlocked
if (lockConfig == 0x00) {
// Write the key to the appropriate slot in the data zone
Serial.println(F("Writing key to slot 0..."));
write_key(key);
} else {
Serial.println(F("Skipping key storage (configuration not locked)."));
Serial.println(F("The configuration must be locked to be able to write a key."));
}
#endif

if (lockValue != 0x00) {
#ifdef LOCK_DATA
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) {
Serial.read();
}
Serial.println(F("Send SPACE character to lock data..."));
while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
// Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
Serial.print(F("Resync failed. Response: "));
Serial.println(ret_code, HEX);
halt();
}

// If configuration is unlocked, key is not updated. Locking data in this case will cause
// slot 0 to contain an unknown (or factory default) key, and this is in practically any
// usecase not the desired behaviour, so ask for additional confirmation in this case.
if (lockConfig != 0x00) {
while (Serial.available()) {
Serial.read();
}
Serial.println(F("*** ATTENTION ***"));
Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
Serial.println(
    F("which cannot be change after locking is done. This is in practically any usecase"));
Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
while (Serial.available() == 0);
if (Serial.read() != ' ') {
Serial.println(F("Unexpected answer. Skipping lock."));
halt();
}
}

// Lock data zone
ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Data lock failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.println(F("Data locked."));

// Update lock flags after locking
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else {
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_DATA
Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
#endif
} else {
Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
}
#endif // not USE_SOFT_SIGNING

Serial.println(F("--------------------------------"));
Serial.println(F("Personalization is now complete."));
#ifndef USE_SOFT_SIGNING
Serial.print(F("Configuration is "));
if (lockConfig == 0x00) {
Serial.println("LOCKED");
} else {
Serial.println("UNLOCKED");
}
Serial.print(F("Data is "));
if (lockValue == 0x00) {
Serial.println("LOCKED");
} else {
Serial.println("UNLOCKED");
}
#endif
}

/** @brief Sketch execution code */
void loop()
{
}


und anschließend wenn die beiden Keys notiert sind

meddie

wird der zweite Sketch hochgeladen in dem die beiden Keys eingesetzt sind:
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*/
/**
* @ingroup MySigninggrp
* @{
* @file SecurityPersonalizer.ino
* @brief Security personalization sketch
*
* REVISION HISTORY
*  - See git log (git log libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino)
*/

/**
* @example SecurityPersonalizer.ino
* This sketch will personalize either none-volatile memory or ATSHA204A for security functions
* available in the MySensors library.
*
* For ATSHA204A:
* It will write factory default settings to the configuration zone
* and then lock it.<br>
* It will then either<br>
* -# Generate a random value to use as a key which will be stored in
* slot 0. The key is printed on UART (115200) in clear text for the user to be
* able to use it as a user-supplied key in other personalization executions
* where the same key is needed.
* -# Use a user-supplied value to use as a key which will be stored in
* slot 0.
* Finally it will lock the data zone.
*
* By default, no locking is performed. User have to manually enable the flags that
* turn on the locking. Furthermore, user have to send a SPACE character on serial
* console when prompted to do any locking. On boards that does not provide UART
* input it is possible to configure the sketch to skip this confirmation.
* Default settings use ATSHA204A on @ref MY_SIGNING_ATSHA204_PIN.
*
* For Soft signing:
* It will<br>
* -# Generate a random value to use as a key which will be stored in EEPROM.
* The key is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied key in other personalization executions where the same
* key is needed.
* -# Use a user-supplied value to use as a key which will be stored in EEPROM.
* -# Generate a random value to use as a serial number which will be stored in EEPROM.
* The serial number is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied serial number in other personalization executions where the
* serial is needed (typically for a whitelist).
* -# Use a user-supplied value to use as a serial which will be stored in EEPROM.
*
* For Encryption support:
* -# Generate a random value to use as a AES key which will be stored in EEPROM.
* The AES key is printed on UART (115200) in clear text for the user to be ablle to
* use it as a user-supplied AES key in other personalization executions where the
* AES key is needed (typically for RF encryption).
* -# Use a user-supplied value to use as a AES key which will be stored in EEPROM.
*
* Personalizing EEPROM or ATSHA204A still require the appropriate configuration of the
* library to actually have an effect. There is no problem personalizing EEPROM and
* ATSHA204A at the same time. There is however a security risk with using the same
* data for EEPROM and ATSHA204A so it is recommended to use different serial and HMAC
* keys on the same device for ATSHA204A vs soft signing settings.
*
* Details on personalization procedure is given in @ref personalization.
*/

#include "sha204_library.h"
#include "sha204_lib_return_codes.h"
#define MY_CORE_ONLY
#include <MySensors.h>

// Doxygen specific constructs, not included when built normally
// This is used to enable disabled macros/definitions to be included in the documentation as well.
#if DOXYGEN
#define LOCK_CONFIGURATION
#define LOCK_DATA
#define SKIP_KEY_STORAGE
#define USER_KEY
#define SKIP_UART_CONFIRMATION
#define USE_SOFT_SIGNING
#define STORE_SOFT_KEY
#define USER_SOFT_KEY
#define STORE_SOFT_SERIAL
#define USER_SOFT_SERIAL
#define STORE_AES_KEY
#define USER_AES_KEY
#endif

/**
* @def LOCK_CONFIGURATION
* @brief Uncomment this to enable locking the configuration zone.
*
* It is still possible to change the key, and this also enable random key generation.
* @warning BE AWARE THAT THIS PREVENTS ANY FUTURE CONFIGURATION CHANGE TO THE CHIP
*/
#define LOCK_CONFIGURATION

/**
* @def LOCK_DATA
* @brief Uncomment this to enable locking the data zone.
*
* It is not required to lock data, key cannot be retrieved anyway, but by locking
* data, it can be guaranteed that nobody even with physical access to the chip,
* will be able to change the key.
* @warning BE AWARE THAT THIS PREVENTS THE KEY TO BE CHANGED
*/
//#define LOCK_DATA

/**
* @def SKIP_KEY_STORAGE
* @brief Uncomment this to skip key storage (typically once key has been written once)
*/
//#define SKIP_KEY_STORAGE

/**
* @def USER_KEY
* @brief Uncomment this to skip key generation and use @ref user_key_data as key instead.
*/
#define USER_KEY

/**
* @def SKIP_UART_CONFIRMATION
* @brief Uncomment this for boards that lack UART
*
* @b Important<br> No confirmation will be required for locking any zones with this configuration!
* Also, key generation is not permitted in this mode as there is no way of presenting the generated key.
*/
#define SKIP_UART_CONFIRMATION

/**
* @def USE_SOFT_SIGNING
* @brief Uncomment this to store data to EEPROM instead of ATSHA204A
*/
//#define USE_SOFT_SIGNING

/**
* @def STORE_SOFT_KEY
* @brief Uncomment this to store soft HMAC key to EEPROM
*/
//#define STORE_SOFT_KEY

/**
* @def USER_SOFT_KEY
* @brief Uncomment this to skip soft HMAC key generation and use @ref user_soft_key_data as HMAC key instead.
*/
//#define USER_SOFT_KEY

/**
* @def STORE_SOFT_SERIAL
* @brief Uncomment this to store soft serial to EEPROM
*/
//#define STORE_SOFT_SERIAL

/**
* @def USER_SOFT_SERIAL
* @brief Uncomment this to skip soft serial generation and use @ref user_soft_serial as serial instead.
*/
//#define USER_SOFT_SERIAL

/**
* @def STORE_AES_KEY
* @brief Uncomment this to store AES key to EEPROM
*/
#define STORE_AES_KEY

/**
* @def USER_AES_KEY
* @brief Uncomment this to skip AES key generation and use @ref user_aes_key as key instead.
*/
#define USER_AES_KEY

#if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
#error You have to define USER_KEY for boards that does not have UART
#endif

#ifdef USER_KEY
/** @brief The user-defined HMAC key to use for personalization */
#define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store in key slot 0 */
const uint8_t user_key_data[32] = {MY_HMAC_KEY};
#endif

#ifdef USER_SOFT_KEY
/** @brief The user-defined soft HMAC key to use for EEPROM personalization */
#define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as soft HMAC key in EEPROM */
const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
#endif

#ifdef USER_SOFT_SERIAL
/** @brief The user-defined soft serial to use for EEPROM personalization */
#define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as soft serial in EEPROM */
const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
#endif

#ifdef USER_AES_KEY
/** @brief The user-defined AES key to use for EEPROM personalization */
#define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/** @brief The data to store as AES key in EEPROM */
const uint8_t user_aes_key[16] = {MY_AES_KEY};
#endif

#ifndef USE_SOFT_SIGNING
const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
atsha204Class sha204(sha204Pin);
#endif

/** @brief Print a error notice and halt the execution */
void halt()
{
Serial.println(F("Halting!"));
while(1);
}

#ifndef USE_SOFT_SIGNING
/**
* @brief Write default configuration and return CRC of the configuration bits
* @returns CRC over the configuration bits
*/
uint16_t write_config_and_get_crc()
{
uint16_t crc = 0;
uint8_t config_word[4];
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
bool do_write;

// We will set default settings from datasheet on all slots. This means that we can use slot 0 for the key
// as that slot will not be readable (key will therefore be secure) and slot 8 for the payload digest
// calculationon as that slot can be written in clear text even when the datazone is locked.
// Other settings which are not relevant are kept as is.

for (int i=0; i < 88; i += 4) {
do_write = true;
if (i == 20) {
config_word[0] = 0x8F;
config_word[1] = 0x80;
config_word[2] = 0x80;
config_word[3] = 0xA1;
} else if (i == 24) {
config_word[0] = 0x82;
config_word[1] = 0xE0;
config_word[2] = 0xA3;
config_word[3] = 0x60;
} else if (i == 28) {
config_word[0] = 0x94;
config_word[1] = 0x40;
config_word[2] = 0xA0;
config_word[3] = 0x85;
} else if (i == 32) {
config_word[0] = 0x86;
config_word[1] = 0x40;
config_word[2] = 0x87;
config_word[3] = 0x07;
} else if (i == 36) {
config_word[0] = 0x0F;
config_word[1] = 0x00;
config_word[2] = 0x89;
config_word[3] = 0xF2;
} else if (i == 40) {
config_word[0] = 0x8A;
config_word[1] = 0x7A;
config_word[2] = 0x0B;
config_word[3] = 0x8B;
} else if (i == 44) {
config_word[0] = 0x0C;
config_word[1] = 0x4C;
config_word[2] = 0xDD;
config_word[3] = 0x4D;
} else if (i == 48) {
config_word[0] = 0xC2;
config_word[1] = 0x42;
config_word[2] = 0xAF;
config_word[3] = 0x8F;
} else if (i == 52 || i == 56 || i == 60 || i == 64) {
config_word[0] = 0xFF;
config_word[1] = 0x00;
config_word[2] = 0xFF;
config_word[3] = 0x00;
} else if (i == 68 || i == 72 || i == 76 || i == 80) {
config_word[0] = 0xFF;
config_word[1] = 0xFF;
config_word[2] = 0xFF;
config_word[3] = 0xFF;
} else {
// All other configs are untouched
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to read config. Response: "));
Serial.println(ret_code, HEX);
halt();
}
// Set config_word to the read data
config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
do_write = false;
}

// Update crc with CRC for the current word
crc = sha204.calculateAndUpdateCrc(4, config_word, crc);

// Write config word
if (do_write) {
ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to write config word at address "));
Serial.print(i);
Serial.print(F(". Response: "));
Serial.println(ret_code, HEX);
halt();
}
}
}
return crc;
}

/**
* @brief Write provided key to slot 0
* @param key The key data to write
*/
void write_key(uint8_t* key)
{
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;

// Write key to slot 0
ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to write key to slot 0. Response: "));
Serial.println(ret_code, HEX);
halt();
}
}
#endif // not USE_SOFT_SIGNING

/** @brief Dump current configuration to UART */
void dump_configuration()
{
uint8_t buffer[32];
#ifndef USE_SOFT_SIGNING
Serial.println(F("EEPROM DATA:"));
#endif
hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
Serial.print(F("SOFT_HMAC_KEY | "));
for (int j=0; j<32; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
Serial.print(F("SOFT_SERIAL   | "));
for (int j=0; j<9; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
Serial.print(F("AES_KEY       | "));
for (int j=0; j<16; j++) {
if (buffer[j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(buffer[j], HEX);
}
Serial.println();
#ifndef USE_SOFT_SIGNING
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
Serial.println(F("ATSHA204A DATA:"));
for (int i=0; i < 88; i += 4) {
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to read config. Response: "));
Serial.println(ret_code, HEX);
halt();
}
if (i == 0x00) {
Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x04) {
Serial.print(F("                          Revnum                         | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x08) {
Serial.print(F("                          SN[4:7]                        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x0C) {
Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x10) {
Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x14) {
Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x18) {
Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x1C) {
Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x20) {
Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x24) {
Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x28) {
Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x2C) {
Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x30) {
Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j == 1) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x34) {
Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x38) {
Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x3C) {
Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x40) {
Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
} else if (i == 0x44) {
Serial.print(F("                      LastKeyUse[0:3]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x48) {
Serial.print(F("                      LastKeyUse[4:7]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x4C) {
Serial.print(F("                      LastKeyUse[8:B]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x50) {
Serial.print(F("                      LastKeyUse[C:F]                    | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
Serial.print(F("   "));
}
Serial.println();
} else if (i == 0x54) {
Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
for (int j=0; j<4; j++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
if (j < 3) {
Serial.print(F(" | "));
} else {
Serial.print(F("   "));
}
}
Serial.println();
}
}
#endif // not USE_SOFT_SIGNING
}

/** @brief Sketch setup code */
void setup()
{
// Delay startup a bit for serial consoles to catch up
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)500);
#ifndef USE_SOFT_SIGNING
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t ret_code;
uint8_t lockConfig = 0;
uint8_t lockValue = 0;
uint16_t crc;
(void)crc;
#else
// initialize pseudo-RNG
randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
#endif
uint8_t key[32];
(void)key;

Serial.begin(115200);
hwInit();
Serial.println(F("Personalization sketch for MySensors usage."));
Serial.println(F("-------------------------------------------"));

#ifndef USE_SOFT_SIGNING
// Wake device before starting operations
ret_code = sha204.sha204c_wakeup(rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to wake device. Response: "));
Serial.println(ret_code, HEX);
halt();
}
// Read out lock config bits to determine if locking is possible
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
#endif

#ifdef STORE_SOFT_KEY
#ifdef USER_SOFT_KEY
memcpy(key, user_soft_key_data, 32);
Serial.println(F("Using this user supplied soft HMAC key:"));
#else
// Retrieve random value to use as soft HMAC key
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 32; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_SOFT_KEY
Serial.print("#define MY_SOFT_HMAC_KEY ");
for (int i=0; i<32; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 31) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
#endif // STORE_SOFT_KEY

#ifdef STORE_SOFT_SERIAL
#ifdef USER_SOFT_SERIAL
memcpy(key, user_soft_serial, 9);
Serial.println(F("Using this user supplied soft serial:"));
#else
// Retrieve random value to use as serial
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 9; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This value will be stored in EEPROM as soft serial:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random serial generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
}
if (lockConfig == 0x00) {
Serial.println(F("This value will be stored in EEPROM as soft serial:"));
} else {
Serial.println(F("Serial is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_SOFT_SERIAL
Serial.print("#define MY_SOFT_SERIAL ");
for (int i=0; i<9; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 8) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
#endif // STORE_SOFT_SERIAL

#ifdef STORE_AES_KEY
#ifdef USER_AES_KEY
memcpy(key, user_aes_key, 16);
Serial.println(F("Using this user supplied AES key:"));
#else
// Retrieve random value to use as key
#ifdef USE_SOFT_SIGNING
for (int i = 0; i < 16; i++) {
key[i] = random(256) ^ micros();
unsigned long enter = hwMillis();
while (hwMillis() - enter < (unsigned long)2);
}
Serial.println(F("This key will be stored in EEPROM as AES key:"));
#else
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("This key will be stored in EEPROM as AES key:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif // not USE_SOFT_SIGNING
#endif // not USER_AES_KEY
Serial.print("#define MY_AES_KEY ");
for (int i=0; i<16; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 15) {
Serial.print(',');
}
}
Serial.println();
hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
#endif // STORE_AES_KEY

#ifdef USE_SOFT_SIGNING
Serial.println(F("EEPROM configuration:"));
dump_configuration();
#else
// Output device revision on console
ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device revision. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.print(F("Device revision: "));
for (int i=0; i<4; i++) {
if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
}
Serial.println();
}

// Output serial number on console
ret_code = sha204.getSerialNumber(rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to obtain device serial number. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.print(F("Device serial:   "));
Serial.print('{');
for (int i=0; i<9; i++) {
Serial.print(F("0x"));
if (rx_buffer[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[i], HEX);
if (i < 8) {
Serial.print(',');
}
}
Serial.print('}');
Serial.println();
for (int i=0; i<9; i++) {
if (rx_buffer[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(rx_buffer[i], HEX);
}
Serial.println();
}

if (lockConfig != 0x00) {
// Write config and get CRC for the updated config
crc = write_config_and_get_crc();

// List current configuration before attempting to lock
Serial.println(F("Chip configuration:"));
dump_configuration();

#ifdef LOCK_CONFIGURATION
// Purge serial input buffer
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) {
Serial.read();
}
Serial.println(F("Send SPACE character now to lock the configuration..."));

while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
Serial.println(F("Locking configuration..."));

// Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
Serial.print(F("Resync failed. Response: "));
Serial.println(ret_code, HEX);
halt();
}

// Lock configuration zone
ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                                  crc, 0, NULL, 0, NULL, 0, NULL,
                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Configuration lock failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.println(F("Configuration locked."));

// Update lock flags after locking
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else {
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_CONFIGURATION
Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
#endif
} else {
Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
Serial.println(F("Chip configuration:"));
dump_configuration();
}

#ifdef SKIP_KEY_STORAGE
Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
#else
#ifdef USER_KEY
memcpy(key, user_key_data, 32);
Serial.println(F("Using this user supplied HMAC key:"));
#else
// Retrieve random value to use as key
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Random key generation failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
}
if (lockConfig == 0x00) {
Serial.println(F("Take note of this key, it will never be the shown again:"));
} else {
Serial.println(F("Key is not randomized (configuration not locked):"));
}
#endif
Serial.print("#define MY_HMAC_KEY ");
for (int i=0; i<32; i++) {
Serial.print("0x");
if (key[i] < 0x10) {
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 31) {
Serial.print(',');
}
if (i+1 == 16) {
Serial.print("\\\n                    ");
}
}
Serial.println();

// It will not be possible to write the key if the configuration zone is unlocked
if (lockConfig == 0x00) {
// Write the key to the appropriate slot in the data zone
Serial.println(F("Writing key to slot 0..."));
write_key(key);
} else {
Serial.println(F("Skipping key storage (configuration not locked)."));
Serial.println(F("The configuration must be locked to be able to write a key."));
}
#endif

if (lockValue != 0x00) {
#ifdef LOCK_DATA
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) {
Serial.read();
}
Serial.println(F("Send SPACE character to lock data..."));
while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
// Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
Serial.print(F("Resync failed. Response: "));
Serial.println(ret_code, HEX);
halt();
}

// If configuration is unlocked, key is not updated. Locking data in this case will cause
// slot 0 to contain an unknown (or factory default) key, and this is in practically any
// usecase not the desired behaviour, so ask for additional confirmation in this case.
if (lockConfig != 0x00) {
while (Serial.available()) {
Serial.read();
}
Serial.println(F("*** ATTENTION ***"));
Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
Serial.println(
    F("which cannot be change after locking is done. This is in practically any usecase"));
Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
while (Serial.available() == 0);
if (Serial.read() != ' ') {
Serial.println(F("Unexpected answer. Skipping lock."));
halt();
}
}

// Lock data zone
ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Data lock failed. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
Serial.println(F("Data locked."));

// Update lock flags after locking
ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
if (ret_code != SHA204_SUCCESS) {
Serial.print(F("Failed to determine device lock status. Response: "));
Serial.println(ret_code, HEX);
halt();
} else {
lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else {
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_DATA
Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
#endif
} else {
Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
}
#endif // not USE_SOFT_SIGNING

Serial.println(F("--------------------------------"));
Serial.println(F("Personalization is now complete."));
#ifndef USE_SOFT_SIGNING
Serial.print(F("Configuration is "));
if (lockConfig == 0x00) {
Serial.println("LOCKED");
} else {
Serial.println("UNLOCKED");
}
Serial.print(F("Data is "));
if (lockValue == 0x00) {
Serial.println("LOCKED");
} else {
Serial.println("UNLOCKED");
}
#endif
}

/** @brief Sketch execution code */
void loop()
{
}

meddie

und anschließend kommt dann das normale Gateway Sketch:
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik EKblad
* Contribution by a-lurker and Anticimex,
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
* Contribution by Tomas Hozza <thozza@gmail.com>
*
*
* DESCRIPTION
* The EthernetGateway sends data received from sensors to the ethernet link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* This GW code is designed for Sensebender GateWay / (Arduino Zero variant)
*
* Wire connections (OPTIONAL):
* - Inclusion button should be connected to SW2
*
* LEDs on board (default assignments):
* - Orange: USB RX/TX - Blink when receiving / transmitting on USB CDC device
* - Yellow: RX  - Blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
* - Green : TX  - Blink fast on radio message transmitted. In inclusion mode will blink slowly
* - Red   : ERR - Fast blink on error during transmission error or recieve crc error
* - Blue  : free - (use with LED_BLUE macro)
*
*/

#include <stdint.h>
#include <pins_arduino.h>
#define SKETCH_VERSION "0.2"
// Enable debug prints to serial monitor
#define MY_DEBUG
#define MY_DEBUG_VERBOSE_SIGNING

// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69

// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
//#define MY_RF24_PA_LEVEL RF24_PA_HIGH

#define MY_SIGNING_ATSHA204
#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
#define MY_SIGNING_REQUEST_SIGNATURES
#ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
#endif                             
#ifndef MY_SIGNING_ATSHA204_PIN
#define MY_SIGNING_ATSHA204_PIN 17
#endif       
#define MY_RF24_ENABLE_ENCRYPTION
   
// Enable gateway ethernet module type
#define MY_GATEWAY_W5100

// W5100 Ethernet module SPI enable (optional if using a shield/module that manages SPI_EN signal)
//#define MY_W5100_SPI_EN 4

// Enable Soft SPI for NRF radio (note different radio wiring is required)
// The W5100 ethernet module seems to have a hard time co-operate with
// radio on the same spi bus.
#if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
#define MY_SOFTSPI
#define MY_SOFT_SPI_SCK_PIN 14
#define MY_SOFT_SPI_MISO_PIN 16
#define MY_SOFT_SPI_MOSI_PIN 15
#endif

// When W5100 is connected we have to move CE/CSN pins for NRF radio
#ifndef MY_RF24_CE_PIN
#define MY_RF24_CE_PIN 5
#endif
#ifndef MY_RF24_CS_PIN
#define MY_RF24_CS_PIN 6
#endif

// Enable to UDP
//#define MY_USE_UDP

#define MY_IP_ADDRESS 10,0,0,253   // If this is disabled, DHCP is used to retrieve address
// Renewal period if using DHCP
//#define MY_IP_RENEWAL_INTERVAL 60000
// The port to keep open on node server mode / or port to contact in client mode
#define MY_PORT 5003

// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254

// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Ardunio examples use  "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED

// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE

// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP

// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN  3

// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300

// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE

// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4  // Error led pin
//#define MY_DEFAULT_RX_LED_PIN  6  // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN  5  // the PCB, on board LED


#if defined(MY_USE_UDP)
#include <EthernetUdp.h>
#endif
#include <Ethernet.h>
#include <MySensors.h>
#include <SD.h>
//#include <drivers/ATSHA204/ATSHA204.cpp>

Sd2Card card;

#define EEPROM_VERIFICATION_ADDRESS 0x01

static uint8_t num_of_leds = 5;
static uint8_t leds[] = {LED_BLUE, LED_RED, LED_GREEN, LED_YELLOW, LED_ORANGE};

void setup()
{
  // Setup locally attached sensors
}

void presentation()
{
  // Present locally attached sensors
}

void loop()
{
  // Send locally attached sensor data here
}


void preHwInit()
{

  pinMode(MY_SWC1, INPUT_PULLUP);
  pinMode(MY_SWC2, INPUT_PULLUP);
  if (digitalRead(MY_SWC1) && digitalRead(MY_SWC2)) {
    return;
  }

  uint8_t tests = 0;

  for (int i=0; i< num_of_leds; i++) {
    pinMode(leds[i], OUTPUT);
  }
  uint8_t led_state = 0;
  if (digitalRead(MY_SWC1)) {
    while (!Serial) {
      digitalWrite(LED_BLUE, led_state);
      led_state ^= 0x01;
      delay(500);
    } // Wait for USB to be connected, before spewing out data.
  }
  digitalWrite(LED_BLUE, LOW);
  if (Serial) {
    Serial.println("Sensebender GateWay test routine");
    Serial.print("Mysensors core version : ");
    Serial.println(MYSENSORS_LIBRARY_VERSION);
    Serial.print("GateWay sketch version : ");
    Serial.println(SKETCH_VERSION);
    Serial.println("----------------------------------");
    Serial.println();
  }
  if (testSha204()) {
    digitalWrite(LED_GREEN, HIGH);
    tests++;
  }
  if (testSDCard()) {
    digitalWrite(LED_YELLOW, HIGH);
    tests++;
  }

  if (testEEProm()) {
    digitalWrite(LED_ORANGE, HIGH);
    tests++;
  }
  if (testAnalog()) {
    digitalWrite(LED_BLUE, HIGH);
    tests++;
  }
  if (tests == 4) {
    while(1) {
      for (int i=0; i<num_of_leds; i++) {
        digitalWrite(leds[i], HIGH);
        delay(200);
        digitalWrite(leds[i], LOW);
      }
    }
  } else {
    while (1) {
      digitalWrite(LED_RED, HIGH);
      delay(200);
      digitalWrite(LED_RED, LOW);
      delay(200);
    }
  }

}

bool testSha204()
{
  uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
  uint8_t ret_code;
  if (Serial) {
    Serial.print("- > SHA204 ");
  }
  atsha204_init(MY_SIGNING_ATSHA204_PIN);
  ret_code = atsha204_wakeup(rx_buffer);

  if (ret_code == SHA204_SUCCESS) {
    ret_code = atsha204_getSerialNumber(rx_buffer);
    if (ret_code != SHA204_SUCCESS) {
      if (Serial) {
        Serial.println(F("Failed to obtain device serial number. Response: "));
      }
      Serial.println(ret_code, HEX);
    } else {
      if (Serial) {
        Serial.print(F("Ok (serial : "));
        for (int i=0; i<9; i++) {
          if (rx_buffer[i] < 0x10) {
            Serial.print('0'); // Because Serial.print does not 0-pad HEX
          }
          Serial.print(rx_buffer[i], HEX);
        }
        Serial.println(")");
      }
      return true;
    }
  } else {
    if (Serial) {
      Serial.println(F("Failed to wakeup SHA204"));
    }
  }
  return false;
}

bool testSDCard()
{
  if (Serial) {
    Serial.print("- > SD CARD ");
  }
  if (!card.init(SPI_HALF_SPEED, MY_SDCARD_CS)) {
    if (Serial) {
      Serial.println("SD CARD did not initialize!");
    }
  } else {
    if (Serial) {
      Serial.print("SD Card initialized correct! - ");
      Serial.print("type detected : ");
      switch(card.type()) {
      case SD_CARD_TYPE_SD1:
        Serial.println("SD1");
        break;
      case SD_CARD_TYPE_SD2:
        Serial.println("SD2");
        break;
      case SD_CARD_TYPE_SDHC:
        Serial.println("SDHC");
        break;
      default:
        Serial.println("Unknown");
      }
    }
    return true;
  }
  return false;
}

bool testEEProm()
{
  uint8_t eeprom_d1, eeprom_d2;
  SerialUSB.print(" -> EEPROM ");
  Wire.begin();
  eeprom_d1 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
  delay(500);
  eeprom_d1 = ~eeprom_d1; // invert the bits
  i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
  delay(500);
  eeprom_d2 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
  if (eeprom_d1 == eeprom_d2) {
    SerialUSB.println("PASSED");
    i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, ~eeprom_d1);
    return true;
  }
  SerialUSB.println("FAILED!");
  return false;
}

bool testAnalog()
{
  int bat_detect = analogRead(MY_BAT_DETECT);
  Serial.print("-> analog : ");
  Serial.print(bat_detect);
  if (bat_detect < 400 || bat_detect > 650) {
    Serial.println(" Failed");
    return false;
  }
  Serial.println(" Passed");
  return true;
}

PeMue

Irgendwie sehe ich noch nicht so richtig den Unterschied zwischen dem ersten Sketch
Zitat von: meddie am 27 Februar 2017, 23:25:50
Wenn ich richtig bin sollten die beiden Sketche dann wie folgt aussehen?
und dem zweiten
Zitat von: meddie am 27 Februar 2017, 23:30:35
wird der zweite Sketch hochgeladen in dem die beiden Keys eingesetzt sind:
(bis auf einige Dinge, die ein- oder auskommentiert sind) ...
Wo werden die Keys eintegragen?
RPi3Bv1.2 rpiaddon 1.66 6.0 1xHM-CC-RT-DN 1.4 1xHM-TC-IT-WM 1.1 2xHB-UW-Sen-THPL-O 0.15 1x-I 0.14OTAU  1xCUNO2 1.67 2xEM1000WZ 2xUniroll 1xASH2200 3xHMS100T(F) 1xRFXtrx 90 1xWT440H 3xTFA30.3150 5xFA21
RPi1Bv2 LCDCSM 1.63 5.8 2xMAX HKT 1xMAX RT V200KW1 Heizung Wasser

SensorMane

Hi,

ja ich bin aus Regen. Nachbarn? Woher kommst du dann?

Schaut alles gut aus was du da konfiguriert hast, auch die Reihenfolge ist richtig. Einmalig generierst du die benötigten Keys und hinterlegst sie dann im Personalisierungs-Sketch. Dann personalisierst du damit das Gateway und die Nodes und lädst dann den Anwendungs-Sketch hoch.

Hast du schon getestet obs funktioniert?

SensorMane

Der erste Sketch ist so konfiguriert, dass ein Key erzeugt und in der Konsole ausgegeben wird. Dieser Key steht dann im zweiten Sketch unter user_key. Hier natürlich nicht - aus Sicherheitsgründen!

meddie

Hallo Markus,

ich wohne in der Nähe von Straubing, also sind wir ja quasi Nachbarn. :-)

Leider geht es nicht, wenn ich den ersten Sketch hochlade, und dann den Serial Monitor starte und auf 112500 Bauds stelle, bekomme ich keine Ausgabe. Es passiert nichts.

SensorMane

Ah ok, ja das gilt noch als Nachbarn  ;)

Das hochladen läuft aber problemlos durch, also ohne Fehlermeldung?

meddie

so ich bin nun wieder einen Schritt weiter. man muss den Serial Monitor noch während des Uploads starten, dann bekommt man die Ausgabe.
Das habe ich erfahren ist "normal". Aber jetzt habe ich noch ein Problem ich bekomme statt Zufallskey Keys angezeigt die nur aus FFFFFFFFFFFFFFFFFFFFFFFFF bestehen.
Hast Du hierzu eine Idee?

SensorMane

Du kannst den Seriellen Monitor immer offen lassen, mach ich auch immer so.

Wenn kein key generiert wird, tippe ich auf den Chip. Der Zufallszahlengenerator des ATSHA204 wird ja hierfür verwendet. Entweder defekt oder er kann nicht angesprochen werden?!! Schau doch mal ob du ihn auf den richtigen Pin gehängt hast.


meddie

Hallo Markus,

ich habe gestern lagen gekämpft und habe den "Fehler" gefunden, der Fehler saß ca. 60 cm vor der Tastatur :-). Ich konnte nun beide Keys generieren, habe aber gestern nicht mehr weitergetestet, da es schon sehr spät war und ich heute ganz früh raus mußte.
Heute Abend gehts es weiter! Ich werde auf jedenfall berichten.

Darf ich mal OT was fragen, was hast Du alles im Einsatz von MySensors? Greifst Du auf fertige Sachen zurück wie Sensebender, Arduino Nano oder alles selbstgedengelt?

Danke für Deine Unterstützung!
Gruß Eddie

SensorMane

Servus,

ja so ists meistens, dass das Problem vor dem Bildschirm sitzt  ;)
Geht mir auch immer wieder so!

Für die Nodes verwende ich eigentlich nur fertige Nanos bzw. Mini. Hab auch einen Sensebender Micro zum testen gekauft, der hat mich aber nicht so überzeugt. Ich kombiniere die fertigen Arduinos dann halt mit Sensorik wie ich sie brauche. Derzeit arbeite ich an der Garagentorsteuerung bzw. wenn das Wetter besser ist werde ich alles einbauen. Darüber kann ich beide Tore ansteuern, per App und über RFID. Luftfeuchtigkeit und Temperatur in der Garage wird übermittelt sowie der Status der Tore (offen/zu). Muss das demnächst mal in mein Wiki einstellen.

Meld dich mal wieder wenn du weiter gemacht hast, ich helf gern wenn ich kann.


Gruß - Markus