# How to authenticate over open channel?

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?

-
You are assuming bidirectional communication between the server and client? –  David Schwartz Mar 27 '12 at 4:36
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. –  Ilmari Karonen Mar 27 '12 at 7:21
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. –  Ryan Mar 27 '12 at 13:20
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. –  Ilmari Karonen Mar 27 '12 at 14:18
I will take another look at using one of these libraries. I still find the original question interesting, however. –  Ryan Mar 27 '12 at 15:47

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.

-

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

-
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. –  Ryan Mar 28 '12 at 13:12
@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. –  Paŭlo Ebermann Mar 28 '12 at 17:47
@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.) –  Paŭlo Ebermann Mar 28 '12 at 17:49

@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: