MySensors Library & Examples  2.3.2
SecurityPersonalizer.ino
Go to the documentation of this file.
1 /*
2  * The MySensors Arduino library handles the wireless radio link and protocol
3  * between your home built sensors/actuators and HA controller of choice.
4  * The sensors forms a self healing radio network with optional repeaters. Each
5  * repeater and gateway builds a routing tables in EEPROM which keeps track of the
6  * network topology allowing messages to be routed to nodes.
7  *
8  * Created by Henrik Ekblad <[email protected]>
9  * Copyright (C) 2013-2019 Sensnology AB
10  * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
11  *
12  * Documentation: http://www.mysensors.org
13  * Support Forum: http://forum.mysensors.org
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * version 2 as published by the Free Software Foundation.
18  *
19  */
38 #include "sha204_library.h"
41 #define MY_CORE_ONLY
42 #include <MySensors.h>
43 
44 /************************************ User defined key data ***************************************/
45 
47 #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
48 
50 #define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
51 
53 #define MY_SOFT_SERIAL 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
54 
55 /***************************** Flags for guided personalization flow ******************************/
56 
66 //#define GENERATE_KEYS_ATSHA204A
67 
81 //#define GENERATE_KEYS_SOFT
82 
90 //#define PERSONALIZE_ATSHA204A
91 
99 //#define PERSONALIZE_SOFT
100 
114 //#define PERSONALIZE_SOFT_RANDOM_SERIAL
115 
116 /*************************** The settings below are for advanced users ****************************/
121 //#define USE_SOFT_SIGNING
122 
130 //#define LOCK_ATSHA204A_CONFIGURATION
131 
142 //#define SKIP_UART_CONFIRMATION
143 
150 //#define GENERATE_HMAC_KEY
151 
156 //#define STORE_HMAC_KEY
157 
164 //#define GENERATE_AES_KEY
165 
170 //#define STORE_AES_KEY
171 
177 //#define GENERATE_SOFT_SERIAL
178 
183 //#define STORE_SOFT_SERIAL
184 
189 //#define PRINT_DETAILED_ATSHA204A_CONFIG
190 
195 //#define RESET_EEPROM_PERSONALIZATION
196 
197 /********************* Guided mode flag configurations (don't change these) ***********************/
198 #ifdef GENERATE_KEYS_ATSHA204A
199 #define LOCK_ATSHA204A_CONFIGURATION // We have to lock configuration to enable random number generation
200 #define GENERATE_HMAC_KEY // Generate random HMAC key
201 #define GENERATE_AES_KEY // Generate random AES key
202 #define SKIP_UART_CONFIRMATION // This is an automated mode
203 #endif
204 
205 #ifdef GENERATE_KEYS_SOFT
206 #define USE_SOFT_SIGNING // Use software backend
207 #define GENERATE_HMAC_KEY // Generate random HMAC key
208 #define GENERATE_AES_KEY // Generate random AES key
209 #define SKIP_UART_CONFIRMATION // This is an automated mode
210 #endif
211 
212 #ifdef PERSONALIZE_ATSHA204A
213 #define LOCK_ATSHA204A_CONFIGURATION // We have to lock configuration to enable random number generation
214 #define STORE_HMAC_KEY // Store the HMAC key
215 #define STORE_AES_KEY // Store the AES key
216 #define SKIP_UART_CONFIRMATION // This is an automated mode
217 #endif
218 
219 #ifdef PERSONALIZE_SOFT_RANDOM_SERIAL
220 #define GENERATE_SOFT_SERIAL // Generate a soft serial number
221 #define PERSONALIZE_SOFT // Do the rest as PERSONALIZE_SOFT
222 #endif
223 
224 #ifdef PERSONALIZE_SOFT
225 #define USE_SOFT_SIGNING // Use software backend
226 #define STORE_HMAC_KEY // Store the HMAC key
227 #define STORE_AES_KEY // Store the AES key
228 #define STORE_SOFT_SERIAL // Store the soft serial number
229 #define SKIP_UART_CONFIRMATION // This is an automated mode
230 #endif
231 
232 #if defined(GENERATE_HMAC_KEY) || defined(GENERATE_AES_KEY) || defined(GENERATE_SOFT_SERIAL)
233 #define GENERATE_SOMETHING
234 #endif
235 
236 #if defined(MY_LOCK_MCU)
237 #undefine MY_LOCK_MCU // The Sketch after SecurityPersonaliter should lock the MCU
238 #endif
239 
240 /********************************** Preprocessor sanitychecks *************************************/
241 #if defined(GENERATE_SOFT_SERIAL) && !defined(USE_SOFT_SIGNING)
242 #error Cannot generate soft serial using ATSHA204A, use USE_SOFT_SINGING for this
243 #endif
244 #if defined(STORE_SOFT_SERIAL) && !defined(USE_SOFT_SIGNING)
245 #error Cannot store soft serial to ATSHA204A, use USE_SOFT_SINGING for this
246 #endif
247 #if defined(PRINT_DETAILED_ATSHA204A_CONFIG) && defined(USE_SOFT_SIGNING)
248 #error Cannot print ATSHA204A config using software signing flag, disable USE_SOFT_SINGING for this
249 #endif
250 #if defined(LOCK_ATSHA204A_CONFIGURATION) && defined(USE_SOFT_SIGNING)
251 #error Cannot lock ATSHA204A config using software signing flag, disable USE_SOFT_SINGING for this
252 #endif
253 #ifdef GENERATE_KEYS_ATSHA204A
254 #ifdef USE_SOFT_SIGNING
255 #error You cannot select soft signing if you want to generate keys using ATSHA204A
256 #endif
257 #ifdef STORE_HMAC_KEY
258 #error Disable STORE_SOFT_KEY, you should not store keys in this mode
259 #endif
260 #ifdef STORE_SOFT_SERIAL
261 #error Disable STORE_SOFT_SERIAL, you should not store serial in this mode
262 #endif
263 #ifdef STORE_AES_KEY
264 #error Disable STORE_AES_KEY, you should not store keys in this mode
265 #endif
266 #if defined(GENERATE_KEYS_SOFT) ||\
267  defined (PERSONALIZE_ATSHA204A) ||\
268  defined (PERSONALIZE_SOFT) ||\
269  defined (PERSONALIZE_SOFT_RANDOM_SERIAL)
270 #error You can not enable GENERATE_KEYS_ATSHA204A together with other guided modes
271 #endif
272 #endif // GENERATE_KEYS_ATSHA204A
273 #ifdef GENERATE_KEYS_SOFT
274 #ifdef STORE_HMAC_KEY
275 #error Disable STORE_SOFT_KEY, you should not store keys in this mode
276 #endif
277 #ifdef STORE_SOFT_SERIAL
278 #error Disable STORE_SOFT_SERIAL, you should not store serial in this mode
279 #endif
280 #ifdef STORE_AES_KEY
281 #error Disable STORE_AES_KEY, you should not store keys in this mode
282 #endif
283 #ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
284 #error You have to set MY_SIGNING_SOFT_RANDOMSEED_PIN to a suitable value in this mode
285 #endif
286 #if defined(GENERATE_KEYS_ATSHA204A) ||\
287  defined (PERSONALIZE_ATSHA204A) ||\
288  defined (PERSONALIZE_SOFT) ||\
289  defined (PERSONALIZE_SOFT_RANDOM_SERIAL)
290 #error You can not enable GENERATE_KEYS_SOFT together with other guided modes
291 #endif
292 #endif // GENERATE_KEYS_SOFT
293 #ifdef PERSONALIZE_ATSHA204A
294 #ifdef USE_SOFT_SIGNING
295 #error You cannot select soft signing if you want to personalize an ATSHA204A
296 #endif
297 #if defined(GENERATE_KEYS_ATSHA204A) ||\
298  defined (GENERATE_KEYS_SOFT) ||\
299  defined (PERSONALIZE_SOFT) ||\
300  defined (PERSONALIZE_SOFT_RANDOM_SERIAL)
301 #error You can not enable PERSONALIZE_ATSHA204A together with other guided modes
302 #endif
303 #ifdef RESET_EEPROM_PERSONALIZATION
304 #error You cannot reset EEPROM personalization when personalizing a device
305 #endif
306 #endif // PERSONALIZE_ATSHA204A
307 #ifdef PERSONALIZE_SOFT
308 #if defined(GENERATE_KEYS_ATSHA204A) ||\
309  defined (GENERATE_KEYS_SOFT) ||\
310  defined (PERSONALIZE_ATSHA204A)
311 #error You can not enable PERSONALIZE_SOFT together with other guided modes
312 #endif
313 #ifdef RESET_EEPROM_PERSONALIZATION
314 #error You cannot reset EEPROM personalization when personalizing a device
315 #endif
316 #endif // PERSONALIZE_SOFT
317 #ifdef PERSONALIZE_SOFT_RANDOM_SERIAL
318 #if defined(GENERATE_KEYS_SOFT) ||\
319  defined (PERSONALIZE_ATSHA204A) ||\
320  defined (GENERATE_KEYS_ATSHA204A)
321 #error You can only enable one of the guided modes at a time
322 #endif
323 #ifdef RESET_EEPROM_PERSONALIZATION
324 #error You cannot reset EEPROM personalization when personalizing a device
325 #endif
326 #endif // PERSONALIZE_SOFT_RANDOM_SERIAL
327 
328 #if !defined(GENERATE_KEYS_ATSHA204A) &&\
329  !defined(GENERATE_KEYS_SOFT) &&\
330  !defined(PERSONALIZE_ATSHA204A) &&\
331  !defined(PERSONALIZE_SOFT) &&\
332  !defined(PERSONALIZE_SOFT_RANDOM_SERIAL) &&\
333  !defined(USE_SOFT_SIGNING) &&\
334  !defined(LOCK_ATSHA204A_CONFIGURATION) &&\
335  !defined(SKIP_UART_CONFIRMATION) &&\
336  !defined(GENERATE_HMAC_KEY) &&\
337  !defined(STORE_HMAC_KEY) &&\
338  !defined(GENERATE_SOFT_SERIAL) &&\
339  !defined(STORE_SOFT_SERIAL) &&\
340  !defined(GENERATE_AES_KEY) &&\
341  !defined(STORE_AES_KEY) &&\
342  !defined(PRINT_DETAILED_ATSHA204A_CONFIG) &&\
343  !defined(RESET_EEPROM_PERSONALIZATION)
344 
345 #define NO_SETTINGS_DEFINED
346 #endif
347 
348 #if defined(GENERATE_KEYS_ATSHA204A) ||\
349  defined(GENERATE_KEYS_SOFT) ||\
350  defined(PERSONALIZE_ATSHA204A) ||\
351  defined(PERSONALIZE_SOFT) ||\
352  defined(PERSONALIZE_SOFT_RANDOM_SERIAL)
353 
354 #define GUIDED_MODE
355 #endif
356 
357 /************************************* Function declarations ***************************************/
358 static void halt(bool success);
359 #ifdef GENERATE_SOMETHING
360 static bool generate_random_data(uint8_t* data, size_t sz);
361 #endif
362 static void generate_keys(void);
363 static void store_keys(void);
364 static void print_hex_buffer(uint8_t* data, size_t sz);
365 static void print_c_friendly_hex_buffer(uint8_t* data, size_t sz);
366 #ifdef STORE_HMAC_KEY
367 static bool store_hmac_key_data(uint8_t* data, size_t sz);
368 #endif
369 #ifdef STORE_AES_KEY
370 static bool store_aes_key_data(uint8_t* data, size_t sz);
371 #endif
372 #ifdef STORE_SOFT_SERIAL
373 static bool store_soft_serial_data(uint8_t* data, size_t sz);
374 #endif
375 #ifndef USE_SOFT_SIGNING
376 static void init_atsha204a_state(void);
377 #ifdef LOCK_ATSHA204A_CONFIGURATION
378 static void lock_atsha204a_config(void);
379 static uint16_t write_atsha204a_config_and_get_crc(void);
380 #endif
381 static bool get_atsha204a_serial(uint8_t* data);
382 #ifdef STORE_HMAC_KEY
383 static bool write_atsha204a_key(uint8_t* key);
384 #endif
385 #endif // not USE_SOFT_SIGNING
386 static void print_greeting(void);
387 static void print_ending(void);
388 static void probe_and_print_peripherals(void);
389 static void print_eeprom_data(void);
390 static void print_whitelisting_entry(void);
391 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
392 static void dump_detailed_atsha204a_configuration(void);
393 #endif
394 #ifdef RESET_EEPROM_PERSONALIZATION
395 static void reset_eeprom(void);
396 #endif
397 static void write_eeprom_checksum(void);
398 
399 /**************************************** File local data *****************************************/
400 #if defined(GENERATE_HMAC_KEY) || defined(STORE_HMAC_KEY)
401 
402 static uint8_t user_hmac_key[32] = {MY_HMAC_KEY};
403 #endif
404 
405 #if defined(GENERATE_SOFT_SERIAL) || defined(STORE_SOFT_SERIAL)
406 
407 static uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
408 #endif
409 
410 #if defined(GENERATE_AES_KEY) || defined(STORE_AES_KEY)
411 /* @brief The data to store as AES key in EEPROM */
412 static uint8_t user_aes_key[16] = {MY_AES_KEY};
413 #endif
414 
415 #ifndef USE_SOFT_SIGNING
418 static uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
419 static uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
420 static uint8_t ret_code;
421 static uint8_t lockConfig = 0;
422 static uint8_t lockValue = 0;
423 #endif
424 static bool has_device_unique_id = false;
425 static const uint8_t reset_buffer[32] = {
426  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
427  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
428  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
429  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
430 };
431 
432 /******************************************* Functions ********************************************/
433 
435 void setup()
436 {
437  // Delay startup a bit for serial consoles to catch up
438  uint32_t enter = hwMillis();
439  while (hwMillis() - enter < (uint32_t)500);
440 #ifdef USE_SOFT_SIGNING
441  // initialize pseudo-RNG
442  hwRandomNumberInit();
443 #endif
444 
445  while(!Serial); // For USB enabled devices, wait for USB enumeration before continuing
446 
447  print_greeting();
448 
449 #ifndef USE_SOFT_SIGNING
450  init_atsha204a_state();
451  // Lock configuration now if requested to enable RNG in ATSHA
452 #ifdef LOCK_ATSHA204A_CONFIGURATION
453  lock_atsha204a_config();
454 #endif
455 #endif
456  // Generate the requested keys (if any)
457  generate_keys();
458 
459 #ifdef RESET_EEPROM_PERSONALIZATION
460  // If requested, reset EEPROM before storing keys
461  reset_eeprom();
462 #endif
463 
464  // Store the keys (if configured to do so)
465  store_keys();
466 
467  // Write a checksum on the EEPROM data
468  write_eeprom_checksum();
469 
470  // Print current EEPROM
471  print_eeprom_data();
472  print_whitelisting_entry();
473  Serial.println();
474 
475  print_ending();
476  halt(true);
477 }
478 
480 void loop()
481 {
482 }
483 
485 static void halt(bool success)
486 {
487  Serial.println();
488  Serial.println(
489  F("+------------------------------------------------------------------------------------+"));
490  Serial.println(
491  F("| Execution result |"));
492  Serial.println(
493  F("+------------------------------------------------------------------------------------+"));
494  if (success) {
495  Serial.println(F(
496  "| SUCCESS |"));
497  } else {
498  Serial.print(F(
499  "| FAILURE "));
500 #ifdef USE_SOFT_SIGNING
501  Serial.println(F(" |"));
502 #else
503  if (ret_code != SHA204_SUCCESS) {
504  Serial.print(F("(last ATSHA204A return code: 0x"));
505  if (ret_code < 0x10) {
506  Serial.print('0'); // Because Serial.print does not 0-pad HEX
507  }
508  Serial.print(ret_code, HEX);
509  Serial.println(F(") |"));
510  } else {
511  Serial.println(F(" |"));
512  }
513 #endif
514  }
515  Serial.println(
516  F("+------------------------------------------------------------------------------------+"));
517  while(1) {
518  doYield();
519  }
520 }
521 
522 #ifdef GENERATE_SOMETHING
523 
529 static bool generate_random_data(uint8_t* data, size_t sz)
530 {
531 #if defined(USE_SOFT_SIGNING) && ! defined(MY_HW_HAS_GETENTROPY)
532  for (size_t i = 0; i < sz; i++) {
533  data[i] = random(256) ^ micros();
534  uint32_t enter = hwMillis();
535  while (hwMillis() - enter < (uint32_t)2);
536  }
537  return true;
538 #elif defined(USE_SOFT_SIGNING) && defined(MY_HW_HAS_GETENTROPY)
539  hwGetentropy(&data, sz);
540 #else
541  ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
542  if ((ret_code != SHA204_SUCCESS) || (lockConfig != 0x00)) {
543  return false;
544  } else {
545  memcpy(data, rx_buffer+SHA204_BUFFER_POS_DATA, sz);
546  return true;
547  }
548 #endif // not USE_SOFT_SIGNING
549 }
550 #endif // GENERATE_SOMETHING
551 
553 static void generate_keys(void)
554 {
555 #ifdef GENERATE_SOMETHING
556  Serial.println(
557  F("+------------------------------------------------------------------------------------+"));
558  Serial.println(
559  F("| Key generation |"));
560  Serial.println(
561  F("+--------+--------+------------------------------------------------------------------+"));
562  Serial.println(
563  F("| Key ID | Status | Key |"));
564  Serial.println(
565  F("+--------+--------+------------------------------------------------------------------+"));
566 #endif
567 #ifdef GENERATE_HMAC_KEY
568  Serial.print(F("| HMAC | "));
569  if (!generate_random_data(user_hmac_key, 32)) {
570  memset(user_hmac_key, 0xFF, 32);
571  Serial.print(F("FAILED | "));
572  } else {
573  Serial.print(F("OK | "));
574  }
575  print_hex_buffer(user_hmac_key, 32);
576  Serial.println(F(" |"));
577 #endif
578 #ifdef GENERATE_AES_KEY
579  Serial.print(F("| AES | "));
580  if (!generate_random_data(user_aes_key, 16)) {
581  memset(user_aes_key, 0xFF, 16);
582  Serial.print(F("FAILED | "));
583  } else {
584  Serial.print(F("OK | "));
585  }
586  print_hex_buffer(user_aes_key, 16);
587  Serial.println(F(" |"));
588 #endif
589 #ifdef GENERATE_SOFT_SERIAL
590  Serial.print(F("| SERIAL | "));
591  if (has_device_unique_id) {
592  Serial.println(F("N/A | MCU has a unique serial which will be used instead. |"));
593  } else {
594  if (!generate_random_data(user_soft_serial, 9)) {
595  memset(user_soft_serial, 0xFF, 9);
596  Serial.print(F("FAILED | "));
597  } else {
598  Serial.print(F("OK | "));
599  }
600  print_hex_buffer(user_soft_serial, 9);
601  Serial.println(F(" |"));
602  }
603 #endif
604 #if defined(GENERATE_SOMETHING) && !defined(PERSONALIZE_SOFT_RANDOM_SERIAL)
605  Serial.println(
606  F("+--------+--------+------------------------------------------------------------------+"));
607  Serial.println();
608  Serial.println(
609  F("+------------------------------------------------------------------------------------+"));
610  Serial.println(
611  F("| Key copy section |"));
612  Serial.println(
613  F("+------------------------------------------------------------------------------------+"));
614 #ifdef GENERATE_HMAC_KEY
615  Serial.print(F("#define MY_HMAC_KEY "));
616  print_c_friendly_hex_buffer(user_hmac_key, 32);
617  Serial.println();
618 #endif
619 #ifdef GENERATE_AES_KEY
620  Serial.print(F("#define MY_AES_KEY "));
621  print_c_friendly_hex_buffer(user_aes_key, 16);
622  Serial.println();
623 #endif
624 #ifdef GENERATE_SOFT_SERIAL
625  Serial.print(F("#define MY_SOFT_SERIAL "));
626  print_c_friendly_hex_buffer(user_soft_serial, 9);
627  Serial.println();
628 #endif
629  Serial.println(
630  F("+------------------------------------------------------------------------------------+"));
631  Serial.println();
632 #elif defined(PERSONALIZE_SOFT_RANDOM_SERIAL)
633  Serial.println(
634  F("+--------+--------+------------------------------------------------------------------+"));
635  Serial.println();
636 #endif
637 }
638 
639 #ifdef RESET_EEPROM_PERSONALIZATION
640 
641 static void reset_eeprom(void)
642 {
643  uint8_t validation_buffer[32];
644  Serial.println(
645  F("+------------------------------------------------------------------------------------+"));
646  Serial.println(
647  F("| EEPROM reset |"));
648  Serial.println(
649  F("+--------+---------------------------------------------------------------------------+"));
650  Serial.println(
651  F("| Key ID | Status |"));
652  Serial.println(
653  F("+--------+---------------------------------------------------------------------------+"));
654  Serial.print(F("| HMAC | "));
655  hwWriteConfigBlock((void*)reset_buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
656  // Validate data written
657  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
658  if (memcmp(validation_buffer, reset_buffer, 32) != 0) {
659  Serial.println(F("FAILED |"));
660  } else {
661  Serial.println(F("OK |"));
662  }
663  Serial.print(F("| AES | "));
664  hwWriteConfigBlock((void*)reset_buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
665  // Validate data written
666  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
667  if (memcmp(validation_buffer, reset_buffer, 16) != 0) {
668  Serial.println(F("FAILED |"));
669  } else {
670  Serial.println(F("OK |"));
671  }
672  Serial.print(F("| SERIAL | "));
673  hwWriteConfigBlock((void*)reset_buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
674  // Validate data written
675  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
676  if (memcmp(validation_buffer, reset_buffer, 9) != 0) {
677  Serial.println(F("FAILED |"));
678  } else {
679  Serial.println(F("OK |"));
680  }
681  Serial.println(
682  F("+--------+---------------------------------------------------------------------------+"));
683 }
684 #endif // RESET_EEPROM_PERSONALIZATION
685 
686 static void write_eeprom_checksum(void)
687 {
689  uint8_t hash[32];
690  uint8_t checksum;
691  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS,
693  hwReadConfigBlock((void*)&buffer[SIZE_SIGNING_SOFT_HMAC_KEY],
695  hwReadConfigBlock((void*)&buffer[SIZE_SIGNING_SOFT_HMAC_KEY + SIZE_RF_ENCRYPTION_AES_KEY],
697  hwReadConfigBlock((void*)&checksum, (void*)EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS,
699 
700  SHA256(hash, buffer, sizeof(buffer));
701  hwWriteConfigBlock((void*)&hash[0], (void*)EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS,
703 }
704 
706 static void store_keys(void)
707 {
708 #if defined(STORE_HMAC_KEY) || defined(STORE_AES_KEY) || defined(STORE_SOFT_SERIAL)
709  Serial.println(
710  F("+------------------------------------------------------------------------------------+"));
711  Serial.println(
712  F("| Key storage |"));
713  Serial.println(
714  F("+--------+--------+------------------------------------------------------------------+"));
715  Serial.println(
716  F("| Key ID | Status | Key |"));
717  Serial.println(
718  F("+--------+--------+------------------------------------------------------------------+"));
719 #endif
720 #ifdef STORE_HMAC_KEY
721  Serial.print(F("| HMAC | "));
722  if (!store_hmac_key_data(user_hmac_key)) {
723  Serial.print(F("FAILED | "));
724  } else {
725  Serial.print(F("OK | "));
726  }
727  print_hex_buffer(user_hmac_key, 32);
728  Serial.println(F(" |"));
729 #endif
730 #ifdef STORE_AES_KEY
731  Serial.print(F("| AES | "));
732  if (!store_aes_key_data(user_aes_key)) {
733  Serial.print(F("FAILED | "));
734  } else {
735  Serial.print(F("OK | "));
736  }
737  print_hex_buffer(user_aes_key, 16);
738  Serial.println(F(" |"));
739 #endif
740 #ifdef STORE_SOFT_SERIAL
741  Serial.print(F("| SERIAL | "));
742  if (has_device_unique_id) {
743  memset(user_soft_serial, 0xFF, 9);
744  }
745  if (!store_soft_serial_data(user_soft_serial)) {
746  Serial.print(F("FAILED | "));
747  } else {
748  Serial.print(F("OK | "));
749  }
750  if (has_device_unique_id) {
751  Serial.println(F("EEPROM reset. MCU has a unique serial which will be used instead.|"));
752  } else {
753  print_hex_buffer(user_soft_serial, 9);
754  Serial.println(F(" |"));
755  }
756 #endif
757 #if defined(STORE_HMAC_KEY) || defined(STORE_AES_KEY) || defined(STORE_SOFT_SERIAL)
758  Serial.println(
759  F("+--------+--------+------------------------------------------------------------------+"));
760  Serial.println();
761 #endif
762 }
763 
769 static void print_hex_buffer(uint8_t* data, size_t sz)
770 {
771  for (size_t i=0; i<sz; i++) {
772  if (data[i] < 0x10) {
773  Serial.print('0'); // Because Serial.print does not 0-pad HEX
774  }
775  Serial.print(data[i], HEX);
776  }
777 }
778 
784 static void print_c_friendly_hex_buffer(uint8_t* data, size_t sz)
785 {
786  for (size_t i=0; i<sz; i++) {
787  Serial.print("0x");
788  if (data[i] < 0x10) {
789  Serial.print('0'); // Because Serial.print does not 0-pad HEX
790  }
791  Serial.print(data[i], HEX);
792  if (i < sz-1) {
793  Serial.print(',');
794  }
795  }
796 }
797 
798 #ifdef STORE_HMAC_KEY
799 
804 static bool store_hmac_key_data(uint8_t* data)
805 {
806 #ifdef USE_SOFT_SIGNING
807  static uint8_t validation_buffer[32];
808  hwWriteConfigBlock((void*)data, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
809  // Validate data written
810  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
811  if (memcmp(validation_buffer, data, 32) != 0) {
812  return false;
813  } else {
814  return true;
815  }
816 #else
817  // It will not be possible to write the key if the configuration zone is unlocked
818  if (lockConfig == 0x00) {
819  // Write the key to the appropriate slot in the data zone
820  if (!write_atsha204a_key(data)) {
821  return false;
822  } else {
823  return true;
824  }
825  } else {
826  return false;
827  }
828 #endif
829 }
830 #endif
831 
832 #ifdef STORE_AES_KEY
833 
838 static bool store_aes_key_data(uint8_t* data)
839 {
840  static uint8_t validation_buffer[16];
841  hwWriteConfigBlock((void*)data, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
842  // Validate data written
843  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
844  if (memcmp(validation_buffer, data, 16) != 0) {
845  return false;
846  } else {
847  return true;
848  }
849 }
850 #endif // STORE_AES_KEY
851 
852 #ifdef STORE_SOFT_SERIAL
853 
858 static bool store_soft_serial_data(uint8_t* data)
859 {
860  static uint8_t validation_buffer[9];
861  hwWriteConfigBlock((void*)data, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
862  // Validate data written
863  hwReadConfigBlock((void*)validation_buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
864  if (memcmp(validation_buffer, data, 9) != 0) {
865  return false;
866  } else {
867  return true;
868  }
869 }
870 #endif // STORE_SOFT_SERIAL
871 
872 #ifndef USE_SOFT_SIGNING
873 
876 static void init_atsha204a_state(void)
877 {
878  // Read out lock config bits to determine if locking is possible
879  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
880  if (ret_code != SHA204_SUCCESS) {
881  halt(false);
882  } else {
883  lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
884  lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
885  }
886 }
887 
888 #ifdef LOCK_ATSHA204A_CONFIGURATION
889 static void lock_atsha204a_config(void)
890 {
891  Serial.println(
892  F("+------------------------------------------------------------------------------------+"));
893  Serial.println(
894  F("| ATSHA204A configuration locking |"));
895  Serial.println(
896  F("+------------------------------------------------------------------------------------+"));
897  if (lockConfig != 0x00) {
898  uint16_t crc;
899  (void)crc;
900 
901  // Write config and get CRC for the updated config
902  crc = write_atsha204a_config_and_get_crc();
903 
904  // List current configuration before attempting to lock
905 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
906  Serial.println(
907  F("| New ATSHA204A Configuration |"));
908  dump_detailed_atsha204a_configuration();
909 #endif // PRINT_DETAILED_ATSHA204A_CONFIG
910 
911 #ifndef SKIP_UART_CONFIRMATION
912  // Purge serial input buffer
913  while (Serial.available()) {
914  Serial.read();
915  }
916  Serial.println(
917  F("| * Send SPACE character now to lock the configuration... |"));
918 
919  while (Serial.available() == 0);
920  if (Serial.read() == ' ')
921 #endif //not SKIP_UART_CONFIRMATION
922  {
923  Serial.print(F("| * Locking configuration..."));
924 
925  // Correct sequence, resync chip
926  ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
927  if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
928  Serial.println(
929  F("+------------------------------------------------------------------------------------+"));
930  halt(false);
931  }
932 
933  // Lock configuration zone
934  ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
935  crc, 0, NULL, 0, NULL, 0, NULL,
936  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
937  if (ret_code != SHA204_SUCCESS) {
938  Serial.println(F("Failed |"));
939  Serial.println(
940  F("+------------------------------------------------------------------------------------+"));
941  halt(false);
942  } else {
943  Serial.println(F("Done |"));
944 
945  // Update lock flags after locking
946  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
947  if (ret_code != SHA204_SUCCESS) {
948  Serial.println(
949  F("+------------------------------------------------------------------------------------+"));
950  halt(false);
951  } else {
952  lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
953  lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
954  }
955  }
956  }
957 #ifndef SKIP_UART_CONFIRMATION
958  else {
959  Serial.println(
960  F("| * Unexpected answer. Skipping locking. |"));
961  Serial.println(
962  F("+------------------------------------------------------------------------------------+"));
963  }
964 #endif //not SKIP_UART_CONFIRMATION
965  } else {
966  Serial.println(
967  F("| * Skipping configuration write and lock (configuration already locked). |"));
968  Serial.println(
969  F("+------------------------------------------------------------------------------------+"));
970  }
971  Serial.println();
972 }
973 
978 static uint16_t write_atsha204a_config_and_get_crc(void)
979 {
980  uint16_t crc = 0;
981  uint8_t config_word[4];
982 
983  // We will set default settings from datasheet on all slots. This means that we can use slot 0 for the key
984  // as that slot will not be readable (key will therefore be secure) and slot 8 for the payload digest
985  // calculationon as that slot can be written in clear text even when the datazone is locked.
986  // Other settings which are not relevant are kept as is.
987 
988  for (int i=0; i < 88; i += 4) {
989  bool do_write = true;
990  if (i == 20) {
991  config_word[0] = 0x8F;
992  config_word[1] = 0x80;
993  config_word[2] = 0x80;
994  config_word[3] = 0xA1;
995  } else if (i == 24) {
996  config_word[0] = 0x82;
997  config_word[1] = 0xE0;
998  config_word[2] = 0xA3;
999  config_word[3] = 0x60;
1000  } else if (i == 28) {
1001  config_word[0] = 0x94;
1002  config_word[1] = 0x40;
1003  config_word[2] = 0xA0;
1004  config_word[3] = 0x85;
1005  } else if (i == 32) {
1006  config_word[0] = 0x86;
1007  config_word[1] = 0x40;
1008  config_word[2] = 0x87;
1009  config_word[3] = 0x07;
1010  } else if (i == 36) {
1011  config_word[0] = 0x0F;
1012  config_word[1] = 0x00;
1013  config_word[2] = 0x89;
1014  config_word[3] = 0xF2;
1015  } else if (i == 40) {
1016  config_word[0] = 0x8A;
1017  config_word[1] = 0x7A;
1018  config_word[2] = 0x0B;
1019  config_word[3] = 0x8B;
1020  } else if (i == 44) {
1021  config_word[0] = 0x0C;
1022  config_word[1] = 0x4C;
1023  config_word[2] = 0xDD;
1024  config_word[3] = 0x4D;
1025  } else if (i == 48) {
1026  config_word[0] = 0xC2;
1027  config_word[1] = 0x42;
1028  config_word[2] = 0xAF;
1029  config_word[3] = 0x8F;
1030  } else if (i == 52 || i == 56 || i == 60 || i == 64) {
1031  config_word[0] = 0xFF;
1032  config_word[1] = 0x00;
1033  config_word[2] = 0xFF;
1034  config_word[3] = 0x00;
1035  } else if (i == 68 || i == 72 || i == 76 || i == 80) {
1036  config_word[0] = 0xFF;
1037  config_word[1] = 0xFF;
1038  config_word[2] = 0xFF;
1039  config_word[3] = 0xFF;
1040  } else {
1041  // All other configs are untouched
1042  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
1043  if (ret_code != SHA204_SUCCESS) {
1044  Serial.println(
1045  F("+------------------------------------------------------------------------------------+"));
1046  halt(false);
1047  }
1048  // Set config_word to the read data
1049  config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
1050  config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
1051  config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
1052  config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
1053  do_write = false;
1054  }
1055 
1056  // Update crc with CRC for the current word
1057  crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
1058 
1059  // Write config word
1060  if (do_write) {
1061  ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
1062  i >> 2, 4, config_word, 0, NULL, 0, NULL,
1063  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
1064  if (ret_code != SHA204_SUCCESS) {
1065  Serial.println(
1066  F("+------------------------------------------------------------------------------------+"));
1067  halt(false);
1068  }
1069  }
1070  }
1071  return crc;
1072 }
1073 #endif
1074 
1075 static bool get_atsha204a_serial(uint8_t* data)
1076 {
1077  ret_code = sha204.getSerialNumber(rx_buffer);
1078  if (ret_code != SHA204_SUCCESS) {
1079  return false;
1080  } else {
1081  memcpy(data, rx_buffer, 9);
1082  return true;
1083  }
1084 }
1085 
1086 #ifdef STORE_HMAC_KEY
1087 
1092 static bool write_atsha204a_key(uint8_t* key)
1093 {
1094  // Write key to slot 0
1095  ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
1096  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
1097  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
1098  if (ret_code != SHA204_SUCCESS) {
1099  return false;
1100  } else {
1101  return true;
1102  }
1103 }
1104 #endif // STORE_HMAC_KEY
1105 #endif // not USE_SOFT_SIGNING
1106 
1108 static void print_greeting(void)
1109 {
1110  Serial.println(
1111  F("+------------------------------------------------------------------------------------+"));
1112  Serial.println(
1113  F("| MySensors security personalizer |"));
1114  Serial.println(
1115  F("+------------------------------------------------------------------------------------+"));
1116  Serial.println();
1117 #ifdef NO_SETTINGS_DEFINED
1118  Serial.println(
1119  F("+------------------------------------------------------------------------------------+"));
1120  Serial.println(
1121  F("| You are running without any configuration flags set. |"));
1122  Serial.println(
1123  F("| No changes will be made to ATSHA204A or EEPROM except for the EEPROM checksum |"));
1124  Serial.println(
1125  F("| which will be updated. |"));
1126  Serial.println(
1127  F("| |"));
1128  Serial.println(
1129  F("| If you want to personalize your device, you have two options. |"));
1130  Serial.println(
1131  F("| |"));
1132  Serial.println(
1133  F("| 1. a. Enable either GENERATE_KEYS_ATSHA204A or GENERATE_KEYS_SOFT |"));
1134  Serial.println(
1135  F("| This will generate keys for ATSHA204A or software signing. |"));
1136  Serial.println(
1137  F("| b. Execute the sketch. You will be guided through the steps below under |"));
1138  Serial.println(
1139  F("| WHAT TO DO NEXT? |"));
1140  Serial.println(
1141  F("| c. Copy the generated keys and replace the topmost definitions in this file. |"));
1142  Serial.println(
1143  F("| d. Save the sketch and then disable the flag you just enabled. |"));
1144  Serial.println(
1145  F("| e. Enable PERSONALIZE_ATSHA204A to personalize the ATSHA204A device. |"));
1146  Serial.println(
1147  F("| or |"));
1148  Serial.println(
1149  F("| Enable PERSONALIZE_SOFT to personalize the EEPROM for software signing. |"));
1150  Serial.println(
1151  F("| If you want to use whitelisting you need to pick a unique serial number |"));
1152  Serial.println(
1153  F("| for each device you run the sketch on and fill in MY_SOFT_SERIAL. |"));
1154  Serial.println(
1155  F("| or |"));
1156  Serial.println(
1157  F("| Enable PERSONALIZE_SOFT_RANDOM_SERIAL to personalzie the EEPROM and |"));
1158  Serial.println(
1159  F("| include a new random serial number every time the sketch is executed. |"));
1160  Serial.println(
1161  F("| Take note of each saved serial number if you plan to use whitelisting. |"));
1162  Serial.println(
1163  F("| f. Execute the sketch on each device you want to personalize that is supposed |"));
1164  Serial.println(
1165  F("| to communicate securely. |"));
1166  Serial.println(
1167  F("| |"));
1168  Serial.println(
1169  F("| 2. Enable any configuration flag as you see fit. |"));
1170  Serial.println(
1171  F("| It is assumed that you know what you are doing. |"));
1172  Serial.println(
1173  F("+------------------------------------------------------------------------------------+"));
1174  Serial.println();
1175 #else
1176  Serial.println(
1177  F("+------------------------------------------------------------------------------------+"));
1178  Serial.println(
1179  F("| Configuration settings |"));
1180  Serial.println(
1181  F("+------------------------------------------------------------------------------------+"));
1182 #if defined(GENERATE_KEYS_ATSHA204A)
1183  Serial.println(
1184  F("| * Guided key generation for ATSHA204A using ATSHA024A |"));
1185 #endif
1186 #if defined(GENERATE_KEYS_SOFT)
1187  Serial.println(
1188  F("| * Guided key generation for EEPROM using software |"));
1189 #endif
1190 #if defined(PERSONALIZE_ATSHA204A)
1191  Serial.println(
1192  F("| * Guided personalization/storage of keys in ATSHA204A |"));
1193 #endif
1194 #if defined(PERSONALIZE_SOFT)
1195  Serial.println(
1196  F("| * Guided personalization/storage of keys in EEPROM |"));
1197 #endif
1198 #if defined(PERSONALIZE_SOFT_RANDOM_SERIAL)
1199  Serial.println(
1200  F("| * Guided storage and generation of random serial in EEPROM |"));
1201 #endif
1202 #if defined(USE_SOFT_SIGNING)
1203  Serial.println(
1204  F("| * Software based personalization (no ATSHA204A usage whatsoever) |"));
1205 #else
1206  Serial.println(
1207  F("| * ATSHA204A based personalization |"));
1208 #endif
1209 #if defined(LOCK_ATSHA204A_CONFIGURATION)
1210  Serial.println(
1211  F("| * Will lock ATSHA204A configuration |"));
1212 #endif
1213 #if defined(SKIP_UART_CONFIRMATION)
1214  Serial.println(
1215  F("| * Will not require any UART confirmations |"));
1216 #endif
1217 #if defined(GENERATE_HMAC_KEY)
1218  Serial.print(
1219  F("| * Will generate HMAC key using "));
1220 #if defined(USE_SOFT_SIGNING)
1221  Serial.println(
1222  F("software |"));
1223 #else
1224  Serial.println(
1225  F("ATSHA204A |"));
1226 #endif
1227 #endif
1228 #if defined(STORE_HMAC_KEY)
1229  Serial.print(F("| * Will store HMAC key to "));
1230 #if defined(USE_SOFT_SIGNING)
1231  Serial.println(
1232  F("EEPROM |"));
1233 #else
1234  Serial.println(
1235  F("ATSHA204A |"));
1236 #endif
1237 #endif
1238 #if defined(GENERATE_AES_KEY)
1239  Serial.print(
1240  F("| * Will generate AES key using "));
1241 #if defined(USE_SOFT_SIGNING)
1242  Serial.println(
1243  F("software |"));
1244 #else
1245  Serial.println(
1246  F("ATSHA204A |"));
1247 #endif
1248 #endif
1249 #if defined(STORE_AES_KEY)
1250  Serial.println(
1251  F("| * Will store AES key to EEPROM |"));
1252 #endif
1253 #if defined(GENERATE_SOFT_SERIAL)
1254  Serial.println(
1255  F("| * Will generate soft serial using software |"));
1256 #endif
1257 #if defined(STORE_SOFT_SERIAL)
1258  Serial.println(
1259  F("| * Will store soft serial to EEPROM |"));
1260 #endif
1261 #if defined(PRINT_DETAILED_ATSHA204A_CONFIG)
1262  Serial.println(
1263  F("| * Will print detailed ATSHA204A configuration |"));
1264 #endif
1265 #if defined(RESET_EEPROM_PERSONALIZATION)
1266  Serial.println(
1267  F("| * Will reset EEPROM personalization data |"));
1268 #endif
1269  Serial.println(
1270  F("+------------------------------------------------------------------------------------+"));
1271  Serial.println();
1272 #endif // not NO_SETTINGS_DEFINED
1273  probe_and_print_peripherals();
1274 }
1275 
1276 static void print_ending(void)
1277 {
1278 #if defined(GUIDED_MODE) || defined(NO_SETTINGS_DEFINED)
1279  Serial.println(
1280  F("+------------------------------------------------------------------------------------+"));
1281  Serial.println(
1282  F("| WHAT TO DO NEXT? |"));
1283  Serial.println(
1284  F("+------------------------------------------------------------------------------------+"));
1285 #ifdef NO_SETTINGS_DEFINED
1286  Serial.println(
1287  F("| To proceed with the personalization, enable GENERATE_KEYS_ATSHA204A or |"));
1288  Serial.println(
1289  F("| GENERATE_KEYS_SOFT depending on what type of signing backend you plan to use. |"));
1290  Serial.println(
1291  F("| Both options will generate an AES key for encryption if you plan to use that. |"));
1292  Serial.println(
1293  F("| Recompile, upload and run the sketch again for further instructions. |"));
1294  Serial.println(
1295  F("+------------------------------------------------------------------------------------+"));
1296 #endif
1297 #ifdef GENERATE_KEYS_ATSHA204A
1298  Serial.println(
1299  F("| To proceed with the personalization, copy the keys shown in the Key copy section, |"));
1300  Serial.println(
1301  F("| and replace the corresponding definitions in the top of the sketch, then disable |"));
1302  Serial.println(
1303  F("| GENERATE_KEYS_ATSHA204A and enable PERSONALIZE_ATSHA204A. |"));
1304  Serial.println(
1305  F("+------------------------------------------------------------------------------------+"));
1306 #endif
1307 #ifdef GENERATE_KEYS_SOFT
1308  Serial.println(
1309  F("| To proceed with the personalization, copy the keys shown in the Key copy section, |"));
1310  Serial.println(
1311  F("| and replace the corresponding definitions in the top of the sketch, then disable |"));
1312  Serial.println(
1313  F("| GENERATE_KEYS_SOFT and enable PERSONALIZE_SOFT or PERSONALIZE_SOFT_RANDOM_SERIAL. |"));
1314  Serial.println(
1315  F("+------------------------------------------------------------------------------------+"));
1316 #endif
1317 #if defined(PERSONALIZE_ATSHA204A) ||\
1318  defined(PERSONALIZE_SOFT) ||\
1319  defined(PERSONALIZE_SOFT_RANDOM_SERIAL)
1320  Serial.println(
1321  F("| This device has now been personalized. Run this sketch with its current settings |"));
1322  Serial.println(
1323  F("| on all the devices in your network that have security enabled. |"));
1324  Serial.println(
1325  F("+------------------------------------------------------------------------------------+"));
1326 #endif
1327 #endif // GUIDED_MODE or NO_SETTINGS_DEFINED
1328 }
1329 
1330 static void probe_and_print_peripherals(void)
1331 {
1332  unique_id_t uniqueID;
1333 
1334  Serial.println(
1335  F("+------------------------------------------------------------------------------------+"));
1336  Serial.println(
1337  F("| Hardware security peripherals |"));
1338  Serial.println(
1339  F("+--------------+--------------+--------------+------------------------------+--------+"));
1340  Serial.println(
1341  F("| Device | Status | Revision | Serial number | Locked |"));
1342  Serial.println(
1343  F("+--------------+--------------+--------------+------------------------------+--------+"));
1344 #if defined(ARDUINO_ARCH_AVR)
1345  Serial.print(F("| AVR | DETECTED | N/A | "));
1346 #elif defined(ARDUINO_ARCH_ESP8266)
1347  Serial.print(F("| ESP8266 | DETECTED | N/A | "));
1348 #elif defined(ARDUINO_ARCH_SAMD)
1349  Serial.print(F("| SAMD | DETECTED | N/A | "));
1350 #elif defined(ARDUINO_ARCH_STM32F1)
1351  Serial.print(F("| STM32F1 | DETECTED | N/A | "));
1352 #elif defined(__linux__)
1353  Serial.print(F("| Linux | DETECTED | N/A | "));
1354 #else
1355  Serial.print(F("| Unknown | DETECTED | N/A | "));
1356 #endif
1357  if (hwUniqueID(&uniqueID)) {
1358  has_device_unique_id = true;
1359  print_hex_buffer(uniqueID, 9);
1360  Serial.println(F(" | N/A |"));
1361  } else {
1362  Serial.println(F("N/A (generation required) | N/A |"));
1363  }
1364  Serial.println(
1365  F("+--------------+--------------+--------------+------------------------------+--------+"));
1366 #ifndef USE_SOFT_SIGNING
1367  Serial.print(F("| ATSHA204A | "));
1368  ret_code = sha204.sha204c_wakeup(rx_buffer);
1369  if (ret_code != SHA204_SUCCESS) {
1370  ret_code = SHA204_SUCCESS; // Reset retcode to avoid false negative execution result
1371  Serial.println(F("NOT DETECTED | N/A | N/A | N/A |"));
1372  } else {
1373  uint8_t buffer[9];
1374  Serial.print(F("DETECTED | "));
1375  ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
1376  if (ret_code != SHA204_SUCCESS) {
1377  Serial.print(F("FAILED | "));
1378  } else {
1379  print_hex_buffer(&rx_buffer[SHA204_BUFFER_POS_DATA], 4);
1380  Serial.print(F(" | "));
1381  }
1382  if (!get_atsha204a_serial(buffer)) {
1383  memset(buffer, 0xFF, 9);
1384  Serial.print(F("FAILED | "));
1385  } else {
1386  print_hex_buffer(buffer, 9);
1387  Serial.print(F(" | "));
1388  }
1389  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
1390  if (ret_code != SHA204_SUCCESS) {
1391  Serial.println("FAILED |");
1392  } else {
1393  if (rx_buffer[SHA204_BUFFER_POS_DATA+3] == 0x00) {
1394  Serial.println("YES |");
1395  } else {
1396  Serial.println("NO |");
1397  }
1398  }
1399  }
1400  Serial.println(
1401  F("+--------------+--------------+--------------+------------------------------+--------+"));
1402 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
1403  Serial.println(
1404  F("+------------------------------------------------------------------------------------+"));
1405  Serial.println(
1406  F("| Current ATSHA204A Configuration |"));
1407  dump_detailed_atsha204a_configuration();
1408 #endif
1409 #endif // not USE_SOFT_SIGNING
1410  Serial.println();
1411 }
1412 
1413 static void print_eeprom_data(void)
1414 {
1415  uint8_t buffer[32];
1416 
1417  Serial.println(
1418  F("+------------------------------------------------------------------------------------+"));
1419  Serial.println(
1420  F("| EEPROM |"));
1421  Serial.println(
1422  F("+--------+--------+------------------------------------------------------------------+"));
1423  Serial.println(
1424  F("| Key ID | Status | Key |"));
1425  Serial.println(
1426  F("+--------+--------+------------------------------------------------------------------+"));
1427  Serial.print(F("| HMAC | "));
1428  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
1429  if (!memcmp(buffer, reset_buffer, 32)) {
1430  Serial.print(F("RESET | "));
1431  } else {
1432  Serial.print(F("OK | "));
1433  }
1434  print_hex_buffer(buffer, 32);
1435  Serial.println(F(" |"));
1436  Serial.print(F("| AES | "));
1437  hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
1438  if (!memcmp(buffer, reset_buffer, 16)) {
1439  Serial.print(F("RESET | "));
1440  } else {
1441  Serial.print(F("OK | "));
1442  }
1443  print_hex_buffer(buffer, 16);
1444  Serial.println(F(" |"));
1445  Serial.print(F("| SERIAL | "));
1446  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
1447  if (!memcmp(buffer, reset_buffer, 9)) {
1448  if (has_device_unique_id) {
1449  Serial.println(F("N/A | Device unique serial, not stored in EEPROM |"));
1450  } else {
1451  Serial.print(F("RESET | "));
1452  print_hex_buffer(buffer, 9);
1453  Serial.println(F(" |"));
1454  }
1455  } else {
1456  Serial.print(F("OK | "));
1457  print_hex_buffer(buffer, 9);
1458  Serial.println(F(" |"));
1459  }
1460  Serial.println(
1461  F("+--------+--------+------------------------------------------------------------------+"));
1462  Serial.println();
1463 }
1464 
1465 static void print_whitelisting_entry(void)
1466 {
1467  uint8_t buffer[9];
1468 #ifdef USE_SOFT_SIGNING
1469  unique_id_t uniqueID;
1470  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
1471  if (!memcmp(buffer, reset_buffer, 9)) {
1472  // Serial reset in EEPROM, check for unique ID
1473  if (hwUniqueID(&uniqueID)) {
1474  memcpy(buffer, uniqueID, 9);
1475  }
1476  }
1477 #else
1478  // If ATSHA204A is used, use that serial here
1479  if (!get_atsha204a_serial(buffer)) {
1480  memset(buffer, 0xFF, 9);
1481  }
1482 #endif
1483  Serial.println(
1484  F("+------------------------------------------------------------------------------------+"));
1485  Serial.println(
1486  F("| This nodes whitelist entry on other nodes |"));
1487  Serial.println(
1488  F("+------------------------------------------------------------------------------------+"));
1489  Serial.print(F("{.nodeId = <ID of this node>,.serial = {"));
1490  print_c_friendly_hex_buffer(buffer, 9);
1491  Serial.println(F("}}"));
1492  Serial.println(
1493  F("+------------------------------------------------------------------------------------+"));
1494 }
1495 
1496 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
1497 
1498 static void dump_detailed_atsha204a_configuration(void)
1499 {
1500  Serial.println(
1501  F("+---------------------------------------------------------------++-------------------+"));
1502  Serial.println(
1503  F("| Fieldname || Data |"));
1504  Serial.println(
1505  F("+-------------------------------+-------------------------------++---------+---------+"));
1506  for (int i=0; i < 88; i += 4) {
1507  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
1508  if (ret_code != SHA204_SUCCESS) {
1509  Serial.println(
1510  F("+------------------------------------------------------------------------------------+"));
1511  halt(false);
1512  }
1513  if (i == 0x00) {
1514  Serial.print(F("| SN[0:1] | SN[2:3] || "));
1515  for (int j=0; j<4; j++) {
1516  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1517  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1518  }
1519  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1520  if (j == 1) {
1521  Serial.print(F(" | "));
1522  } else if (j < 3) {
1523  Serial.print(F(" "));
1524  }
1525  }
1526  Serial.println(F(" |"));
1527  Serial.println(
1528  F("+-------------------------------+-------------------------------++---------+---------+"));
1529  } else if (i == 0x04) {
1530  Serial.print(F("| Revnum || "));
1531  for (int j=0; j<4; j++) {
1532  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1533  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1534  }
1535  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1536  if (j < 3) {
1537  Serial.print(F(" "));
1538  }
1539  }
1540  Serial.println(F(" |"));
1541  Serial.println(
1542  F("+---------------------------------------------------------------++-------------------+"));
1543  } else if (i == 0x08) {
1544  Serial.print(F("| SN[4:7] || "));
1545  for (int j=0; j<4; j++) {
1546  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1547  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1548  }
1549  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1550  if (j < 3) {
1551  Serial.print(F(" "));
1552  }
1553  }
1554  Serial.println(F(" |"));
1555  Serial.println(
1556  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1557  } else if (i == 0x0C) {
1558  Serial.print(F("| SN[8] | Reserved13 | I2CEnable | Reserved15 || "));
1559  for (int j=0; j<4; j++) {
1560  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1561  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1562  }
1563  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1564  if (j < 3) {
1565  Serial.print(F(" | "));
1566  } else {
1567  Serial.println(F(" |"));
1568  }
1569  }
1570  Serial.println(
1571  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1572  } else if (i == 0x10) {
1573  Serial.print(F("| I2CAddress | TempOffset | OTPmode | SelectorMode || "));
1574  for (int j=0; j<4; j++) {
1575  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1576  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1577  }
1578  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1579  if (j < 3) {
1580  Serial.print(F(" | "));
1581  } else {
1582  Serial.println(F(" |"));
1583  }
1584  }
1585  Serial.println(
1586  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1587  } else if (i == 0x14) {
1588  Serial.print(F("| SlotConfig00 | SlotConfig01 || "));
1589  for (int j=0; j<4; j++) {
1590  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1591  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1592  }
1593  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1594  if (j == 1) {
1595  Serial.print(F(" | "));
1596  } else if (j < 3) {
1597  Serial.print(F(" "));
1598  }
1599  }
1600  Serial.println(F(" |"));
1601  Serial.println(
1602  F("+-------------------------------+-------------------------------++---------+---------+"));
1603  } else if (i == 0x18) {
1604  Serial.print(F("| SlotConfig02 | SlotConfig03 || "));
1605  for (int j=0; j<4; j++) {
1606  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1607  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1608  }
1609  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1610  if (j == 1) {
1611  Serial.print(F(" | "));
1612  } else if (j < 3) {
1613  Serial.print(F(" "));
1614  }
1615  }
1616  Serial.println(F(" |"));
1617  Serial.println(
1618  F("+-------------------------------+-------------------------------++---------+---------+"));
1619  } else if (i == 0x1C) {
1620  Serial.print(F("| SlotConfig04 | SlotConfig05 || "));
1621  for (int j=0; j<4; j++) {
1622  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1623  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1624  }
1625  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1626  if (j == 1) {
1627  Serial.print(F(" | "));
1628  } else if (j < 3) {
1629  Serial.print(F(" "));
1630  }
1631  }
1632  Serial.println(F(" |"));
1633  Serial.println(
1634  F("+-------------------------------+-------------------------------++---------+---------+"));
1635  } else if (i == 0x20) {
1636  Serial.print(F("| SlotConfig06 | SlotConfig07 || "));
1637  for (int j=0; j<4; j++) {
1638  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1639  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1640  }
1641  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1642  if (j == 1) {
1643  Serial.print(F(" | "));
1644  } else if (j < 3) {
1645  Serial.print(F(" "));
1646  }
1647  }
1648  Serial.println(F(" |"));
1649  Serial.println(
1650  F("+-------------------------------+-------------------------------++---------+---------+"));
1651  } else if (i == 0x24) {
1652  Serial.print(F("| SlotConfig08 | SlotConfig09 || "));
1653  for (int j=0; j<4; j++) {
1654  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1655  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1656  }
1657  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1658  if (j == 1) {
1659  Serial.print(F(" | "));
1660  } else if (j < 3) {
1661  Serial.print(F(" "));
1662  }
1663  }
1664  Serial.println(F(" |"));
1665  Serial.println(
1666  F("+-------------------------------+-------------------------------++---------+---------+"));
1667  } else if (i == 0x28) {
1668  Serial.print(F("| SlotConfig0A | SlotConfig0B || "));
1669  for (int j=0; j<4; j++) {
1670  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1671  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1672  }
1673  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1674  if (j == 1) {
1675  Serial.print(F(" | "));
1676  } else if (j < 3) {
1677  Serial.print(F(" "));
1678  }
1679  }
1680  Serial.println(F(" |"));
1681  Serial.println(
1682  F("+-------------------------------+-------------------------------++---------+---------+"));
1683  } else if (i == 0x2C) {
1684  Serial.print(F("| SlotConfig0C | SlotConfig0D || "));
1685  for (int j=0; j<4; j++) {
1686  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1687  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1688  }
1689  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1690  if (j == 1) {
1691  Serial.print(F(" | "));
1692  } else if (j < 3) {
1693  Serial.print(F(" "));
1694  }
1695  }
1696  Serial.println(F(" |"));
1697  Serial.println(
1698  F("+-------------------------------+-------------------------------++---------+---------+"));
1699  } else if (i == 0x30) {
1700  Serial.print(F("| SlotConfig0E | SlotConfig0F || "));
1701  for (int j=0; j<4; j++) {
1702  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1703  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1704  }
1705  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1706  if (j == 1) {
1707  Serial.print(F(" | "));
1708  } else if (j < 3) {
1709  Serial.print(F(" "));
1710  }
1711  }
1712  Serial.println(F(" |"));
1713  Serial.println(
1714  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1715  } else if (i == 0x34) {
1716  Serial.print(F("| UseFlag00 | UpdateCount00 | UseFlag01 | UpdateCount01 || "));
1717  for (int j=0; j<4; j++) {
1718  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1719  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1720  }
1721  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1722  if (j < 3) {
1723  Serial.print(F(" | "));
1724  } else {
1725  Serial.println(F(" |"));
1726  }
1727  }
1728  Serial.println(
1729  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1730  } else if (i == 0x38) {
1731  Serial.print(F("| UseFlag02 | UpdateCount02 | UseFlag03 | UpdateCount03 || "));
1732  for (int j=0; j<4; j++) {
1733  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1734  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1735  }
1736  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1737  if (j < 3) {
1738  Serial.print(F(" | "));
1739  } else {
1740  Serial.println(F(" |"));
1741  }
1742  }
1743  Serial.println(
1744  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1745  } else if (i == 0x3C) {
1746  Serial.print(F("| UseFlag04 | UpdateCount04 | UseFlag05 | UpdateCount05 || "));
1747  for (int j=0; j<4; j++) {
1748  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1749  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1750  }
1751  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1752  if (j < 3) {
1753  Serial.print(F(" | "));
1754  } else {
1755  Serial.println(F(" |"));
1756  }
1757  }
1758  Serial.println(
1759  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1760  } else if (i == 0x40) {
1761  Serial.print(F("| UseFlag06 | UpdateCount06 | UseFlag07 | UpdateCount07 || "));
1762  for (int j=0; j<4; j++) {
1763  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1764  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1765  }
1766  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1767  if (j < 3) {
1768  Serial.print(F(" | "));
1769  } else {
1770  Serial.println(F(" |"));
1771  }
1772  }
1773  Serial.println(
1774  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1775  } else if (i == 0x44) {
1776  Serial.print(F("| LastKeyUse[0:3] || "));
1777  for (int j=0; j<4; j++) {
1778  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1779  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1780  }
1781  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1782  if (j < 3) {
1783  Serial.print(F(" "));
1784  }
1785  }
1786  Serial.println(F(" |"));
1787  Serial.println(
1788  F("+---------------------------------------------------------------++-------------------+"));
1789  } else if (i == 0x48) {
1790  Serial.print(F("| LastKeyUse[4:7] || "));
1791  for (int j=0; j<4; j++) {
1792  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1793  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1794  }
1795  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1796  if (j < 3) {
1797  Serial.print(F(" "));
1798  }
1799  }
1800  Serial.println(F(" |"));
1801  Serial.println(
1802  F("+---------------------------------------------------------------++-------------------+"));
1803  } else if (i == 0x4C) {
1804  Serial.print(F("| LastKeyUse[8:B] || "));
1805  for (int j=0; j<4; j++) {
1806  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1807  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1808  }
1809  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1810  if (j < 3) {
1811  Serial.print(F(" "));
1812  }
1813  }
1814  Serial.println(F(" |"));
1815  Serial.println(
1816  F("+---------------------------------------------------------------++-------------------+"));
1817  } else if (i == 0x50) {
1818  Serial.print(F("| LastKeyUse[C:F] || "));
1819  for (int j=0; j<4; j++) {
1820  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1821  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1822  }
1823  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1824  if (j < 3) {
1825  Serial.print(F(" "));
1826  }
1827  }
1828  Serial.println(F(" |"));
1829  Serial.println(
1830  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1831  } else if (i == 0x54) {
1832  Serial.print(F("| UserExtra | Selector | LockValue | LockConfig || "));
1833  for (int j=0; j<4; j++) {
1834  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1835  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1836  }
1837  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1838  if (j < 3) {
1839  Serial.print(F(" | "));
1840  } else {
1841  Serial.println(F(" |"));
1842  }
1843  }
1844  Serial.println(
1845  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1846  }
1847  }
1848 }
1849 #endif // PRINT_DETAILED_ATSHA204A_CONFIG
1850 
1851 // Doxygen specific constructs, not included when built normally
1852 // This is used to enable disabled macros/definitions to be included in the documentation as well.
1853 #if DOXYGEN
1854 #define GENERATE_KEYS_ATSHA204A
1855 #define GENERATE_KEYS_SOFT
1856 #define PERSONALIZE_ATSHA204A
1857 #define PERSONALIZE_SOFT
1858 #define PERSONALIZE_SOFT_RANDOM_SERIAL
1859 #define USE_SOFT_SIGNING
1860 #define LOCK_ATSHA204A_CONFIGURATION
1861 #define SKIP_UART_CONFIRMATION
1862 #define GENERATE_HMAC_KEY
1863 #define STORE_HMAC_KEY
1864 #define GENERATE_AES_KEY
1865 #define STORE_AES_KEY
1866 #define GENERATE_SOFT_SERIAL
1867 #define STORE_SOFT_SERIAL
1868 #define PRINT_DETAILED_ATSHA204A_CONFIG
1869 #define RESET_EEPROM_PERSONALIZATION
1870 #endif
1871 
data
char data[MAX_PAYLOAD_SIZE+1]
Buffer for raw payload data.
Definition: MyMessage.h:653
SHA204_SUCCESS
#define SHA204_SUCCESS
Function succeeded.
Definition: sha204_lib_return_codes.h:27
sha204Pin
const int sha204Pin
The IO pin to use for ATSHA204A.
Definition: SecurityPersonalizer.ino:416
atsha204Class::sha204c_wakeup
uint8_t sha204c_wakeup(uint8_t *response)
Wake up device.
EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS
#define EEPROM_PERSONALIZATION_CHECKSUM_ADDRESS
Personalization checksum (set by SecurityPersonalizer.ino)
Definition: MyEepromAddresses.h:66
SIZE_PERSONALIZATION_CHECKSUM
#define SIZE_PERSONALIZATION_CHECKSUM
Size personalization checksum.
Definition: MyEepromAddresses.h:40
SIZE_SIGNING_SOFT_HMAC_KEY
#define SIZE_SIGNING_SOFT_HMAC_KEY
Size soft signing HMAC key.
Definition: MyEepromAddresses.h:47
atsha204Class::sha204m_read
uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address)
Read from device.
loop
void loop()
Sketch execution code (unused)
Definition: SecurityPersonalizer.ino:480
atsha204Class::calculateAndUpdateCrc
uint16_t calculateAndUpdateCrc(uint8_t length, uint8_t *data, uint16_t current_crc)
Calculates and update crc.
SIZE_RF_ENCRYPTION_AES_KEY
#define SIZE_RF_ENCRYPTION_AES_KEY
Size RF AES encryption key.
Definition: MyEepromAddresses.h:49
MY_SOFT_SERIAL
#define MY_SOFT_SERIAL
The user-defined soft serial to use for soft signing unless GENERATE_SOFT_SERIAL is set.
Definition: SecurityPersonalizer.ino:53
hwUniqueID
bool hwUniqueID(unique_id_t *uniqueID)
doYield
void doYield(void)
EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS
#define EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS
Address RF AES encryption key. This is set with SecurityPersonalizer.ino.
Definition: MyEepromAddresses.h:84
atsha204Class::sha204c_resync
uint8_t sha204c_resync(uint8_t size, uint8_t *response)
Resyncronize the device.
sha204
atsha204Class sha204(sha204Pin)
atsha204Class
atsha204Class::sha204m_dev_rev
uint8_t sha204m_dev_rev(uint8_t *tx_buffer, uint8_t *rx_buffer)
Read device revision.
unique_id_t
uint8_t unique_id_t[16]
unique ID
Definition: MyHwHAL.h:77
sha204_lib_return_codes.h
SHA204 Library Return Code Definitions.
SHA204_RESYNC_WITH_WAKEUP
#define SHA204_RESYNC_WITH_WAKEUP
re-synchronization succeeded, but only after generating a Wake-up
Definition: sha204_lib_return_codes.h:40
MY_AES_KEY
#define MY_AES_KEY
The user-defined AES key to store in EEPROM unless GENERATE_AES_KEY is set.
Definition: SecurityPersonalizer.ino:50
atsha204Class::sha204m_random
uint8_t sha204m_random(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t mode)
Generate random data.
SIZE_SIGNING_SOFT_SERIAL
#define SIZE_SIGNING_SOFT_SERIAL
Size soft signing serial.
Definition: MyEepromAddresses.h:48
setup
void setup()
Sketch setup code (all personalization is done here as it is a run-once sketch)
Definition: SecurityPersonalizer.ino:435
atsha204Class::sha204m_execute
uint8_t sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2, uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3, uint8_t *data3, uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
Execute command.
atsha204Class::getSerialNumber
uint8_t getSerialNumber(uint8_t *response)
Gets the serial number.
StdInOutStream::available
int available()
This function does nothing.
atsha204Class
Definition: sha204_library.h:303
MySensors.h
API declaration for MySensors.
EEPROM_SIGNING_SOFT_SERIAL_ADDRESS
#define EEPROM_SIGNING_SOFT_SERIAL_ADDRESS
Address soft signing serial key. This is set with SecurityPersonalizer.ino.
Definition: MyEepromAddresses.h:82
StdInOutStream::read
int read()
Reads 1 key pressed from the keyboard.
EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS
#define EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS
Address soft signing HMAC key. This is set with SecurityPersonalizer.ino.
Definition: MyEepromAddresses.h:80
MY_SIGNING_ATSHA204_PIN
#define MY_SIGNING_ATSHA204_PIN
A3 - pin where ATSHA204 is attached.
Definition: SecureActuator.ino:69
MY_HMAC_KEY
#define MY_HMAC_KEY
The user-defined HMAC key to use unless GENERATE_HMAC_KEY is set.
Definition: SecurityPersonalizer.ino:47