This blog posting is me thinking out loud about how to improve the flawed Smart Config process.
However by the end I essentially come to the conclusion that there's not much that can be done.
So unless you're interested in seeing what ideas I had and why they don't work in practice I'd skip this post.
I do look at workable alternatives in my later posting "Smart Config for consumer products? Alternatives?"
As Smart Config exists at the moment I think it has two main problems:
- The user has to enter a longish AES key in order for their network password to be securely transmitted to a CC3000 device.
- The CC3000 may not pick up the transmitted data if the Smart Config client is running on a machine talking to its wifi access point (AP) using 802.11n.
In normal operation the CC3000 only supports 802.11b and 802.11g. During the setup phase for a CC3000 enabled device the 802.11 protocol used by the device running the Smart Config application should ideally not be relevant to the process. Unfortunately it is - as discussed in this post the CC3000 can receive Smart Config data from some devices that talk to the AP using 802.11n but not from others. And it's clear the situation will not improve as newer protocols such as 802.11ac become available.
Below I look at using an asymmetric key algorithm, rather than AES (which uses symmetric keys), in order to create a better end user experience in relation to key handling.
And I look at using wifi probes to communicate information in a manner independent of the 802.11 protocol version so avoiding the 802.11n and MIMO issues seen with the current approach.
However in the end the best features of both ideas depend on functionality that while available on Android, Mac OS X, Windows and Linux is crucially not available via any public interface for iOS (see later for the exact details).
So on the whole they're an interesting thought experiment, however a few smaller improvements are also covered that would be possible to make.
Encryption
If we accept that encryption keys are required then is there a way to make the handling of these keys easier or even invisible to the end user?Entering random character sequences is difficult for human beings and as the user will get no feedback if the sequence is entered incorrectly, other than the failure of the given CC3000 enabled device to connect to their network, one should ensure one catches entry errors up front.
This can be done by including a checksum as part of the sequence that needs to be entered, this allows the Smart Config application to verify the sequence and point out that it's incorrect. The current TI Smart Config applications do not do this.
Unfortunately adding a checksum makes the sequence even longer. The CC3000 supports 128 bit AES, to enter a complete 128 bit key would require a sequence of 32 hex digits, not even accounting for the checksum. If instead of hex digits we use all printable ASCII characters we can encode a little more than 6 bits per character so reducing the number of characters required to around 20 but introducing a different problem - characters that are hard to distinguish for the end user who has to enter them, e.g. zero and capital O.
A 128 bits is the maximum supported key length. Are shorter keys secure enough? I can't find a definitive reference - I see that in the 2002 RSA challenge they found it would take the computing power of 45,000 2GHz AMD processors running for 790 days to work through the complete 64 bit keyspace. RSA is obviously quite a different algorithm to AES and costs drop off very rapidly as the key size decreases.
This recent article by one of the people behind 1Password claims that for AES it would require all the computer power on earth a year to check all the keys possible with 75 bits. A totally untuned unscientific experiment in Java on my 1.8GHz Intel Core i5 Macbook Air using 100% of all cores could only check all keys possible with 38 bits in a day, presumably tuned assembler GPU logic could do orders of magnitude better (but remember e.g. that 3 orders of magnitude would still only be equivalent to 10 additional bits). Note: if instead of truly random keys the attacker knows you're creating keys from human friendly text like "LetMeIn" then the search space is reduced massively in size. So while "LetMeIn" may be encoded as 7 bytes, i.e. 56 bits (or 42 bits if you take into account that each character only really encodes 6 bits if we consider just the printable ASCII characters) don't equate this number of bits with a random key of anything like equivalent length.
Side note: TI use the simplest AES encryption mode, called electronic cookbook (ECB) mode. It's interesting to note that on the relevant Wikipedia page it's claimed ECB "is not recommended for use in cryptographic protocols at all." However to be fair the issues outlined don't really come into play in the way AES is used with the CC3000.
Asymmetric keys
There might be a different way though to reduce down the size of the key that needs to be entered to something the length of a bank PIN.On one of my previous posts someone asked if using RSA rather than AES would make a difference. AES is a symmetric key algorithm - the same key is used for both encryption and decryption so one has to be very careful with the distribution of the key. RSA is an asymmetric key algorithm, basically one key is used to encrypt the data but a different key is needed to decrypt it - so you can give out one key (called the public key) without taking any care to keep it secret - if someone wants to send you data they encrypt it with this key but no one can use this key to decrypt the resulting data - this can only be done with the other key (called the private key) that you have never given out to anyone.
Note: RSA and AES aren't really alternatives to each other - RSA is only used to encode small amounts of data while AES is used for arbitrarily large amounts of data. In fact the two are often used together, e.g. in TLS, the protocol used by https, the data is exchanged using AES but at the start of the connection process the AES key is first randomly generated and then exchanged using RSA.
So would using an asymmetric algorithm make any difference? My initial thought was that it wouldn't.
With AES there is just one key which is known to the CC3000 enabled device and is also included on a sticker, or such like, with the device so the end user can enter it in the Smart Config application.
With RSA the key included on the sticker would be different to the one known to the CC3000 enabled device.
So even if one knew the key on the sticker one wouldn't be able to use it to decode a password encrypted with it and transmitted by Smart Config.
For a closed source device it would make a difference - one could could safely use a single well known public key for all your devices if the key known to the devices was kept secret. However hardcoding keys into devices doesn't have a very successful history - the keys are either eventually recovered by hacking the physical devices or leaked - see e.g. the history of DVD encryption (DVD keys are now brute forced in a matter of seconds but DeCSS started with a key recovered by disassembling a software DVD player).
If instead of one public/private key pair, common to all instances of a given device, one had a different key pair per device would this provide any advantage versus one AES key per device (as would be required for any sensible use of AES with the CC3000) ?
It would mean that recovering the private key of one device would have no implications for any other device and it would mean that absolutely no special care would need to be taken with packaging the public key with the device, whereas with an AES key one should take some care to ensure it cannot easily be recorded by another party before one takes delivery of it. However even I admit in a previous post that if someone who wants to decrypt your network traffic has had physical access to a device you intend to connect to that network then you probably have bigger problems, and that in the end an AES key printed on a sticker within the physical shrink wrapped packaging is probably completely adequate.
Side note: I've seen it suggested that keys cannot be kept private in an open source based project. This isn't the case - keys do not have to be hard coded into the microcontroller code and thus visible to all. For a situation where one intends to mass produce a given product the MCU code can e.g. reference a particular EEPROM memory location at which it expects to find the key and this location can be written with a unique key value generated per device as part of the process that loads the compiled code into each individual MCU. Or one could have the keys pairs preprogrammed onto tiny and cheap serial EEPROM chips that are then included as a part of each device (keeping track of which public key went with each device would still be an issue). This process would be no different for a closed or open source project. Simpler schemes could be constructed for projects intended for individual makers to force them to create a unique key for their instance of the project rather than providing a common hard coded one.
So if there isn't much advantage in using asymmetric keys in the same manner as we currently use AES keys is there some other way they could be used that wouldn't be possible with AES keys?
I thought there might be but it depended on being able to exchange keys. On all platforms except iOS this could be done using wifi probes, however on iOS there is no public interface for sending or receiving them. All low level network activity is handled by iOS itself, applications can basically only determine if they are connected or not via wifi or mobile/cellular (using Reachability in the System Configuration Framework) and then use the higher level services of the CFNetwork Framework.
The following section depends on being able to exchange keys so unless a solution for iOS can be found it's currently unimplementable.
Side note: RSA is considerably more expensive space wise to implement and space and time wise to run that AES - this is a serious issue for an embedded system implementation, e.g. see this implementation for the PIC18 which requires 5KB of flash, 700 bytes of RAM and 120 seconds (yes, really) for a single block decode operation. The decode cost effectively excludes RSA from use irrespective of other issues.
Public Key Exchange
Instead of the end user entering the public key of a public/private key pair into the Smart Config application the CC3000 could broadcast its public key and the Smart Config application could pick this up without the user needing to do anything, any password then encrypted with this key could only be decoded by the device that had broadcast it and also had the corresponding private key - the public key being of no use for decryption to anyone who captured it.The CC3000 wouldn't even have to be preconfigured with a unique public/private key pair - it could generate its own just as e.g. ssh-keygen does (or it could use something similar to the Atmel ATSHA204 crypto chip).
However there's an obvious problem, the solution I described for recovering non-AES protected passwords just involved passive monitoring but with an active component one could overcome this asymmetric approach too.
The Smart Config application would have to do something to tell the CC3000 to announce its public key, e.g. the Smart Config application could send a wifi probe request and the CC3000 could include the key in a wifi probe response (encoded it as a dummy SSID). Or the CC3000 enabled device could be put into a setup mode, e.g. by pressing a button on its case, that caused the CC3000 to repeatedly announce its key in some way.
If I was an outside party and saw a Smart Config application requesting a public key I'd simply respond with my own key and hope the device saw my response before the real one. Similarly if I saw a CC3000 repeatedly announcing its public key I would do the same and hope the Smart Config application would see my key before the real one.
The end user would of course see that their CC3000 enabled device didn't then connect to the network but this would just look like a random failure. The system generating the fake public keys would stop interfering once it had received the network password sent by Smart Config and the user would probably just restart the Smart Config application and try again with everything apparently going without problem the second time.
The Smart Config application could look out for these issues - but it couldn't do anything much about them other than report them to the end user and refuse to allow them to setup the device they'd just bought.
In many security protocols each party has their own public/private key pair and before communication starts between them they exchange their public key with the other.
So another approach would be for both the CC3000 enabled device and the Smart Config application to generate their own public/private key pairs and for the CC3000 to in addition have a unique short PIN code, e.g. 4 digits long. First the Smart Config application would announce its public key such that the CC3000 could pick it up, the CC3000 would use this key to encrypt its PIN and include this along with its public key when it announces it such that the Smart Config application can pick it up in return.
The PIN would also be included on a sticker with the device - and the end user would have to enter it in the place where the AES key goes currently - the Smart Config application could compare this with the PIN it decrypts using its private key from the response assumed to be from the CC3000 device, if it matches the response is accepted otherwise it is simply ignored.
Note: if one was using a request and response to retrieve the public key from the CC3000 enabled device it might seem acceptable to just send the PIN unencoded in the response (and so not bother with a key pair for the Smart Config application), but as wifi packets are often discarded for one reason or another despite having been visible on the network this is probably not a great idea. If everything doesn't go perfectly for the first packet seen that contains the PIN then it will become known to the outside party and can be used to create a fake response before any followup real response.
The user still has to enter something (or one could instead display the PIN received from the device and ask them to confirm it matches the one on the device. However user interface testing shows users generally don't read dialog messages and just press whatever button they think will get the process finished).
A 4 digit PIN, using just the digits 0 to 9, is far easier for an end user to handle than a long sequence of random characters.
Why is a 4 digit PIN acceptable here, while an AES key of random characters twice this length would be completely unacceptable? Because with the current AES approach one can record the traffic and work through all the possible permutations at leisure whereas with this approach it's the Smart Config application that effectively dictates the number of chances, i.e. one, to generate the correct value.
This new approach would be far more complex to implement but it does make the security aspect, a 4 digit PIN vs a long random character sequence, easier for the end user. The implementation would only need to be done once and would prevent many end user problems and support issues.
However as noted it's currently not implementable at all, at least with wifi probes, on iOS.
802.11 Protocol
The original IEEE 802.11 standard was established in 1997 (unfortunately the IEEE standards are not available free of charge - they cost $250 each to download as PDFs).The subsequent protocols, e.g. 802.11b, 802.11g or 802.11n, are amendments to this original standard.
Ideally Smart Config would use an element common to all the protocol versions in order to communicate the SSID etc.
This would eliminate the problem where the Smart Config application was running on a machine that used a protocol that the CC3000 does not know or uses an aspect of a protocol, e.g. MIMO, that affects the ability of the CC3000 to monitor the relevant traffic.
Wifi probes are just such an element.
Wifi probes contain 32 bytes that are usually used to encode an SSID but which could be used to encode arbitrary information (in fact TI used to use probes in this way in their old, and very unsatisfactory, First Time Configuration process).
However again iOS is the problem platform - as noted above it provides no low level network access so one cannot send or receive wifi probes with an iOS app. One must use a mechanism that works with high level network constructs, e.g. UDP as with the current Smart Config approach.