Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. [security] Introducing signing support to MySensors

[security] Introducing signing support to MySensors

Scheduled Pinned Locked Moved Development
security
491 Posts 48 Posters 334.0k Views 30 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    meddie
    wrote on last edited by
    #301

    @Anticimex
    Hi, i have just uploaded the GatewayW5100 Sketch to the Gateway and the HumidtyTemp Sketch to the Node and it works fine, but without signing and encryption.

    AnticimexA 1 Reply Last reply
    0
    • M meddie

      @Anticimex
      Hi, i have just uploaded the GatewayW5100 Sketch to the Gateway and the HumidtyTemp Sketch to the Node and it works fine, but without signing and encryption.

      AnticimexA Offline
      AnticimexA Offline
      Anticimex
      Contest Winner
      wrote on last edited by
      #302

      @meddie You had encryption enabled when it failed? That could explain the failure of the broadcast if you did not have a matching setting between the nodes/gateway.

      Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

      M 1 Reply Last reply
      0
      • AnticimexA Anticimex

        @meddie You had encryption enabled when it failed? That could explain the failure of the broadcast if you did not have a matching setting between the nodes/gateway.

        M Offline
        M Offline
        meddie
        wrote on last edited by
        #303

        @Anticimex
        yes the encryption was enabled. Should i upload the personalized sketch again with my keys?

        AnticimexA 1 Reply Last reply
        0
        • M meddie

          @Anticimex
          yes the encryption was enabled. Should i upload the personalized sketch again with my keys?

          AnticimexA Offline
          AnticimexA Offline
          Anticimex
          Contest Winner
          wrote on last edited by
          #304

          @meddie You can just run an unmodified personalizer to have it read the EEPROM contents. That way you can verify that all devices share the exact same AES key. Assuming a mismatch in the AES key was the reason for the problem.
          But I strongly encourage you to just enable one security feature at a time if you are not sure what you are doing or it will be hard to debug what is going wrong.

          Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

          M 1 Reply Last reply
          0
          • AnticimexA Anticimex

            @meddie You can just run an unmodified personalizer to have it read the EEPROM contents. That way you can verify that all devices share the exact same AES key. Assuming a mismatch in the AES key was the reason for the problem.
            But I strongly encourage you to just enable one security feature at a time if you are not sure what you are doing or it will be hard to debug what is going wrong.

            M Offline
            M Offline
            meddie
            wrote on last edited by
            #305

            @Anticimex
            yes, i try to activate one feature and when it works the next. So i decided to activate the encryption and then when it works then i try to activate the signing. But first i would to check the keys like you said and when i now upload the securitypersonalization sketch unmodified i dont get any output on the serial monitor.
            :disappointed:

            AnticimexA 1 Reply Last reply
            0
            • M meddie

              @Anticimex
              yes, i try to activate one feature and when it works the next. So i decided to activate the encryption and then when it works then i try to activate the signing. But first i would to check the keys like you said and when i now upload the securitypersonalization sketch unmodified i dont get any output on the serial monitor.
              :disappointed:

              AnticimexA Offline
              AnticimexA Offline
              Anticimex
              Contest Winner
              wrote on last edited by
              #306

              @meddie Well, you have to make the patch to the baud rate and the changes we discussed earlier. I presume you did something necessary since you got output previously.

              Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

              M 1 Reply Last reply
              0
              • AnticimexA Anticimex

                @meddie Well, you have to make the patch to the baud rate and the changes we discussed earlier. I presume you did something necessary since you got output previously.

                M Offline
                M Offline
                meddie
                wrote on last edited by
                #307

                @Anticimex
                when i run the personalizer sketch i see in all keys FFFFFF....... What does it mean that no keys are stored?

                AnticimexA 1 Reply Last reply
                0
                • M meddie

                  @Anticimex
                  when i run the personalizer sketch i see in all keys FFFFFF....... What does it mean that no keys are stored?

                  AnticimexA Offline
                  AnticimexA Offline
                  Anticimex
                  Contest Winner
                  wrote on last edited by
                  #308

                  @meddie yes, that mean eeprom is in default state. The node has not been properly personalized.

                  Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                  M 1 Reply Last reply
                  0
                  • AnticimexA Anticimex

                    @meddie yes, that mean eeprom is in default state. The node has not been properly personalized.

                    M Offline
                    M Offline
                    meddie
                    wrote on last edited by
                    #309

                    @Anticimex
                    ok, i think i know what went wrong! But i dont know how to fix it. On the first run when i tried came the prompt to sens space to lock configuration i did it.
                    Now when i upload the modified personalization sketch with my keys i get this output on serial monitor:
                    of course i removed my keys with xx!

                    Device serial:   {0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX}
                    xxxxxxxxxxxxxxxxxxxxx
                    Skipping configuration write and lock (configuration already locked).
                    Chip configuration:
                    EEPROM DATA:
                    SOFT_HMAC_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                    SOFT_SERIAL   | FFFFFFFFFFFFFFFFFF
                    AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                    ATSHA204A DATA:
                               SN[0:1]           |         SN[2:3]           | XX   XX | XX   XX   
                                              Revnum                         | 00   09   04   00   
                                              SN[4:7]                        | XX   XX   XX   XX   
                        SN[8]    |  Reserved13   | I2CEnable | Reserved15    | EE | 10 | 00 | 00   
                      I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | C8 | 00 | 55 | 00   
                             SlotConfig00        |       SlotConfig01        | 8F   80 | 80   A1   
                             SlotConfig02        |       SlotConfig03        | 82   E0 | A3   60   
                             SlotConfig04        |       SlotConfig05        | 94   40 | A0   85   
                             SlotConfig06        |       SlotConfig07        | 86   40 | 87   07   
                             SlotConfig08        |       SlotConfig09        | 0F   00 | 89   F2   
                             SlotConfig0A        |       SlotConfig0B        | 8A   7A | 0B   8B   
                             SlotConfig0C        |       SlotConfig0D        | 0C   4C | DD   4D   
                             SlotConfig0E        |       SlotConfig0F        | C2   42 | AF   8F   
                      UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | FF | 00 | FF | 00   
                      UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | FF | 00 | FF | 00   
                      UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | FF | 00 | FF | 00   
                      UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | FF | 00 | FF | 00   
                                          LastKeyUse[0:3]                    | FF   FF   FF   FF   
                                          LastKeyUse[4:7]                    | FF   FF   FF   FF   
                                          LastKeyUse[8:B]                    | FF   FF   FF   FF   
                                          LastKeyUse[C:F]                    | FF   FF   FF   FF   
                      UserExtra  |    Selector   | LockValue |  LockConfig   | 00 | 00 | 55 | 00   
                    Using this user supplied HMAC key:
                    #define MY_HMAC_KEY 0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,\
                                        0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx
                    Writing key to slot 0...
                    Data not locked. Define LOCK_DATA to lock for real.
                    --------------------------------
                    Personalization is now complete.
                    Configuration is LOCKED
                    Data is UNLOCKED
                    

                    i thin this is the reason:

                    Skipping configuration write and lock (configuration already locked).
                    

                    and what i find very interestin that the first two signs of AES Key are correct the rest of them are FFFFF

                    AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                    

                    is it possible to unlock the configuration or did i kill the chip?
                    Thank you
                    Greets Eddie

                    AnticimexA 1 Reply Last reply
                    0
                    • M meddie

                      @Anticimex
                      ok, i think i know what went wrong! But i dont know how to fix it. On the first run when i tried came the prompt to sens space to lock configuration i did it.
                      Now when i upload the modified personalization sketch with my keys i get this output on serial monitor:
                      of course i removed my keys with xx!

                      Device serial:   {0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX}
                      xxxxxxxxxxxxxxxxxxxxx
                      Skipping configuration write and lock (configuration already locked).
                      Chip configuration:
                      EEPROM DATA:
                      SOFT_HMAC_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                      SOFT_SERIAL   | FFFFFFFFFFFFFFFFFF
                      AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                      ATSHA204A DATA:
                                 SN[0:1]           |         SN[2:3]           | XX   XX | XX   XX   
                                                Revnum                         | 00   09   04   00   
                                                SN[4:7]                        | XX   XX   XX   XX   
                          SN[8]    |  Reserved13   | I2CEnable | Reserved15    | EE | 10 | 00 | 00   
                        I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | C8 | 00 | 55 | 00   
                               SlotConfig00        |       SlotConfig01        | 8F   80 | 80   A1   
                               SlotConfig02        |       SlotConfig03        | 82   E0 | A3   60   
                               SlotConfig04        |       SlotConfig05        | 94   40 | A0   85   
                               SlotConfig06        |       SlotConfig07        | 86   40 | 87   07   
                               SlotConfig08        |       SlotConfig09        | 0F   00 | 89   F2   
                               SlotConfig0A        |       SlotConfig0B        | 8A   7A | 0B   8B   
                               SlotConfig0C        |       SlotConfig0D        | 0C   4C | DD   4D   
                               SlotConfig0E        |       SlotConfig0F        | C2   42 | AF   8F   
                        UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | FF | 00 | FF | 00   
                        UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | FF | 00 | FF | 00   
                        UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | FF | 00 | FF | 00   
                        UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | FF | 00 | FF | 00   
                                            LastKeyUse[0:3]                    | FF   FF   FF   FF   
                                            LastKeyUse[4:7]                    | FF   FF   FF   FF   
                                            LastKeyUse[8:B]                    | FF   FF   FF   FF   
                                            LastKeyUse[C:F]                    | FF   FF   FF   FF   
                        UserExtra  |    Selector   | LockValue |  LockConfig   | 00 | 00 | 55 | 00   
                      Using this user supplied HMAC key:
                      #define MY_HMAC_KEY 0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,\
                                          0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx,0xxx
                      Writing key to slot 0...
                      Data not locked. Define LOCK_DATA to lock for real.
                      --------------------------------
                      Personalization is now complete.
                      Configuration is LOCKED
                      Data is UNLOCKED
                      

                      i thin this is the reason:

                      Skipping configuration write and lock (configuration already locked).
                      

                      and what i find very interestin that the first two signs of AES Key are correct the rest of them are FFFFF

                      AES_KEY       | XXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                      

                      is it possible to unlock the configuration or did i kill the chip?
                      Thank you
                      Greets Eddie

                      AnticimexA Offline
                      AnticimexA Offline
                      Anticimex
                      Contest Winner
                      wrote on last edited by
                      #310

                      @meddie you cannot undo a lock, and you have to lock the chip in order to use it. And it is not an error that it reports chip is already locked since you have locked it already.
                      Furthermore, AES key and eeprom has nothing to do with the atsha204a chip so the lock state of the chip is irrelevant.
                      Now, why your AES key is only partially stored, I am not sure. But my bet would be that you have an error in the line where you define it in the sketch. A space or something like that.
                      Finally, as long as you don't lock the data zone, and you don't tamper with the configuration bits for the atsha204a device, you cannot destroy the chip. You can always replace the hmac key, which is the only thing you program to the atsha using the personalizer. Except for the chip configuration bits, and those the sketch handles for you and once config is locked they are fixed in place.

                      Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                      M 2 Replies Last reply
                      0
                      • AnticimexA Anticimex

                        @meddie you cannot undo a lock, and you have to lock the chip in order to use it. And it is not an error that it reports chip is already locked since you have locked it already.
                        Furthermore, AES key and eeprom has nothing to do with the atsha204a chip so the lock state of the chip is irrelevant.
                        Now, why your AES key is only partially stored, I am not sure. But my bet would be that you have an error in the line where you define it in the sketch. A space or something like that.
                        Finally, as long as you don't lock the data zone, and you don't tamper with the configuration bits for the atsha204a device, you cannot destroy the chip. You can always replace the hmac key, which is the only thing you program to the atsha using the personalizer. Except for the chip configuration bits, and those the sketch handles for you and once config is locked they are fixed in place.

                        M Offline
                        M Offline
                        meddie
                        wrote on last edited by
                        #311

                        @Anticimex
                        i checked the sketch already few times but i dont see an error.
                        here is the code i have only change my key with XX

                        
                        
                        #include "sha204_library.h"
                        #include "sha204_lib_return_codes.h"
                        #define MY_CORE_ONLY
                        #include <MySensors.h>
                        
                        #if DOXYGEN
                        #define LOCK_CONFIGURATION
                        #define LOCK_DATA
                        #define SKIP_KEY_STORAGE
                        #define USER_KEY
                        #define SKIP_UART_CONFIRMATION
                        #define USE_SOFT_SIGNING
                        #define STORE_SOFT_KEY
                        #define USER_SOFT_KEY
                        #define STORE_SOFT_SERIAL
                        #define USER_SOFT_SERIAL
                        #define STORE_AES_KEY
                        #define USER_AES_KEY
                        #endif
                        
                        #define LOCK_CONFIGURATION
                        
                        //#define LOCK_DATA
                        
                        //#define SKIP_KEY_STORAGE
                        
                        #define USER_KEY
                        
                        //#define SKIP_UART_CONFIRMATION
                        
                        //#define USE_SOFT_SIGNING
                        
                        //#define STORE_SOFT_KEY
                        
                        //#define USER_SOFT_KEY
                        
                        //#define STORE_SOFT_SERIAL
                        
                        //#define USER_SOFT_SERIAL
                        
                        #define STORE_AES_KEY
                        
                        #define USER_AES_KEY
                        
                        #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
                        #error You have to define USER_KEY for boards that does not have UART
                        #endif
                        
                        #ifdef USER_KEY
                        /** @brief The user-defined HMAC key to use for personalization */
                        #define MY_HMAC_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
                        /** @brief The data to store in key slot 0 */
                        const uint8_t user_key_data[32] = {MY_HMAC_KEY};
                        #endif
                        
                        #ifdef USER_SOFT_KEY
                        /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
                        #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                        /** @brief The data to store as soft HMAC key in EEPROM */
                        const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
                        #endif
                        
                        #ifdef USER_SOFT_SERIAL
                        /** @brief The user-defined soft serial to use for EEPROM personalization */
                        #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                        /** @brief The data to store as soft serial in EEPROM */
                        const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
                        #endif
                        
                        #ifdef USER_AES_KEY
                        /** @brief The user-defined AES key to use for EEPROM personalization */
                        #define MY_AES_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
                        /** @brief The data to store as AES key in EEPROM */
                        const uint8_t user_aes_key[16] = {MY_AES_KEY};
                        #endif
                        
                        #ifndef USE_SOFT_SIGNING
                        const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
                        atsha204Class sha204(sha204Pin);
                        #endif
                        
                        /** @brief Print a error notice and halt the execution */
                        void halt()
                        {
                        	Serial.println(F("Halting!"));
                        	while(1);
                        }
                        
                        #ifndef USE_SOFT_SIGNING
                        
                        uint16_t write_config_and_get_crc()
                        {
                        	uint16_t crc = 0;
                        	uint8_t config_word[4];
                        	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                        	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                        	uint8_t ret_code;
                        	bool do_write;
                        
                        	for (int i=0; i < 88; i += 4) {
                        		do_write = true;
                        		if (i == 20) {
                        			config_word[0] = 0x8F;
                        			config_word[1] = 0x80;
                        			config_word[2] = 0x80;
                        			config_word[3] = 0xA1;
                        		} else if (i == 24) {
                        			config_word[0] = 0x82;
                        			config_word[1] = 0xE0;
                        			config_word[2] = 0xA3;
                        			config_word[3] = 0x60;
                        		} else if (i == 28) {
                        			config_word[0] = 0x94;
                        			config_word[1] = 0x40;
                        			config_word[2] = 0xA0;
                        			config_word[3] = 0x85;
                        		} else if (i == 32) {
                        			config_word[0] = 0x86;
                        			config_word[1] = 0x40;
                        			config_word[2] = 0x87;
                        			config_word[3] = 0x07;
                        		} else if (i == 36) {
                        			config_word[0] = 0x0F;
                        			config_word[1] = 0x00;
                        			config_word[2] = 0x89;
                        			config_word[3] = 0xF2;
                        		} else if (i == 40) {
                        			config_word[0] = 0x8A;
                        			config_word[1] = 0x7A;
                        			config_word[2] = 0x0B;
                        			config_word[3] = 0x8B;
                        		} else if (i == 44) {
                        			config_word[0] = 0x0C;
                        			config_word[1] = 0x4C;
                        			config_word[2] = 0xDD;
                        			config_word[3] = 0x4D;
                        		} else if (i == 48) {
                        			config_word[0] = 0xC2;
                        			config_word[1] = 0x42;
                        			config_word[2] = 0xAF;
                        			config_word[3] = 0x8F;
                        		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
                        			config_word[0] = 0xFF;
                        			config_word[1] = 0x00;
                        			config_word[2] = 0xFF;
                        			config_word[3] = 0x00;
                        		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
                        			config_word[0] = 0xFF;
                        			config_word[1] = 0xFF;
                        			config_word[2] = 0xFF;
                        			config_word[3] = 0xFF;
                        		} else {
                        			// All other configs are untouched
                        			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                        			if (ret_code != SHA204_SUCCESS) {
                        				Serial.print(F("Failed to read config. Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			}
                        			// Set config_word to the read data
                        			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
                        			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
                        			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                        			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                        			do_write = false;
                        		}
                        
                        		// Update crc with CRC for the current word
                        		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
                        
                        		// Write config word
                        		if (do_write) {
                        			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
                        			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
                        			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                        			if (ret_code != SHA204_SUCCESS) {
                        				Serial.print(F("Failed to write config word at address "));
                        				Serial.print(i);
                        				Serial.print(F(". Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			}
                        		}
                        	}
                        	return crc;
                        }
                        
                        /**
                         * @brief Write provided key to slot 0
                         * @param key The key data to write
                         */
                        void write_key(uint8_t* key)
                        {
                        	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                        	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                        	uint8_t ret_code;
                        
                        	// Write key to slot 0
                        	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
                        	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
                        	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Failed to write key to slot 0. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	}
                        }
                        #endif // not USE_SOFT_SIGNING
                        
                        /** @brief Dump current configuration to UART */
                        void dump_configuration()
                        {
                        	uint8_t buffer[32];
                        #ifndef USE_SOFT_SIGNING
                        	Serial.println(F("EEPROM DATA:"));
                        #endif
                        	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                        	Serial.print(F("SOFT_HMAC_KEY | "));
                        	for (int j=0; j<32; j++) {
                        		if (buffer[j] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(buffer[j], HEX);
                        	}
                        	Serial.println();
                        	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                        	Serial.print(F("SOFT_SERIAL   | "));
                        	for (int j=0; j<9; j++) {
                        		if (buffer[j] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(buffer[j], HEX);
                        	}
                        	Serial.println();
                        	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                        	Serial.print(F("AES_KEY       | "));
                        	for (int j=0; j<16; j++) {
                        		if (buffer[j] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(buffer[j], HEX);
                        	}
                        	Serial.println();
                        #ifndef USE_SOFT_SIGNING
                        	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                        	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                        	uint8_t ret_code;
                        	Serial.println(F("ATSHA204A DATA:"));
                        	for (int i=0; i < 88; i += 4) {
                        		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                        		if (ret_code != SHA204_SUCCESS) {
                        			Serial.print(F("Failed to read config. Response: "));
                        			Serial.println(ret_code, HEX);
                        			halt();
                        		}
                        		if (i == 0x00) {
                        			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x04) {
                        			Serial.print(F("                          Revnum                         | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x08) {
                        			Serial.print(F("                          SN[4:7]                        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x0C) {
                        			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x10) {
                        			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x14) {
                        			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x18) {
                        			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x1C) {
                        			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x20) {
                        			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x24) {
                        			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x28) {
                        			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x2C) {
                        			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x30) {
                        			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j == 1) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x34) {
                        			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x38) {
                        			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x3C) {
                        			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x40) {
                        			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		} else if (i == 0x44) {
                        			Serial.print(F("                      LastKeyUse[0:3]                    | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x48) {
                        			Serial.print(F("                      LastKeyUse[4:7]                    | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x4C) {
                        			Serial.print(F("                      LastKeyUse[8:B]                    | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x50) {
                        			Serial.print(F("                      LastKeyUse[C:F]                    | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				Serial.print(F("   "));
                        			}
                        			Serial.println();
                        		} else if (i == 0x54) {
                        			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
                        			for (int j=0; j<4; j++) {
                        				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                        					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        				}
                        				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                        				if (j < 3) {
                        					Serial.print(F(" | "));
                        				} else {
                        					Serial.print(F("   "));
                        				}
                        			}
                        			Serial.println();
                        		}
                        	}
                        #endif // not USE_SOFT_SIGNING
                        }
                        
                        /** @brief Sketch setup code */
                        void setup()
                        {
                        	// Delay startup a bit for serial consoles to catch up
                        	unsigned long enter = hwMillis();
                        	while (hwMillis() - enter < (unsigned long)500);
                        #ifndef USE_SOFT_SIGNING
                        	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                        	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                        	uint8_t ret_code;
                        	uint8_t lockConfig = 0;
                        	uint8_t lockValue = 0;
                        	uint16_t crc;
                        	(void)crc;
                        #else
                        	// initialize pseudo-RNG
                        	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
                        #endif
                        	uint8_t key[32];
                        	(void)key;
                        
                          Serial.begin(9600);
                        	hwInit();
                        	Serial.println(F("Personalization sketch for MySensors usage."));
                        	Serial.println(F("-------------------------------------------"));
                        
                        #ifndef USE_SOFT_SIGNING
                        	// Wake device before starting operations
                        	ret_code = sha204.sha204c_wakeup(rx_buffer);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Failed to wake device. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	}
                        	// Read out lock config bits to determine if locking is possible
                        	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Failed to determine device lock status. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                        		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                        	}
                        #endif
                        
                        #ifdef STORE_SOFT_KEY
                        #ifdef USER_SOFT_KEY
                        	memcpy(key, user_soft_key_data, 32);
                        	Serial.println(F("Using this user supplied soft HMAC key:"));
                        #else
                        	// Retrieve random value to use as soft HMAC key
                        #ifdef USE_SOFT_SIGNING
                        	for (int i = 0; i < 32; i++) {
                        		key[i] = random(256) ^ micros();
                        		unsigned long enter = hwMillis();
                        		while (hwMillis() - enter < (unsigned long)2);
                        	}
                        	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                        #else
                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Random key generation failed. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                        	}
                        	if (lockConfig == 0x00) {
                        		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                        	} else {
                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                        	}
                        #endif // not USE_SOFT_SIGNING
                        #endif // not USER_SOFT_KEY
                        	Serial.print("#define MY_SOFT_HMAC_KEY ");
                        	for (int i=0; i<32; i++) {
                        		Serial.print("0x");
                        		if (key[i] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(key[i], HEX);
                        		if (i < 31) {
                        			Serial.print(',');
                        		}
                        	}
                        	Serial.println();
                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                        #endif // STORE_SOFT_KEY
                        
                        #ifdef STORE_SOFT_SERIAL
                        #ifdef USER_SOFT_SERIAL
                        	memcpy(key, user_soft_serial, 9);
                        	Serial.println(F("Using this user supplied soft serial:"));
                        #else
                        	// Retrieve random value to use as serial
                        #ifdef USE_SOFT_SIGNING
                        	for (int i = 0; i < 9; i++) {
                        		key[i] = random(256) ^ micros();
                        		unsigned long enter = hwMillis();
                        		while (hwMillis() - enter < (unsigned long)2);
                        	}
                        	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                        #else
                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Random serial generation failed. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
                        	}
                        	if (lockConfig == 0x00) {
                        		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                        	} else {
                        		Serial.println(F("Serial is not randomized (configuration not locked):"));
                        	}
                        #endif // not USE_SOFT_SIGNING
                        #endif // not USER_SOFT_SERIAL
                        	Serial.print("#define MY_SOFT_SERIAL ");
                        	for (int i=0; i<9; i++) {
                        		Serial.print("0x");
                        		if (key[i] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(key[i], HEX);
                        		if (i < 8) {
                        			Serial.print(',');
                        		}
                        	}
                        	Serial.println();
                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                        #endif // STORE_SOFT_SERIAL
                        
                        #ifdef STORE_AES_KEY
                        #ifdef USER_AES_KEY
                        	memcpy(key, user_aes_key, 16);
                        	Serial.println(F("Using this user supplied AES key:"));
                        #else
                        	// Retrieve random value to use as key
                        #ifdef USE_SOFT_SIGNING
                        	for (int i = 0; i < 16; i++) {
                        		key[i] = random(256) ^ micros();
                        		unsigned long enter = hwMillis();
                        		while (hwMillis() - enter < (unsigned long)2);
                        	}
                        	Serial.println(F("This key will be stored in EEPROM as AES key:"));
                        #else
                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Random key generation failed. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                        	}
                        	if (lockConfig == 0x00) {
                        		Serial.println(F("This key will be stored in EEPROM as AES key:"));
                        	} else {
                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                        	}
                        #endif // not USE_SOFT_SIGNING
                        #endif // not USER_AES_KEY
                        	Serial.print("#define MY_AES_KEY ");
                        	for (int i=0; i<16; i++) {
                        		Serial.print("0x");
                        		if (key[i] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(key[i], HEX);
                        		if (i < 15) {
                        			Serial.print(',');
                        		}
                        	}
                        	Serial.println();
                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                        #endif // STORE_AES_KEY
                        
                        #ifdef USE_SOFT_SIGNING
                        	Serial.println(F("EEPROM configuration:"));
                        	dump_configuration();
                        #else
                        	// Output device revision on console
                        	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Failed to determine device revision. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		Serial.print(F("Device revision: "));
                        		for (int i=0; i<4; i++) {
                        			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        			}
                        			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
                        		}
                        		Serial.println();
                        	}
                        
                        	// Output serial number on console
                        	ret_code = sha204.getSerialNumber(rx_buffer);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Failed to obtain device serial number. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		Serial.print(F("Device serial:   "));
                        		Serial.print('{');
                        		for (int i=0; i<9; i++) {
                        			Serial.print(F("0x"));
                        			if (rx_buffer[i] < 0x10) {
                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        			}
                        			Serial.print(rx_buffer[i], HEX);
                        			if (i < 8) {
                        				Serial.print(',');
                        			}
                        		}
                        		Serial.print('}');
                        		Serial.println();
                        		for (int i=0; i<9; i++) {
                        			if (rx_buffer[i] < 0x10) {
                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        			}
                        			Serial.print(rx_buffer[i], HEX);
                        		}
                        		Serial.println();
                        	}
                        
                        	if (lockConfig != 0x00) {
                        		// Write config and get CRC for the updated config
                        		crc = write_config_and_get_crc();
                        
                        		// List current configuration before attempting to lock
                        		Serial.println(F("Chip configuration:"));
                        		dump_configuration();
                        
                        #ifdef LOCK_CONFIGURATION
                        		// Purge serial input buffer
                        #ifndef SKIP_UART_CONFIRMATION
                        		while (Serial.available()) {
                        			Serial.read();
                        		}
                        		Serial.println(F("Send SPACE character now to lock the configuration..."));
                        
                        		while (Serial.available() == 0);
                        		if (Serial.read() == ' ')
                        #endif //not SKIP_UART_CONFIRMATION
                        		{
                        			Serial.println(F("Locking configuration..."));
                        
                        			// Correct sequence, resync chip
                        			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                        			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                        				Serial.print(F("Resync failed. Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			}
                        
                        			// Lock configuration zone
                        			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                        			                                  crc, 0, NULL, 0, NULL, 0, NULL,
                        			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                        			if (ret_code != SHA204_SUCCESS) {
                        				Serial.print(F("Configuration lock failed. Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			} else {
                        				Serial.println(F("Configuration locked."));
                        
                        				// Update lock flags after locking
                        				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                        				if (ret_code != SHA204_SUCCESS) {
                        					Serial.print(F("Failed to determine device lock status. Response: "));
                        					Serial.println(ret_code, HEX);
                        					halt();
                        				} else {
                        					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                        					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                        				}
                        			}
                        		}
                        #ifndef SKIP_UART_CONFIRMATION
                        		else {
                        			Serial.println(F("Unexpected answer. Skipping lock."));
                        		}
                        #endif //not SKIP_UART_CONFIRMATION
                        #else //LOCK_CONFIGURATION
                        		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
                        #endif
                        	} else {
                        		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
                        		Serial.println(F("Chip configuration:"));
                        		dump_configuration();
                        	}
                        
                        #ifdef SKIP_KEY_STORAGE
                        	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
                        #else
                        #ifdef USER_KEY
                        	memcpy(key, user_key_data, 32);
                        	Serial.println(F("Using this user supplied HMAC key:"));
                        #else
                        	// Retrieve random value to use as key
                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                        	if (ret_code != SHA204_SUCCESS) {
                        		Serial.print(F("Random key generation failed. Response: "));
                        		Serial.println(ret_code, HEX);
                        		halt();
                        	} else {
                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                        	}
                        	if (lockConfig == 0x00) {
                        		Serial.println(F("Take note of this key, it will never be the shown again:"));
                        	} else {
                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                        	}
                        #endif
                        	Serial.print("#define MY_HMAC_KEY ");
                        	for (int i=0; i<32; i++) {
                        		Serial.print("0x");
                        		if (key[i] < 0x10) {
                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                        		}
                        		Serial.print(key[i], HEX);
                        		if (i < 31) {
                        			Serial.print(',');
                        		}
                        		if (i+1 == 16) {
                        			Serial.print("\\\n                    ");
                        		}
                        	}
                        	Serial.println();
                        
                        	// It will not be possible to write the key if the configuration zone is unlocked
                        	if (lockConfig == 0x00) {
                        		// Write the key to the appropriate slot in the data zone
                        		Serial.println(F("Writing key to slot 0..."));
                        		write_key(key);
                        	} else {
                        		Serial.println(F("Skipping key storage (configuration not locked)."));
                        		Serial.println(F("The configuration must be locked to be able to write a key."));
                        	}
                        #endif
                        
                        	if (lockValue != 0x00) {
                        #ifdef LOCK_DATA
                        #ifndef SKIP_UART_CONFIRMATION
                        		while (Serial.available()) {
                        			Serial.read();
                        		}
                        		Serial.println(F("Send SPACE character to lock data..."));
                        		while (Serial.available() == 0);
                        		if (Serial.read() == ' ')
                        #endif //not SKIP_UART_CONFIRMATION
                        		{
                        			// Correct sequence, resync chip
                        			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                        			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                        				Serial.print(F("Resync failed. Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			}
                        
                        			// If configuration is unlocked, key is not updated. Locking data in this case will cause
                        			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
                        			// usecase not the desired behaviour, so ask for additional confirmation in this case.
                        			if (lockConfig != 0x00) {
                        				while (Serial.available()) {
                        					Serial.read();
                        				}
                        				Serial.println(F("*** ATTENTION ***"));
                        				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
                        				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
                        				Serial.println(
                        				    F("which cannot be change after locking is done. This is in practically any usecase"));
                        				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
                        				while (Serial.available() == 0);
                        				if (Serial.read() != ' ') {
                        					Serial.println(F("Unexpected answer. Skipping lock."));
                        					halt();
                        				}
                        			}
                        
                        			// Lock data zone
                        			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                        			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                        			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                        			if (ret_code != SHA204_SUCCESS) {
                        				Serial.print(F("Data lock failed. Response: "));
                        				Serial.println(ret_code, HEX);
                        				halt();
                        			} else {
                        				Serial.println(F("Data locked."));
                        
                        				// Update lock flags after locking
                        				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                        				if (ret_code != SHA204_SUCCESS) {
                        					Serial.print(F("Failed to determine device lock status. Response: "));
                        					Serial.println(ret_code, HEX);
                        					halt();
                        				} else {
                        					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                        					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                        				}
                        			}
                        		}
                        #ifndef SKIP_UART_CONFIRMATION
                        		else {
                        			Serial.println(F("Unexpected answer. Skipping lock."));
                        		}
                        #endif //not SKIP_UART_CONFIRMATION
                        #else //LOCK_DATA
                        		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
                        #endif
                        	} else {
                        		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
                        	}
                        #endif // not USE_SOFT_SIGNING
                        
                        	Serial.println(F("--------------------------------"));
                        	Serial.println(F("Personalization is now complete."));
                        #ifndef USE_SOFT_SIGNING
                        	Serial.print(F("Configuration is "));
                        	if (lockConfig == 0x00) {
                        		Serial.println("LOCKED");
                        	} else {
                        		Serial.println("UNLOCKED");
                        	}
                        	Serial.print(F("Data is "));
                        	if (lockValue == 0x00) {
                        		Serial.println("LOCKED");
                        	} else {
                        		Serial.println("UNLOCKED");
                        	}
                        #endif
                        }
                        
                        /** @brief Sketch execution code */
                        void loop()
                        {
                        }```
                        AnticimexA 1 Reply Last reply
                        0
                        • AnticimexA Anticimex

                          @meddie you cannot undo a lock, and you have to lock the chip in order to use it. And it is not an error that it reports chip is already locked since you have locked it already.
                          Furthermore, AES key and eeprom has nothing to do with the atsha204a chip so the lock state of the chip is irrelevant.
                          Now, why your AES key is only partially stored, I am not sure. But my bet would be that you have an error in the line where you define it in the sketch. A space or something like that.
                          Finally, as long as you don't lock the data zone, and you don't tamper with the configuration bits for the atsha204a device, you cannot destroy the chip. You can always replace the hmac key, which is the only thing you program to the atsha using the personalizer. Except for the chip configuration bits, and those the sketch handles for you and once config is locked they are fixed in place.

                          M Offline
                          M Offline
                          meddie
                          wrote on last edited by
                          #312

                          @Anticimex
                          the interesting thing is when i upload the same sketch to the sensebender micro it works the AES Key will be stored correctly.
                          But on the Sensebender Gateway only the first two digits

                          AnticimexA 1 Reply Last reply
                          0
                          • M meddie

                            @Anticimex
                            i checked the sketch already few times but i dont see an error.
                            here is the code i have only change my key with XX

                            
                            
                            #include "sha204_library.h"
                            #include "sha204_lib_return_codes.h"
                            #define MY_CORE_ONLY
                            #include <MySensors.h>
                            
                            #if DOXYGEN
                            #define LOCK_CONFIGURATION
                            #define LOCK_DATA
                            #define SKIP_KEY_STORAGE
                            #define USER_KEY
                            #define SKIP_UART_CONFIRMATION
                            #define USE_SOFT_SIGNING
                            #define STORE_SOFT_KEY
                            #define USER_SOFT_KEY
                            #define STORE_SOFT_SERIAL
                            #define USER_SOFT_SERIAL
                            #define STORE_AES_KEY
                            #define USER_AES_KEY
                            #endif
                            
                            #define LOCK_CONFIGURATION
                            
                            //#define LOCK_DATA
                            
                            //#define SKIP_KEY_STORAGE
                            
                            #define USER_KEY
                            
                            //#define SKIP_UART_CONFIRMATION
                            
                            //#define USE_SOFT_SIGNING
                            
                            //#define STORE_SOFT_KEY
                            
                            //#define USER_SOFT_KEY
                            
                            //#define STORE_SOFT_SERIAL
                            
                            //#define USER_SOFT_SERIAL
                            
                            #define STORE_AES_KEY
                            
                            #define USER_AES_KEY
                            
                            #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
                            #error You have to define USER_KEY for boards that does not have UART
                            #endif
                            
                            #ifdef USER_KEY
                            /** @brief The user-defined HMAC key to use for personalization */
                            #define MY_HMAC_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
                            /** @brief The data to store in key slot 0 */
                            const uint8_t user_key_data[32] = {MY_HMAC_KEY};
                            #endif
                            
                            #ifdef USER_SOFT_KEY
                            /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
                            #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                            /** @brief The data to store as soft HMAC key in EEPROM */
                            const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
                            #endif
                            
                            #ifdef USER_SOFT_SERIAL
                            /** @brief The user-defined soft serial to use for EEPROM personalization */
                            #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                            /** @brief The data to store as soft serial in EEPROM */
                            const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
                            #endif
                            
                            #ifdef USER_AES_KEY
                            /** @brief The user-defined AES key to use for EEPROM personalization */
                            #define MY_AES_KEY 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
                            /** @brief The data to store as AES key in EEPROM */
                            const uint8_t user_aes_key[16] = {MY_AES_KEY};
                            #endif
                            
                            #ifndef USE_SOFT_SIGNING
                            const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
                            atsha204Class sha204(sha204Pin);
                            #endif
                            
                            /** @brief Print a error notice and halt the execution */
                            void halt()
                            {
                            	Serial.println(F("Halting!"));
                            	while(1);
                            }
                            
                            #ifndef USE_SOFT_SIGNING
                            
                            uint16_t write_config_and_get_crc()
                            {
                            	uint16_t crc = 0;
                            	uint8_t config_word[4];
                            	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                            	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                            	uint8_t ret_code;
                            	bool do_write;
                            
                            	for (int i=0; i < 88; i += 4) {
                            		do_write = true;
                            		if (i == 20) {
                            			config_word[0] = 0x8F;
                            			config_word[1] = 0x80;
                            			config_word[2] = 0x80;
                            			config_word[3] = 0xA1;
                            		} else if (i == 24) {
                            			config_word[0] = 0x82;
                            			config_word[1] = 0xE0;
                            			config_word[2] = 0xA3;
                            			config_word[3] = 0x60;
                            		} else if (i == 28) {
                            			config_word[0] = 0x94;
                            			config_word[1] = 0x40;
                            			config_word[2] = 0xA0;
                            			config_word[3] = 0x85;
                            		} else if (i == 32) {
                            			config_word[0] = 0x86;
                            			config_word[1] = 0x40;
                            			config_word[2] = 0x87;
                            			config_word[3] = 0x07;
                            		} else if (i == 36) {
                            			config_word[0] = 0x0F;
                            			config_word[1] = 0x00;
                            			config_word[2] = 0x89;
                            			config_word[3] = 0xF2;
                            		} else if (i == 40) {
                            			config_word[0] = 0x8A;
                            			config_word[1] = 0x7A;
                            			config_word[2] = 0x0B;
                            			config_word[3] = 0x8B;
                            		} else if (i == 44) {
                            			config_word[0] = 0x0C;
                            			config_word[1] = 0x4C;
                            			config_word[2] = 0xDD;
                            			config_word[3] = 0x4D;
                            		} else if (i == 48) {
                            			config_word[0] = 0xC2;
                            			config_word[1] = 0x42;
                            			config_word[2] = 0xAF;
                            			config_word[3] = 0x8F;
                            		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
                            			config_word[0] = 0xFF;
                            			config_word[1] = 0x00;
                            			config_word[2] = 0xFF;
                            			config_word[3] = 0x00;
                            		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
                            			config_word[0] = 0xFF;
                            			config_word[1] = 0xFF;
                            			config_word[2] = 0xFF;
                            			config_word[3] = 0xFF;
                            		} else {
                            			// All other configs are untouched
                            			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                            			if (ret_code != SHA204_SUCCESS) {
                            				Serial.print(F("Failed to read config. Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			}
                            			// Set config_word to the read data
                            			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
                            			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
                            			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                            			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                            			do_write = false;
                            		}
                            
                            		// Update crc with CRC for the current word
                            		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
                            
                            		// Write config word
                            		if (do_write) {
                            			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
                            			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
                            			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                            			if (ret_code != SHA204_SUCCESS) {
                            				Serial.print(F("Failed to write config word at address "));
                            				Serial.print(i);
                            				Serial.print(F(". Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			}
                            		}
                            	}
                            	return crc;
                            }
                            
                            /**
                             * @brief Write provided key to slot 0
                             * @param key The key data to write
                             */
                            void write_key(uint8_t* key)
                            {
                            	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                            	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                            	uint8_t ret_code;
                            
                            	// Write key to slot 0
                            	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
                            	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
                            	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Failed to write key to slot 0. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	}
                            }
                            #endif // not USE_SOFT_SIGNING
                            
                            /** @brief Dump current configuration to UART */
                            void dump_configuration()
                            {
                            	uint8_t buffer[32];
                            #ifndef USE_SOFT_SIGNING
                            	Serial.println(F("EEPROM DATA:"));
                            #endif
                            	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                            	Serial.print(F("SOFT_HMAC_KEY | "));
                            	for (int j=0; j<32; j++) {
                            		if (buffer[j] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(buffer[j], HEX);
                            	}
                            	Serial.println();
                            	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                            	Serial.print(F("SOFT_SERIAL   | "));
                            	for (int j=0; j<9; j++) {
                            		if (buffer[j] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(buffer[j], HEX);
                            	}
                            	Serial.println();
                            	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                            	Serial.print(F("AES_KEY       | "));
                            	for (int j=0; j<16; j++) {
                            		if (buffer[j] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(buffer[j], HEX);
                            	}
                            	Serial.println();
                            #ifndef USE_SOFT_SIGNING
                            	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                            	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                            	uint8_t ret_code;
                            	Serial.println(F("ATSHA204A DATA:"));
                            	for (int i=0; i < 88; i += 4) {
                            		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                            		if (ret_code != SHA204_SUCCESS) {
                            			Serial.print(F("Failed to read config. Response: "));
                            			Serial.println(ret_code, HEX);
                            			halt();
                            		}
                            		if (i == 0x00) {
                            			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x04) {
                            			Serial.print(F("                          Revnum                         | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x08) {
                            			Serial.print(F("                          SN[4:7]                        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x0C) {
                            			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x10) {
                            			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x14) {
                            			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x18) {
                            			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x1C) {
                            			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x20) {
                            			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x24) {
                            			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x28) {
                            			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x2C) {
                            			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x30) {
                            			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j == 1) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x34) {
                            			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x38) {
                            			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x3C) {
                            			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x40) {
                            			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		} else if (i == 0x44) {
                            			Serial.print(F("                      LastKeyUse[0:3]                    | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x48) {
                            			Serial.print(F("                      LastKeyUse[4:7]                    | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x4C) {
                            			Serial.print(F("                      LastKeyUse[8:B]                    | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x50) {
                            			Serial.print(F("                      LastKeyUse[C:F]                    | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				Serial.print(F("   "));
                            			}
                            			Serial.println();
                            		} else if (i == 0x54) {
                            			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
                            			for (int j=0; j<4; j++) {
                            				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                            					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            				}
                            				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                            				if (j < 3) {
                            					Serial.print(F(" | "));
                            				} else {
                            					Serial.print(F("   "));
                            				}
                            			}
                            			Serial.println();
                            		}
                            	}
                            #endif // not USE_SOFT_SIGNING
                            }
                            
                            /** @brief Sketch setup code */
                            void setup()
                            {
                            	// Delay startup a bit for serial consoles to catch up
                            	unsigned long enter = hwMillis();
                            	while (hwMillis() - enter < (unsigned long)500);
                            #ifndef USE_SOFT_SIGNING
                            	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                            	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                            	uint8_t ret_code;
                            	uint8_t lockConfig = 0;
                            	uint8_t lockValue = 0;
                            	uint16_t crc;
                            	(void)crc;
                            #else
                            	// initialize pseudo-RNG
                            	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
                            #endif
                            	uint8_t key[32];
                            	(void)key;
                            
                              Serial.begin(9600);
                            	hwInit();
                            	Serial.println(F("Personalization sketch for MySensors usage."));
                            	Serial.println(F("-------------------------------------------"));
                            
                            #ifndef USE_SOFT_SIGNING
                            	// Wake device before starting operations
                            	ret_code = sha204.sha204c_wakeup(rx_buffer);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Failed to wake device. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	}
                            	// Read out lock config bits to determine if locking is possible
                            	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Failed to determine device lock status. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                            		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                            	}
                            #endif
                            
                            #ifdef STORE_SOFT_KEY
                            #ifdef USER_SOFT_KEY
                            	memcpy(key, user_soft_key_data, 32);
                            	Serial.println(F("Using this user supplied soft HMAC key:"));
                            #else
                            	// Retrieve random value to use as soft HMAC key
                            #ifdef USE_SOFT_SIGNING
                            	for (int i = 0; i < 32; i++) {
                            		key[i] = random(256) ^ micros();
                            		unsigned long enter = hwMillis();
                            		while (hwMillis() - enter < (unsigned long)2);
                            	}
                            	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                            #else
                            	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Random key generation failed. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                            	}
                            	if (lockConfig == 0x00) {
                            		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                            	} else {
                            		Serial.println(F("Key is not randomized (configuration not locked):"));
                            	}
                            #endif // not USE_SOFT_SIGNING
                            #endif // not USER_SOFT_KEY
                            	Serial.print("#define MY_SOFT_HMAC_KEY ");
                            	for (int i=0; i<32; i++) {
                            		Serial.print("0x");
                            		if (key[i] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(key[i], HEX);
                            		if (i < 31) {
                            			Serial.print(',');
                            		}
                            	}
                            	Serial.println();
                            	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                            #endif // STORE_SOFT_KEY
                            
                            #ifdef STORE_SOFT_SERIAL
                            #ifdef USER_SOFT_SERIAL
                            	memcpy(key, user_soft_serial, 9);
                            	Serial.println(F("Using this user supplied soft serial:"));
                            #else
                            	// Retrieve random value to use as serial
                            #ifdef USE_SOFT_SIGNING
                            	for (int i = 0; i < 9; i++) {
                            		key[i] = random(256) ^ micros();
                            		unsigned long enter = hwMillis();
                            		while (hwMillis() - enter < (unsigned long)2);
                            	}
                            	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                            #else
                            	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Random serial generation failed. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
                            	}
                            	if (lockConfig == 0x00) {
                            		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                            	} else {
                            		Serial.println(F("Serial is not randomized (configuration not locked):"));
                            	}
                            #endif // not USE_SOFT_SIGNING
                            #endif // not USER_SOFT_SERIAL
                            	Serial.print("#define MY_SOFT_SERIAL ");
                            	for (int i=0; i<9; i++) {
                            		Serial.print("0x");
                            		if (key[i] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(key[i], HEX);
                            		if (i < 8) {
                            			Serial.print(',');
                            		}
                            	}
                            	Serial.println();
                            	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                            #endif // STORE_SOFT_SERIAL
                            
                            #ifdef STORE_AES_KEY
                            #ifdef USER_AES_KEY
                            	memcpy(key, user_aes_key, 16);
                            	Serial.println(F("Using this user supplied AES key:"));
                            #else
                            	// Retrieve random value to use as key
                            #ifdef USE_SOFT_SIGNING
                            	for (int i = 0; i < 16; i++) {
                            		key[i] = random(256) ^ micros();
                            		unsigned long enter = hwMillis();
                            		while (hwMillis() - enter < (unsigned long)2);
                            	}
                            	Serial.println(F("This key will be stored in EEPROM as AES key:"));
                            #else
                            	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Random key generation failed. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                            	}
                            	if (lockConfig == 0x00) {
                            		Serial.println(F("This key will be stored in EEPROM as AES key:"));
                            	} else {
                            		Serial.println(F("Key is not randomized (configuration not locked):"));
                            	}
                            #endif // not USE_SOFT_SIGNING
                            #endif // not USER_AES_KEY
                            	Serial.print("#define MY_AES_KEY ");
                            	for (int i=0; i<16; i++) {
                            		Serial.print("0x");
                            		if (key[i] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(key[i], HEX);
                            		if (i < 15) {
                            			Serial.print(',');
                            		}
                            	}
                            	Serial.println();
                            	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                            #endif // STORE_AES_KEY
                            
                            #ifdef USE_SOFT_SIGNING
                            	Serial.println(F("EEPROM configuration:"));
                            	dump_configuration();
                            #else
                            	// Output device revision on console
                            	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Failed to determine device revision. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		Serial.print(F("Device revision: "));
                            		for (int i=0; i<4; i++) {
                            			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
                            				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            			}
                            			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
                            		}
                            		Serial.println();
                            	}
                            
                            	// Output serial number on console
                            	ret_code = sha204.getSerialNumber(rx_buffer);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Failed to obtain device serial number. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		Serial.print(F("Device serial:   "));
                            		Serial.print('{');
                            		for (int i=0; i<9; i++) {
                            			Serial.print(F("0x"));
                            			if (rx_buffer[i] < 0x10) {
                            				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            			}
                            			Serial.print(rx_buffer[i], HEX);
                            			if (i < 8) {
                            				Serial.print(',');
                            			}
                            		}
                            		Serial.print('}');
                            		Serial.println();
                            		for (int i=0; i<9; i++) {
                            			if (rx_buffer[i] < 0x10) {
                            				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            			}
                            			Serial.print(rx_buffer[i], HEX);
                            		}
                            		Serial.println();
                            	}
                            
                            	if (lockConfig != 0x00) {
                            		// Write config and get CRC for the updated config
                            		crc = write_config_and_get_crc();
                            
                            		// List current configuration before attempting to lock
                            		Serial.println(F("Chip configuration:"));
                            		dump_configuration();
                            
                            #ifdef LOCK_CONFIGURATION
                            		// Purge serial input buffer
                            #ifndef SKIP_UART_CONFIRMATION
                            		while (Serial.available()) {
                            			Serial.read();
                            		}
                            		Serial.println(F("Send SPACE character now to lock the configuration..."));
                            
                            		while (Serial.available() == 0);
                            		if (Serial.read() == ' ')
                            #endif //not SKIP_UART_CONFIRMATION
                            		{
                            			Serial.println(F("Locking configuration..."));
                            
                            			// Correct sequence, resync chip
                            			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                            			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                            				Serial.print(F("Resync failed. Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			}
                            
                            			// Lock configuration zone
                            			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                            			                                  crc, 0, NULL, 0, NULL, 0, NULL,
                            			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                            			if (ret_code != SHA204_SUCCESS) {
                            				Serial.print(F("Configuration lock failed. Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			} else {
                            				Serial.println(F("Configuration locked."));
                            
                            				// Update lock flags after locking
                            				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                            				if (ret_code != SHA204_SUCCESS) {
                            					Serial.print(F("Failed to determine device lock status. Response: "));
                            					Serial.println(ret_code, HEX);
                            					halt();
                            				} else {
                            					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                            					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                            				}
                            			}
                            		}
                            #ifndef SKIP_UART_CONFIRMATION
                            		else {
                            			Serial.println(F("Unexpected answer. Skipping lock."));
                            		}
                            #endif //not SKIP_UART_CONFIRMATION
                            #else //LOCK_CONFIGURATION
                            		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
                            #endif
                            	} else {
                            		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
                            		Serial.println(F("Chip configuration:"));
                            		dump_configuration();
                            	}
                            
                            #ifdef SKIP_KEY_STORAGE
                            	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
                            #else
                            #ifdef USER_KEY
                            	memcpy(key, user_key_data, 32);
                            	Serial.println(F("Using this user supplied HMAC key:"));
                            #else
                            	// Retrieve random value to use as key
                            	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                            	if (ret_code != SHA204_SUCCESS) {
                            		Serial.print(F("Random key generation failed. Response: "));
                            		Serial.println(ret_code, HEX);
                            		halt();
                            	} else {
                            		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                            	}
                            	if (lockConfig == 0x00) {
                            		Serial.println(F("Take note of this key, it will never be the shown again:"));
                            	} else {
                            		Serial.println(F("Key is not randomized (configuration not locked):"));
                            	}
                            #endif
                            	Serial.print("#define MY_HMAC_KEY ");
                            	for (int i=0; i<32; i++) {
                            		Serial.print("0x");
                            		if (key[i] < 0x10) {
                            			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                            		}
                            		Serial.print(key[i], HEX);
                            		if (i < 31) {
                            			Serial.print(',');
                            		}
                            		if (i+1 == 16) {
                            			Serial.print("\\\n                    ");
                            		}
                            	}
                            	Serial.println();
                            
                            	// It will not be possible to write the key if the configuration zone is unlocked
                            	if (lockConfig == 0x00) {
                            		// Write the key to the appropriate slot in the data zone
                            		Serial.println(F("Writing key to slot 0..."));
                            		write_key(key);
                            	} else {
                            		Serial.println(F("Skipping key storage (configuration not locked)."));
                            		Serial.println(F("The configuration must be locked to be able to write a key."));
                            	}
                            #endif
                            
                            	if (lockValue != 0x00) {
                            #ifdef LOCK_DATA
                            #ifndef SKIP_UART_CONFIRMATION
                            		while (Serial.available()) {
                            			Serial.read();
                            		}
                            		Serial.println(F("Send SPACE character to lock data..."));
                            		while (Serial.available() == 0);
                            		if (Serial.read() == ' ')
                            #endif //not SKIP_UART_CONFIRMATION
                            		{
                            			// Correct sequence, resync chip
                            			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                            			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                            				Serial.print(F("Resync failed. Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			}
                            
                            			// If configuration is unlocked, key is not updated. Locking data in this case will cause
                            			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
                            			// usecase not the desired behaviour, so ask for additional confirmation in this case.
                            			if (lockConfig != 0x00) {
                            				while (Serial.available()) {
                            					Serial.read();
                            				}
                            				Serial.println(F("*** ATTENTION ***"));
                            				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
                            				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
                            				Serial.println(
                            				    F("which cannot be change after locking is done. This is in practically any usecase"));
                            				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
                            				while (Serial.available() == 0);
                            				if (Serial.read() != ' ') {
                            					Serial.println(F("Unexpected answer. Skipping lock."));
                            					halt();
                            				}
                            			}
                            
                            			// Lock data zone
                            			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                            			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                            			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                            			if (ret_code != SHA204_SUCCESS) {
                            				Serial.print(F("Data lock failed. Response: "));
                            				Serial.println(ret_code, HEX);
                            				halt();
                            			} else {
                            				Serial.println(F("Data locked."));
                            
                            				// Update lock flags after locking
                            				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                            				if (ret_code != SHA204_SUCCESS) {
                            					Serial.print(F("Failed to determine device lock status. Response: "));
                            					Serial.println(ret_code, HEX);
                            					halt();
                            				} else {
                            					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                            					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                            				}
                            			}
                            		}
                            #ifndef SKIP_UART_CONFIRMATION
                            		else {
                            			Serial.println(F("Unexpected answer. Skipping lock."));
                            		}
                            #endif //not SKIP_UART_CONFIRMATION
                            #else //LOCK_DATA
                            		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
                            #endif
                            	} else {
                            		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
                            	}
                            #endif // not USE_SOFT_SIGNING
                            
                            	Serial.println(F("--------------------------------"));
                            	Serial.println(F("Personalization is now complete."));
                            #ifndef USE_SOFT_SIGNING
                            	Serial.print(F("Configuration is "));
                            	if (lockConfig == 0x00) {
                            		Serial.println("LOCKED");
                            	} else {
                            		Serial.println("UNLOCKED");
                            	}
                            	Serial.print(F("Data is "));
                            	if (lockValue == 0x00) {
                            		Serial.println("LOCKED");
                            	} else {
                            		Serial.println("UNLOCKED");
                            	}
                            #endif
                            }
                            
                            /** @brief Sketch execution code */
                            void loop()
                            {
                            }```
                            AnticimexA Offline
                            AnticimexA Offline
                            Anticimex
                            Contest Winner
                            wrote on last edited by
                            #313

                            @meddie sorry, I cannot see anything out of the ordinary. What hardware do you run on? SAMD? I know the personalizer to work on AVR.
                            Have you executed a sketch between personalizer rounds? Perhaps it overwrite parts of the eeprom.

                            Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                            M 1 Reply Last reply
                            0
                            • AnticimexA Anticimex

                              @meddie sorry, I cannot see anything out of the ordinary. What hardware do you run on? SAMD? I know the personalizer to work on AVR.
                              Have you executed a sketch between personalizer rounds? Perhaps it overwrite parts of the eeprom.

                              M Offline
                              M Offline
                              meddie
                              wrote on last edited by
                              #314

                              @Anticimex
                              the troubles i have on sensebender gateway its a samd. On the micro (avr based) works fine.
                              On the gateway i didnt upload a sketch between. I have uploaded the personalizer sketch and after them i tried the unmoded personalizer.

                              1 Reply Last reply
                              0
                              • M meddie

                                @Anticimex
                                the interesting thing is when i upload the same sketch to the sensebender micro it works the AES Key will be stored correctly.
                                But on the Sensebender Gateway only the first two digits

                                AnticimexA Offline
                                AnticimexA Offline
                                Anticimex
                                Contest Winner
                                wrote on last edited by
                                #315

                                @meddie ok, so samd hardware. @tbowmo is eeprom handling on samd fully compatible with avr? It would appear something is not quite right with eeprom writes (or reads) on samd.

                                Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                                1 Reply Last reply
                                0
                                • tbowmoT Offline
                                  tbowmoT Offline
                                  tbowmo
                                  Admin
                                  wrote on last edited by
                                  #316

                                  @Anticimex

                                  eeprom on samd is handled differently, than avr, since it's an external I2C eeprom. So the normal avr commands for read/write to the eeprom doesn't work.

                                  the pieces that handle eeprom is located in MyHwSAMD.cpp between line 45 and 100
                                  https://github.com/mysensors/MySensors/blob/development/core/MyHwSAMD.cpp#L45

                                  AnticimexA 1 Reply Last reply
                                  0
                                  • tbowmoT tbowmo

                                    @Anticimex

                                    eeprom on samd is handled differently, than avr, since it's an external I2C eeprom. So the normal avr commands for read/write to the eeprom doesn't work.

                                    the pieces that handle eeprom is located in MyHwSAMD.cpp between line 45 and 100
                                    https://github.com/mysensors/MySensors/blob/development/core/MyHwSAMD.cpp#L45

                                    AnticimexA Offline
                                    AnticimexA Offline
                                    Anticimex
                                    Contest Winner
                                    wrote on last edited by
                                    #317

                                    @tbowmo
                                    That may be, but I would still expect hwReadConfigBlock and hwWriteConfigBlock to be chip agnostic.

                                    Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      meddie
                                      wrote on last edited by
                                      #318

                                      @tbowmo
                                      sorry can you say me please what i have to add to the sketch that will store my aes key on the sensebender gateway?
                                      I am a very very noob
                                      thanks

                                      AnticimexA 1 Reply Last reply
                                      0
                                      • M meddie

                                        @tbowmo
                                        sorry can you say me please what i have to add to the sketch that will store my aes key on the sensebender gateway?
                                        I am a very very noob
                                        thanks

                                        AnticimexA Offline
                                        AnticimexA Offline
                                        Anticimex
                                        Contest Winner
                                        wrote on last edited by
                                        #319

                                        @meddie could you please try an experiment?
                                        Configure the personalizer to use soft signing and store a soft hmac key and serial to eeprom? Just make up some numbers as keys and see if the same problem happen with those or if it is just the AES key that fail.

                                        Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                                        M 2 Replies Last reply
                                        0
                                        • AnticimexA Anticimex

                                          @meddie could you please try an experiment?
                                          Configure the personalizer to use soft signing and store a soft hmac key and serial to eeprom? Just make up some numbers as keys and see if the same problem happen with those or if it is just the AES key that fail.

                                          M Offline
                                          M Offline
                                          meddie
                                          wrote on last edited by
                                          #320

                                          @Anticimex
                                          yes of course!!!
                                          here is the sketch:

                                          #include "sha204_library.h"
                                          #include "sha204_lib_return_codes.h"
                                          #define MY_CORE_ONLY
                                          #include <MySensors.h>
                                          
                                          // Doxygen specific constructs, not included when built normally
                                          // This is used to enable disabled macros/definitions to be included in the documentation as well.
                                          #if DOXYGEN
                                          #define LOCK_CONFIGURATION
                                          #define LOCK_DATA
                                          #define SKIP_KEY_STORAGE
                                          #define USER_KEY
                                          #define SKIP_UART_CONFIRMATION
                                          #define USE_SOFT_SIGNING
                                          #define STORE_SOFT_KEY
                                          #define USER_SOFT_KEY
                                          #define STORE_SOFT_SERIAL
                                          #define USER_SOFT_SERIAL
                                          #define STORE_AES_KEY
                                          #define USER_AES_KEY
                                          #endif
                                          
                                          #define LOCK_CONFIGURATION
                                          
                                          
                                          //#define LOCK_DATA
                                          
                                          
                                          //#define SKIP_KEY_STORAGE
                                          
                                          
                                          //#define USER_KEY
                                          
                                          
                                          //#define SKIP_UART_CONFIRMATION
                                          
                                          
                                          #define USE_SOFT_SIGNING
                                          
                                          
                                          #define STORE_SOFT_KEY
                                          
                                          
                                          #define USER_SOFT_KEY
                                          
                                          
                                          #define STORE_SOFT_SERIAL
                                          
                                          
                                          #define USER_SOFT_SERIAL
                                          
                                          
                                          #define STORE_AES_KEY
                                          
                                          
                                          //#define USER_AES_KEY
                                          
                                          #if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY)
                                          #error You have to define USER_KEY for boards that does not have UART
                                          #endif
                                          
                                          #ifdef USER_KEY
                                          /** @brief The user-defined HMAC key to use for personalization */
                                          #define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                          /** @brief The data to store in key slot 0 */
                                          const uint8_t user_key_data[32] = {MY_HMAC_KEY};
                                          #endif
                                          
                                          #ifdef USER_SOFT_KEY
                                          /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
                                          #define MY_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x010,0x11,0x12,0x13,0x14,0x15,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xAA,0xAB,0xBA,0xBB,0xAC,0xAD,0xAE,0xEB,0xEC,0xED,0xDD
                                          /** @brief The data to store as soft HMAC key in EEPROM */
                                          const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
                                          #endif
                                          
                                          #ifdef USER_SOFT_SERIAL
                                          /** @brief The user-defined soft serial to use for EEPROM personalization */
                                          #define MY_SOFT_SERIAL 0x10,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02
                                          /** @brief The data to store as soft serial in EEPROM */
                                          const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
                                          #endif
                                          
                                          #ifdef USER_AES_KEY
                                          /** @brief The user-defined AES key to use for EEPROM personalization */
                                          #define MY_AES_KEY 0x15,0x14,0x13,0x12,0x11,0x10,0x09,0x08,0x07,0x06,0x05,0x05,0x04,0x03,0x14,0x15
                                          /** @brief The data to store as AES key in EEPROM */
                                          const uint8_t user_aes_key[16] = {MY_AES_KEY};
                                          #endif
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
                                          atsha204Class sha204(sha204Pin);
                                          #endif
                                          
                                          /** @brief Print a error notice and halt the execution */
                                          void halt()
                                          {
                                          	Serial.println(F("Halting!"));
                                          	while(1);
                                          }
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          
                                          uint16_t write_config_and_get_crc()
                                          {
                                          	uint16_t crc = 0;
                                          	uint8_t config_word[4];
                                          	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                                          	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                                          	uint8_t ret_code;
                                          	bool do_write;
                                          
                                          	
                                          	for (int i=0; i < 88; i += 4) {
                                          		do_write = true;
                                          		if (i == 20) {
                                          			config_word[0] = 0x8F;
                                          			config_word[1] = 0x80;
                                          			config_word[2] = 0x80;
                                          			config_word[3] = 0xA1;
                                          		} else if (i == 24) {
                                          			config_word[0] = 0x82;
                                          			config_word[1] = 0xE0;
                                          			config_word[2] = 0xA3;
                                          			config_word[3] = 0x60;
                                          		} else if (i == 28) {
                                          			config_word[0] = 0x94;
                                          			config_word[1] = 0x40;
                                          			config_word[2] = 0xA0;
                                          			config_word[3] = 0x85;
                                          		} else if (i == 32) {
                                          			config_word[0] = 0x86;
                                          			config_word[1] = 0x40;
                                          			config_word[2] = 0x87;
                                          			config_word[3] = 0x07;
                                          		} else if (i == 36) {
                                          			config_word[0] = 0x0F;
                                          			config_word[1] = 0x00;
                                          			config_word[2] = 0x89;
                                          			config_word[3] = 0xF2;
                                          		} else if (i == 40) {
                                          			config_word[0] = 0x8A;
                                          			config_word[1] = 0x7A;
                                          			config_word[2] = 0x0B;
                                          			config_word[3] = 0x8B;
                                          		} else if (i == 44) {
                                          			config_word[0] = 0x0C;
                                          			config_word[1] = 0x4C;
                                          			config_word[2] = 0xDD;
                                          			config_word[3] = 0x4D;
                                          		} else if (i == 48) {
                                          			config_word[0] = 0xC2;
                                          			config_word[1] = 0x42;
                                          			config_word[2] = 0xAF;
                                          			config_word[3] = 0x8F;
                                          		} else if (i == 52 || i == 56 || i == 60 || i == 64) {
                                          			config_word[0] = 0xFF;
                                          			config_word[1] = 0x00;
                                          			config_word[2] = 0xFF;
                                          			config_word[3] = 0x00;
                                          		} else if (i == 68 || i == 72 || i == 76 || i == 80) {
                                          			config_word[0] = 0xFF;
                                          			config_word[1] = 0xFF;
                                          			config_word[2] = 0xFF;
                                          			config_word[3] = 0xFF;
                                          		} else {
                                          			// All other configs are untouched
                                          			ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Failed to read config. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          			// Set config_word to the read data
                                          			config_word[0] = rx_buffer[SHA204_BUFFER_POS_DATA+0];
                                          			config_word[1] = rx_buffer[SHA204_BUFFER_POS_DATA+1];
                                          			config_word[2] = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          			config_word[3] = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          			do_write = false;
                                          		}
                                          
                                          		// Update crc with CRC for the current word
                                          		crc = sha204.calculateAndUpdateCrc(4, config_word, crc);
                                          
                                          		// Write config word
                                          		if (do_write) {
                                          			ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_CONFIG,
                                          			                                  i >> 2, 4, config_word, 0, NULL, 0, NULL,
                                          			                                  WRITE_COUNT_SHORT, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Failed to write config word at address "));
                                          				Serial.print(i);
                                          				Serial.print(F(". Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          		}
                                          	}
                                          	return crc;
                                          }
                                          
                                          
                                          void write_key(uint8_t* key)
                                          {
                                          	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                                          	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                                          	uint8_t ret_code;
                                          
                                          	// Write key to slot 0
                                          	ret_code = sha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG,
                                          	                                  0, SHA204_ZONE_ACCESS_32, key, 0, NULL, 0, NULL,
                                          	                                  WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to write key to slot 0. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	}
                                          }
                                          #endif // not USE_SOFT_SIGNING
                                          
                                          /** @brief Dump current configuration to UART */
                                          void dump_configuration()
                                          {
                                          	uint8_t buffer[32];
                                          #ifndef USE_SOFT_SIGNING
                                          	Serial.println(F("EEPROM DATA:"));
                                          #endif
                                          	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                                          	Serial.print(F("SOFT_HMAC_KEY | "));
                                          	for (int j=0; j<32; j++) {
                                          		if (buffer[j] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(buffer[j], HEX);
                                          	}
                                          	Serial.println();
                                          	hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                                          	Serial.print(F("SOFT_SERIAL   | "));
                                          	for (int j=0; j<9; j++) {
                                          		if (buffer[j] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(buffer[j], HEX);
                                          	}
                                          	Serial.println();
                                          	hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                                          	Serial.print(F("AES_KEY       | "));
                                          	for (int j=0; j<16; j++) {
                                          		if (buffer[j] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(buffer[j], HEX);
                                          	}
                                          	Serial.println();
                                          #ifndef USE_SOFT_SIGNING
                                          	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                                          	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                                          	uint8_t ret_code;
                                          	Serial.println(F("ATSHA204A DATA:"));
                                          	for (int i=0; i < 88; i += 4) {
                                          		ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i);
                                          		if (ret_code != SHA204_SUCCESS) {
                                          			Serial.print(F("Failed to read config. Response: "));
                                          			Serial.println(ret_code, HEX);
                                          			halt();
                                          		}
                                          		if (i == 0x00) {
                                          			Serial.print(F("           SN[0:1]           |         SN[2:3]           | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x04) {
                                          			Serial.print(F("                          Revnum                         | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x08) {
                                          			Serial.print(F("                          SN[4:7]                        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x0C) {
                                          			Serial.print(F("    SN[8]    |  Reserved13   | I2CEnable | Reserved15    | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x10) {
                                          			Serial.print(F("  I2CAddress |  TempOffset   |  OTPmode  | SelectorMode  | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x14) {
                                          			Serial.print(F("         SlotConfig00        |       SlotConfig01        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x18) {
                                          			Serial.print(F("         SlotConfig02        |       SlotConfig03        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x1C) {
                                          			Serial.print(F("         SlotConfig04        |       SlotConfig05        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x20) {
                                          			Serial.print(F("         SlotConfig06        |       SlotConfig07        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x24) {
                                          			Serial.print(F("         SlotConfig08        |       SlotConfig09        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x28) {
                                          			Serial.print(F("         SlotConfig0A        |       SlotConfig0B        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x2C) {
                                          			Serial.print(F("         SlotConfig0C        |       SlotConfig0D        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x30) {
                                          			Serial.print(F("         SlotConfig0E        |       SlotConfig0F        | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j == 1) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x34) {
                                          			Serial.print(F("  UseFlag00  | UpdateCount00 | UseFlag01 | UpdateCount01 | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x38) {
                                          			Serial.print(F("  UseFlag02  | UpdateCount02 | UseFlag03 | UpdateCount03 | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x3C) {
                                          			Serial.print(F("  UseFlag04  | UpdateCount04 | UseFlag05 | UpdateCount05 | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x40) {
                                          			Serial.print(F("  UseFlag06  | UpdateCount06 | UseFlag07 | UpdateCount07 | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x44) {
                                          			Serial.print(F("                      LastKeyUse[0:3]                    | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x48) {
                                          			Serial.print(F("                      LastKeyUse[4:7]                    | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x4C) {
                                          			Serial.print(F("                      LastKeyUse[8:B]                    | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x50) {
                                          			Serial.print(F("                      LastKeyUse[C:F]                    | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				Serial.print(F("   "));
                                          			}
                                          			Serial.println();
                                          		} else if (i == 0x54) {
                                          			Serial.print(F("  UserExtra  |    Selector   | LockValue |  LockConfig   | "));
                                          			for (int j=0; j<4; j++) {
                                          				if (rx_buffer[SHA204_BUFFER_POS_DATA+j] < 0x10) {
                                          					Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          				}
                                          				Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+j], HEX);
                                          				if (j < 3) {
                                          					Serial.print(F(" | "));
                                          				} else {
                                          					Serial.print(F("   "));
                                          				}
                                          			}
                                          			Serial.println();
                                          		}
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          }
                                          
                                          /** @brief Sketch setup code */
                                          void setup()
                                          {
                                          	// Delay startup a bit for serial consoles to catch up
                                          	unsigned long enter = hwMillis();
                                          	while (hwMillis() - enter < (unsigned long)500);
                                          #ifndef USE_SOFT_SIGNING
                                          	uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
                                          	uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
                                          	uint8_t ret_code;
                                          	uint8_t lockConfig = 0;
                                          	uint8_t lockValue = 0;
                                          	uint16_t crc;
                                          	(void)crc;
                                          #else
                                          	// initialize pseudo-RNG
                                          	randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN));
                                          #endif
                                          	uint8_t key[32];
                                          	(void)key;
                                          
                                          	Serial.begin(9600);
                                          	hwInit();
                                          	Serial.println(F("Personalization sketch for MySensors usage."));
                                          	Serial.println(F("-------------------------------------------"));
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          	// Wake device before starting operations
                                          	ret_code = sha204.sha204c_wakeup(rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to wake device. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	}
                                          	// Read out lock config bits to determine if locking is possible
                                          	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to determine device lock status. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          	}
                                          #endif
                                          
                                          #ifdef STORE_SOFT_KEY
                                          #ifdef USER_SOFT_KEY
                                          	memcpy(key, user_soft_key_data, 32);
                                          	Serial.println(F("Using this user supplied soft HMAC key:"));
                                          #else
                                          	// Retrieve random value to use as soft HMAC key
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 32; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_SOFT_KEY
                                          	Serial.print("#define MY_SOFT_HMAC_KEY ");
                                          	for (int i=0; i<32; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 31) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                                          #endif // STORE_SOFT_KEY
                                          
                                          #ifdef STORE_SOFT_SERIAL
                                          #ifdef USER_SOFT_SERIAL
                                          	memcpy(key, user_soft_serial, 9);
                                          	Serial.println(F("Using this user supplied soft serial:"));
                                          #else
                                          	// Retrieve random value to use as serial
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 9; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random serial generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                          	} else {
                                          		Serial.println(F("Serial is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_SOFT_SERIAL
                                          	Serial.print("#define MY_SOFT_SERIAL ");
                                          	for (int i=0; i<9; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 8) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                                          #endif // STORE_SOFT_SERIAL
                                          
                                          #ifdef STORE_AES_KEY
                                          #ifdef USER_AES_KEY
                                          	memcpy(key, user_aes_key, 16);
                                          	Serial.println(F("Using this user supplied AES key:"));
                                          #else
                                          	// Retrieve random value to use as key
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 16; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_AES_KEY
                                          	Serial.print("#define MY_AES_KEY ");
                                          	for (int i=0; i<16; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 15) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                                          #endif // STORE_AES_KEY
                                          
                                          #ifdef USE_SOFT_SIGNING
                                          	Serial.println(F("EEPROM configuration:"));
                                          	dump_configuration();
                                          #else
                                          	// Output device revision on console
                                          	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to determine device revision. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		Serial.print(F("Device revision: "));
                                          		for (int i=0; i<4; i++) {
                                          			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
                                          		}
                                          		Serial.println();
                                          	}
                                          
                                          	// Output serial number on console
                                          	ret_code = sha204.getSerialNumber(rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to obtain device serial number. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		Serial.print(F("Device serial:   "));
                                          		Serial.print('{');
                                          		for (int i=0; i<9; i++) {
                                          			Serial.print(F("0x"));
                                          			if (rx_buffer[i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[i], HEX);
                                          			if (i < 8) {
                                          				Serial.print(',');
                                          			}
                                          		}
                                          		Serial.print('}');
                                          		Serial.println();
                                          		for (int i=0; i<9; i++) {
                                          			if (rx_buffer[i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[i], HEX);
                                          		}
                                          		Serial.println();
                                          	}
                                          
                                          	if (lockConfig != 0x00) {
                                          		// Write config and get CRC for the updated config
                                          		crc = write_config_and_get_crc();
                                          
                                          		// List current configuration before attempting to lock
                                          		Serial.println(F("Chip configuration:"));
                                          		dump_configuration();
                                          
                                          #ifdef LOCK_CONFIGURATION
                                          		// Purge serial input buffer
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		while (Serial.available()) {
                                          			Serial.read();
                                          		}
                                          		Serial.println(F("Send SPACE character now to lock the configuration..."));
                                          
                                          		while (Serial.available() == 0);
                                          		if (Serial.read() == ' ')
                                          #endif //not SKIP_UART_CONFIRMATION
                                          		{
                                          			Serial.println(F("Locking configuration..."));
                                          
                                          			// Correct sequence, resync chip
                                          			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                          				Serial.print(F("Resync failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          
                                          			// Lock configuration zone
                                          			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                                          			                                  crc, 0, NULL, 0, NULL, 0, NULL,
                                          			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Configuration lock failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			} else {
                                          				Serial.println(F("Configuration locked."));
                                          
                                          				// Update lock flags after locking
                                          				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          				if (ret_code != SHA204_SUCCESS) {
                                          					Serial.print(F("Failed to determine device lock status. Response: "));
                                          					Serial.println(ret_code, HEX);
                                          					halt();
                                          				} else {
                                          					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          				}
                                          			}
                                          		}
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		else {
                                          			Serial.println(F("Unexpected answer. Skipping lock."));
                                          		}
                                          #endif //not SKIP_UART_CONFIRMATION
                                          #else //LOCK_CONFIGURATION
                                          		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
                                          #endif
                                          	} else {
                                          		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
                                          		Serial.println(F("Chip configuration:"));
                                          		dump_configuration();
                                          	}
                                          
                                          #ifdef SKIP_KEY_STORAGE
                                          	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
                                          #else
                                          #ifdef USER_KEY
                                          	memcpy(key, user_key_data, 32);
                                          	Serial.println(F("Using this user supplied HMAC key:"));
                                          #else
                                          	// Retrieve random value to use as key
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("Take note of this key, it will never be the shown again:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif
                                          	Serial.print("#define MY_HMAC_KEY ");
                                          	for (int i=0; i<32; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 31) {
                                          			Serial.print(',');
                                          		}
                                          		if (i+1 == 16) {
                                          			Serial.print("\\\n                    ");
                                          		}
                                          	}
                                          	Serial.println();
                                          
                                          	// It will not be possible to write the key if the configuration zone is unlocked
                                          	if (lockConfig == 0x00) {
                                          		// Write the key to the appropriate slot in the data zone
                                          		Serial.println(F("Writing key to slot 0..."));
                                          		write_key(key);
                                          	} else {
                                          		Serial.println(F("Skipping key storage (configuration not locked)."));
                                          		Serial.println(F("The configuration must be locked to be able to write a key."));
                                          	}
                                          #endif
                                          
                                          	if (lockValue != 0x00) {
                                          #ifdef LOCK_DATA
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		while (Serial.available()) {
                                          			Serial.read();
                                          		}
                                          		Serial.println(F("Send SPACE character to lock data..."));
                                          		while (Serial.available() == 0);
                                          		if (Serial.read() == ' ')
                                          #endif //not SKIP_UART_CONFIRMATION
                                          		{
                                          			// Correct sequence, resync chip
                                          			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                          				Serial.print(F("Resync failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          
                                          			// If configuration is unlocked, key is not updated. Locking data in this case will cause
                                          			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
                                          			// usecase not the desired behaviour, so ask for additional confirmation in this case.
                                          			if (lockConfig != 0x00) {
                                          				while (Serial.available()) {
                                          					Serial.read();
                                          				}
                                          				Serial.println(F("*** ATTENTION ***"));
                                          				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
                                          				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
                                          				Serial.println(
                                          				    F("which cannot be change after locking is done. This is in practically any usecase"));
                                          				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
                                          				while (Serial.available() == 0);
                                          				if (Serial.read() != ' ') {
                                          					Serial.println(F("Unexpected answer. Skipping lock."));
                                          					halt();
                                          				}
                                          			}
                                          
                                          			// Lock data zone
                                          			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                                          			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                                          			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Data lock failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			} else {
                                          				Serial.println(F("Data locked."));
                                          
                                          				// Update lock flags after locking
                                          				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          				if (ret_code != SHA204_SUCCESS) {
                                          					Serial.print(F("Failed to determine device lock status. Response: "));
                                          					Serial.println(ret_code, HEX);
                                          					halt();
                                          				} else {
                                          					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          				}
                                          			}
                                          		}
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		else {
                                          			Serial.println(F("Unexpected answer. Skipping lock."));
                                          		}
                                          #endif //not SKIP_UART_CONFIRMATION
                                          #else //LOCK_DATA
                                          		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
                                          #endif
                                          	} else {
                                          		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          
                                          	Serial.println(F("--------------------------------"));
                                          	Serial.println(F("Personalization is now complete."));
                                          #ifndef USE_SOFT_SIGNING
                                          	Serial.print(F("Configuration is "));
                                          	if (lockConfig == 0x00) {
                                          		Serial.println("LOCKED");
                                          	} else {
                                          		Serial.println("UNLOCKED");
                                          	}
                                          	Serial.print(F("Data is "));
                                          	if (lockValue == 0x00) {
                                          		Serial.println("LOCKED");
                                          	} else {
                                          		Serial.println("UNLOCKED");
                                          	}
                                          #endif
                                          }
                                          
                                          /** @brief Sketch execution code */
                                          void loop()
                                          {
                                          }
                                          
                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          8

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular