7
$\begingroup$

I am making an arduino project to open my garage door. I want to make it so users with the passphrase can open the door. Due to computational restrictions it is unlikely encryption is possible. Under the assumption that only hashing algorithms are available, what is a secure way of protecting the door? My thoughts:

Client sends request to open door. Server increments counter.
Server responds with current counter value, timestamp and date, with hmac of the above. Client responds with H(passphrase + counter) + above server response. Server verifies hmac of server response, timestamp is within valid window, and sent hash matches known secret appended with counter.

Have I thought this one through properly or am I missing something?

$\endgroup$
7
  • $\begingroup$ You are assuming bidirectional communication between the server and client? $\endgroup$ Mar 27, 2012 at 4:36
  • 3
    $\begingroup$ Why do you assume that hashing is feasible but encryption is not? IME, modern block ciphers and hash functions tend to have pretty much comparable complexity and performance. Of course, there's a lot of variation between algorithms and platforms, but the point is that it's not at all obvious which one would be faster and/or simpler. $\endgroup$ Mar 27, 2012 at 7:21
  • $\begingroup$ My Arduino (8 bit cpu) does not have any built in crypto libraries. I have found an MD5 implementation that will work. I cannot find a cipher implementation and I do not trust myself enough to implement one. $\endgroup$
    – Ryan
    Mar 27, 2012 at 13:20
  • 1
    $\begingroup$ There are several crypto libraries for AVR processors (and for the Arduino platform specifically) out there. The most comprehensive one, of those that I found in a few minutes of searching, seems to be AVR-Crypto-Lib. $\endgroup$ Mar 27, 2012 at 14:18
  • $\begingroup$ I will take another look at using one of these libraries. I still find the original question interesting, however. $\endgroup$
    – Ryan
    Mar 27, 2012 at 15:47

3 Answers 3

4
$\begingroup$

Some points:

  • Make sure you authenticate everything you send, not only parts of it. So, append a HMAC(password, everything) to the end of each message (which means both messages, not only the ones sent by the clients). If you do this, the message itself doesn't need to contain the password or any hash of it, though it should contain counter and/or timestamp, and be different for client and server.

  • Don't use MD5. While it is quite fast to compute, it has now a reputation as "broken" (because of quite fast collision attacks). While there is not yet a break which makes HMAC-MD5 attackable, better be save and use a better hash function, like one from the SHA-2 family (SHA-265 should be enough).

  • As said by Ilmari in a comment, a secure block cipher would not necessarily be harder to implement (or take more resources) than a secure hash function. Actually, many hash functions use some kind of block cipher internally in the compression function. You can construct a MAC from a block cipher (for example CMAC), too.

$\endgroup$
7
$\begingroup$

What you're suggesting is likely good enough, and very likely far more secure than just about any other lock on your house.

If the only hash function you can find is MD5, go with it, but make sure to HMAC with the passphrase as the key. Again, it's not going to be the weak point of your security. I'm sure I could pick the lock on your front door faster than I could break an MD5 HMAC. Obviously, HMAC-SHA1 would be better, or SHA-256, even. See if you can find a SHA-1 for Arduino.

I don't understand the exact protocol you're proposing. Why the timestamp and a counter? Either alone would work fine, assuming you take more than one second to do the protocol. It doesn't hurt to do both, but let's break it down:

  1. Client sends a request to open.

  2. Server sends a unique string to the client.

  3. Client computes HMAC(passphrase, unique-string) and sends the HMAC back to the server.

  4. Server also computes the HMAC and compares them. If they match, the door opens.

That seems good enough to me, the only thing we're debating is the content of the unique string. A timestamp alone would work if you prevent replays. You could do that by having the Arduino spin until the clock ticks. But there's also nothing wrong with an equivalent of:

static int counter = 0;

...

sprintf(challenge, "%d-%d", time(0), counter++);
send(challenge);

and that would be unique enough.

The risk in this basic protocol would be someone pre-computing an appropriate HMAC. Strictly speaking, the timestamp and the counter helps thwart this, but in practical terms it isn't really going to help. If someone intercepts any given successful challenge and response, they can run a dictionary search on passphrases to find the right HMAC.

But still, it's almost certainly more secure than the locks on the other doors.

Jon

$\endgroup$
3
  • $\begingroup$ The reason the time stamp was also there in the event of a counter roll-over attack. Without the time stamp, the (client->server) message could technically be replayed and accepted. $\endgroup$
    – Ryan
    Mar 28, 2012 at 13:12
  • $\begingroup$ @Jon: I don't really see the problem of a replay attack using the same time stamp ... if the rightful client is already opening the door, there is no problem if a second "open door" command comes at the same time. $\endgroup$ Mar 28, 2012 at 17:47
  • $\begingroup$ @Ryan: Simply make the counter long enough so it can't overflow in the lifetime of your engine. (You'll have the problem with overflowing the timestamp, too.) $\endgroup$ Mar 28, 2012 at 17:49
2
$\begingroup$

@Ryan You don't need a timestamp to avoid a replay attack. There's a message on the handshake that is generated by the server, so it can be anything random enough. A 32-byte random string is random enough to make a bruteforce unlikely, as the server Arduino have very low computing power to make it viable.

A timestamp is something very predictable, and if an attacker suspects that a timestamp is part of the challenge-response protocol, it would be easier to guess the other parts of the message. A random value don't have this weakness.

So, I think this protocol would suffice:

  1. Client asks for opening
  2. Server sends random string RS1
  3. Client sends HMAC(RS1 + PASSWORD)
  4. Server calculates HMAC(RS1 + PASSWORD) and compares with result

But as Jon said, is way easier to break a lock than to break a hash.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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