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 333.9k 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.
  • alexsh1A Offline
    alexsh1A Offline
    alexsh1
    wrote on last edited by
    #267

    @Anticimex I must admit that signing is working really-really nicely on my custom made nodes (Soft sign and ATSHA204A)

    Apart from a small issue with the sensebender, which I believe is not a signing issue, it is working like a charm. All credit to you! Thank you

    Starting sensor (RNNNAS, 2.0.0-beta)
    Radio init successful.
    HTU21D Sensor1.1 - Online!
    isMetric: 1
    TempDiff :1098.00
    HumDiff  :136.75
    T: 998.00
    H: 36.75
    send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:998.0
    send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
    send: 5-5-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.29
    send: 5-5-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:106
    Signing required
    send: 5-5-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok:
    Waiting for GW to send signing preferences...
    Skipping security for command 3 type 15
    read: 0-0-5 s=255,c=3,t=15,pt=0,l=2,sg=0:
    Mark node 0 as one that do not require signed messages
    Mark node 0 as one that do not require whitelisting
    send: 5-5-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta
    send: 5-5-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    Skipping security for command 3 type 16
    read: 0-0-5 s=255,c=3,t=16,pt=0,l=0,sg=0:
    Signing backend: ATSHA204Soft
    SHA256: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE00000000000000
    Transmittng nonce
    send: 5-5-0-0 s=255,c=3,t=17,pt=6,l=25,sg=0,st=ok:2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE
    Signature in message: 01C31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC8
    Message to process: 00050E0306FF4D
    Current nonce: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FEAAAAAAAAAAAAAA
    HMAC: 0CC31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC89A82A89D87E931B8
    Signature OK
    read: 0-0-5 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    send: 5-5-0-0 s=255,c=3,t=11,pt=0,l=24,sg=0,st=ok:Temp/Hum Sensor - HTU21D
    send: 5-5-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.1
    send: 5-5-0-0 s=0,c=0,t=6,pt=0,l=0,sg=0,st=ok:
    send: 5-5-0-0 s=1,c=0,t=7,pt=0,l=0,sg=0,st=ok:
    send: 5-5-0-0 s=2,c=0,t=13,pt=0,l=0,sg=0,st=ok:
    Init complete, id=5, parent=0, distance=1
    TempDiff :971.94
    HumDiff  :0.02
    T: 26.06
    H: 36.72
    send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:26.1
    send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
    
    AnticimexA 1 Reply Last reply
    1
    • alexsh1A alexsh1

      @Anticimex I must admit that signing is working really-really nicely on my custom made nodes (Soft sign and ATSHA204A)

      Apart from a small issue with the sensebender, which I believe is not a signing issue, it is working like a charm. All credit to you! Thank you

      Starting sensor (RNNNAS, 2.0.0-beta)
      Radio init successful.
      HTU21D Sensor1.1 - Online!
      isMetric: 1
      TempDiff :1098.00
      HumDiff  :136.75
      T: 998.00
      H: 36.75
      send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:998.0
      send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
      send: 5-5-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.29
      send: 5-5-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:106
      Signing required
      send: 5-5-0-0 s=255,c=3,t=15,pt=0,l=2,sg=0,st=ok:
      Waiting for GW to send signing preferences...
      Skipping security for command 3 type 15
      read: 0-0-5 s=255,c=3,t=15,pt=0,l=2,sg=0:
      Mark node 0 as one that do not require signed messages
      Mark node 0 as one that do not require whitelisting
      send: 5-5-0-0 s=255,c=0,t=17,pt=0,l=10,sg=0,st=ok:2.0.0-beta
      send: 5-5-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
      Skipping security for command 3 type 16
      read: 0-0-5 s=255,c=3,t=16,pt=0,l=0,sg=0:
      Signing backend: ATSHA204Soft
      SHA256: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE00000000000000
      Transmittng nonce
      send: 5-5-0-0 s=255,c=3,t=17,pt=6,l=25,sg=0,st=ok:2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FE
      Signature in message: 01C31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC8
      Message to process: 00050E0306FF4D
      Current nonce: 2C4A871ACCAE26760F41E547DD39B7B816FE22EEBCD8DFA2FEAAAAAAAAAAAAAA
      HMAC: 0CC31110DAE29D5DCD3771F68B6F29B5CCCF43A3D5397CC89A82A89D87E931B8
      Signature OK
      read: 0-0-5 s=255,c=3,t=6,pt=0,l=1,sg=0:M
      send: 5-5-0-0 s=255,c=3,t=11,pt=0,l=24,sg=0,st=ok:Temp/Hum Sensor - HTU21D
      send: 5-5-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.1
      send: 5-5-0-0 s=0,c=0,t=6,pt=0,l=0,sg=0,st=ok:
      send: 5-5-0-0 s=1,c=0,t=7,pt=0,l=0,sg=0,st=ok:
      send: 5-5-0-0 s=2,c=0,t=13,pt=0,l=0,sg=0,st=ok:
      Init complete, id=5, parent=0, distance=1
      TempDiff :971.94
      HumDiff  :0.02
      T: 26.06
      H: 36.72
      send: 5-5-0-0 s=0,c=1,t=0,pt=7,l=5,sg=0,st=ok:26.1
      send: 5-5-0-0 s=1,c=1,t=1,pt=7,l=5,sg=0,st=ok:36.7
      
      AnticimexA Offline
      AnticimexA Offline
      Anticimex
      Contest Winner
      wrote on last edited by
      #268

      @alexsh1 I'm really glad to hear that. Thank you! Glad that signing is being used and is perceived as something not to complicated to bother with. It sets us apart from many other projects dealing with the same thing :)

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

      alexsh1A 1 Reply Last reply
      0
      • AnticimexA Anticimex

        @alexsh1 I'm really glad to hear that. Thank you! Glad that signing is being used and is perceived as something not to complicated to bother with. It sets us apart from many other projects dealing with the same thing :)

        alexsh1A Offline
        alexsh1A Offline
        alexsh1
        wrote on last edited by
        #269

        @Anticimex I did not say it was not complicated :)
        Just kidding - speaking just for myself, it did require some time investment to understand the concept and then upgrading my gateway and my nodes (I am still in the process of rolling signing across the rest of my nodes) to MySensors 2.0b. I probably spent more time upgrading MySensors lib and breaking some hardware in the meantime (the SMA connector on the nrf24l01+ PA+LNA) than the actual signing.

        AnticimexA 1 Reply Last reply
        0
        • alexsh1A alexsh1

          @Anticimex I did not say it was not complicated :)
          Just kidding - speaking just for myself, it did require some time investment to understand the concept and then upgrading my gateway and my nodes (I am still in the process of rolling signing across the rest of my nodes) to MySensors 2.0b. I probably spent more time upgrading MySensors lib and breaking some hardware in the meantime (the SMA connector on the nrf24l01+ PA+LNA) than the actual signing.

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

          @alexsh1 yeah, well if there is room for improvement in the documentation then feel free to help put with suggestions if there is anything unclear about that :) I use doxygen to document signing features, and a link is available on the GitHub "front-page" (the readme.md)

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

          alexsh1A 1 Reply Last reply
          0
          • AnticimexA Anticimex

            @alexsh1 yeah, well if there is room for improvement in the documentation then feel free to help put with suggestions if there is anything unclear about that :) I use doxygen to document signing features, and a link is available on the GitHub "front-page" (the readme.md)

            alexsh1A Offline
            alexsh1A Offline
            alexsh1
            wrote on last edited by
            #271

            @Anticimex I think a noob's section would be good. Having said that, the point is that signing is not something beginners should touch. What do you think?

            How about a section on the web-site? Somewhere here - https://www.mysensors.org/build/

            AnticimexA 1 Reply Last reply
            0
            • alexsh1A alexsh1

              @Anticimex I think a noob's section would be good. Having said that, the point is that signing is not something beginners should touch. What do you think?

              How about a section on the web-site? Somewhere here - https://www.mysensors.org/build/

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

              @alexsh1 hm, yeah, perhaps something for @hek to consider. At least a link to the signing section of the doxygen docs could be placed there. I have tried to make the documentation as step-by-step friendly as I can. That said, as I also did the actual implementation, I may well be blind for certain aspects I take for granted that a "novice" does not.

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

              1 Reply Last reply
              0
              • hekH Offline
                hekH Offline
                hek
                Admin
                wrote on last edited by
                #273

                The next release of the main site will be much more flexible and integrated with openhardware-added projects. The idea is to allow community members to maintain their projects and/or "articles" themselves. The how-to for signing is a good example of an article.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  Fabien
                  wrote on last edited by
                  #274

                  This tutorial is up to date for 2.0 release ?

                  AnticimexA 1 Reply Last reply
                  0
                  • F Fabien

                    This tutorial is up to date for 2.0 release ?

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

                    @Fabien Yes, top post is now updated for 2.0.0. Documentation is in doxygen.

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

                    1 Reply Last reply
                    1
                    • F Offline
                      F Offline
                      Fabien
                      wrote on last edited by
                      #276

                      Thank you @Anticimex I will update my network soon and had RFM69 Encryption too.

                      1 Reply Last reply
                      0
                      • NiklasON Offline
                        NiklasON Offline
                        NiklasO
                        wrote on last edited by NiklasO
                        #277

                        Trying this:
                        https://www.mysensors.org/build/raspberry

                        How do I enable signing and give the gateway the serial, hmac and aes-key when running on Linux? (rPi).

                        Edit: Pin 7 as random number generator maybe need some change?

                        AnticimexA 1 Reply Last reply
                        0
                        • NiklasON NiklasO

                          Trying this:
                          https://www.mysensors.org/build/raspberry

                          How do I enable signing and give the gateway the serial, hmac and aes-key when running on Linux? (rPi).

                          Edit: Pin 7 as random number generator maybe need some change?

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

                          @NiklasO @marceloaqno is working on this.

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

                          1 Reply Last reply
                          1
                          • E Offline
                            E Offline
                            executivul
                            wrote on last edited by
                            #279

                            Hi,
                            I have about 100 ATSHA204 I2C variant to be used in a MySensors project.
                            Do you think that by modifying the personalizer sketch to disable the I2C bit in the configuration (0x03 word address) the chips can be set to be used as single-wire, or are they hardcoded to use only one protocol, but then why having the config bit?

                            AnticimexA 1 Reply Last reply
                            0
                            • E executivul

                              Hi,
                              I have about 100 ATSHA204 I2C variant to be used in a MySensors project.
                              Do you think that by modifying the personalizer sketch to disable the I2C bit in the configuration (0x03 word address) the chips can be set to be used as single-wire, or are they hardcoded to use only one protocol, but then why having the config bit?

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

                              @executivul The bit is readonly. You cannot change it. It is used to determine the variant of chip, not to select mode of operation.
                              From the documentation:
                              0_1478094689558_upload-93242040-4814-4ad6-8951-4ad4d1e99a23
                              But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.

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

                              E 1 Reply Last reply
                              0
                              • AnticimexA Anticimex

                                @executivul The bit is readonly. You cannot change it. It is used to determine the variant of chip, not to select mode of operation.
                                From the documentation:
                                0_1478094689558_upload-93242040-4814-4ad6-8951-4ad4d1e99a23
                                But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.

                                E Offline
                                E Offline
                                executivul
                                wrote on last edited by
                                #281

                                @Anticimex said:
                                But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.

                                Please excuse my noobish ignorance: How and where do I submit one?

                                AnticimexA 1 Reply Last reply
                                0
                                • E executivul

                                  @Anticimex said:
                                  But you are welcome to submit a pull request for adding support for I2C variants of ATSHA204a. I have none myself so I have not bothered looking into that and currently I am out of time to spend on it I am afraid.

                                  Please excuse my noobish ignorance: How and where do I submit one?

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

                                  @executivul By forking the MySensors core repository and create a local git branch, do your code, push it back to your fork on GitHub and then create a pull request from that. There are good guides on GitHub for how do do it.

                                  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
                                    #283

                                    ok, thank you, but do you know why the sketch didnt generate the keys, and instead of random i get only keys ffffffffffff ?
                                    thank you

                                    AnticimexA 1 Reply Last reply
                                    0
                                    • M meddie

                                      ok, thank you, but do you know why the sketch didnt generate the keys, and instead of random i get only keys ffffffffffff ?
                                      thank you

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

                                      @meddie Without actually seeing your sketch it is pretty hard for me to help with anything ;)
                                      My guess is, you did not enable the proper defines to instruct it to generate and store any keys.

                                      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
                                        #285

                                        @Anticimex
                                        Hi i have posted my sketch few posts ago, but no problem here is it:

                                        
                                        
                                        #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 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                        /** @brief The data to store in key slot 0 */
                                        const uint8_t user_key_data[32] = {MY_HMAC_KEY};
                                        #endif
                                        
                                        #ifdef USER_SOFT_KEY
                                        /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
                                        #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                        /** @brief The data to store as soft HMAC key in EEPROM */
                                        const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
                                        #endif
                                        
                                        #ifdef USER_SOFT_SERIAL
                                        /** @brief The user-defined soft serial to use for EEPROM personalization */
                                        #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                        /** @brief The data to store as soft serial in EEPROM */
                                        const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
                                        #endif
                                        
                                        #ifdef USER_AES_KEY
                                        /** @brief The user-defined AES key to use for EEPROM personalization */
                                        #define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                        /** @brief The data to store as AES key in EEPROM */
                                        const uint8_t user_aes_key[16] = {MY_AES_KEY};
                                        #endif
                                        
                                        #ifndef USE_SOFT_SIGNING
                                        const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
                                        atsha204Class sha204(sha204Pin);
                                        #endif
                                        
                                        /** @brief Print a error notice and halt the execution */
                                        void halt()
                                        {
                                        	Serial.println(F("Halting!"));
                                        	while(1);
                                        }
                                        
                                        #ifndef USE_SOFT_SIGNING
                                        
                                        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(115200);
                                        	hwInit();
                                        	Serial.println(F("Personalization sketch for MySensors usage."));
                                        	Serial.println(F("-------------------------------------------"));
                                        
                                        #ifndef USE_SOFT_SIGNING
                                        	// Wake device before starting operations
                                        	ret_code = sha204.sha204c_wakeup(rx_buffer);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Failed to wake device. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	}
                                        	// Read out lock config bits to determine if locking is possible
                                        	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Failed to determine device lock status. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                        		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                        	}
                                        #endif
                                        
                                        #ifdef STORE_SOFT_KEY
                                        #ifdef USER_SOFT_KEY
                                        	memcpy(key, user_soft_key_data, 32);
                                        	Serial.println(F("Using this user supplied soft HMAC key:"));
                                        #else
                                        	// Retrieve random value to use as soft HMAC key
                                        #ifdef USE_SOFT_SIGNING
                                        	for (int i = 0; i < 32; i++) {
                                        		key[i] = random(256) ^ micros();
                                        		unsigned long enter = hwMillis();
                                        		while (hwMillis() - enter < (unsigned long)2);
                                        	}
                                        	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                        #else
                                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Random key generation failed. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                        	}
                                        	if (lockConfig == 0x00) {
                                        		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                        	} else {
                                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                                        	}
                                        #endif // not USE_SOFT_SIGNING
                                        #endif // not USER_SOFT_KEY
                                        	Serial.print("#define MY_SOFT_HMAC_KEY ");
                                        	for (int i=0; i<32; i++) {
                                        		Serial.print("0x");
                                        		if (key[i] < 0x10) {
                                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        		}
                                        		Serial.print(key[i], HEX);
                                        		if (i < 31) {
                                        			Serial.print(',');
                                        		}
                                        	}
                                        	Serial.println();
                                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                                        #endif // STORE_SOFT_KEY
                                        
                                        #ifdef STORE_SOFT_SERIAL
                                        #ifdef USER_SOFT_SERIAL
                                        	memcpy(key, user_soft_serial, 9);
                                        	Serial.println(F("Using this user supplied soft serial:"));
                                        #else
                                        	// Retrieve random value to use as serial
                                        #ifdef USE_SOFT_SIGNING
                                        	for (int i = 0; i < 9; i++) {
                                        		key[i] = random(256) ^ micros();
                                        		unsigned long enter = hwMillis();
                                        		while (hwMillis() - enter < (unsigned long)2);
                                        	}
                                        	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                        #else
                                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Random serial generation failed. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
                                        	}
                                        	if (lockConfig == 0x00) {
                                        		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                        	} else {
                                        		Serial.println(F("Serial is not randomized (configuration not locked):"));
                                        	}
                                        #endif // not USE_SOFT_SIGNING
                                        #endif // not USER_SOFT_SERIAL
                                        	Serial.print("#define MY_SOFT_SERIAL ");
                                        	for (int i=0; i<9; i++) {
                                        		Serial.print("0x");
                                        		if (key[i] < 0x10) {
                                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        		}
                                        		Serial.print(key[i], HEX);
                                        		if (i < 8) {
                                        			Serial.print(',');
                                        		}
                                        	}
                                        	Serial.println();
                                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                                        #endif // STORE_SOFT_SERIAL
                                        
                                        #ifdef STORE_AES_KEY
                                        #ifdef USER_AES_KEY
                                        	memcpy(key, user_aes_key, 16);
                                        	Serial.println(F("Using this user supplied AES key:"));
                                        #else
                                        	// Retrieve random value to use as key
                                        #ifdef USE_SOFT_SIGNING
                                        	for (int i = 0; i < 16; i++) {
                                        		key[i] = random(256) ^ micros();
                                        		unsigned long enter = hwMillis();
                                        		while (hwMillis() - enter < (unsigned long)2);
                                        	}
                                        	Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                        #else
                                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Random key generation failed. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                        	}
                                        	if (lockConfig == 0x00) {
                                        		Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                        	} else {
                                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                                        	}
                                        #endif // not USE_SOFT_SIGNING
                                        #endif // not USER_AES_KEY
                                        	Serial.print("#define MY_AES_KEY ");
                                        	for (int i=0; i<16; i++) {
                                        		Serial.print("0x");
                                        		if (key[i] < 0x10) {
                                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        		}
                                        		Serial.print(key[i], HEX);
                                        		if (i < 15) {
                                        			Serial.print(',');
                                        		}
                                        	}
                                        	Serial.println();
                                        	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                                        #endif // STORE_AES_KEY
                                        
                                        #ifdef USE_SOFT_SIGNING
                                        	Serial.println(F("EEPROM configuration:"));
                                        	dump_configuration();
                                        #else
                                        	// Output device revision on console
                                        	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Failed to determine device revision. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		Serial.print(F("Device revision: "));
                                        		for (int i=0; i<4; i++) {
                                        			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
                                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        			}
                                        			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
                                        		}
                                        		Serial.println();
                                        	}
                                        
                                        	// Output serial number on console
                                        	ret_code = sha204.getSerialNumber(rx_buffer);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Failed to obtain device serial number. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		Serial.print(F("Device serial:   "));
                                        		Serial.print('{');
                                        		for (int i=0; i<9; i++) {
                                        			Serial.print(F("0x"));
                                        			if (rx_buffer[i] < 0x10) {
                                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        			}
                                        			Serial.print(rx_buffer[i], HEX);
                                        			if (i < 8) {
                                        				Serial.print(',');
                                        			}
                                        		}
                                        		Serial.print('}');
                                        		Serial.println();
                                        		for (int i=0; i<9; i++) {
                                        			if (rx_buffer[i] < 0x10) {
                                        				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        			}
                                        			Serial.print(rx_buffer[i], HEX);
                                        		}
                                        		Serial.println();
                                        	}
                                        
                                        	if (lockConfig != 0x00) {
                                        		// Write config and get CRC for the updated config
                                        		crc = write_config_and_get_crc();
                                        
                                        		// List current configuration before attempting to lock
                                        		Serial.println(F("Chip configuration:"));
                                        		dump_configuration();
                                        
                                        #ifdef LOCK_CONFIGURATION
                                        		// Purge serial input buffer
                                        #ifndef SKIP_UART_CONFIRMATION
                                        		while (Serial.available()) {
                                        			Serial.read();
                                        		}
                                        		Serial.println(F("Send SPACE character now to lock the configuration..."));
                                        
                                        		while (Serial.available() == 0);
                                        		if (Serial.read() == ' ')
                                        #endif //not SKIP_UART_CONFIRMATION
                                        		{
                                        			Serial.println(F("Locking configuration..."));
                                        
                                        			// Correct sequence, resync chip
                                        			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                        			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                        				Serial.print(F("Resync failed. Response: "));
                                        				Serial.println(ret_code, HEX);
                                        				halt();
                                        			}
                                        
                                        			// Lock configuration zone
                                        			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                                        			                                  crc, 0, NULL, 0, NULL, 0, NULL,
                                        			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                        			if (ret_code != SHA204_SUCCESS) {
                                        				Serial.print(F("Configuration lock failed. Response: "));
                                        				Serial.println(ret_code, HEX);
                                        				halt();
                                        			} else {
                                        				Serial.println(F("Configuration locked."));
                                        
                                        				// Update lock flags after locking
                                        				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                        				if (ret_code != SHA204_SUCCESS) {
                                        					Serial.print(F("Failed to determine device lock status. Response: "));
                                        					Serial.println(ret_code, HEX);
                                        					halt();
                                        				} else {
                                        					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                        					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                        				}
                                        			}
                                        		}
                                        #ifndef SKIP_UART_CONFIRMATION
                                        		else {
                                        			Serial.println(F("Unexpected answer. Skipping lock."));
                                        		}
                                        #endif //not SKIP_UART_CONFIRMATION
                                        #else //LOCK_CONFIGURATION
                                        		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
                                        #endif
                                        	} else {
                                        		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
                                        		Serial.println(F("Chip configuration:"));
                                        		dump_configuration();
                                        	}
                                        
                                        #ifdef SKIP_KEY_STORAGE
                                        	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
                                        #else
                                        #ifdef USER_KEY
                                        	memcpy(key, user_key_data, 32);
                                        	Serial.println(F("Using this user supplied HMAC key:"));
                                        #else
                                        	// Retrieve random value to use as key
                                        	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                        	if (ret_code != SHA204_SUCCESS) {
                                        		Serial.print(F("Random key generation failed. Response: "));
                                        		Serial.println(ret_code, HEX);
                                        		halt();
                                        	} else {
                                        		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                        	}
                                        	if (lockConfig == 0x00) {
                                        		Serial.println(F("Take note of this key, it will never be the shown again:"));
                                        	} else {
                                        		Serial.println(F("Key is not randomized (configuration not locked):"));
                                        	}
                                        #endif
                                        	Serial.print("#define MY_HMAC_KEY ");
                                        	for (int i=0; i<32; i++) {
                                        		Serial.print("0x");
                                        		if (key[i] < 0x10) {
                                        			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                        		}
                                        		Serial.print(key[i], HEX);
                                        		if (i < 31) {
                                        			Serial.print(',');
                                        		}
                                        		if (i+1 == 16) {
                                        			Serial.print("\\\n                    ");
                                        		}
                                        	}
                                        	Serial.println();
                                        
                                        	// It will not be possible to write the key if the configuration zone is unlocked
                                        	if (lockConfig == 0x00) {
                                        		// Write the key to the appropriate slot in the data zone
                                        		Serial.println(F("Writing key to slot 0..."));
                                        		write_key(key);
                                        	} else {
                                        		Serial.println(F("Skipping key storage (configuration not locked)."));
                                        		Serial.println(F("The configuration must be locked to be able to write a key."));
                                        	}
                                        #endif
                                        
                                        	if (lockValue != 0x00) {
                                        #ifdef LOCK_DATA
                                        #ifndef SKIP_UART_CONFIRMATION
                                        		while (Serial.available()) {
                                        			Serial.read();
                                        		}
                                        		Serial.println(F("Send SPACE character to lock data..."));
                                        		while (Serial.available() == 0);
                                        		if (Serial.read() == ' ')
                                        #endif //not SKIP_UART_CONFIRMATION
                                        		{
                                        			// Correct sequence, resync chip
                                        			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                        			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                        				Serial.print(F("Resync failed. Response: "));
                                        				Serial.println(ret_code, HEX);
                                        				halt();
                                        			}
                                        
                                        			// If configuration is unlocked, key is not updated. Locking data in this case will cause
                                        			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
                                        			// usecase not the desired behaviour, so ask for additional confirmation in this case.
                                        			if (lockConfig != 0x00) {
                                        				while (Serial.available()) {
                                        					Serial.read();
                                        				}
                                        				Serial.println(F("*** ATTENTION ***"));
                                        				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
                                        				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
                                        				Serial.println(
                                        				    F("which cannot be change after locking is done. This is in practically any usecase"));
                                        				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
                                        				while (Serial.available() == 0);
                                        				if (Serial.read() != ' ') {
                                        					Serial.println(F("Unexpected answer. Skipping lock."));
                                        					halt();
                                        				}
                                        			}
                                        
                                        			// Lock data zone
                                        			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                                        			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                                        			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                        			if (ret_code != SHA204_SUCCESS) {
                                        				Serial.print(F("Data lock failed. Response: "));
                                        				Serial.println(ret_code, HEX);
                                        				halt();
                                        			} else {
                                        				Serial.println(F("Data locked."));
                                        
                                        				// Update lock flags after locking
                                        				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                        				if (ret_code != SHA204_SUCCESS) {
                                        					Serial.print(F("Failed to determine device lock status. Response: "));
                                        					Serial.println(ret_code, HEX);
                                        					halt();
                                        				} else {
                                        					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                        					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                        				}
                                        			}
                                        		}
                                        #ifndef SKIP_UART_CONFIRMATION
                                        		else {
                                        			Serial.println(F("Unexpected answer. Skipping lock."));
                                        		}
                                        #endif //not SKIP_UART_CONFIRMATION
                                        #else //LOCK_DATA
                                        		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
                                        #endif
                                        	} else {
                                        		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
                                        	}
                                        #endif // not USE_SOFT_SIGNING
                                        
                                        	Serial.println(F("--------------------------------"));
                                        	Serial.println(F("Personalization is now complete."));
                                        #ifndef USE_SOFT_SIGNING
                                        	Serial.print(F("Configuration is "));
                                        	if (lockConfig == 0x00) {
                                        		Serial.println("LOCKED");
                                        	} else {
                                        		Serial.println("UNLOCKED");
                                        	}
                                        	Serial.print(F("Data is "));
                                        	if (lockValue == 0x00) {
                                        		Serial.println("LOCKED");
                                        	} else {
                                        		Serial.println("UNLOCKED");
                                        	}
                                        #endif
                                        }
                                        
                                        /** @brief Sketch execution code */
                                        void loop()
                                        {
                                        }```
                                        AnticimexA 1 Reply Last reply
                                        0
                                        • M meddie

                                          @Anticimex
                                          Hi i have posted my sketch few posts ago, but no problem here is it:

                                          
                                          
                                          #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 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                          /** @brief The data to store in key slot 0 */
                                          const uint8_t user_key_data[32] = {MY_HMAC_KEY};
                                          #endif
                                          
                                          #ifdef USER_SOFT_KEY
                                          /** @brief The user-defined soft HMAC key to use for EEPROM personalization */
                                          #define MY_SOFT_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                          /** @brief The data to store as soft HMAC key in EEPROM */
                                          const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY};
                                          #endif
                                          
                                          #ifdef USER_SOFT_SERIAL
                                          /** @brief The user-defined soft serial to use for EEPROM personalization */
                                          #define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                          /** @brief The data to store as soft serial in EEPROM */
                                          const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL};
                                          #endif
                                          
                                          #ifdef USER_AES_KEY
                                          /** @brief The user-defined AES key to use for EEPROM personalization */
                                          #define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                          /** @brief The data to store as AES key in EEPROM */
                                          const uint8_t user_aes_key[16] = {MY_AES_KEY};
                                          #endif
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A
                                          atsha204Class sha204(sha204Pin);
                                          #endif
                                          
                                          /** @brief Print a error notice and halt the execution */
                                          void halt()
                                          {
                                          	Serial.println(F("Halting!"));
                                          	while(1);
                                          }
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          
                                          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(115200);
                                          	hwInit();
                                          	Serial.println(F("Personalization sketch for MySensors usage."));
                                          	Serial.println(F("-------------------------------------------"));
                                          
                                          #ifndef USE_SOFT_SIGNING
                                          	// Wake device before starting operations
                                          	ret_code = sha204.sha204c_wakeup(rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to wake device. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	}
                                          	// Read out lock config bits to determine if locking is possible
                                          	ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to determine device lock status. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          		lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          	}
                                          #endif
                                          
                                          #ifdef STORE_SOFT_KEY
                                          #ifdef USER_SOFT_KEY
                                          	memcpy(key, user_soft_key_data, 32);
                                          	Serial.println(F("Using this user supplied soft HMAC key:"));
                                          #else
                                          	// Retrieve random value to use as soft HMAC key
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 32; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This value will be stored in EEPROM as soft HMAC key:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_SOFT_KEY
                                          	Serial.print("#define MY_SOFT_HMAC_KEY ");
                                          	for (int i=0; i<32; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 31) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
                                          #endif // STORE_SOFT_KEY
                                          
                                          #ifdef STORE_SOFT_SERIAL
                                          #ifdef USER_SOFT_SERIAL
                                          	memcpy(key, user_soft_serial, 9);
                                          	Serial.println(F("Using this user supplied soft serial:"));
                                          #else
                                          	// Retrieve random value to use as serial
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 9; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random serial generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This value will be stored in EEPROM as soft serial:"));
                                          	} else {
                                          		Serial.println(F("Serial is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_SOFT_SERIAL
                                          	Serial.print("#define MY_SOFT_SERIAL ");
                                          	for (int i=0; i<9; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 8) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
                                          #endif // STORE_SOFT_SERIAL
                                          
                                          #ifdef STORE_AES_KEY
                                          #ifdef USER_AES_KEY
                                          	memcpy(key, user_aes_key, 16);
                                          	Serial.println(F("Using this user supplied AES key:"));
                                          #else
                                          	// Retrieve random value to use as key
                                          #ifdef USE_SOFT_SIGNING
                                          	for (int i = 0; i < 16; i++) {
                                          		key[i] = random(256) ^ micros();
                                          		unsigned long enter = hwMillis();
                                          		while (hwMillis() - enter < (unsigned long)2);
                                          	}
                                          	Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                          #else
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("This key will be stored in EEPROM as AES key:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          #endif // not USER_AES_KEY
                                          	Serial.print("#define MY_AES_KEY ");
                                          	for (int i=0; i<16; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 15) {
                                          			Serial.print(',');
                                          		}
                                          	}
                                          	Serial.println();
                                          	hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
                                          #endif // STORE_AES_KEY
                                          
                                          #ifdef USE_SOFT_SIGNING
                                          	Serial.println(F("EEPROM configuration:"));
                                          	dump_configuration();
                                          #else
                                          	// Output device revision on console
                                          	ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to determine device revision. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		Serial.print(F("Device revision: "));
                                          		for (int i=0; i<4; i++) {
                                          			if (rx_buffer[SHA204_BUFFER_POS_DATA+i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[SHA204_BUFFER_POS_DATA+i], HEX);
                                          		}
                                          		Serial.println();
                                          	}
                                          
                                          	// Output serial number on console
                                          	ret_code = sha204.getSerialNumber(rx_buffer);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Failed to obtain device serial number. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		Serial.print(F("Device serial:   "));
                                          		Serial.print('{');
                                          		for (int i=0; i<9; i++) {
                                          			Serial.print(F("0x"));
                                          			if (rx_buffer[i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[i], HEX);
                                          			if (i < 8) {
                                          				Serial.print(',');
                                          			}
                                          		}
                                          		Serial.print('}');
                                          		Serial.println();
                                          		for (int i=0; i<9; i++) {
                                          			if (rx_buffer[i] < 0x10) {
                                          				Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          			}
                                          			Serial.print(rx_buffer[i], HEX);
                                          		}
                                          		Serial.println();
                                          	}
                                          
                                          	if (lockConfig != 0x00) {
                                          		// Write config and get CRC for the updated config
                                          		crc = write_config_and_get_crc();
                                          
                                          		// List current configuration before attempting to lock
                                          		Serial.println(F("Chip configuration:"));
                                          		dump_configuration();
                                          
                                          #ifdef LOCK_CONFIGURATION
                                          		// Purge serial input buffer
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		while (Serial.available()) {
                                          			Serial.read();
                                          		}
                                          		Serial.println(F("Send SPACE character now to lock the configuration..."));
                                          
                                          		while (Serial.available() == 0);
                                          		if (Serial.read() == ' ')
                                          #endif //not SKIP_UART_CONFIRMATION
                                          		{
                                          			Serial.println(F("Locking configuration..."));
                                          
                                          			// Correct sequence, resync chip
                                          			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                          				Serial.print(F("Resync failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          
                                          			// Lock configuration zone
                                          			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_CONFIG,
                                          			                                  crc, 0, NULL, 0, NULL, 0, NULL,
                                          			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Configuration lock failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			} else {
                                          				Serial.println(F("Configuration locked."));
                                          
                                          				// Update lock flags after locking
                                          				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          				if (ret_code != SHA204_SUCCESS) {
                                          					Serial.print(F("Failed to determine device lock status. Response: "));
                                          					Serial.println(ret_code, HEX);
                                          					halt();
                                          				} else {
                                          					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          				}
                                          			}
                                          		}
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		else {
                                          			Serial.println(F("Unexpected answer. Skipping lock."));
                                          		}
                                          #endif //not SKIP_UART_CONFIRMATION
                                          #else //LOCK_CONFIGURATION
                                          		Serial.println(F("Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
                                          #endif
                                          	} else {
                                          		Serial.println(F("Skipping configuration write and lock (configuration already locked)."));
                                          		Serial.println(F("Chip configuration:"));
                                          		dump_configuration();
                                          	}
                                          
                                          #ifdef SKIP_KEY_STORAGE
                                          	Serial.println(F("Disable SKIP_KEY_STORAGE to store key."));
                                          #else
                                          #ifdef USER_KEY
                                          	memcpy(key, user_key_data, 32);
                                          	Serial.println(F("Using this user supplied HMAC key:"));
                                          #else
                                          	// Retrieve random value to use as key
                                          	ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
                                          	if (ret_code != SHA204_SUCCESS) {
                                          		Serial.print(F("Random key generation failed. Response: "));
                                          		Serial.println(ret_code, HEX);
                                          		halt();
                                          	} else {
                                          		memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32);
                                          	}
                                          	if (lockConfig == 0x00) {
                                          		Serial.println(F("Take note of this key, it will never be the shown again:"));
                                          	} else {
                                          		Serial.println(F("Key is not randomized (configuration not locked):"));
                                          	}
                                          #endif
                                          	Serial.print("#define MY_HMAC_KEY ");
                                          	for (int i=0; i<32; i++) {
                                          		Serial.print("0x");
                                          		if (key[i] < 0x10) {
                                          			Serial.print('0'); // Because Serial.print does not 0-pad HEX
                                          		}
                                          		Serial.print(key[i], HEX);
                                          		if (i < 31) {
                                          			Serial.print(',');
                                          		}
                                          		if (i+1 == 16) {
                                          			Serial.print("\\\n                    ");
                                          		}
                                          	}
                                          	Serial.println();
                                          
                                          	// It will not be possible to write the key if the configuration zone is unlocked
                                          	if (lockConfig == 0x00) {
                                          		// Write the key to the appropriate slot in the data zone
                                          		Serial.println(F("Writing key to slot 0..."));
                                          		write_key(key);
                                          	} else {
                                          		Serial.println(F("Skipping key storage (configuration not locked)."));
                                          		Serial.println(F("The configuration must be locked to be able to write a key."));
                                          	}
                                          #endif
                                          
                                          	if (lockValue != 0x00) {
                                          #ifdef LOCK_DATA
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		while (Serial.available()) {
                                          			Serial.read();
                                          		}
                                          		Serial.println(F("Send SPACE character to lock data..."));
                                          		while (Serial.available() == 0);
                                          		if (Serial.read() == ' ')
                                          #endif //not SKIP_UART_CONFIRMATION
                                          		{
                                          			// Correct sequence, resync chip
                                          			ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS && ret_code != SHA204_RESYNC_WITH_WAKEUP) {
                                          				Serial.print(F("Resync failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			}
                                          
                                          			// If configuration is unlocked, key is not updated. Locking data in this case will cause
                                          			// slot 0 to contain an unknown (or factory default) key, and this is in practically any
                                          			// usecase not the desired behaviour, so ask for additional confirmation in this case.
                                          			if (lockConfig != 0x00) {
                                          				while (Serial.available()) {
                                          					Serial.read();
                                          				}
                                          				Serial.println(F("*** ATTENTION ***"));
                                          				Serial.println(F("Configuration is not locked. Are you ABSULOUTELY SURE you want to lock data?"));
                                          				Serial.println(F("Locking data at this stage will cause slot 0 to contain a factory default key"));
                                          				Serial.println(
                                          				    F("which cannot be change after locking is done. This is in practically any usecase"));
                                          				Serial.println(F("NOT the desired behavour. Send SPACE character now to lock data anyway..."));
                                          				while (Serial.available() == 0);
                                          				if (Serial.read() != ' ') {
                                          					Serial.println(F("Unexpected answer. Skipping lock."));
                                          					halt();
                                          				}
                                          			}
                                          
                                          			// Lock data zone
                                          			ret_code = sha204.sha204m_execute(SHA204_LOCK, SHA204_ZONE_DATA | LOCK_ZONE_NO_CRC,
                                          			                                  0x0000, 0, NULL, 0, NULL, 0, NULL,
                                          			                                  LOCK_COUNT, tx_buffer, LOCK_RSP_SIZE, rx_buffer);
                                          			if (ret_code != SHA204_SUCCESS) {
                                          				Serial.print(F("Data lock failed. Response: "));
                                          				Serial.println(ret_code, HEX);
                                          				halt();
                                          			} else {
                                          				Serial.println(F("Data locked."));
                                          
                                          				// Update lock flags after locking
                                          				ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2);
                                          				if (ret_code != SHA204_SUCCESS) {
                                          					Serial.print(F("Failed to determine device lock status. Response: "));
                                          					Serial.println(ret_code, HEX);
                                          					halt();
                                          				} else {
                                          					lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3];
                                          					lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2];
                                          				}
                                          			}
                                          		}
                                          #ifndef SKIP_UART_CONFIRMATION
                                          		else {
                                          			Serial.println(F("Unexpected answer. Skipping lock."));
                                          		}
                                          #endif //not SKIP_UART_CONFIRMATION
                                          #else //LOCK_DATA
                                          		Serial.println(F("Data not locked. Define LOCK_DATA to lock for real."));
                                          #endif
                                          	} else {
                                          		Serial.println(F("Skipping OTP/data zone lock (zone already locked)."));
                                          	}
                                          #endif // not USE_SOFT_SIGNING
                                          
                                          	Serial.println(F("--------------------------------"));
                                          	Serial.println(F("Personalization is now complete."));
                                          #ifndef USE_SOFT_SIGNING
                                          	Serial.print(F("Configuration is "));
                                          	if (lockConfig == 0x00) {
                                          		Serial.println("LOCKED");
                                          	} else {
                                          		Serial.println("UNLOCKED");
                                          	}
                                          	Serial.print(F("Data is "));
                                          	if (lockValue == 0x00) {
                                          		Serial.println("LOCKED");
                                          	} else {
                                          		Serial.println("UNLOCKED");
                                          	}
                                          #endif
                                          }
                                          
                                          /** @brief Sketch execution code */
                                          void loop()
                                          {
                                          }```
                                          AnticimexA Offline
                                          AnticimexA Offline
                                          Anticimex
                                          Contest Winner
                                          wrote on last edited by
                                          #286

                                          @meddie Sorry, missed that post.
                                          You have SKIP_KEY_STORAGE defined so no keys will be stored. This is the default and intentional, to avoid people just executing the sketch and accidentally overwrite existing keys.
                                          Furthermore, you have selected to personalize a ATSHA device, and have it generate the keys. That means that you have to define LOCK_CONFIGURATION or the ATSHA random number generator will not work.

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

                                          M 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          14

                                          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