MySensors Library & Examples  2.3.2-62-ge298769
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-2022 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_MEGAAVR)
1347  Serial.print(F("| megaAVR | DETECTED | N/A | "));
1348 #elif defined(ARDUINO_ARCH_ESP8266)
1349  Serial.print(F("| ESP8266 | DETECTED | N/A | "));
1350 #elif defined(ARDUINO_ARCH_SAMD)
1351  Serial.print(F("| SAMD | DETECTED | N/A | "));
1352 #elif defined(ARDUINO_ARCH_STM32F1)
1353  Serial.print(F("| STM32F1 | DETECTED | N/A | "));
1354 #elif defined(__linux__)
1355  Serial.print(F("| Linux | DETECTED | N/A | "));
1356 #else
1357  Serial.print(F("| Unknown | DETECTED | N/A | "));
1358 #endif
1359  if (hwUniqueID(&uniqueID)) {
1360  has_device_unique_id = true;
1361  print_hex_buffer(uniqueID, 9);
1362  Serial.println(F(" | N/A |"));
1363  } else {
1364  Serial.println(F("N/A (generation required) | N/A |"));
1365  }
1366  Serial.println(
1367  F("+--------------+--------------+--------------+------------------------------+--------+"));
1368 #ifndef USE_SOFT_SIGNING
1369  Serial.print(F("| ATSHA204A | "));
1370  ret_code = sha204.sha204c_wakeup(rx_buffer);
1371  if (ret_code != SHA204_SUCCESS) {
1372  ret_code = SHA204_SUCCESS; // Reset retcode to avoid false negative execution result
1373  Serial.println(F("NOT DETECTED | N/A | N/A | N/A |"));
1374  } else {
1375  uint8_t buffer[9];
1376  Serial.print(F("DETECTED | "));
1377  ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
1378  if (ret_code != SHA204_SUCCESS) {
1379  Serial.print(F("FAILED | "));
1380  } else {
1381  print_hex_buffer(&rx_buffer[SHA204_BUFFER_POS_DATA], 4);
1382  Serial.print(F(" | "));
1383  }
1384  if (!get_atsha204a_serial(buffer)) {
1385  memset(buffer, 0xFF, 9);
1386  Serial.print(F("FAILED | "));
1387  } else {
1388  print_hex_buffer(buffer, 9);
1389  Serial.print(F(" | "));
1390  }
1391  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
1392  if (ret_code != SHA204_SUCCESS) {
1393  Serial.println("FAILED |");
1394  } else {
1395  if (rx_buffer[SHA204_BUFFER_POS_DATA+3] == 0x00) {
1396  Serial.println("YES |");
1397  } else {
1398  Serial.println("NO |");
1399  }
1400  }
1401  }
1402  Serial.println(
1403  F("+--------------+--------------+--------------+------------------------------+--------+"));
1404 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
1405  Serial.println(
1406  F("+------------------------------------------------------------------------------------+"));
1407  Serial.println(
1408  F("| Current ATSHA204A Configuration |"));
1409  dump_detailed_atsha204a_configuration();
1410 #endif
1411 #endif // not USE_SOFT_SIGNING
1412  Serial.println();
1413 }
1414 
1415 static void print_eeprom_data(void)
1416 {
1417  uint8_t buffer[32];
1418 
1419  Serial.println(
1420  F("+------------------------------------------------------------------------------------+"));
1421  Serial.println(
1422  F("| EEPROM |"));
1423  Serial.println(
1424  F("+--------+--------+------------------------------------------------------------------+"));
1425  Serial.println(
1426  F("| Key ID | Status | Key |"));
1427  Serial.println(
1428  F("+--------+--------+------------------------------------------------------------------+"));
1429  Serial.print(F("| HMAC | "));
1430  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
1431  if (!memcmp(buffer, reset_buffer, 32)) {
1432  Serial.print(F("RESET | "));
1433  } else {
1434  Serial.print(F("OK | "));
1435  }
1436  print_hex_buffer(buffer, 32);
1437  Serial.println(F(" |"));
1438  Serial.print(F("| AES | "));
1439  hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
1440  if (!memcmp(buffer, reset_buffer, 16)) {
1441  Serial.print(F("RESET | "));
1442  } else {
1443  Serial.print(F("OK | "));
1444  }
1445  print_hex_buffer(buffer, 16);
1446  Serial.println(F(" |"));
1447  Serial.print(F("| SERIAL | "));
1448  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
1449  if (!memcmp(buffer, reset_buffer, 9)) {
1450  if (has_device_unique_id) {
1451  Serial.println(F("N/A | Device unique serial, not stored in EEPROM |"));
1452  } else {
1453  Serial.print(F("RESET | "));
1454  print_hex_buffer(buffer, 9);
1455  Serial.println(F(" |"));
1456  }
1457  } else {
1458  Serial.print(F("OK | "));
1459  print_hex_buffer(buffer, 9);
1460  Serial.println(F(" |"));
1461  }
1462  Serial.println(
1463  F("+--------+--------+------------------------------------------------------------------+"));
1464  Serial.println();
1465 }
1466 
1467 static void print_whitelisting_entry(void)
1468 {
1469  uint8_t buffer[9];
1470 #ifdef USE_SOFT_SIGNING
1471  unique_id_t uniqueID;
1472  hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
1473  if (!memcmp(buffer, reset_buffer, 9)) {
1474  // Serial reset in EEPROM, check for unique ID
1475  if (hwUniqueID(&uniqueID)) {
1476  memcpy(buffer, uniqueID, 9);
1477  }
1478  }
1479 #else
1480  // If ATSHA204A is used, use that serial here
1481  if (!get_atsha204a_serial(buffer)) {
1482  memset(buffer, 0xFF, 9);
1483  }
1484 #endif
1485  Serial.println(
1486  F("+------------------------------------------------------------------------------------+"));
1487  Serial.println(
1488  F("| This nodes whitelist entry on other nodes |"));
1489  Serial.println(
1490  F("+------------------------------------------------------------------------------------+"));
1491  Serial.print(F("{.nodeId = <ID of this node>,.serial = {"));
1492  print_c_friendly_hex_buffer(buffer, 9);
1493  Serial.println(F("}}"));
1494  Serial.println(
1495  F("+------------------------------------------------------------------------------------+"));
1496 }
1497 
1498 #ifdef PRINT_DETAILED_ATSHA204A_CONFIG
1499 
1500 static void dump_detailed_atsha204a_configuration(void)
1501 {
1502  Serial.println(
1503  F("+---------------------------------------------------------------++-------------------+"));
1504  Serial.println(
1505  F("| Fieldname || Data |"));
1506  Serial.println(
1507  F("+-------------------------------+-------------------------------++---------+---------+"));
1508  for (int i=0; i < 88; i += 4) {
1509  ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
1510  if (ret_code != SHA204_SUCCESS) {
1511  Serial.println(
1512  F("+------------------------------------------------------------------------------------+"));
1513  halt(false);
1514  }
1515  if (i == 0x00) {
1516  Serial.print(F("| SN[0:1] | SN[2:3] || "));
1517  for (int j=0; j<4; j++) {
1518  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1519  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1520  }
1521  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1522  if (j == 1) {
1523  Serial.print(F(" | "));
1524  } else if (j < 3) {
1525  Serial.print(F(" "));
1526  }
1527  }
1528  Serial.println(F(" |"));
1529  Serial.println(
1530  F("+-------------------------------+-------------------------------++---------+---------+"));
1531  } else if (i == 0x04) {
1532  Serial.print(F("| Revnum || "));
1533  for (int j=0; j<4; j++) {
1534  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1535  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1536  }
1537  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1538  if (j < 3) {
1539  Serial.print(F(" "));
1540  }
1541  }
1542  Serial.println(F(" |"));
1543  Serial.println(
1544  F("+---------------------------------------------------------------++-------------------+"));
1545  } else if (i == 0x08) {
1546  Serial.print(F("| SN[4:7] || "));
1547  for (int j=0; j<4; j++) {
1548  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1549  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1550  }
1551  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1552  if (j < 3) {
1553  Serial.print(F(" "));
1554  }
1555  }
1556  Serial.println(F(" |"));
1557  Serial.println(
1558  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1559  } else if (i == 0x0C) {
1560  Serial.print(F("| SN[8] | Reserved13 | I2CEnable | Reserved15 || "));
1561  for (int j=0; j<4; j++) {
1562  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1563  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1564  }
1565  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1566  if (j < 3) {
1567  Serial.print(F(" | "));
1568  } else {
1569  Serial.println(F(" |"));
1570  }
1571  }
1572  Serial.println(
1573  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1574  } else if (i == 0x10) {
1575  Serial.print(F("| I2CAddress | TempOffset | OTPmode | SelectorMode || "));
1576  for (int j=0; j<4; j++) {
1577  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1578  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1579  }
1580  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1581  if (j < 3) {
1582  Serial.print(F(" | "));
1583  } else {
1584  Serial.println(F(" |"));
1585  }
1586  }
1587  Serial.println(
1588  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1589  } else if (i == 0x14) {
1590  Serial.print(F("| SlotConfig00 | SlotConfig01 || "));
1591  for (int j=0; j<4; j++) {
1592  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1593  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1594  }
1595  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1596  if (j == 1) {
1597  Serial.print(F(" | "));
1598  } else if (j < 3) {
1599  Serial.print(F(" "));
1600  }
1601  }
1602  Serial.println(F(" |"));
1603  Serial.println(
1604  F("+-------------------------------+-------------------------------++---------+---------+"));
1605  } else if (i == 0x18) {
1606  Serial.print(F("| SlotConfig02 | SlotConfig03 || "));
1607  for (int j=0; j<4; j++) {
1608  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1609  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1610  }
1611  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1612  if (j == 1) {
1613  Serial.print(F(" | "));
1614  } else if (j < 3) {
1615  Serial.print(F(" "));
1616  }
1617  }
1618  Serial.println(F(" |"));
1619  Serial.println(
1620  F("+-------------------------------+-------------------------------++---------+---------+"));
1621  } else if (i == 0x1C) {
1622  Serial.print(F("| SlotConfig04 | SlotConfig05 || "));
1623  for (int j=0; j<4; j++) {
1624  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1625  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1626  }
1627  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1628  if (j == 1) {
1629  Serial.print(F(" | "));
1630  } else if (j < 3) {
1631  Serial.print(F(" "));
1632  }
1633  }
1634  Serial.println(F(" |"));
1635  Serial.println(
1636  F("+-------------------------------+-------------------------------++---------+---------+"));
1637  } else if (i == 0x20) {
1638  Serial.print(F("| SlotConfig06 | SlotConfig07 || "));
1639  for (int j=0; j<4; j++) {
1640  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1641  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1642  }
1643  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1644  if (j == 1) {
1645  Serial.print(F(" | "));
1646  } else if (j < 3) {
1647  Serial.print(F(" "));
1648  }
1649  }
1650  Serial.println(F(" |"));
1651  Serial.println(
1652  F("+-------------------------------+-------------------------------++---------+---------+"));
1653  } else if (i == 0x24) {
1654  Serial.print(F("| SlotConfig08 | SlotConfig09 || "));
1655  for (int j=0; j<4; j++) {
1656  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1657  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1658  }
1659  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1660  if (j == 1) {
1661  Serial.print(F(" | "));
1662  } else if (j < 3) {
1663  Serial.print(F(" "));
1664  }
1665  }
1666  Serial.println(F(" |"));
1667  Serial.println(
1668  F("+-------------------------------+-------------------------------++---------+---------+"));
1669  } else if (i == 0x28) {
1670  Serial.print(F("| SlotConfig0A | SlotConfig0B || "));
1671  for (int j=0; j<4; j++) {
1672  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1673  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1674  }
1675  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1676  if (j == 1) {
1677  Serial.print(F(" | "));
1678  } else if (j < 3) {
1679  Serial.print(F(" "));
1680  }
1681  }
1682  Serial.println(F(" |"));
1683  Serial.println(
1684  F("+-------------------------------+-------------------------------++---------+---------+"));
1685  } else if (i == 0x2C) {
1686  Serial.print(F("| SlotConfig0C | SlotConfig0D || "));
1687  for (int j=0; j<4; j++) {
1688  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1689  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1690  }
1691  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1692  if (j == 1) {
1693  Serial.print(F(" | "));
1694  } else if (j < 3) {
1695  Serial.print(F(" "));
1696  }
1697  }
1698  Serial.println(F(" |"));
1699  Serial.println(
1700  F("+-------------------------------+-------------------------------++---------+---------+"));
1701  } else if (i == 0x30) {
1702  Serial.print(F("| SlotConfig0E | SlotConfig0F || "));
1703  for (int j=0; j<4; j++) {
1704  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1705  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1706  }
1707  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1708  if (j == 1) {
1709  Serial.print(F(" | "));
1710  } else if (j < 3) {
1711  Serial.print(F(" "));
1712  }
1713  }
1714  Serial.println(F(" |"));
1715  Serial.println(
1716  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1717  } else if (i == 0x34) {
1718  Serial.print(F("| UseFlag00 | UpdateCount00 | UseFlag01 | UpdateCount01 || "));
1719  for (int j=0; j<4; j++) {
1720  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1721  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1722  }
1723  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1724  if (j < 3) {
1725  Serial.print(F(" | "));
1726  } else {
1727  Serial.println(F(" |"));
1728  }
1729  }
1730  Serial.println(
1731  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1732  } else if (i == 0x38) {
1733  Serial.print(F("| UseFlag02 | UpdateCount02 | UseFlag03 | UpdateCount03 || "));
1734  for (int j=0; j<4; j++) {
1735  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1736  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1737  }
1738  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1739  if (j < 3) {
1740  Serial.print(F(" | "));
1741  } else {
1742  Serial.println(F(" |"));
1743  }
1744  }
1745  Serial.println(
1746  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1747  } else if (i == 0x3C) {
1748  Serial.print(F("| UseFlag04 | UpdateCount04 | UseFlag05 | UpdateCount05 || "));
1749  for (int j=0; j<4; j++) {
1750  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1751  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1752  }
1753  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1754  if (j < 3) {
1755  Serial.print(F(" | "));
1756  } else {
1757  Serial.println(F(" |"));
1758  }
1759  }
1760  Serial.println(
1761  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1762  } else if (i == 0x40) {
1763  Serial.print(F("| UseFlag06 | UpdateCount06 | UseFlag07 | UpdateCount07 || "));
1764  for (int j=0; j<4; j++) {
1765  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1766  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1767  }
1768  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1769  if (j < 3) {
1770  Serial.print(F(" | "));
1771  } else {
1772  Serial.println(F(" |"));
1773  }
1774  }
1775  Serial.println(
1776  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1777  } else if (i == 0x44) {
1778  Serial.print(F("| LastKeyUse[0:3] || "));
1779  for (int j=0; j<4; j++) {
1780  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1781  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1782  }
1783  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1784  if (j < 3) {
1785  Serial.print(F(" "));
1786  }
1787  }
1788  Serial.println(F(" |"));
1789  Serial.println(
1790  F("+---------------------------------------------------------------++-------------------+"));
1791  } else if (i == 0x48) {
1792  Serial.print(F("| LastKeyUse[4:7] || "));
1793  for (int j=0; j<4; j++) {
1794  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1795  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1796  }
1797  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1798  if (j < 3) {
1799  Serial.print(F(" "));
1800  }
1801  }
1802  Serial.println(F(" |"));
1803  Serial.println(
1804  F("+---------------------------------------------------------------++-------------------+"));
1805  } else if (i == 0x4C) {
1806  Serial.print(F("| LastKeyUse[8:B] || "));
1807  for (int j=0; j<4; j++) {
1808  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1809  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1810  }
1811  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1812  if (j < 3) {
1813  Serial.print(F(" "));
1814  }
1815  }
1816  Serial.println(F(" |"));
1817  Serial.println(
1818  F("+---------------------------------------------------------------++-------------------+"));
1819  } else if (i == 0x50) {
1820  Serial.print(F("| LastKeyUse[C:F] || "));
1821  for (int j=0; j<4; j++) {
1822  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1823  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1824  }
1825  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1826  if (j < 3) {
1827  Serial.print(F(" "));
1828  }
1829  }
1830  Serial.println(F(" |"));
1831  Serial.println(
1832  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1833  } else if (i == 0x54) {
1834  Serial.print(F("| UserExtra | Selector | LockValue | LockConfig || "));
1835  for (int j=0; j<4; j++) {
1836  if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
1837  Serial.print('0'); // Because Serial.print does not 0-pad HEX
1838  }
1839  Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
1840  if (j < 3) {
1841  Serial.print(F(" | "));
1842  } else {
1843  Serial.println(F(" |"));
1844  }
1845  }
1846  Serial.println(
1847  F("+---------------+---------------+---------------+---------------++----+----+----+----+"));
1848  }
1849  }
1850 }
1851 #endif // PRINT_DETAILED_ATSHA204A_CONFIG
1852 
1853 // Doxygen specific constructs, not included when built normally
1854 // This is used to enable disabled macros/definitions to be included in the documentation as well.
1855 #if DOXYGEN
1856 #define GENERATE_KEYS_ATSHA204A
1857 #define GENERATE_KEYS_SOFT
1858 #define PERSONALIZE_ATSHA204A
1859 #define PERSONALIZE_SOFT
1860 #define PERSONALIZE_SOFT_RANDOM_SERIAL
1861 #define USE_SOFT_SIGNING
1862 #define LOCK_ATSHA204A_CONFIGURATION
1863 #define SKIP_UART_CONFIRMATION
1864 #define GENERATE_HMAC_KEY
1865 #define STORE_HMAC_KEY
1866 #define GENERATE_AES_KEY
1867 #define STORE_AES_KEY
1868 #define GENERATE_SOFT_SERIAL
1869 #define STORE_SOFT_SERIAL
1870 #define PRINT_DETAILED_ATSHA204A_CONFIG
1871 #define RESET_EEPROM_PERSONALIZATION
1872 #endif
1873 
data
char data[MAX_PAYLOAD_SIZE+1]
Buffer for raw payload data.
Definition: MyMessage.h:654
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:70
SIZE_PERSONALIZATION_CHECKSUM
#define SIZE_PERSONALIZATION_CHECKSUM
Size personalization checksum.
Definition: MyEepromAddresses.h:44
SIZE_SIGNING_SOFT_HMAC_KEY
#define SIZE_SIGNING_SOFT_HMAC_KEY
Size soft signing HMAC key.
Definition: MyEepromAddresses.h:51
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:53
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:88
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:81
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:52
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.
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:86
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:84
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