Saturday, October 12, 2013

CC3000 and security



People talk about a coming Internet of Things (IoT), pervasive small cheap headless devices that connect to the internet and do things like keep your plants watered.

When you connect a new device to your home network you have to tell it the name (SSID) of your network and the password (assuming you've setup WPA2 or something similar), but as IoT devices typically have neither screen nor keyboard it's hard to see how to do this easily.

There have been various solutions to this problem - all of them somewhat unsatisfactory in one way or another.

TI's solution to this problem is the CC3000 module, a self-contained wireless network processor, along with their Smart Config technology. Using a Smart Config app on your smartphone, laptop or PC you simply enter your network name and password and these are magically communicated to your new IoT device which then uses them to connect to your network.


When I first saw the CC3000 with Smart Config I really wanted it to be the perfect solution to the initial network setup problem.

And without AES it certainly looks like the solution, with AES I think it's still good but other solutions start to look perhaps as attractive.

So what is AES about? Well here's where the problems start - if you're even a little bit interested in cryptography then it's obvious but if, like much of the world, you feel there are better things to spend your time on than symmetric keys, elliptic curves etc. then it might not be obvious - and TI don't go out of their way to clear things up.

The AES element of the product doesn't get much coverage in their promotional literature etc. This video, produced by TI, is typical - wind forward to the 9 minute mark and listen for about a minute:


There's a pretty unclear explanation of why one might want to use an AES key - I'm getting a strong yadda-yadda feel here, kind of "you might want AES for some obscure use cases." I'm not hearing him clearly state something like "if you don't use the AES option then the device will broadcast the end user's network password to anyone who cares to listen, with no special equipment required to do so - any laptop or desktop computer will do."

It's not even entirely clear from this video whether using a key is a manufacturer or end user issue.

Initially TI did clearly document how the SSID and network password were transmitted to a CC3000 enabled device as shown here via a wifi probe. Now they use a different process which they have chosen not to document, referring to it as a trade secret, despite the mechanism being fairly clear from looking at the wifi traffic any Smart Config application generates or from the example Smart Config applications that they distribute (without NDA or obvious restrictions). TI certainly, at the very least, imply that this new mechanism affords some degree of protection from packet sniffing.

TI do not deny that not using an AES key is the less secure option, but not using AES is the option you see most often in their demonstrations, literature etc. So can it really be that insecure not to use AES?

I've heard smart people dismiss the issue as one of "momentary insecurity" - the idea being that it's not really that big a deal if the password is exposed for just a few seconds. Security without an AES key will be "good enough" for most users and anyone who requires more security should stick to devices that do use an AES key.

I'd argue that "good enough" security rarely turns out to be good enough in practice.

What Smart Config does is different from what people generally think about when they think "lax security." If my neighbor uses a website that features a non-SSL login process it still requires active, and clearly malicious effort, on my part to intercept my neighbor's DSL traffic. With Smart Config my neighbor's network password is actively broadcast, no special hardware or tapping of lines is required to receive that data. And I'd argue that a person's home network password is generally far more important than that of some bulletin board that can't afford an SSL certificate.

I'd equate pulling a password out of the air, that's been broadcast by Smart Config, with bittorrenting an episode of Game of Thrones - to many people it doesn't (despite the best efforts of the MPAA, RIAA etc.) feel terribly illegal - while hacking my neighbors DSL is non-trival, involves "real world" actions and feels more like stealing a Game of Thrones box set from a store, i.e. very clearly illegal to most people.

But the Smart Config setup process is so brief - are people really going to notice and capture such events? Computers are tireless, once they've been set to perform a task the briefness provides no protection. Any cheap laptop can monitor nearby wifi traffic and one can buy cheap small dedicated devices to do this job, such as the WiFi Pineapple for around $100.

In my apartment, even without the large external antennas of the WiFi Pineapple, and despite the poor propagation characteristics of the 2.4GHZ and 5GHz bands, my laptop can still see an amazing 28 wifi networks in the immediate vicinity. Even if I ignore half of them due to low signal strength that still leaves 14 networks.

In their paper from January 2013 - Building Blocks for Smart Networks - the OECD estimates that by 2022 the average household will have around 50 IoT devices (with everything, the toaster included, wired in one way or another).

Even if we pick a far more conservative number at random, e.g. 10, and estimate that such devices will last 3 or 4 years (Apple only supported the first edition iPad for less than 2.5 years) and one monitors 14 nearby networks then on average one would only have to wait 9 days between setup events (though I suspect you'd get serious bunching up of events around Thanks Giving and Christmas).

So with a cheap dedicated device, like the WiFi Pineapple, such events hardly fall into the category of extremely rare. One can imagine anyone looking out for such events - from the local nuisance to sophisticated criminals running botnets where the individual bots monitor for setup events, in addition to their main job (though putting a bot's wifi setup into monitor mode generally makes it unusable for other purposes, e.g. sending spam).

As more and more IoT devices start being used it will become more and more worth while looking out for the setup events, any current acceptability of momentary insecurity will disappear fast.

Most of us are lucky enough not to live within range of someone malicious or criminal, so no mater how insecure our home networks are or how irresponsible the devices we connect are with our passwords we'll never get hacked. Many people still use WEP and despite that experience no unfortunate consequences. However some small percentage of people do get hacked and for them it's a very unpleasant experience.

TI and downstream manufacturers using Smart Config without AES will be complicit in attacks resulting from compromised network passwords. The fact that many people use insecure wifi setups doesn't make it somehow OK to produce fundamentally insecure systems. And producing insecure systems is what TI is encouraging by allowing Smart Config to be used without AES.

I certainly wouldn't want to produce a device in the knowledge that only some of my end users will experience serious negative consequences as a result of using it.

One could claim that it's up to end users to make a decision on whether the risks in using CC3000 enabled devices without AES are acceptable. But I think that's hardly reasonable - end users are not in a position to make informed decisions on complex technical issues - on the whole they have to trust device manufacturers to be responsible. End users assume someone else has thought about security, especially when that someone is asking them for a password that protects something valuable, whether it be access to their online banking or their home network.

Most end users (one hopes) now know not to give their passwords to a random web app or downloaded application but tend to trust hardware and things with a clear real world source, they assume such devices will handle their passwords in a responsible manner. When asking for a password there's an expectation it will be used in a secure manner, with Smart Config without AES this is definitely not the case.

The engineering department for the CC3000 may not want to make a big deal about using AES in their product literature etc. as using it makes the product somewhat less attractive, and as such less likely to succeed. But if it does succeed in a big way and manufacturers do use the non-AES option then I think it will only be a matter of time before TI's legal and liability department has to deal with serious reputational and financial consequences.

If I was an end user, for whom the issues involved hadn't been clear, and who had his or her network compromised (whether personal photos were destroyed or bank details taken) and I found that similar things had happened to various other people I'd certainly be looking at a class action suit and for someone to blame, i.e. TI and the downstream manufacturers.

Fundamentally I don't believe TI should be offering the option to use Smart Config without AES - I simply don't see that there is any real class of end user for whom the security/convenience compromise can be considered acceptable.

If someone like me with only a casual interest in security, who has only occasionally used wireshark and never looked at wifi traffic before can write a small application in a few days that can recover non-AES protected passwords broadcast by Smart Config then I think this option has to be considered completely insecure and should not be offered as an option. Security through obscurity is no real security.

Stories such as this one from the BBC, involving a baby monitoring camera that could be hacked, show the large potential reputational risk for companies producing internet connected devices. I think the story will be far worse when someone eventually gets hacked as a result of using a CC3000 enabled device without AES and find out that corporation X knowing sold them a device that broadcast their network password and that TI mass produced the underlying hardware which supported this behavior. The manufacturers of the first generation of smart wifi enabled embedded devices may have had some excuse for overlooking security but now that the hacking of such devices even comes up as a plot theme in popular culture, e.g. the killing of the vice-president in Homeland by hacking his pacemaker, ignorance of the issue is no longer a reasonable excuse.

Technical details

For more technical details see my other CC300 related blog postings and see these discussions:
  • On the Spark Core forums - "CC3000 broadcasts network password unencrypted." There's some thoughtful input from the Spark team itself and from their users. The Spark Core is a great little device that uses the CC3000 and I hope that any discussion I've kicked off around Smart Config does not affect the success of their product.
  • On the TI support forums for the CC3000 - "How does TI CC3000 wifi smart config work on wpa2 encrypted home network?" This discussion is quite long but brings up all the interesting points, note that in this discussion some remarks by me, and more surprisingly by TI representatives, are incorrect - things only become clearer as the conversation proceeds.
In the TI forum discussion TI representatives make references to trade secrets and patents - one can look up patents and pending patent applications on the United States Patent and Trademark Office search for patents page. However I couldn't find any application relating to Smart Config etc. nor can TI provide pointers to the relevant applications - if anyone has any details please comment otherwise one is left to assume that no such applications exist.

Alternative approaches

Using AES reduces the convenience to end users (they have to type in a long AES key in addition to the name and password for the network they want the device to connect to) and it increases complexity for the manufacturers (they have to program individual AES keys into their devices and deliver the keys in a secure manner to end users). This somewhat reduces the attractiveness of the CC3000 with Smart Config when compared to competing approaches. There are various alternatives, none of which seem perfect either, here are some of them and I'd be interested in comments on any other approaches people have come across:
  • transferring credentials via USB - this requires manufacturers to include a USB port on their devise, along with cable, for the one off network setup task. While USB is pervasive in the laptop/desktop space it is not so ideal for use with smartphones, one would have to provide adapters (for lightening or the old style 30-pin connector for Apple devices, mini and micro USB for Android etc.) and iOS don't make communicating with arbitrary USB devices easy.
  • transferring credentials via light or audio - transferring data to headless devices has been around for a long time, back in 1994 Timex and Microsoft teamed up to produce Datalink watches where data was transferred to the watch from the PC by holding the watch to the the screen, the PC would flash the relevant screen area on and off and the watch would decode the data transmitted to it in this way. There are almost certainly earlier examples. The Electric Imp, a competitor (in some ways) to the CC3000, uses this mechanism to transmit SSID and password to the imp (a device with wifi, antenna and MCU all in one small package). They say there are patents pending (see their product page) on their process, which they call BlinkUp - one hopes only on some obscure aspect of the process given that the basic idea has been around forever. Transferring data by audio (using a headphone jack to jack connection rather than a speaker to microphone setup makes things more reliable and less annoying to the end user) is also possible, see devices such as the SparkFun audio jack modem for iPhone and Android.
  • making the device act as an access point (AP) and connecting to that AP and entering the credentials directly via e.g. a web interface. Like the CC3000 approach this doesn't require any additional hardware beyond the already necessary wifi chipset - however switching APs involves a degree of difficulty that many end users are not comfortable with. Devices such as those from GoPro use the AP approach for controlling headless devices (but not for setting them up to connect to one's home network).
  • Wi-Fi Protected Setup was supposed to address this issue and was built into many home APs - unfortunately it was broken from the start (in a surprisingly obvious and fundamental way) and since the flaws became well known it has been in many cases disabled in the latest software updates for those APs that once supported it.
Approaches using USB, light or audio require additional hardware but no third party can watch the traffic or impersonate the device (even when using light there's little opportunity for third parties to pick this up).

Any comments, thoughts etc. on any or all of the above would be much welcomed. Thanks for reading this far.

Thursday, October 10, 2013

CC3000 Smart Config and keyphrase recovery

Having previously described how the SSID and keyphrase are transmitted to a CC3000 enabled device I thought I should put my money where my mouth is and prove that it's possible to create an application capable of recovering such information.

This proved a bit more difficult than expected but ultimately the code required turned out to be fairly simple.

Capturing wifi packets

While sniffing ethernet packets on a wired network is something pretty much any computer can do the same is not true for looking at wifi packets. To be able to look at all packets, not just ones involving the machine doing the sniffing, one has to be able to enable what's called monitor mode. The ease with which this can be done seems to depend on the wifi chipset, the OS and other factors. Even if one can enable monitor mode one may be able to see the headers for packets without being able to see the data portion, again this seems to be dependent on chipset and other factors.

After much unsuccessful experimentation on Linux I eventually found it was actually easier to get things working without any issues or special tricks on my Mac. I did eventually get things to work on my Linux box and this is described later, but as it's rather more involved I'll stick with describing the Mac setup initially.

I just downloaded and installed the latest Mac version of Wireshark (the de-facto standard packet analysis tool). After installation the command line version, called tshark, and other tools could be found in /usr/local/bin. Note: when I installed Wireshark it created /usr/local/bin such that it belonged to a userid that did not exist and with 0700 permissions, so I did:

$ sudo chmod 755 /usr/local/bin

First I found the wifi device like so:

$ tshark -D

It was en0, then I tested that I could capture packets including the data portion like so:

$ tshark -i en0 -I -V

The options tell tshark to capture packets from en0 (-i en0), using monitor mode (-I) and to produce verbose output (-V). Verbose output will show the binary contents of the data portions of any packets that have data. The fact that the data is encrypted isn't important.

Filtering for relevant packets and outputting relevant information

The -V options shows way more detail than is actually needed and without filters one sees information about many packets that aren't of interest.

After some experimentation I came up the following:
$ tshark -o 'wlan.enable_decryption:FALSE' \
    -i en0 -I -f 'subtype qos-data' \
    -Y 'wlan.fc.retry==0' -T fields \
    -e wlan.bssid -e radiotap.channel.freq -e wlan.sa -e wlan.da -e data.len
As we can't decrypt the packet data we can't look at the higher level protocol information, so we can't simply filter for UDP traffic. But we can ignore all packets that can't possibly contain the UDP traffic we're interested in. We do this by excluding all packets that are not of subtype QoS data (-f 'subtype qos-data'). And we ignore all retransmitted packets (-Y 'wlan.fc.retry==0'), this may not sound intuitive but handling them in a meaningful manner is difficult and on the whole they tend to duplicate data that we actually already have rather than providing data that has somehow been missed (which was my initial assumption).

The -T fields and subsequent -e arguments are our replacement for -V and only output the very limited set of fields values that we are interested in:
  • BSSID - the numeric address behind the human readable SSID - see Basic service set identification.
  • Channel frequency - see WLAN channels (and more on channel hopping later).
  • Source address - the address of the sender of a given packet.
  • Destination address - the destination address of a given packet.
  • Data length - the length of the encrypted data portion of a given packet.
BBSID and channel frequency are just output for reference - they are not actually required by any of the SSID or keyphrase recovery logic.

Note: wireshark and tshark can actually decrypt wifi packets if you provide the necessary information. If you've already configured and enabled decryption then tshark will pick this up from your ~/.wirehark file and automatically decrypt packets. Above I've actively disabled this behavior with the -o 'wlan.enable_decryption:FALSE' option, if you don't have decryption already configured you don't need this.

SSID and keyphrase recovery application

I've written an application in Java that parses the output of tshark and recovers the SSID and keyphrase information from this data. If you've got git installed you can just clone the relevant repository from GitHub like so:

$ git clone https://github.com/george-hawkins/betaengine

If you don't have git you can just download the repository contents as a zip file from here:

https://github.com/george-hawkins/betaengine

The code is fairly simple and short (700 lines in total) and just consists of the following classes:
  • Consumer - contains the main method and reads and parses the output from tshark.
  • Analyzer - maintains a LinkManager per source/destination pair seen.
  • LinkManager - looks for data length differences that might indicate Smart Config data.
  • LengthDecoder - finds SSID and keyphrase sequences.
  • Solver - attempts to combine partial SSID and keyphrase sequences to generate and decode complete sequences.
  • EncodedData and Link - trivial support classes.
The files come with a README.md that briefly outlines how to compile and run the application (for the run instructions look at the "Decoder" section). Basically you just run tshark and pipe its output directly into the application. If you then use a Smart Config application to communicate an SSID and keyphrase to a CC3000 enabled devise you should soon see something like:

Solved SSID: [MyPlace]
Solved keyphrase: [LetMeIn]
Scan succeeded

This shows that we succeeded in recovering the SSID, in this case "MyPlace", and the keyphrase, in this case "LetMeIn". Note that it may find the SSID or keyphrase long before the other.

Any characters that are not printable character in the Unicode range 0x20 to 0xFF are printed as Unicode escapes, e.g. the € symbol would appear as "\u20AC".

If you don't succeed in recovering the password then it maybe that you are not listening on the right wifi channel - see the channel hopping section later. However generally you will be on the right channel already as a result of having being previous connected to the relevant wifi access point (AP).

Note that while tshark is running in monitor mode your machine will be disassociated from your AP and other applications on the machine will not be able to access the network.

If you used AES encryption then the keyphrase displayed will be the still encrypted version and will probably appear largely as Unicode escapes due to non-printing characters etc. I haven't added AES decryption logic, this is left as an exercise for the reader, it's simple actually if you create a cipher using AES Electronic Cook Book transformation with no padding as described briefly in the middle of this post. Obviously any such logic will need the relevant AES key to decrypt a given keyphrase.

Important update Dec 8th, 2014: please see this comment from Mark and my reply. I have not updated my code to reflect any recent changes such as this and do not plan to do so.

Implementation issues

So what were the main difficulties encountered in creating the application?

When I started I thought it would be easier to filter the packets I was interested in from all the other packets and I assumed I would see cleaner runs of packets corresponding to the SSID and keyphrase.

However while one can group packets by source and destination, when one cannot decrypt the packets one can only do so much to distinguish between Smart Config related packets and other similar traffic between a given source and destination.

Using what we know about Smart Config it's possible to filter out many packets but we still end up with a combination of extra invalid values and missing values between the packets that delimit the SSID and keyphrase. I refer to the invalid extra values as spam and the missing values as holes in my code. The holes are presumably the product of packet collision, the spam the product of unrelated traffic that can't be distinguished from Smart Config traffic due to encryption. And remember that the packets that have an appropriate data length such that they appear to be Smart Config tags, separators etc. may themselves just be the result of unrelated traffic that coincidentally involves packets that have the lengths being looked for.

Note: packet collision shouldn't be the issue it is on wired ethernet networks due to the need to use CSMA/CA on wifi networks.

The Smart Config application transmits the same sequences over and over again. The Solver class takes multiple received sequences, each probably containing spam and holes, and tries to construct a clean sequence of the required length that obeys the upper nibble rules etc., described in my previous post, that we know have to apply.

The current Solver is just one possible implementation, one could imagine taking completely different approaches with different pros and cons. It should certainly possible to come up with more complex logic that can recover the SSID and keyphrase from fewer repeats of the underlying sequences in the face of greater amounts of spam and collisions.

Note: the current solver tries hard to patch pieces from multiple sequences together to create a complete clean sequence. Sometimes it will actually produce multiple valid solutions and you'll see output like this:

Solved SSID: [MyPlacf]
Solved SSID: [MyPlace]

Obviously only one solution is the right one - with a little extra effort it would be possible to generate statistics for each solution, on e.g. things like how much patching was involved, to give some indication as to how likely a given solution is to be the right one. Sometimes if an SSID or keyphrase tag gets lost in transmission the current solver can occasionally produce a largish number of very poor solutions.

Channel hopping

The tshark logic described above will only listen on whatever channel your wifi device is currently configured for, typically channel 1, 6 or 11. The CC3000 must presumably do channel hopping to find the relevant channel. Tshark and related utilities don't directly support channel hopping - but it's relatively easy to setup channel hopping - see the channel hopping section of the Wireshark wiki page on capture setup.

On Mac things are even easier - one can use the standard, but well hidden, airport application that can be found here:
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
With this command you can scan for nearby networks and see what channel they're using, you can disassociate from your current network and change the current channel of your wifi device. See e.g. CNET's overview of various Mac network related CLI commands for more details.

Setting up aircrack and tshark on Linux

As outlined above it proved to be easier getting tshark working on Mac. I did eventually get it working on my Ubuntu 12.04 machine. The main issue was enabling monitor mode. To do this I required airmon-ng, a tool that's part of Aircrack-ng. Aircrack wasn't available via apt-get so I had to download and compile it. On doing make install it installed airmon-ng to /usr/local/sbin.

Then I was able to enable monitor mode like so, where wlan0 is the name of my wifi device as reported by ifconfig (it may have a different name on your system):

$ sudo /usr/local/sbin/airmon-ng start wlan0 11

It output "monitor mode enabled on mon0" - mon0 is a pseudo device created by airmon-ng that tshark will listen to rather than wlan0. However the command also outputs a warning about processes that may interfere with its operation. They do indeed interfere but it's not as simple as killing the suggested PIDs as some of them are related to services that will simply restart them if they're seen to die. So I had to stop the relevant services like so:

$ sudo service network-manager stop
$ sudo service avahi-daemon stop
$ sudo service upstart-udev-bridge stop

I then stopped monitor mode - note that this needs to done on mon0 rather than wlan0:

$ sudo /usr/local/sbin/airmon-ng stop mon0

Then I started monitor mode, as above, again and this time it only warned about one process and I killed the listed PID with a normal kill (using sudo).

Note that stopping the above services will disconnect you from your wifi network, even before you use tshark with the monitor mode enabled pseudo device mon0. If you need to reconnect, e.g. if you find initially as I did that you don't have tshark installed and need to apt-get it, then just redo the service commands above with start instead of stop.

OK - now we're ready to start tshark almost as above on the Mac:
$ tshark -o 'wlan.enable_decryption:FALSE' \
    -i mon0 -f 'subtype qos-data' \
    -R 'wlan.fc.retry==0' -T fields \
    -e wlan.bssid -e radiotap.channel.freq -e wlan.sa -e wlan.da -e data.len
Note that I use the mon0 pseudo device and use -R rather than -Y as the version of tshark available via apt-get for Ubuntu 12.04 is older than the version I have on my Mac and doesn't support the -Y flag. And I don't use -I as mon0 is already in monitor mode (and trying to use -I will cause tshark to fail).

Unlike on the Mac, where no special steps need to be taken once one you've finished capturing packets with tshark, one should stop the pseudo device as shown above and restart the various services (also as described above).

Note that in the airmon-ng start command above we explicitly specify what channel we want to monitor, in the example it's channel 11. If you wanted to do channel hopping see the Wireshark wiki page (also mentioned above).

Extra features of the Smart Config library

In a previous post I covered details of the TI Smart Config library that may (most likely) be historical left overs from TI's development process or may possibly be useable in combination with some non-default configuration of a CC3000 device. The only one of these that could affect the ability of the code I've written to recover SSIDs and keyphrases is being able to set the length of the two separator value. Currently my code looks for packets that differ in length by the difference between these two values, so this logic would no longer work if these values were changed. However it would be simple to adjust the logic to look for values that reoccur frequently and deduce that they were the separator values being used in this particular situation.

Tuesday, October 8, 2013

The CC3000, 802.11n and MIMO

MIMO creates a significant issue for the CC3000.

Most modern wifi access points (APs) support at least the following three 802.11 protocols:
  • 802.11b which supports 11Mbs.
  • 802.11g which supports 54Mbs.
  • 802.11n which supports up to 600Mbs.
Such APs by default generally operate in what's called mixed mode, i.e. they support all protocol variants concurrently, one client may be connected to the network using 802.11g while another is connected using  802.11n.

The CC3000 only supports 802.11b and 802.11g - so it can connect to old APs that only support one or both of these protocols or to a modern AP that's running in mixed mode.

Note: it's a commonly held belief that a mixed mode network runs at the speed of the slowest device connected to it. I.e. if there's an 802.11b (11Mbs) client on a network then all other clients will also be restricted to this speed, even two 802.11n clients (capable e.g. of 156Mbs) talking just to each other. If this was ever true it is not true any more for modern APs.

With the older 802.11 protocols a device had no choice but to support the relevant speed, i.e. 11Mbs or 54Mbs.

802.11n is interesting in that a device capable of no better speed than that supported by e.g. 802.11g can still be 802.11n compliant.

Being 802.11n capable means that a device understands the protocol and can work, if required, on a network that only supports 802.11n. However each device negotiates the speed it can handle and the AP will adjust the speed of its transmissions to a particular client according to that clients capabilities.

The main factor affecting the maximum 802.11n speed a device can support is MIMO. Basically with 802.11n the more MIMO capable antennas a device has the higher the speed it can support.

Typically the smaller and more energy frugal a device needs to be the fewer antennas it will have.

A typical home AP will have enough antennas to support the fastest current desktop wifi setups, but will adjust its transmission speed for each client according to the capabilities of the client.

This leads to an interesting problem for the CC3000. To pick up the SSID etc. transmitted by a Smart Config application it needs to run in monitor mode, i.e. be able to watch all traffic on a network.

Currently it can monitor traffic from 802.11b and 802.11g clients, and interestingly, even though it doesn't support 802.11n once it is connected to a network, it can monitor Smart Config traffic from certain 802.11n clients.

Which 802.11n clients it can monitor seems to depend on MIMO. If the client is something like a smartphone there doesn't seem to be an issue but if the client is a modern laptop capable of the higher 802.11n speeds then things don't work.

So it's not enough for the CC3000 to just add 802.11n support explicitly. Unlike previous 802.11 protocols, where supporting the protocol was enough in itself, monitoring all 802.11n traffic on a network also requires that the given device has enough MIMO capable antennas needed to handle the highest traffic speeds seen on that network.

For a tiny embedded device like the CC3000 this isn't really feasible. So while the Smart Config idea plays well for older 802.11 protocols there are issues with improving the CC3000 such that a Smart Config setup application could be run from any 802.11n client irrespective of the speed supported by that client.

Note: I said "seems to depend on MIMO" above - I'm not a MIMO expert but experimentation with different 802.11n devices seems to confirm what I believe. I'd be interested in input from a real 802.11n/MIMO expert.

Among other things my experimentation has included forcing my Macbook Air which can talk, using its built-in wifi, to my AP at 144Mbs to instead use a cheap USB wifi dongle. If I use built-in wifi my CC3000 device cannot pick up the data transmitted by my Smart Config application but when I use the cheap USB wifi dongle it can.

Note: there are lots of cheap small 802.11n USB adapters for Windows and Linux but while there are a few older 802.11g adapters for Mac there aren't many 802.11n adapters. Presumably this is because all modern Apple hardware comes with builtin wifi. So I ended up looking at what USB adapters people are using with Hackintoshes (home brew, i.e. non-Apple, Intel based hardware capable of running Mac OS X). I found a number of recommendations on MacBreaker.com and deliberately chose the smallest and cheapest one in order to get something 802.11n compatible while minimizing my chances that it would support the higher end 802.11n capabilities that cause the problems discussed in this post. I chose the D-Link DWA-131 - they don't sell it as Mac compatible but it comes with a Realtek RTL8191SU chipset and the MacBreaker page provided a link to the Realtek driver page for this chipset. There Realtek provide a Montain Lion driver that works fine - once installed you need to turn off your normal wifi first and then use their somewhat underwhelming Wireless Network Utility instead. Everything works fine and as reported my CC3000 device picks up the data transmitted by Smart Config when I use this adapter in place of my builtin wifi.

Monday, October 7, 2013

CC3000 Smart Config and AES

One can use AES with the CC3000 and Smart Config - this will prevent arbitrary third parties who do not know the relevant AES key from recovering the passphrase when transmitted by a Smart Config setup application.

AES uses symmetric keys - the same key must be known to the CC3000 enabled device and to the user of the Smart Config setup application.

Smart Config supports 128 bit AES keys. To enter such a key the end user would have to enter a 32 digit hex value, along with the relevant SSID and the passphrase for the relevant network.

Note: the TI Smart Config setup application for Java currently only supports entering 16 characters, each of which may be any valid character value. If we consider the ASCII range from the space character to the tilde, this allows us to encode a little more than 6 bits per character or about 103 bits in total, i.e. noticeably less than 128 bits and considerably less if one excludes characters, such as zero and capital O, that would be hard to distinguish for a user reading the key e.g. from a printed label.

As entering random sequences of characters correctly is not easy for human beings any setup application should probably also require some additional checksum digits so that it can detect if mistakes are made (otherwise if the passphrase is encrypted with an incorrect AES key then the user will get no other feedback beyond the CC3000 enabled device failing to connect to the network).

If an AES key is provided by the end user then the same procedure is used as described before to encode the passphrase except that the passphrase is encrypted into a sequence of bytes using a cipher that implements the AES Electronic Cook Book transformation with no padding, and it is then these bytes that are split into high and low nibble values etc.

Note: AES Electronic Cook Book transformation with no padding would be expressed as "AES/ECB/NoPadding" when creating a cipher in Java - see the "Creating a Cipher Object" in the JCA reference guide and the "Cipher Algorithm Names" section in the JCA standard cipher algorithm names documentation (and the following sections on modes and padding).

Using AES increases complexity for manufacturers, they must encode a unique AES key into each device and determine a way to securely provide this key to the end user, and it reduces the convenience of the whole approach for the end user as they must enter a long AES key as part of the setup process in addition to the SSID and passphrase of the network they are actually interested in.

However without an AES key device manufacturers expose their end users to the risk of broadcasting the passphrase of their network to a malicious third party. Many end users will not be in a position to evaluate this risk properly, incorrectly assuming that any application requesting their network password will handle it in a secure manner.

Delivering AES keys to the end user is non-trivial, e.g. if one manufacturer provides the component with the CC3000 device and sets up the AES key but is not the provider of the completed product then they must provide the key with each component in such a way that the relationship between key and component can be maintained downstream and provided to the end user.

Delivering the keys securely is also a problem. E.g. if the keys were printed on stickers that accompanied the product then it might be possible for an attacker to record the keys before they were delivered to a particular end user. Tamper proof packaging for the key, similar to that used for bank PINs, could at least alert an end user to the fact that the key had been compromised.

Note: even I accept that I'm probably overplaying the secure key delivery issue. A determined attacker, with physical access to devices before they are delivered to the end user, can obviously overcome any issue (even replacing devices with ones they produced themselves). No effort is currently taken to protect against such issues e.g. with wireless routers - the firmware of a wireless router is generally easy to replace and yet no steps are taken by manufacturers to ensure that routers reach end users with unchanged firmware. AES keys printed on simple stickers are probably an acceptable approach.

One could reduce the difficulty of entering an AES key by providing it as a QR code, however QR codes are unpopular with many users and are only appropriate for the smartphone versions of any setup application.
CC3000 enabled devices cannot be used in environments using WPA-Enterprise, i.e. setups where, instead of using a pre-shared key as in home and small office networks, per-user authentication using RADIUS servers is used. As such, devices that do not use an AES key are only putting home and small office environments at risk. This may be a relief to corporate network administrators but is hardly reassuring for everyone else.

Note: in this post I've used the term passphrase, while I've used the term keyphrase in other posts. I did this to to try and distinguish more clearly between the passphrase used to access a network with a given SSID and the AES key used, as described here, to encrypt the passphrase before transmitting it to a CC3000 enabled device.

CC3000 Smart Config - transmitting SSID and keyphrase

Initially TI clearly documented how the SSID and password were transmitted to a CC3000 enabled device in their "CC3000 First Time Configuration" document. However with release 1.10 they changed the approach to one called Smart Config and now document the API but no longer explain what is happening at the network level. Here I cover this missing information for the new approach.

So let's start at the start - we have a problem - we want to send two pieces of information, an SSID and the keyphrase, from one party that is already a member of the wifi network to an external party who can monitor all the encrypted wifi traffic but who cannot decrypt it.

Someone who cannot decrypt the wifi traffic can still see quite a lot of information, e.g. they can see the source and receiver MAC addresses of every packet sent.

They can also see the length of the data portion of the packets. The encryption affects that size of the packets sent but in a consistent manner, e.g. if one sends n bytes of data in a given packet then the encrypted packet will contain (n + x) bytes where x is constant across all packets.

So the solution to our problem is to encode the information in the size of the packets sent (the actual content is irrelevant).

The party on the secured network just sends UDP packets with particular lengths to another party on the network. That the other party is not interested in receiving the packets is not important.

The external party cannot tell directly that a packet that it is looking at contains UDP data, however the packets still include basic type information that allows many packets to be excluded from consideration, e.g. any packet that is not of 802.11 subtype "QoS data" can be excluded.

As the external party does not know in advance which wifi channel to look at or which source and receiver address pair to pay attention to one must, in addition to the underlying data, i.e. encoded SSID etc., send regular repeating patterns that allow this data to be spotted.

We convert our SSID and keyphrase into a sequence of tag values, string lengths, nibble values and separators values and then encode and transmit all these values as packet lengths.

Let's look in detail at the values sent.

We use two tags - an SSID tag with value 1399 and a keyphrase tag with value 1459 and one standard separator sequence consisting of two values - 3 followed by 23.

And we use two constants, L with value 28 and C with value 593, that we will see used below.

So for the SSID the following sequence of values are generated in this order:
  • The SSID tag 1399.
  • L plus the length of the SSID in bytes.
  • The two separator values 3 and 23.
  • Then we loop over each byte of the SSID and generate a set of four values for each:
    Two values - one for each nibble of the byte, as described in the next section.
    Followed by the two separator values 3 and 23.
Values are generated in an identical fashion for the keyphrase (except that the keyphrase tag 1459 is used in place of the SSID tag).

Note: the TI Android library and Java applet library generate values as described above, oddly the TI iOS library produces a slightly different ordering (which clearly doesn't affect the CC3000's ability to decode the data). This difference can be seen in the example data length dumps shown latter.

Once we have all these values then UDP packets, each with an amount of data corresponding to one of these values, are sent from the machine running the Smart Config application, i.e. the one that has generated the values just described, to another system on the same network (currently always the network's default gateway).

The values are sent repeatedly until the external party, i.e. the CC3000 enabled device, successfully sifts them out from all the other network traffic and uses them to connect to the network, at which point it advertises its presence on the network in a manner that the transmitting application can detect and which causes it to stop transmitting.

Note that the range of packet lengths that need to be supported places a lower bound on the maximum transmission unit (MTU) for the network. Currently the Smart Config client application expects the MTU to be 1500 or greater (this is a reasonable expectation on any normal network).

The TI Smart Config reference implementation resends the full set of UDP packets corresponding to the SSID and keyphrase repeatedly. The TI Java applet library pauses 100ms after each complete transmission of the full set of values, the Android and iOS libraries do not bother pausing.

Encoding the characters of the SSID or keyphrase.

If an SSID consists of n characters 0 to n - 1 then we generate 2n corresponding values.

Note: according to IEEE standard 802.11i-2004, Annex H.4.1, users may enter keys as a string of 64 hexadecimal digits (or alternatively as a passphrase of printable ASCII characters). Presumably WEP and WPA specify similar restrictions. The SSID must be a sequence of between 1 and 32 bytes, there is no mandated character set (more details in this StackOverflow answer) and how the SSID is displayed is left up to the end user application (however many routers apparently only accept printable ASCII characters for the SSID).

So if we assume ASCII characters encoded as 8 bit values then each value consists of a high and low nibble.

E.g. 'M' in ASCII is hex 0x4D, the high nibble is 0x4 and the lower nibble is 0xD.

If we maintain a sequence number starting from 0 and increment it each time we generate a value then for character i of the SSID, consisting of a high and low nibble Hi and Li, we generate two values with sequence number 2i and (2i + 1) respectively. Each of these values has a high and low nibble calculated as follows:

Seq.HighLow
2iLi-1 ^ (2i % 16)Hi
2i+1Hi ^ ((2i + 1) % 16)Li

Note that the value containing the high nibble of i is generated before the one containing the low nibble of i. And note that caret, i.e. '^', is used here to mean XOR, rather than power of.

The following shows how the SSID "MyPlace" would be split up into high and low nibbles:

'M''y''P''l''a''c''e'
Hex:0x4D0x790x500x6C0x610x630x65
Nibbles:0x40xD0x70x90x50x00x60xC0x60x10x60x30x60x5
H0L0H1L1H2L2H3L3H4L4H5L5H6L6

For each 4 bit nibble we generate a value whose lower 4 bits consist of the nibble itself and whose higher 4 bits consist of the current sequence number XORed with the value of the previously used nibble value. We then add the constant C mentioned above, i.e. 593, to each value generated in this way and this becomes the length of the packet that encodes such a value.

Note that the 4 bit constraint means that we only use the lower 4 bits of the current sequence number, i.e. if the sequence number S is above 15 then we use S % 16.

This results in the generation of 14 values for the 7 character of the SSID name "MyPlace" like so:

C
h
a
r
S
e
q
Hi Lo Byte Hi Lo Hi Lo Sum Len
'M'00x0H00x4D0x00x40x00x40x04 + 593597
1H0 ^ 0x1L00x4 ^ 0x10xD0x50xD0x5D + 593686
'y'2L0 ^ 0x2H10x790xD ^ 0x20x70xF0x70xF7 + 593840
3H1 ^ 0x3L10x7 ^ 0x30x90x40x90x49 + 593666
'P'4L1 ^ 0x4H20x500x9 ^ 0x40x50xD0x50xD5 + 593806
5H2 ^ 0x5L20x5 ^ 0x50x00x00x00x00 + 593593
'l'6L2 ^ 0x6H30x6C0x0 ^ 0x60x60x60x60x66 + 593695
7H3 ^ 0x7L30x6 ^ 0x70xC0x10xC0x1C + 593621
'a'8L3 ^ 0x8H40x610xC ^ 0x80x60x40x60x46 + 593663
9H4 ^ 0x9L40x6 ^ 0x90x10xF0x10xF1 + 593834
'c'10L4 ^ 0xAH50x630x1 ^ 0xA0x60xB0x60xB6 + 593775
11H5 ^ 0xBL50x6 ^ 0xB0x30xD0x30xD3 + 593804
'e'12L5 ^ 0xCH60x650x3 ^ 0xC0x60xF0x60xF6 + 593839
13H6 ^ 0xDL60x6 ^ 0xD0x50xB0x50xB5 + 593774

The keyphrase is encoded in the same way, note that the sequence number starts again from 0 when encoding the keyphrase, i.e. the value is not carried over from encoding the SSID.

Currently Smart Config enforces an upper limit of 32 characters on the keyphrase length, i.e. shorter than the maximum length allowed by the relevant WPA2 standard.

I find the approach used to actively leak information from a secure wireless network to an external party (that does not have the relevant network keyphrase) interesting and would like to hear if anyone has come across it before or whether it is novel? I asked about this on Stack Overflow but have since moved the question to the sister site crypto.stackexchange.com after people suggested it was more appropriate there.

Update Oct 21, 2013: I've now got at least one good answer. In a paper from 2007 by P. Martin called "Covert channels in secure wireless networks" you can find section 4.4.2 "UDP Packet Size vs MAC Frame Size Experiment" that essentially describes exactly the process used by Smart Config. The question of patents has come up once or twice in relation to Smart Config (though no one has ever provided pointers to any actual patent applications or granted patent numbers). The answers and other comments on my question would seem to suggest that there's definitely prior art for the fundamental idea behind Smart Config.

Choosing the destination for the UDP packets

The current logic always sends the UDP messages, that encode the SSID etc., to the default gateway address. However it doesn't actually matter what address they're sent to as long as it's the address of another machine on the network that actually exists and is capable of receiving packets. However it makes sense to have decided on a definite address.

The CC3000 doesn't support ad hoc networks so you are never going to get a situation where it is used on a network that doesn't have an access point (AP), and in most normal setups the AP is also the default gateway. However I don't think a default gateway is mandatory (someone can correct me on this?), one can imagine a self contained wifi network where the AP isn't a gateway to anywhere else.

I wonder why TI didn't choose on the address of the AP rather than the default gateway. Even if the two are almost always the same I think an end user is probably likely to have much more luck, if needed, asking Google or their ISP first level technical support how they find the address of their wifi AP than asking about default gateways.

Note: in a network using an AP all traffic goes via the AP, so even if one chose the address of a machine other than the AP the traffic would still be received by the AP and retransmitted by the AP to the destination machine. This doesn't cause an issue if you try it with the CC3000 but it does mean the traffic in pointlessly duplicated.

Further details of the Smart Config library

The sections above cover the heart of how Smart Config works, the following covers details of TI's Smart Config Java applet library that don't immediately seem relevant - they may be left over from the development process and have just never been cleaned out or they may relate to non-default functionality that it's possible to use if a particular CC3000 device is configured in a particular way.

  • One can set the DatagramSocket used to send the UDP packets to something other than one simply setup to bind to any available port on the local machine.
  • One can set the port to which the UDP packets are sent to something other than 15000.
  • One can set the port on which mDNS UDP messages are expected to something other than 5353.
  • One can set can the timeout, i.e. the time the application waits, for the CC3000 enabled device to connect to something other than 5 minutes.
  • One can set the number of times all the details are retransmitted before taking a 100ms pause. By default this is 1, i.e. the logic takes a 100ms pause between every full transmission of the details.
  • One can set the two separators values, i.e. 3 and 23 mentioned above, to different values and more bizarrely set the characters used to make up the packets with these lengths.
These features are available in the library but are never made use of by the TI Smart Config application built on top of this library.

One can also set the network interface of the socket used to listen for mDNS message. However this seems completely pointless as this just affects outgoing multicast datagrams and the relevant logic is only looking for incoming datagrams.

With one exception all of this configurability looks pointless.

  • It's hard to think of why one might want to specify the bind address of the DatagramSocket used to send the UDP packets.
  • The machine receiving the packets will ignore them and so choosing a particular port seems irrelevant and with encrypted network traffic one cannot see port information so it shouldn't be relevant to the CC3000 device's ability to detect the relevant traffic.
  • mDNS always uses port 5353 and given how mDNS is used it's hard to imagine that port number being changed on a particular network.
  • The timeout is fairly arbitrary, 5 minutes seems extremely long so it does seem reasonable to adjust it down if one really cares about this.
  • Being able to set the number of full retransmits before a pause has no obvious benefits.
That leaves us with being able to change the separator lengths. Perhaps this is configurable on CC3000 devices. I can't see a reason why you'd want to change the default values. And if one did I suspect one would have to be careful what values one chose. The tag values for SSID and keyphrase, and the constants C and L mentioned above, along with the two separator length values, all seem to have been chosen to ensure no overlap in values between one kind of thing and another, the current setup means no packet length encoding a nibble of an SSID character or keyphrase will end up with a length equal to the tags or separator values.

Note: the port number 15000 mentioned above has not been registered by TI and actually belongs to a legitimate service called "hydap" which has been registered by HYPACK Inc. with IANA. This shouldn't be an issue for anyone.

Multicast mDNS

Above you saw some mention of mDNS. This is involved in detecting that a CC3000 device has successfully connected to the network and is discussed in more detail in this post.

What character set does the CC3000 use?

The Smart Config Java applet library stores the SSID etc. as standard Java strings, i.e. sequences of Unicode characters. It converts back and forward between these strings and arrays of bytes at various points, but takes no care of character sets, e.g. when it calls String.getBytes() it always uses the form that uses the platform's default character set. This will work on most systems, including pretty much everything in the US and Western Europe, but will obviously be an issue elsewhere. The CC3000 presumably has a fixed character set and this should be used explicitly in the library when converting between characters and bytes.

Update: experimentation shows that while the TI Java applet library just uses the default character set of the machine it's running on, when converting to and from bytes, the TI iOS and Android apps both seem to consistently use UTF-8.

Packet length dumps from the TI Smart Config applications

If any of the above wasn't too clear, hopefully this section will help with a practical example of the packet lengths generated by the TI Smart Config applications when sending the SSID "MyPlace" and the password "LetMeIn".

The first dump shows the packet lengths generated by the Android and Java applet applications. The first colum just shows the UNIX time the packet was sent at, the second column shows the length of the packet and this is then followed by an indication of what the length of packet is encoding.
1381084544.032552000    1399 <----- SSID tag
1381084544.033572000    35   <----- SSID length + 28
1381084544.033589000    3    <--+-- separator
1381084544.033594000    23   <--'
1381084544.033667000    597  <----- 'M' hi-nibble
1381084544.033675000    3    <--+-- separator
1381084544.033723000    23   <--'
1381084544.034369000    686  <----- 'M' lo-nibble
1381084544.035385000    3    <--+-- separator
1381084544.036271000    23   <--'
1381084544.036448000    840  <----- 'y' hi-nibble
1381084544.036467000    3    <--+-- separator
1381084544.036481000    23   <--'
1381084544.036541000    666  <----- 'y' lo-nibble
1381084544.037262000    3    <--+-- separator
1381084544.037271000    23   <--'
1381084544.037496000    806  <----- 'P' hi-nibble
1381084544.038019000    3    <--+-- separator
1381084544.038032000    23   <--'
1381084544.038097000    593  <----- 'P' lo-nibble
1381084544.043096000    3    <--+-- separator
1381084544.044209000    23   <--'
1381084544.044785000    695  <----- 'l' hi-nibble
1381084544.045422000    3    <--+-- separator
1381084544.045855000    23   <--'
1381084544.048359000    621  <----- 'l' lo-nibble
1381084544.049327000    3    <--+-- separator
1381084544.049347000    23   <--'
1381084544.049406000    663  <----- 'a' hi-nibble
1381084544.049412000    3    <--+-- separator
1381084544.049416000    23   <--'
1381084544.049568000    834  <----- 'a' lo-nibble
1381084544.050052000    3    <--+-- separator
1381084544.050067000    23   <--'
1381084544.050808000    775  <----- 'c' hi-nibble
1381084544.051463000    3    <--+-- separator
1381084544.052082000    23   <--'
1381084544.055415000    804  <----- 'c' lo-nibble
1381084544.056319000    3    <--+-- separator
1381084544.056334000    23   <--'
1381084544.056398000    839  <----- 'e' hi-nibble
1381084544.056404000    3    <--+-- separator
1381084544.056407000    23   <--'
1381084544.056644000    774  <----- 'e' lo-nibble
1381084544.058021000    3    <--+-- separator
1381084544.058034000    23   <--'
1381084544.059236000    1459 <----- passphrase tag
1381084544.059252000    35   <----- passphrase length + 28
1381084544.059255000    3    <--+-- separator
1381084544.059258000    23   <--'
1381084544.059261000    597  <----- 'L' hi-nibble
1381084544.059937000    3    <--+-- separator
1381084544.059949000    23   <--'
1381084544.060043000    685  <----- 'L' lo-nibble
1381084544.060723000    3    <--+-- separator
1381084544.060729000    23   <--'
1381084544.060884000    823  <----- 'e' hi-nibble
1381084544.061407000    3    <--+-- separator
1381084544.061411000    23   <--'
1381084544.061954000    678  <----- 'e' lo-nibble
1381084544.062651000    3    <--+-- separator
1381084544.062709000    23   <--'
1381084544.063217000    616  <----- 't' hi-nibble
1381084544.063696000    3    <--+-- separator
1381084544.063699000    23   <--'
1381084544.064344000    629  <----- 't' lo-nibble
1381084544.064893000    3    <--+-- separator
1381084544.064897000    23   <--'
1381084544.065561000    629  <----- 'M' hi-nibble
1381084544.066131000    3    <--+-- separator
1381084544.066221000    23   <--'
1381084544.066947000    654  <----- 'M' lo-nibble
1381084544.066955000    3    <--+-- separator
1381084544.067371000    23   <--'
1381084544.067491000    679  <----- 'e' hi-nibble
1381084544.067871000    3    <--+-- separator
1381084544.068325000    23   <--'
1381084544.069089000    838  <----- 'e' lo-nibble
1381084544.069097000    3    <--+-- separator
1381084544.069593000    23   <--'
1381084544.069711000    837  <----- 'I' hi-nibble
1381084544.070191000    3    <--+-- separator
1381084544.070656000    23   <--'
1381084544.074244000    842  <----- 'I' lo-nibble
1381084544.074259000    3    <--+-- separator
1381084544.075225000    23   <--'
1381084544.075286000    679  <----- 'n' hi-nibble
1381084544.075291000    3    <--+-- separator
1381084544.075293000    23   <--'
1381084544.075521000    783  <----- 'n' lo-nibble
1381084544.075533000    3    <--+-- separator
1381084544.076058000    23   <--'
--------------------------   No delay on Android, 100ms delay with Java applet library, then repeat from start again.
1381084544.076246000    1399 <----- SSID tag
1381084544.076850000    35   <----- SSID length + 28
...
The output generated by the TI iOS and Java applet Smart Config applications is identical (except for the noted 100ms delay). However oddly the iOS Smart Config application does not interleave the separator values 3 and 23 between the characters of the SSID and keyphrase, instead it always sends out a sequence of 10 separator value pairs as shown here and then sends out the SSID and keyphrase. So here one can hardly call 3 and 23 separators but I've stuck with this name here:
1381085051.154799000    3    <--+-- separator 1
1381085051.159414000    23   <--'
1381085051.164143000    3    <--+-- separator 2
1381085051.170050000    23   <--'
1381085051.174861000    3    <--+-- separator 3
1381085051.179503000    23   <--'
1381085051.185282000    3    <--+-- separator 4
1381085051.190274000    23   <--'
1381085051.195296000    3    <--+-- separator 5
1381085051.200047000    23   <--'
1381085051.206394000    3    <--+-- separator 6
1381085051.211076000    23   <--'
1381085051.215383000    3    <--+-- separator 7
1381085051.225363500    23   <--'
1381085051.235344000    3    <--+-- separator 8
1381085051.235459000    23   <--'
1381085051.236902000    3    <--+-- separator 9
1381085051.241718000    23   <--'
1381085051.249366000    3    <--+-- separator 10
1381085051.253099000    23   <--'
1381085051.257767000    1399 <----- SSID tag
1381085051.262315500    35   <----- SSID length + 28
1381085051.266864000    597  <----- 'M' hi-nibble
1381085051.273117000    686  <----- 'M' lo-nibble
1381085051.278023500    840  <----- 'y' hi-nibble
1381085051.282930000    666  <----- 'y' lo-nibble
1381085051.291178000    806  <----- 'P' hi-nibble
1381085051.294688000    593  <----- 'P' lo-nibble
1381085051.299266000    695  <----- 'l' hi-nibble
1381085051.308603000    621  <----- 'l' lo-nibble
1381085051.311723000    663  <----- 'a' hi-nibble
1381085051.315706000    834  <----- 'a' lo-nibble
1381085051.321567000    775  <----- 'c' hi-nibble
1381085051.326156000    804  <----- 'c' lo-nibble
1381085051.332654000    839  <----- 'e' hi-nibble
1381085051.337025000    774  <----- 'e' lo-nibble
1381085051.342818000    1459 <----- passphrase tag
1381085051.346519000    35   <----- passphrase length + 28
1381085051.353083000    597  <----- 'L' hi-nibble
1381085051.359196000    685  <----- 'L' lo-nibble
1381085051.362984000    823  <----- 'e' hi-nibble
1381085051.366772000    678  <----- 'e' lo-nibble
1381085051.373192000    616  <----- 't' hi-nibble
1381085051.382117000    629  <----- 't' lo-nibble
1381085051.386131000    629  <----- 'M' hi-nibble
1381085051.390145000    654  <----- 'M' lo-nibble
1381085051.393997000    679  <----- 'e' hi-nibble
1381085051.400047000    838  <----- 'e' lo-nibble
1381085051.404880000    837  <----- 'I' hi-nibble
1381085051.412003000    842  <----- 'I' lo-nibble
1381085051.414365000    679  <----- 'n' hi-nibble
1381085051.420336000    783  <----- 'n' lo-nibble
---------------------------  No delay then repeat from start again.
1381085051.432048500    3    <--+-- separator 1
1381085051.443761000    23   <--'
...

Dumping and decrypting wifi packets using tshark

The above dumps were produced with the command line version of the well known packet analyser tool Wireshark that's called tshark. Wireshark is available for Mac OS X, Windows and Linux. The following shows how I used it to produce these dumps.

First I started it off recording packets before doing anything with the particular TI Smart Config application I was working with like so:

$ tshark -i en0 -I -w output.pcap

Note that the -I flag puts your machine's wifi network interface into monitor mode, this disables standard network access for everything else on the machine while tshark is running but allows tshark to see all the traffic on the network, not just traffic intended for the machine that it's running on. On my Mac putting the network interface into monitor mode works fine but on other platforms this can be far more complicated - I'll discuss this further in a later post.

I then ran the particular Smart Config application on a different machine, i.e. an iPhone, an Android phone or a different desktop machine. I hit the start button that you find in each Smart Config application that tells it to start transmitting the SSID etc., and let it run for a while. There's no requirement to have an actual CC3000 enabled device listening for the data. After a few seconds I killed the tshark process with control-C and hit stop in the Smart Config application.

The resulting network traffic ends up in the file output.pcap, note the size of this file can grow very quickly as we're recording all traffic on a given wifi channel, not just the Smart Config related traffic.

Then we can filter out the Smart Config traffic and dump it out as above like so:
$ tshark -r output.pcap -o 'wlan.enable_decryption:TRUE' \
    -Y 'wlan.fc.retry == 0 && !icmp && udp && ip.src == 192.168.1.177 && ip.dst == 192.168.1.1 && udp.dstport == 15000'
    -T fields -e frame.time_epoch -e data.len | head -n 512
ip.src must to be changed to the IP address of the device running the Smart Config application, e.g. an iPhone, and ip.dst must be the IP address used as the gateway by the application.

Note that I exclude icmp packets, these are control packets that can contain embedded UDP packets that would be matched by the udp filter. In our case icmp packets are generated to tell us that the port we are sending the packets to is unreachable. With the wlan.fc.retry filter I also exclude retransmitted packets - I'll discuss this more in a later post.

As shown here tshark can actually decrypt the wifi packets (something which a CC3000 enabled device that's waiting for the network password obviously cannot do). Having done so it can then filter the traffic using higher level network terms like the IP protocol, in this case UDP, and IP addresses.

If the option wlan.enable_decryption is set to TRUE, as shown above, tshark will search for the keyphrase necessary to do the decryption in the file ~/.wireshark/80211_keys where it will expect to find something like:

"wpa-pwd","LetMeIn:MyPlace"

Note that the keyphrase comes before the SSID and that storing keys (in plain text, yes) in the file 80211_keys is relatively new to wireshark/tshark. For earlier versions of tshark you may have to specify the key information as a command line option - Google for what works for your version.

However even if it has the keyphrase it can only decrypt the traffic if your pcap file contains the EAPOL packets that are generated when the device designated by ip.src goes through the initial negotiation of a secure connection with the AP. To force my devices to generate such packets I flipped the phones in and out of airplane mode and on my desktops I temporarily disabled and then reenabled wifi. This didn't always seem to work - I don't know if even on being disabled and reenabled a device can sometimes avoid having to renegotiate its connection. One can check if the pcap file contains EAPOL packets like so:

$ tshark -r sc-ios.pcap -Y eapol

You should see about four packets which correspond to your device (check that the displayed MAC addresses match the MAC address of the device).

Obviously the CC3000 cannot decrypt the packets like this - I'll discuss in a later post how it does much the same as we've done here but without having the relevant decryption information.

Sunday, October 6, 2013

Smart Config clients for iOS, Android, Mac OS X, Windows and Linux

TI supplies a number of Smart Config reference implementation clients for developers here:

http://www.ti.com/tool/smartconfig

However they're really for developers - they're not easy to install, ready to go packages for end users.

If you just want to download and use a Smart Config client you're better off following these instructions for:
iOS: TI have made the iOS Smart Config client available via iTunes. Once installed you should have a new application called "SMARTCONFIG" which when opened looks like this:


Android: oddly the Android version isn't available via Google Play. You can download the reference client from TI but for no obvious reason they've wrapped it up in a Windows executable (that depends on Java being installed). An easier option is download the SmartConfigCC3X_v1_1.zip file from my Google drive. This is the full TI Android Smart Config development project, just unpack the zip file and open the subfolder called "bin". Then connect your Android phone to your computer, enabled USB sharing and copy the file SmartConfigCC3X.apk from the bin folder to your phone. Then turn off USB storage and disconnect your phone from your computer, use a file browser app on your phone to find the file SmartConfigCC3X.apk and click on it, you should then be offered the option to install the file. If you're Android phone doesn't come with a file browser there are many available, e.g. ES File Explorer. Note: before you can install apps from locations other than the Google Play you may have to enable the "Unknown sources" setting as described here (you should disable this setting again after finishing the install). Once installed you should have a new application called "SmartConfigCC3X" which when opened looks like this:

Note: it's also possible to open the SmartConfigCC3X_v1_1.zip file directly on Google Drive and just download the SmartConfigCC3X.apk file.

Mac OS X, Windows and Linux: install my Java based Smart Config desktop client (that uses a closed source TI library to do all the real work) as described here. Note: if you are connected to your wifi access point using 802.11n this may not work for the reasons TI outline in the "limitations" section of this document. For more information on determining if you are using 802.11n and how to switch down to 802.11g if required can be found in this blog post. When run it looks like this on Mac OS X, Windows and Ubuntu 12.04 respectively:





Thursday, October 3, 2013

Java Smart Config desktop client


I've written a desktop Smart Config user interface in Java for setting up CC3000 enabled devices. It's available under the Apache License, Version 2.0 from GitHub here:

https://github.com/george-hawkins/betaengine

It's also available as a ready to go precompiled binary package here:

https://github.com/george-hawkins/betaengine/releases

Just download the zip file and follow the instructions in the included README.txt file.

Among other things it consists of two executable jar files. You must first run the one called repackage.jar to repackage the included TI Smart Config library into a useable form. This only needs to be done once. Then you can run the main executable jar called net.betaengine.smartconfig-ui.jar.

This is covered in more detail in the README.txt.

The TI Smart Config library depends on Java 7 or later. The README.txt describes you how you can check your Java version. If you don't have Java 7 you should download a suitable JRE or if you plan to develop applications, in addition to just running them, you should instead download a suitable JDK.

This application may not be able to successfully transmit the SSID etc. to a CC3000 if the machine that you're running it on is connected to your wireless access point using 802.11n. If you're using 802.11b or 802.11g then it always seems to work - however if you are using 802.11n then whether it works or not depends on factors that I have yet to determine. If you are using 802.11n then please add a comment and tell me whether it works for you and what setup you're using. See this blog post to determine which 802.11 protocol (b, g or n) you are using:

http://depletionregion.blogspot.ch/2013/09/determining-80211-protocol-b-g-or-n.html

Update Sept 8th 2013: I now believe the main issue as to whether a particular client using 802.11n will work or not is MIMO. This is covered as one of the issues in the limitations section of this TI document. I've covered this in more detail in another post.

The image up above shows how the application looks on Mac OS X, here's how it looks on Ubuntu 12.04 and Windows 8:


More Details

TI provide reference implementations of Smart Config setup applications for iOS, Android and Java here:

http://www.ti.com/tool/smartconfig

However the Java implementation is a signed applet. I'm a Java developer and even I'm amazed whenever I see something shipping as a Java applet. They often fail to work for various reasons that are non-obvious to the end user, even more so when signing is involved. And even Java fans tend to disable the Java browser plugin due to the numerous security issues that it has experienced (note that this is a web-meets-Java-meets-browser issue and not a fundamental Java issue as is sometimes incorrectly claimed).

So I thought it would be nice to have a standard desktop application implementation. I extracted the TI SmartConfig library from version 1.1 of SMARTCONFIG-JAVA. It is covered by the TI Commercial License and the right to redistribute it is established here:

http://e2e.ti.com/support/low_power_rf/f/851/p/286323/1001377.aspx

I've taken the library and added a Swing UI and other features. In later posts I will discuss reimplementing the TI library to provide a completely open source solution.

The TI implementation only provides support for automatically retrieving the network name etc. for Linux and Windows. I've added support for Mac and fixed an issue where the TI logic would fail to determine the wifi frequency on some versions of Linux (e.g. Ubuntu 12.04).

As the TI library comes it is not actually useable as a library by third parties. All the classes it provides are in the default package and so cannot be called from other packages:

http://stackoverflow.com/a/283828/245602

This means you can only use these classes from other classes that are also in the default package. However as the TI library is signed even this is not possible as if some classes in a given package are signed then all classes in that package must be signed by the same signer. As TI have signed their classes in the default package you cannot add further classes in the default package unless you can also sign them as you were TI.

So I used JarJar to move the TI classes out of the default package and given them a sensible package name, i.e. "com.ti.smartconfig". If you download the binary distribution above you will find that it comes with the unmodified TI Smart Config library and the executable jar repackage.jar which the end user can run to automatically do the necessary repackaging. I did this as TI grant the right to redistribute their library but such rights rarely extend to redistributing modified versions of the original, e.g. I presume Microsoft would complain if one tried to sell modified versions of Windows even if one had acquired a suitable number of licenses for the original product.

If you download the source for my project from GitHub the README.md in the top level directory describes how to repackage the TI library in the normal JarJar command line fashion rather than using my repackage logic (which also calls JarJar do all the real work).

A side affect of moving the classes into a properly named package is to cause them to become unsigned. However signing was only necessary for the applet environment in order to gain the increased privileges needed to perform network operations etc. In a normal application environment this is not relevant.

The source for my code can be cloned from GitHub like so:

$ git clone https://github.com/george-hawkins/betaengine.git betaengine

Or if you don't have git you can download the contents of the repository as a zip file here.

All my classes can be found in the package net.betaengine.smartconfig or one of it's subpackages. There's nothing too surprising in the code. I don't like the TI API so I've created a package called tisupport where the few classes of mine that have direct dependencies on TI classes go, these and my interface DesktopSmartConfig isolate the rest of my code base from the TI API.

It should be relatively easy to localize this application for other languages (though I haven't taken care to handle more complex issues like right-to-left scripts). All the text is accessed through a resource bundle called TextBundle. Currently I've only provided a US English TextBundle.properties file.

Note: the wifi image used in the main panel is public domain and comes from openclipart.org.

Reimplementing the TI library in open source

As mentioned above the interface DesktopSmartConfig isolates the TI library from the rest of the code.

In the next few days I will be discussing exactly what the TI library does but not how it does it. I.e. I will provide the requirements needed to do a clean room reimplementation of the TI library, along with tools to test the resulting implementation.

It will be easy to develop a completely open source implementation of this interface. If you take a look at the interface you can see that it's not too complicated. Much of the code in the TI library revolves around platform specific logic for Windows and Linux to retrieve the SSID, wifi network device name, the default gateway address and the current wifi frequency being used. A very small amount of the code is involved in encoding the SSID and passphrase (and optionally encrypting the passphrase with an AES key) and transmitting this information such that a CC3000 enabled device can pick it up, and an even smaller amount of code is involved in waiting for an indication that the device has successfully connected to the network.

In the class net.betaengine.smartconfig.desktop.tisupport.MacNetServices that I wrote for Mac OS X you can see how I retrieved the SSID and other required information. Anyone with any reasonable networking experience should have little trouble doing the same for Windows and Linux with just a little Googling, i.e. they can easily duplicate the logic in the TI library without looking at how TI did things.

I've already discussed how one can detect that a CC3000 enabled device has successfully connected to the network here:

http://depletionregion.blogspot.ch/2013/10/cc3000-advertises-presence-on-network.html

And in following posts I will discuss how the SSID and passphrase are encoded and transmitted.

 

Copyright @ 2013 Depletion Region.

Designed by Templateify & Sponsored By Twigplay