Yado – A Secure Door Opener

There’s been many DIY IoT garage door openers but none of them offered the level of security that is required to secure my home. While it’s true that most are “good enough” placed behind a secure Wifi router, that level of security is unacceptable for a device that is on the publicly facing internet. I trust this device enough where the URL is actually publicly accessible. The only real vulnerability would be a Denial of Service attack. There’s not much that can be done to secure against that on a uC that costs $2 in unit quantities on eBay.

This project is being published not only to enable you to remake this for yourself, but to also share the novel way of securing payloads between devices without the expensive overhead of TLS/SSL.

While this was made for the ESP8266, the code and required computation would also be easily ported (I performed some proof of concept tests of this) to an 8 bit Atmel uC.

For a full feature set, take a look at at the front page of the Yado project on GitHub.

  

Open Source

All the files can be downloaded from the Yado repository on GitHub.

Update 1 (May 8, 2016) – Source has been revised to support the v2.0.0 Arduino ESP8266 API. Don’t build with any version of Arduino ESP8266 API prior to v2.0.0.

How it works – Basics

Yado Front Page

Built around the ESP8266 at a cost of about $20-$30 to produce in single unit quantities, Yado uses multiple layers of one way SHA1 message digesting to secure the payload being transmitted. At no time is your password sent in clear text. You can also configure multiple passwords through the Admin UI for the people in your household.

How it works – Security

The message exchange methodology implemented is similar to the (yet custom) implementation to what is used by the SAML Single Sign On  Specification. Other than digesting the network payloads, the other form of attack that had to be addressed was that of packet replay attacks specifically around the inability generate cryptography secure  random numbers. A solution was implemented which uses the time required to acquire and log into a WiFi AP as part of the seed of a random number generator. This protocol is also resistant to brute force attacks. This is real security!

How it works – Psudocode

Client to Server (Initial Request)

> Get /

Server

Timestamp = 999

Secret = “Secret”

Password = “letmein”

preDigest = “999xSecret”

serverDigest = sha1(“999xSecret”)

                       8a2ca83d614812d6fa9d49650601b143baf8ef66

Server to Client (Response)

Timestamp = 999

serverDigest = 8a2ca83d614812d6fa9d49650601b143baf8ef66

Client

clientTime = Timestamp

Password = letmein

requestPassword = sha1(Password + serverDigest)

requestPassword = sha1(letmein + 8a2ca83d614812d6fa9d49650601b143baf8ef66)

requestPassword = sha1(letmein8a2ca83d614812d6fa9d49650601b143baf8ef66)

requestPassword = d738f7baa6a3fa5c3013dedea9ef76831e59469b

Client to Server (Request)

> Get /?requestPassword=d738f7baa6a3fa5c3013dedea9ef76831e59469b&clientTime=Timestamp

Server

# Is request too old? If no, continue

If clientTime+60 < Timestamp

Continue

Else

Go Away

# Recompute server, this time with the associated password.

Server Hash Recompute

Timestamp = 999

Secret = “Secret”

preDigest = “999xSecret”

serverDigest = sha1(“999xSecret”)

                       8a2ca83d614812d6fa9d49650601b143baf8ef66

serverDigestWithPassword = sha1( “letmein” + “8a2ca83d614812d6fa9d49650601b143baf8ef66”)

                                            d738f7baa6a3fa5c3013dedea9ef76831e59469b

# requestPassword came from client

clientDigestWithPassword = requestPassword

if clientDigestWithPassword == serverDigestWithPassword

You’re in! YAY!

 

Related posts