2
$\begingroup$

I'm building a project on Arduino Mega microcontroller and I need some nonce generator for challenge-response exchange. But I failed to find some alphanumerical string generators. Then I came up with an idea to make one using the random() function that generates random int in limit you give and hash that integer with HMAC using another secret key (one that could be auto-generated on startup since it doesn't need to be consistent).

Does this approach make my nonce less secure in some way?

$\endgroup$
6
  • $\begingroup$ Use this than SHA256? codeproject.com/Articles/5311070/… $\endgroup$
    – kelalaka
    Nov 13 '21 at 20:07
  • $\begingroup$ I'm not sure I understand what are you saying. Should I use SHA256 to hash the random value instead? I use HMAC because I'll be using that library already and I need to make the program as small as I can. $\endgroup$
    – krystof18
    Nov 13 '21 at 20:33
  • $\begingroup$ HMAC must be used with a hash function that should be available to you, or use HMAC as you wish since it is designed to be a PRF. $\endgroup$
    – kelalaka
    Nov 13 '21 at 20:45
  • $\begingroup$ You're right, I have SHA256 available in that same library. What are the advantages of using SHA256 over HMAC? I guess it'll be faster calculating the nonce right? $\endgroup$
    – krystof18
    Nov 13 '21 at 20:49
  • $\begingroup$ For you HMAC calculated double SHA-256, and you don't need a keyed hash( sometimes called Keyed MAC, but actually HMAC is a technique for constructing pseudorandom function families (PRFs)). SHA-256 should be enough for nonces. $\endgroup$
    – kelalaka
    Nov 13 '21 at 20:53
2
$\begingroup$

The approach you use depends on the requirements of the nonce. In the case you describe, a challenge-response protocol, the requirements of the nonce are usually that it's unique and never reused. However, there are other situations where the nonce needs to be unpredictable as well, such as if you're using CBC mode for encryption.

You can use HMAC with this and for a hash function to use with it I'd recommend SHA-256. However, I would not recommend generating the value to HMAC using random because that might repeat and then so would your nonce. In general, you cannot rely on the quality of the PRNGs in standard C and POSIX. You could use a monotonically increasing counter instead, which would ensure that it never repeats, but you would have to have some way to persist the counter between uses.

$\endgroup$
2
  • $\begingroup$ The problem with counter is that it is propable that the microcontroler will lose power and the counter will reset. But I could use external RTC with sepparate batery, that would ensure non-repeating atlest for few years. Is that bad idea? $\endgroup$
    – krystof18
    Nov 16 '21 at 6:15
  • $\begingroup$ There is also EEPROM included, which is persistent memory. Problem with that is that it will have a limited number of writes. However, maybe it is possible to write a sequential counter for each startup, and then have a separate in-memory counter. Just thinking aloud here. $\endgroup$
    – Maarten Bodewes
    Dec 16 '21 at 16:13
2
$\begingroup$

random() is rubbish. See some of the source here.

The best way to generate nonces is via a true random number generator, unless you want >10,000 nonces per second which is unlikely in a microcontroller situation. You can do that without any additional hardware using the Arduino Entropy Library. The library utilises the natural jitter between the AVR's clock and the watchdog timer. This is a well researched area of TRNG design commonly used in ring oscillators. Or roll your own variant (it's not that hard if you review the original code).

It's not very fast, (64 bits/s) but it will give you a truly random 96 bit nonce in less than two seconds. That way you don't need to keep track of used nonces. And it's reboot proof.

$\endgroup$
3
  • $\begingroup$ Once you have 96 bits then you can use that to seed a CSPRNG, which should generally be much faster. Paul will probably object that a TRNG is more secure, but for practical purposes I think a well seeded CSPRNG is generally the way forward. $\endgroup$
    – Maarten Bodewes
    Dec 16 '21 at 16:15
  • $\begingroup$ Paul sez that a continuous stream cipher is not a nonce. Which was the question. $\endgroup$
    – Paul Uszak
    Dec 16 '21 at 20:09
  • $\begingroup$ Nobody requires a single nonce though, so although that may be the case, I guess the use case is to generate multiple nonces, and that requires an RNG if you want to have them randomized. $\endgroup$
    – Maarten Bodewes
    Dec 16 '21 at 23:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.