[security] Introducing signing support to MySensors
-
Yes.
-
@Anticimex mmmm
Can't it be implemented in a way so that whitelist is to be defined by the controller ?
For example, an internal message to be used to set the data.My concern is that auto assignation of nodes is flexible but at the same time you may need to choose which sensor node to be added to your whitelist. Thus if a Controller can show you all your nodes, like vera or domoticz, I guess this option can be added to the plugin to send an internal message to the GW to choose which sensor node to be added.
Am I saying something logic ?
-
Possibly. But that would mean that security features is dictaded by the controller plugins and I do not like that at all.
For months I have been trying to convince the Domoticz people that their ACK timeout is way to short and needs to be configurable for signing to work with Domoticz, but they do not even reply to me.
And I do not trust controllers at all and want to have full control over all configuration aspects of the signing solution. So I do not think it is good to move that logic off the nodes (whitelisting can also be used by a node, communicating with another node).
It is not only a GW that can have a whitelist. So although it might have been flexible to have it configurable, I think it compromises security (who knows, your controller could be hacked to inject a whitelist that permits a rogue node in your network).
Of course, security is at some level compromised anyway if the controller is hacked. But it is not the signing solution that is compromised in this case.
And ultimately, that feature would mean that the level of signing security and signing features for MySensors, becomes controller specific. And that I do not think is a good idea. If I want to change or improve the feature, the controller plugins all also have to be updated. It just becomes a too big turnaround for something as important as this in my opinion.
-
Yeah I got your point of view and convinced me. The only solution to implement this is that other communities works together to improve flexibility and security. This is not that easy of course as you have said.
Thanks a lot for your time.
-
Thanks for understanding
-
Also in all cases I see that if your controller is being hacked there will be no use to play with the whitelist The attacker has full control already to blow my house if he wants to
Anyway maybe I need to reflash using signing to understand things more.
Keep it up
-
Hi again.
I managed to set run the softsign and everything seems fine till now. I just want to understand the system much more if you please.
Now my Gateway sends this data when I turn on Light.
( I am using GatewayW5100 with Domoticz ) Development branch0;0;3;0;9;Eth: 0;0;3;0;18;PING 0;0;3;0;9;Eth: 2;7;1;0;2;1 0;0;3;0;9;send: 0-0-2-2 s=7,c=3,t=16,pt=0,l=0,sg=0,st=ok: 0;0;3;0;9;read: 2-2-0 s=255,c=3,t=17,pt=6,l=25,sg=0:01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACAC 0;0;3;0;9;Signing backend: ATSHA204Soft 0;0;3;0;9;Message to process: 00020E01020731 0;0;3;0;9;Current nonce: 01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACACAAAAAAAAAAAAAA 0;0;3;0;9;HMAC: 135DBD85528E869ECC86C9C53679795D7FDA7B789DB7A0A74053C94FE8D668F0 0;0;3;0;9;Signature in message: 015DBD85528E869ECC86C9C53679795D7FDA7B789DB7A0A7 0;0;3;0;9;send: 0-0-2-2 s=7,c=1,t=2,pt=0,l=1,sg=1,st=ok:1
I want to know how was the following data calculated please:
- sg=0:01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACAC
- Message to process: 00020E01020731
- Current nonce: 01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACACAAAAAAAAAAAAAA
- HMAC: 135DBD85528E869ECC86C9C53679795D7FDA7B789DB7A0A74053C94FE8D668F0
- Signature in message: 015DBD85528E869ECC86C9C53679795D7FDA7B789DB7A0A7
So how was sg= calculated ?
What is message to process ?
The nonce is depending on analogue signal + what ? to get this value ?
I have already defined a random HMAC, but this one is different. It is a combination of what ?
Finally what is signature in message ?On the other side I am trying to sniff the data by a serialgateway which is trying to hack the network. It only read the following data:
0;0;3;0;9;read: 2-2-0 s=255,c=3,t=17,pt=6,l=25,sg=0:01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACAC 2;255;3;0;17;01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACAC
It is the sg only which it succeeded to read. Also I do understood form the topic that the attacker can read values sent between nodes unencrypted, but here I can't figure out where is the unencrypted data which can be sniffed by the attacker but we don't bother ourselves with cas we protect our network by using signing.
Lots of questions but I am trying to understand the logic and architecture in details to understand what I am doing
Thanks a lot.
-
Hi,
I suggest you read the doxygen documentation for signing carefully as it answers the questions you have. Signing does not in any way prevent anyone from reading your messages. As I have described in the documentation, it provides authenticity. That is, you can trust the sender of a signed message to be yours and not someone else's.
-
@Anticimex Yeah I understand it doesn't prevent anyone from reading my messages, and that's what I am trying to do now. To hack the system depending on the data available. But when I read the post I understood that encryption is not a priority as signing is enough now to prevent an attacker from sending data, but it can read text. I thought I will find clear text describing that I am sending to node X value Y but I found this 2;255;3;0;17;01F470C061A0B9FF3DE248835736E2B85E31C8D6D1844AACAC
so I wanted to ask.Anyway I'll re read the documents more carefully and return to you back please. Thanks.
-
Encryption is available for both rf24 and rf69 radios. But encryption and signing are two different things, and I work with signing. And signing is more efficient against hackers than encryption. Encryption is more if you care about privacy.
-
@Anticimex @hek is it possible to encrypt the data sent over nrf modules using this https://github.com/DavyLandman/AESLib ???
-
@noelgeorgi AES encryption is already supported for both NRF24 and RFM69 radios. See MyConfig.h on the development branch for the flag to use. Doyxgen documentation I link to in this thread on the topic post also contain the personalization instructions for encryption on the development branch.
-
@Anticimex said:
@noelgeorgi AES encryption is already supported for both NRF24 and RFM69 radios. See MyConfig.h on the development branch for the flag to use. Doyxgen documentation I link to in this thread on the topic post also contain the personalization instructions for encryption on the development branch.
Thanks for the info.
I'm getting the following errors when compiling securitypersonalizer:Arduino: 1.6.7 (Linux), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)" /home/technoman/Arduino/libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino:83:28: fatal error: sha204_library.h: No such file or directory #include <sha204_library.h> ^ compilation terminated. exit status 1 Error compiling. This report would have more information with "Show verbose output during compilation" enabled in File > Preferences.
doesnt the ATSHA204 library has ATSHA204.h
-
@noelgeorgi master or development branch?
-
@Anticimex development branch
-
@noelgeorgi have you made changes to the sketch? Jenkins builds it without problems.
-
@Anticimex no, I'm using the sketch from the examples.....
am i missing some libraries????
-
@noelgeorgi if you have cloned the arduino git you have everything you need. I can build that sketch myself and have used it many times. I suspect you have a problem with your environment if you get compilation errors in it. We continously test the repository and build all examples nightly to make sure it all works as it is supposed to. You can see this at ci.mysensors.org
-
@Anticimex sorry for the interruption, i was using rsync to get eveything synced and i might have messed something uop, sha204 library was missing from my libraries folder, now everything works, thanks for the prompt and fast support.
-
-
@Anticimex - thanks for this. I finally got around to enabling signing on everything while I was testing out my new board design. I followed your schematic from your board design when I built mine and I just went through the instructions to configure the crypto chip and everything went smoothly. Thanks for the work and the good instructions!
-
@TD22057 that's really nice to hear! Are you using a stable release or the development/beta channel?
-
@Anticimex
I used the signing sketch on the dev branch - I'm in the process of shifting my stuff over to the dev branch from 1.5 now.
-
Ok, cool. As you might have noticed, personalization has changed a bit on development. Also, whitelisting works slightly differently/better.
-
Isn't blacklisting cool too to use ?
Like, if we know the "name" of the sensor lost, we push it to the black list and voila ? This way, we don't have to put a long list a agreed sensors if we have only two nodes outside the house.
... I think.
-
@Pierre-P because if a node is lost, you no longer control that node. So anyone could reprogram it to have it identify itself in any way possible. We have to assume an attacker has full source code access, so they can rewrite the signing algorithm to use a fake serial as salt for the signature to trick the GW to believe it is a new node. A whitelist mean the attacker has to know the ID/serial of one of the nodes you trust. Which they won't know unless they can get access to that node.
-
Thanks for the complet answer !
-
@Pierre-P you are welcome. Security is best when it is totally open and the implementation is aware of this. That makes it quite difficult to circumvent, and it also allows to be challenged. That way, with many eyes examining it, it gets stronger and stronger I welcome all attempts to crack it. White or black hat style.
-
Hello all! What would require less flash memory? Signing by ATSHA204A Chip or by software?
-
Signing by ATSHA204A require less flash memory, but takes longer to execute (at least on 8MHz AtMega328).
-
@Anticimex assumed that, but this post on the forum got me confused: http://forum.mysensors.org/topic/2005/software-aes-encryption-for-nrf24/19
According to that post, he uses software on the SenseBender with Encryption because, according to him "...encryption and ATSHA204A is to big for the SenseBender... ".
I would like to add Signing and encryption to my nodes, but I don't know if it will fit on my Atmega328 flash!
-
Well, how much space you have depend on your sketch and on the features you enable in the library, so it is impossible to predict how your code will fit. I suggest you just try to enable what you want and compile, and you'll know
-
The easiest way to find out is to look at the output in Arduino IDE when you click "Verify".
There are some factors that affect size:
- Size of bootloader
- MySensors version (different versions of the library have different size requirements)
- MySensors features used (software signing, encryption, debug on or off, etc)
- Size of other libraries you use in your sketch
- Size of your sketch
-
ouch, @Anticimex was a bit faster
oh, and the problem in the thread you quoted @Soloam is encryption. At least at that time, encryption used too much space so there wasn't space to include either hardware or software signing.
-
Yes, encryption and signing! I'll try to order this and test it out! http://www.ebay.com/itm/5PCS-ATSHA204A-STUCZ-T-IC-CRYPTO-4-5KB-SWI-204A-SHA204A-/191782104901?hash=item2ca71aaf45:g:zEQAAOSwwE5WZk9O
-
And on development branch, @tekka has an open PR where he has cut down significantly on the size of the NRF24 driver as well.
-
And you might also have read mine and @mfalkvidd's stand on encryption, so don't be discouraged if you find that you can't fit both. Just skip the encryption in that case. It adds far less in security than signing does.
-
Yes, if I have to discard one it would be encryption! Thank you for the help @Anticimex and @mfalkvidd
-
Hello,
I currently testing various bootloader to measure impact on CPU speed on the power consumption.
I got a lot ofnonce error
when using 1 MHz configuration.Is signing feature possible at 1 MHz ?
Thanks.
David.
-
@carlierd could you specify a bit clearer what you mean by "nonce error"? Signing should work, but the atsha driver is not tested @ 1MHz and might get bad timing. Also, for soft (and hard) signing, if 1MHz is used, performance could degrade to the point that the nonce timeout needs to be increased.
-
Hello.
I am using soft signing.
find parent send: 255-255-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,st=bc: read: 255-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0: sensor started, id=255, parent=255, distance=255 find parent send: 255-255-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,st=bc: read: 0-0-255 s=255,c=3,t=8,pt=1,l=1,sg=0:0 parent=0, d=1 read: 0-0-255 s=255,c=3,t=8,pt=1,l=1,sg=0:0 req id send: 255-255-0-0 s=255,c=3,t=3,pt=0,l=0,sg=0,st=ok: read: 0-0-255 s=255,c=3,t=4,pt=0,l=1,sg=0:9 send: 9-9-0-0 s=255,c=3,t=15,pt=2,l=2,sg=0,st=fail:1 read and drop: 9-9-0 s=255,c=3,t=15,pt=2,l=2,sg=0:1 read: 0-0-9 s=255,c=3,t=15,pt=2,l=2,sg=0:1 send: 9-9-0-0 s=255,c=3,t=16,pt=0,l=0,sg=0,st=fail: nonce tr err send: 9-9-0-0 s=255,c=3,t=16,pt=0,l=0,sg=0,st=fail: nonce tr err read and drop: 9-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0:0 read: 0-0-9 s=255,c=3,t=17,pt=6,l=25,sg=0:0129D04B64916F5E805EFDF704C34F56B47E547FDDE93805BE id=9 send: 9-9-0-0 s=0,c=0,t=0,pt=0,l=0,sg=0,st=ok: send: 9-9-0-0 s=1,c=0,t=30,pt=0,l=0,sg=0,st=fail: [Setup duration: 9928 ms] send: 9-9-0-0 s=0,c=3,t=16,pt=0,l=0,sg=0,st=fail: nonce tr err send: 9-9-0-0 s=1,c=3,t=16,pt=0,l=0,sg=0,st=fail: nonce tr err send: 9-9-0-0 s=255,c=3,t=16,pt=0,l=0,sg=0,st=fail: nonce tr err Value is 1 Cycle is 1 3.39 v [753 ms]
Thanks,
David.
-
@carlierd you have a lot of st=fail, so your problem is radio related, not signing related. I also see non nonce related messages fail so you need to stabilize your rf connection before signing can work. And since signing uses the maximum payload size, it has the least probability to succeed to be sent, so you could find that unsigned messages work while nonces and signed messages fail, but this is normal of the rf link is not fully working. If you get st=fail, it is a radio problem. See this discussion for details: http://forum.mysensors.org/topic/3386/mqttclientgateway-broken-after-upgrade-signature-failure
-
@Anticimex Hello. Everything is working at 16 or 8MHz so I am pretty sure it's not an issue with the material.
I will burn the bootloader again and create a new post if it's still not correct. I will also disable signing feature to be sure there is no impact.David.
-
@carlierd well, st=fail indicate transmission failure so it is pretty clear that you have a issue with rf, at least on that frequency. st=fail is not signing related. But, like previously discussed, enabling signing can trigger more st=fail because the payload gets bigger and is more sensitive to noise.
-
@calierd You can have a look here at the discussion I had with a similar problem which I was able to resolve finally. See the last reply in the aforementioned thread where I summarized how I resolved it, eventually.
-
@Anticimex @tomkxy
Perhaps the arduino and RFM69 can't run at 1MHz. I have capacitors and I tried with two different power sources. Without signing it's better but still a lot of st=fail. No matter, it was just for testing purpose
-
@calierd I cannot comment on RFM69 since I have non in operation. Sorry, try to place the nodes further apart and look whether it changes.
-
@Anticimex Thank you for the effort you have put into signing, this is great!
Would it make sense to explore the I2C version of ATSHA204A ? The reason I'm asking is speed.
-
Thanks @duovis,
Yes, I welcome anyone who has the HW to provide a IO routine for I2C-variants of ATSHA204A. I don't have the hw myself though.
-
@Anticimex Ok, I'll try to play with it and see if I can come up with something that works on I2C.
-
@duovis Great. I'll happily review any code. You should only need to worry about the low level stuff.
-
Hello all!
Two fast question! Can I have nodes working with ATSHA204A chip and others with software?
And, can I have nodes with signing on and others off? Or if I add signing to my network, all nodes must have it?
Thank you all!
-
@Soloam
You can mix nodes with soft signing and ATSHA signing as you like.
You can mix nodes with signing on and off as well. The GW will only sign messages to nodes that require it, and it will also only check signatures from nodes that require signatures. So you can have one node which support/require signing and another which don't. The GW will be able to exchange messages with both nodes.
-
Great work indeed!
Thank you @Anticimex
-
@Soloam thanks
-
Slightly silly question, but did anyone manage to get signing working (MySigningAtsha204Soft signer;) on Arduino Uno on MS 1.5.4 on the Ethernet gateway please? I am going out of memory and really hate to upgrade it to Mega
-
@alexsh1 if you feel adventurous try 2.0.0-beta2, or if you are patient, go to 2.0.0 in a few months and redesigns will have made space available for you.
-
@Anticimex Thanks - I am currently trying an Ethernet GW and a node (Sensebender Micro) with dev branch. I am stuck at personalisation. I cannot lock data. Any idea what I am doing wrong?
This is Sensebender (with ATSHA204):
Personalization sketch for MySensors usage. ------------------------------------------- Device revision: 00020009 Device serial: {0x01,0x23,0x53,0x3F,0x52,0x6A,0x1A,0x06,0xEE} 0123533F526A1A06EE Skipping configuration write and lock (configuration already locked). Chip configuration: EEPROM DATA: SOFT_HMAC_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SOFT_SERIAL | FFFFFFFFFFFFFFFFFF AES_KEY | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ATSHA204A DATA: SN[0:1] | SN[2:3] | 01 23 | 53 3F Revnum | 00 09 04 00 SN[4:7] | 52 6A 1A 06 SN[8] | Reserved13 | I2CEnable | Reserved15 | EE | 13 | 00 | 00 I2CAddress | TempOffset | OTPmode | SelectorMode | C8 | 00 | 55 | 00 SlotConfig00 | SlotConfig01 | 8F 80 | 80 A1 SlotConfig02 | SlotConfig03 | 82 E0 | A3 60 SlotConfig04 | SlotConfig05 | 94 40 | A0 85 SlotConfig06 | SlotConfig07 | 86 40 | 87 07 SlotConfig08 | SlotConfig09 | 0F 00 | 89 F2 SlotConfig0A | SlotConfig0B | 8A 7A | 0B 8B SlotConfig0C | SlotConfig0D | 0C 4C | DD 4D SlotConfig0E | SlotConfig0F | C2 42 | AF 8F UseFlag00 | UpdateCount00 | UseFlag01 | UpdateCount01 | FF | 00 | FF | 00 UseFlag02 | UpdateCount02 | UseFlag03 | UpdateCount03 | FF | 00 | FF | 00 UseFlag04 | UpdateCount04 | UseFlag05 | UpdateCount05 | FF | 00 | FF | 00 UseFlag06 | UpdateCount06 | UseFlag07 | UpdateCount07 | FF | 00 | FF | 00 LastKeyUse[0:3] | FF FF FF FF LastKeyUse[4:7] | FF FF FF FF LastKeyUse[8:B] | FF FF FF FF LastKeyUse[C:F] | FF FF FF FF UserExtra | Selector | LockValue | LockConfig | 00 | 00 | 55 | 00 Take note of this key, it will never be the shown again: #define MY_HMAC_KEY [deleted] Writing key to slot 0... Send SPACE character to lock data... Data lock failed. Response: D3 Halting!
-
@alexsh1 actually, I have never actually locked data. Could be a bug there. But I also highly recommend that you don't. If you do, you will never be able to change hmac key in that device.
-
@Anticimex So this is no problem if the key is not locked? I was just following the manual
On a separate note, I cannot get soft_serial written into the EEPROM:
#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```
I have defined the key under #define MY_SOFT_SERIAL [key]
Personalization sketch for MySensors usage. ------------------------------------------- This value will be stored in EEPROM as soft HMAC key: #define MY_SOFT_HMAC_KEY [deleted] Using this user supplied AES key: #define MY_AES_KEY [deleted] EEPROM configuration: SOFT_HMAC_KEY | [deleted] SOFT_SERIAL | FFFFFFFFFFFFFFFFFF AES_KEY | [deleted] -------------------------------- Personalization is now complete.
-
@alexsh1 Hopefully the manual informs about the risks with locking data (that you cannot change the key afterwards). Atmel is somewhat vague on the security implications; they say that you can not read the key anyway but it is "more secure" to lock data. But personally, I have not found a way to read it, and I prefer to be able to change my HMAC key in my devices if it should be compromised.
Strange that you don't get the soft serial. I see nothing obviously wrong with your config. But I do see that you probably sensored your uart log a bit too hard because there are other lines missing there.
You should have seen thisUsing this user supplied soft HMAC key: #define MY_SOFT_HMAC_KEY [deleted]
if you have enabled this:
#define STORE_SOFT_KEY #define USER_SOFT_KEY
You are sure you have no #undef or some accidental comment or similar. As you see in the personalizer code, it is not that complicated. If the flags are enabled, you should at least get some printouts. But since (if your UART dump is correct) you get nothing, I suspect the flags are not really "on".
-
@Anticimex said:
Strange that you don't get the soft serial. I see nothing obviously wrong with your config. But I do see that you probably sensored your uart log a bit too hard because there are other lines missing there.
You should have seen thisUsing this user supplied soft HMAC key: #define MY_SOFT_HMAC_KEY [deleted]
if you have enabled this:
#define STORE_SOFT_KEY #define USER_SOFT_KEY
You are sure you have no #undef or some accidental comment or similar. As you see in the personalizer code, it is not that complicated. If the flags are enabled, you should at least get some printouts. But since (if your UART dump is correct) you get nothing, I suspect the flags are not really "on".
OK, it was Arduino glitch - any changes in the sketch were not reflected on the compilation. Rebooted my PC and restarted Arduino and all works as expected.
A few questions: Mixing ATSHA204 and soft signing - Does HMAC key (one stored in ATSHA204 of say a node and another one in GW's EEPROM) have to be the same? Also I understand one can store HMAC key on both ATSHA204 and EEPROM of one device (say, Sensebender)? I understand that SOFT_KEY has to be unique for every device?
-
@alexsh1 Ok, well Arduino IDE sucks totally.
You can mix ATSHA204A and soft signing as much as you like. But for any two nodes to exchange signed data the HMAC keys have to be identical.
Yes, you can store a HMAC key in both ATSHA204A and EEPROM. These can be different if you like (and I recommend they are as the EEPROM can be dumped if the node falls into the wrong hands).
However, if you want that node to communicate signed data to another node, that node must use a matching HMAC key.
SOFT_KEY is the HMAC key stored in EEPROM, it must not be unique for every device. If it is, no device will be able to sign data to any other node and expect that node to accept that data.
SOFT_SERIAL on the other hand, must be unique to serve any useful purpose for whitelisting. If you use the ATSHA204A, the serial fused in the device will be used and that cannot be changed, and is according to Atmel, unique.
-
@Anticimex Ok, but is there a reason why one would have HMAC key in both ATSHA204a and EEPROM?
-
@alexsh1 no, not really. If you have a atsha204a the only reason to not use it would be performance. Software signing executes slightly faster due to the single write protocol of the atsha.
-
@Anticimex Thanks very much for your help - I must admit it was a bit of a challenge to jump straight away from a stable 1.5.4 to 2.0 beta
-
@alexsh1 yes there have been a lot of changes but hopefully they are perceived as improvements. Feedback on signing usability is always welcome
-
@Anticimex BTW, is signing compatible between 1.5.4 and 2.0b?
-
@alexsh1 no, it is not
-
@Anticimex Right, this is why I am not able to sign 1.5.4 nodes with 2.0b GW.
In fact when I inserted #define MY_SIGNING_REQUEST_SIGNATURES into the GW code, some nodes stopped working and I think it has to be with signing as GW is throwing a lot of messages that signing failed.Bottom line is that I need to upgrade pretty much all sensors
-
@alexsh1 yes, Unfortunately. But it is a huge release upcoming. And a major version step, hence the incompatibilities. Hopefully, the changes made will make it easier to do future maintenance.
-
Hi. Is there any difference in using RFM69? Signing is supported using that radio? Thanks
-
@cingolanifede signing has nothing to to with which radio you choose so yes. It supports any transport, but to my knowledge it has only been actually tested with nrf24 and rfm69.
-
@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
-
@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
-
@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.
-
@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)
-
@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/
-
@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.
-
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.
-
This tutorial is up to date for 2.0 release ?
-
@Fabien Yes, top post is now updated for 2.0.0. Documentation is in doxygen.
-
Thank you @Anticimex I will update my network soon and had RFM69 Encryption too.
-
Trying this:
https://www.mysensors.org/build/raspberryHow 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?
-
@NiklasO @marceloaqno is working on this.
-
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?
-
@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:
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.
-
@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?
-
@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.
-
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
-
@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.
-
@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() { }```
-
@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.
-
You can read about personalization here.
-
Ah, thank you very much, yes now i get generated a key. But one more question the AES key will not be generated? I got only the HMAC Key, do i have to put the AES Key at myself?
Thank you very much!
-
@meddie Please read the documentation and the sketch carefully. It quite clearly states in both documentation and code that you need to define STORE_AES_KEY to generate and store an AES key.
-
@Anticimex
sorry sorry for so many questions, i have read the how to use already some times, but maybe its my bad english or the fear to do something wrong or to destroy the chip. I get a little bit unsure.Now i get both keys. If i understood correctly, the keys are now stored, i have now to put the shown keys to the sketch as HMAC and AES Key, and run this sketch on the sensor nodes.
On the gateway on which i generated the keys i dont need to do anything more as to upload the gateway sketch ?
Thank you very much for your support!
-
@meddie assuming you locked the configuration of the atsha, no you should not need to do more.
-
@Anticimex said in Sensebender Gateway:
@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.@Anticimex
sorry i have one more question, because i didnt fully understand this. In the gettings started how to you wrote:Pick a “master” device with serial debug port. Set the following sketch configuration of the personalizer: ... Enable SKIP_KEY_STORAGE ... Execute the sketch on the “master” device to obtain a randomized key. Save this key to a secure location and keep it confidential so that you can retrieve it if you need to personalize more devices later on. Now reconfigure the sketch with these settings: ... Disable SKIP_KEY_STORAGE ... Put the saved key in the user_key_data variable. Now execute the sketch on all devices you want to personalize with this secret key.
on the first run i have to enable SKIP_KEY_STORAGE so i removed the comments.
But here in forum you write i have to disable this. After i has disabled it wroked fine for me.But now i have to run the sketch on my node, and i think i have to disable the SKIP function too, because i need that the keys will be stored in the node.
So if i am right, the on both runs the SKIP function has to be commented out? Or i am wrong?
Thank you.
-
@meddie If your read the text carefully it says:
Set the following sketch configuration of the personalizer:
...
Execute the sketch on the “master” device to obtain a randomized key. Save this key to a secure location and keep it confidential so that you can retrieve it if you need to personalize more devices later on.
Now reconfigure the sketch with these settings:
...
Now execute the sketch on all devices you want to personalize with this secret key.So in other words; you first use the settings described in the first setting, execute that once. Follow the instructions carefully. Write down the key you got. Then you reconfigure the sketch and execute it on all devices you want to personalize. That is, you execute it twice on the first device.
I wrote that you need to undefine SKIP_KEY_STORAGE if you want to store a key. But the first set of instructions in the documentation is not saying that you are supposed to store a key. It says "Execute the sketch on the “master” device to obtain a randomized key."So the documentation is correct, and describe a flow where you personalize nodes and gateways with the minimum amount of changes needed. First you generate a key, and this step can actually be skipped altogether if you just make your own random key or password to use for HMAC/AES.
Then you reconfigure the personalizer to use your generated (or selected) key and write it to all your devices.