Sunday, February 21, 2010

XML of SmartRF Studio 7

by Travis Goodspeed <travis at radiantmachines.com>
concerning TI SmartRF Studio 7.

For those who have not personally suffered the experience, choosing radio register values is an absolute pain. In this brief article, I will demonstrate a method for extracting settings in bulk from SmartRF 7 Studio for use in other projects.

Suppose that a program should configure a CC1110 to operate on a particular frequency, in a particular encoding, etc. The code will like the following, which is from the CC1110 examples. This will generate a carrier wave near 823 MHz, as the 2.433GHz FREQ[] value is outside of the allowed range.

Chipcon Settings

To choose a different center frequency, the engineer is expected to either find the register's definition within the datasheet or use SmartRF Studio, a screenshot of which is below. The software is a Windows application for communicating with a radio through a serial port. It also allows an engineer to load preconfigured profiles for certain types of modulation, such as IEEE 802.15.4 or SimpliciTI. Once loaded, the settings may be tweaked and loaded into a packet-sniffer firmware for debugging projects.

Chipcon Range Limits

The screenshot above, from SmartRF 6, can provide a decent idea of how infuriating the software might become. For product development, the register settings are to be copied and pasted into opaque source files. It can instill the same sort of anger as an uncooperative web form, even after the old Visual Studio 6 libraries have been located to make it work under Wine.

SmartRF 7--at Beta 0.9.1 as of this writing--is a new client under active development, one which seems to have been rewritten from scratch or at least significantly refactored. The old Win32 GUI has been replaced with QT4, making a future Linux or Mac port possible. Most importantly of all, however, is that the default configurations, as well as register explanations, are stored as XML.

SmartRF 7

The screenshot above shows how default configurations are chosen for the target radio. Users can select an example, then change any of the settings they like. These configurations are further abstracted into an "Easy Mode" which hides all the messy minutia of radio, abstracting use to standards and channel numbers.

These configuration settings are to be found as XML in the config/xml/ directory, organized by chip and presentation. The following is an example of one such configuration file for the CC1110.
SmartRF 7 XML

Patching these configurations allows for the easy addition of new standards. For example, I added support for my Tennessee Belt Buckle radio by adding a new stanza to easymode_settings.xml.
SmartRF Belt Buckle

The register definitions and their bitfields are also defined in XML. The following from register_definition.xml for the CC1110 described the FREQ2 register's meaning.
SmartRF 7 XML Register Def

Printing SDCC special-function register definitions, such as those found in cc1110.h, is as easy as a bit of Python magic,

#!/usr/bin/python

# Simple script for dumping Chipcon register definitions to SDCC header.
# Only intended as a rough example.
# by Travis Goodspeed, Engineer of Superior Belt Buckles

import xml.dom.minidom
def get_dom(chip="cc1110",doc="register_definition.xml"):
fn="/opt/smartrf7/config/xml/%s/%s" % (chip,doc);
return xml.dom.minidom.parse(fn)

dom=get_dom();

for e in dom.getElementsByTagName("registerdefinition"):
for f in e.childNodes:
if f.localName=="DeviceName":
print "// %s=%s" % (f.localName,f.childNodes[0].nodeValue);
elif f.localName=="Register":
name="unknownreg";
address="0xdead";
description="";
for g in f.childNodes:
if g.localName=="Name":
name=g.childNodes[0].nodeValue;
elif g.localName=="Address":
address=g.childNodes[0].nodeValue;
elif g.localName=="Description":
if g.childNodes:
description=g.childNodes[0].nodeValue;
print "SFRX(%10s, %s); /* %50s */" % (name,address, description);


These configuration files should allow for new Chipcon radio applications and development tools to be written in short order. Please contact me if you would be so kind as to write a complete Python class for querying this data.

Friday, February 5, 2010

Call for Info Flash

by Travis Goodspeed <travis at radiantmachines.com>
continuing a discussion of MSP430 Info Flash

Neighborly MSP430 developers, please do me a favor and email me the contents of memory from 0x1000 to 0x1100 of every MSP430F2xx device that you can. I'm trying to reverse engineer the exact distributions of the CALBC1_16MHZ and CALDCO_16MHZ values in order to build a UART library that operates without Info Flash. The GoodFET does this well enough, but I still get the occasional bug report when a device is slightly out of range. I can reduce the default to baud rate or try similar tricks to get around this, but I want to know exactly which values are safe.

If your GoodFET can be programmed by goodfet.bsl but does not respond after programming, try the info flash images available in /contrib/infos/ to see if any of them work.
air% goodfet.bsl -e -p 2618-002.txt;\
goodfet.bsl -p ../../trunk/firmware/goodfet.hex
MSP430 Bootstrap Loader Version: 1.39-goodfet-8
Mass Erase...
Transmit default password ...
Invoking BSL...
Transmit default password ...
Current bootstrap loader version: 2.13 (Device ID: f26f)
Program ...
256 bytes programmed.
MSP430 Bootstrap Loader Version: 1.39-goodfet-8
Invoking BSL...
Transmit default password ...
Current bootstrap loader version: 2.13 (Device ID: f26f)
Program ...
10596 bytes programmed.
air% goodfet.monitor peek 1000 100A
1000 55aa
1002 3fff
1004 abcd
1006 55aa
1008 1234
air%


Previously programmed GoodFETs have info flash wiped during programming, but if yours has never been programmed, you can dump the info with
goodfet.bsl --dumpinfo >info.txt

Monday, January 25, 2010

ZStack PRNG Fixed

by Travis Goodspeed <travis at radiantmachines.com>
concerning versions 2.2.2 and 2.3.0 of TI Z-Stack
and a fix of the ZigBee Smart Energy Profile ECC vulnerability.

Texas Instruments has released version 2.3.0 of Z-Stack, their ZigBee stack for the TI/Chipcon CC2530, MSP430, and CC430 chips. The new version adds a variety of new features, but chief among them is a fix to the random number generator which used to be utterly insufficient for cryptographic use. Technical details on the vulnerability were first revealed publicly in my last article. (Nate Lawson's translation is here.)

Source code for the new generator is not included, but rather references as a Security Service Provider (SSP). Since 2.2.3, they have extended the SSP API to include SSP_GetTrueRandAES() for generating random numbers by an AES key.

ZStack 2.3.0-1.40 TrueRand Functions

This is then called in zclGeneral_KeyEstablishment_GetRandom(), which in previous versions used the 16-bit LFSR.

ZStack 2.3.0-1.4.0

Authors of firmware for ZigBee Smart Energy devices that have used this code should patch their source code and issue firmware upgrades as quickly as possible. Those with independent crypto implementations should check to ensure that they have not made similar mistakes. Programmers should also note that

Electric utilities with equipment using the MSP430 or Chipcon CC2530 should contact their vendors for such updates. Unlike Windows and Linux, there's no easy way to perform an upgrade of a fragment of microcontroller firmware to which you haven't got the source.

This fix only applies to the remote recovery of keys by PRNG attacks; local key extraction is still possible by the methods that I outlined in Extracting Keys from Second Generation ZigBee Chips.

Saturday, January 9, 2010

PRNG Vulnerability of Z-Stack ZigBee SEP ECC

by Travis Goodspeed <travis at radiantmachines.com>
with neighborly thanks to Nick DePetrillo,
concerning version 2.2.2-1.30 of TI Z-Stack
and a ZigBee Smart Energy Profile ECC vulnerability.

Not Quite Random

In past articles, I've presented a variety of local attacks against microcontrollers and ZigBee radios. While I maintain that local vulnerabilities are still very relevant to ZigBee devices, this article presents a remotely exploitable vulnerability in the way that random keys are generated by TI's Z-Stack ZCL implementation of the ZigBee Cluster Library. Randomly generated numbers--those fed into the Certicom ECC crypto library--are predictable, repeated in one of two 32kB cycles. Details follow, with links to source code and a complete list of random numbers.

Dumping Random Bytes


I dumped byte sequences from the CC2430 using the GoodFET to debug a live chip. The chip runs a program which populates IRAM with PRNG bytes, then halts with a soft breakpoint (Opcode 0xA5) for the debugger to grab all sampled values. The main loop looks something like this:
Chipcon RNG Dumper
The firmware was compiled with the Small Device C Compiler, flashed by the GoodFET. A quick Python script then used the GoodFET library to debug the target, dumping random values through the same interface that programmed the chip.
Chipcon Byte Dumper

Short PRNG Period


Page 18 of the CC2530 Datasheet describes the random number generator peripheral, which is shared by all other 8051-based ZigBee SoC devices in the series.
The random-number generator uses a 16-bit LFSR to generate pseudorandom numbers, which can be read by the CPU or used directly by the command strobe processor. The random numbers can, e.g., be used to generate random keys used for security.

The state of this RNG is initialized in the hardware abstraction library by feeding 32 bytes from the ADCTSTH special function register into RNDH register. Bytes read from ADCTSTH are physically random, but poorly distributed. RNDH and RNDL are the High and Low bytes of a 16-bit CRC Linear Feedback Shift Register, the state of which can be advanced by writing to RNDH or overwritten by writing to RNDL. In between reading or writing from RND, the state is advanced by setting the fourth bit of ADCCON1. Detailed descriptions of these registers can also be found within the datasheet.

CC2430 examples randomize the seed by mixing 32 values into the RNG,
for(i=0;i<32;i++){
RNDH=ADCTSTH;
ADCCON1|=0x04;
}

Because these numbers are not evenly distributed, Z-Stack prefers to sample just the least significant bit of the RF random number generator sixteen times, then write them in directly as the state without mixing them. Further, it checks to ensure that the state is not a dead-end, substituting another if it is. This method is also advocated within the CC2530 programming guides.
for(i=0; i<16; i++)
rndSeed = (rndSeed << 1) | (RFRND & 0x01);
if (rndSeed == 0x0000 || rndSeed == 0x0380)
rndSeed = 0xBABE;
RNDL = rndSeed & 0xFF;
RNDL = rndSeed >> 8;


Once the RNG has been seeded, it has an initially random 16-bit state. From then on, however, it produces random bytes in a predictable sequence. Only the starting point is random, as ADCTSTH is never used for future reseeding. As shown in the screenshot above, if the sequence "7c e1 e8 4e f4 87" is observed, the probability of the next bytes being "62 49 56 fe 80 00 60" is 100 percent. Further, because the domain is so small, it can be exhaustively searched for keys in little time.

Not Quite Random

Code for dumping these values through the GoodFET debugger can be found by svn, along with a complete dump of the PRNG sequence.
svn co https://goodfet.svn.sourceforge.net/svnroot/goodfet/contrib/ccrandtest

Seed Values


Seed Histogram

The plot above shows the histogram of radio ADCTSTL values used to seed the PRNG. These are far from random, but when sampled slowly enough, their least significant bit is probably good enough for key generation. There are, however, two things of interest with this.

First, if the crypto library is used infrequently, it would make sense to use this source of entropy instead of the inadequately random PRNG output. There would be a cost in power consumption, as ADCTSTL is only random while the radio is operating, but the resulting increase to security is necessary.

Second, if the peaks on the histogram come from a measurement of the radio, it might be possible to generate a radio signal that forces even the least significant bit to be a predictable value. Steps such as AES whitening should be taken to avoid such an attack.

ZigBee SEP, ECC


A less than perfect random number generator is not much of an issue when symmetric keys are pre-shared, but because pre-shared keys are vulnerable to local attacks, the ZigBee Smart Energy profile recommends the use of session keys signed by elliptic curve cryptography. See the USAF paper Cryptanalysis of an elliptic curve cryptosystem for wireless sensor networks for a prior break of ECC with a poor RNG.

As will be shown in the next section, Chipcon's ZStack makes use of poorly random PRNG data as key material, allowing for a key domain of only 16 bits. This is small enough to be exhaustively searched, either by a PC or by a "Chinese Lottery" of previously compromised wireless sensors.

ZStack Usage


ZStack 2.2.2-1.30 for the CC2530 makes use of the PRNG to implement the Smart Energy Profile's asymmetric cryptography. The Windows installer works perfectly under Wine, leaving ZStack installed to an awkward directory. I symlink it to /opt/zstack for convenience.
CC2530 in Wine

Once installed, the following Functions are of interest.

mac_mcu.c contains macMcuRandomByte() and macMcuRandomWord(). As the two are largely the same, take the former for an example. First the PRNG is clocked, then the high byte is sampled.
ZStack macMcuRandomByte()

zcl_key_establish.c is used to generate keys by the ZigBee Cluster Library specification, available for free by form from ZigBee.org. The code fragment below takes the low bytes of macMcuRandomWord(), redefined as osal_rand(), to populate a session key before signature.
ZCL KeyEstablishment GetRandom

The ultimate function for ECC key generation is ZSE_ECCGenerateKey(), which is defined in eccapi.h but whose source is missing. Reading ecc.r51 yields a few filenames as part of stored compiler warnings. The developer's filename was "C:\SVN-ZStack-2.2.0\Components\stack\sec\eccapi.c", but it is only a stand-in for the Certicom Security Builder MCE library that is not shipped with the development kit. In any case, the vulnerability here lies in ZStack and not in Security Builder.

Conclusions


This article has shown that the Chipcon ZStack library, as of version 2.2.2-1.30 for CC2530, uses an insufficiently random PRNG for cryptographic signatures and session keys. PRNG data repeat every 32,767 samples, and there are at most 16 bits of entropy in any key. Searching the entire key space ought to be possible in very little time. Contrary to the CC2530's documentation, these random numbers must not be used to generate random keys used for security.

All users of this library, particularly those using it for Smart Grid devices and other industrial applications, are recommended to re-implement macMcuRandomWord() and to ensure that nothing requiring cryptographic security operates from the PRNG alone. Users of other libraries for the Chipcon devices should ensure that those libraries are not using the PRNG data.

Competing devices and libraries should also be checked for similar vulnerabilities, as well as commercial products such as Smart Meters that might have forked the ZStack code or followed the datasheet's recommendation of using the PRNG for key generation.

Monday, November 2, 2009

S4 Paper

Howdy Y'all,

A paper of mine from S4/Miami, Low-Level Design Vulnerabilties in Wireless Control Systems Hardware, has recently been made publicly available by Digital Bond. Coauthored with Brad Singletary and Darren Highfill, it provides a detailed survey of vulnerabilities that might be found in the hardware and firmware of AMI Smart Meters and similar equipment.

Please note that the paper, written late last year, is now outdated in two respects. First, the self-propagating worm presented hypothetically in Section 3.1 is no longer hypothetical. Mike Davis has written one. Second, the System-on-Chip Zigbee devices advocated in the conclusion of Section 4.1 are not secure, as I have since demonstrated in Extracting Keys from Second Generation Zigbee Chips.

--Travis Goodspeed
<travis at radiantmachines.com>

Wednesday, October 28, 2009

MSP430 Info Flash

by Travis Goodspeed <travis at radiantmachines.com>

The following is a description of the MSP430F2xx Info Flash, as well as my ugly--yet reliable--hack for initializing the DCO of MSP430F2xx chips after my use of the Serial Bootstrap Loader (BSL) has destroyed the contents of that flash on the GoodFET. This ought to be of use to anyone who wishes to make an MSP430 design without a crystal, as well as for anyone who has accidentally erased info flash.

The mask-ROM bootstrap loader, BSL, of the MSP430 chips is damned handy, despite some security concerns. It allows you to very quickly program a chip by the same USB/serial converter that you use to interface it with a computer, without any of the hassles of having to flash a bootloader onto the chip. In this article, I describe the way in which the MSP430F2xx flash can be accidentally corrupted by the bootloader, as well as a method for repairing that damage by backing up the info flash while the password is left as the default.

The MSP430F2xx family has another dandy feature, that clock configuration values need not be calibrated to an external clock, such as the 32KHz crystal of the older GoodFET models. Instead, configuration data is calculated at the factory and placed into info1 flash, a region of 256 bytes at 0x1000. Using this, code that would be rather complicated can become trivially simple.

The code that configures the clock is configured on the GoodFET with MSP430F1xx chips is too complicated for me to include here. By contrast, on the MSP430F2xx chips, it becomes just
void msp430_init_dco() {
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
}


The security model of the BSL is a bit confusing. Upon connecting, you are required to present a password before reading, writing, or doing anything else that might affect the security of the device. You are, however, allowed to erase all of flash memory--including the info flash--to 0xFFFF. As this is traditionally the first command that you send upon connecting to a device, you will wipe all of the configuration data of a chip in programming it. Finding this problem is hellish, because the exact same code will work if programmed by JTAG and you quite often have not got JTAG handly if you intend to program everything by the BSL.

As part of the GoodFET project, I've forked TinyOS's tos-bsl client to add support for the MSP430F2xx. I've also implemented a "--dumpinfo" command for dumping info flash to a TI Text file. This file can be reflashed after the chip has been erased to restore its factory settings.

petite%  goodfet.bsl --dumpinfo          
MSP430 Bootstrap Loader Version: 1.39-goodfet-8
Use -h for help
Transmit default password ...
@1000
aa 55 ff 3f cd ab aa 55 34 12 ff ff aa 55
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff b4 85 fe 16
ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff 08 10 00 80 01 00
62 7f b2 0b e8 0d 98 7f 01 07 56 08 fe 08
ff ff ff ff ff ff ff ff 01 08 7f 8f 85 8e
74 8d c2 86
q

petite%


This output is in the TI Text format, which is easily converted to Intel-hex, but is a hell of a lot easier to write. Piping it into a file allows me to restore the contents of flash after erasure, and also to extract the configuration values which are used on this chip. Because the chips are similar physically, it turns out that the calibration values for one are often sufficient to program another. So by observing the model number (in big endian at 0x0FF0), I can guess in the absence of calibration values.


//! Initialize the MSP430 clock.
void msp430_init_dco() {
if(CALBC1_16MHZ!=0xFF){
//Clear DCL for BCL12
DCOCTL = 0x00;
//Info is intact, use it.
BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;
}else{
//Info is missing, guess at a good value.
BCSCTL1 = 0x8f; //CALBC1_16MHZ at 0x10f9
DCOCTL = 0x7f; //CALDCO_16MHZ at 0x10f8
}
}


When I find the time, I intend to test a large quantity MSP430 chips to determine the exact tolerances of manufacturing, the variances of CALBC1_16MHZ and CALDCO_16MHZ, and the probability that a given unit will so drastically differ from these values that serial communications become impossible. For now, I've found that the hardwired values above seem to work for all recently acquired MSP430F2274, MSP430F2254, and MSP430F2618 microcontrollers when using the hardware UART at 115,200 bits per second. Further, the GoodFET firmware does not require a crystal when running on these chips.

Saturday, October 17, 2009

CC2430 Debug Protocol, First Notes

by Travis Goodspeed <travis at radiantmachines.com>
with thanks to Peter Kuhar

CC2430 Node

The following are my notes on the debugging mechanism of the CC2430 and other chips (such as the CC2530) from Chipcon using an 8051 core. These notes do not apply to the upcoming CC430. As most of this was written before I implemented the protocol, plenty of errata are likely to exist.

These notes are intended for those who wish to understand how the device is programmed, not for those who merely want a device programmer. See CCFlasher or the GoodFET for that.

Be sure to have a copy of SWRA124, which is the official documentation for this protocol.

Concerning pins, there are three related to debugging. Debug Data (DATA) is a synchronous, bidirectional data line. Debug Clock (DCLK) is its clock, but its edges also control when commands are interpreted, and it is crucial to initializing the chip's debugging unit. The third pin, !RST, puts the chip into a reset state when pulled low, but is also used to start the chip with the debugger enabled. The clock idles low, while !RST idles high. Data is posted during the rising edge, sampled during the falling edge. As there is no equivalent of the SPI !SS pin, it is necessary to dead-reckon commands; a command of incorrect length will cause unneighborly consequences.

To initialize the debugger, pull !RST low while sending two clock pulses on DCLK. It will look something like this,
CC2430 Debug Initialization

The command byte 0x34 looks something like this,
CC2430 Data

Concerning commands, once the debugger has been initialized, the chip will accept a command byte, optionally followed by up to three additional parameter bytes. It will then reply with at least one byte, which might be discarded. Some commands reply with two bytes rather than one.

A command byte is composed of 8 bits. Bits 1 and 0--the least significant--contain the number of data bytes following the command. Bit 2 is labeled "return input byte to host", but it doesn't appear to be observed regularly by the documented examples. The remaining five bits specify the command itself.

Only twelve commands are described in the documentation, but either 16 or 32 commands are possible, depending upon whether the MSBit is variable or fixed to 0 as a sort of start bit.

These commands were chosen to be easy to implement in hardware. They include CHIP_ERASE, RD_CONFIG, WR_CONFIG, HALT, RESUME, GET_PC, and DEBUG_INSTR. There are no primitive commands for peeking or poking memory, nor for managing flash. Instead, macro commands are built up by using DEBUG_INSTR.

Concerning command execution, it is clear from the documentation that a command with no parameters begins to execute at the instant of the eighth falling debug clock edge. Multi-byte commands likely execute on multiple clock edges, each being the last falling edge of an instruction.

In any case, to debug a command, you simply send DEBUG_INSTR (0x54) summed with the length of the instruction, up to 3 bytes, then read a single byte reply. So to execute "NOP", send {0x55, 0x00}. Except for a jump, this will not affect the program counter.

Concerning memory access, there are no debugging commands to read or write memory. Instead, DEBUG_INSTR (0x54) is used to do the same. For example, to fetch from Data memory, first debug {0x90, AH, AL} to move the address into the data pointer. Then debug {0xE0, 0, 0} to MOVX from the data pointer into A. The 0's aren't part of the instruction, but they are necessary to give the device time to fetch the target of the pointer.

The is the code that fetches a byte from Data memory,
cc_peekdatabyte

Concerning the writing of Flash, it is necessary to load a RAM buffer, then to copy that buffer into Flash by use of a short assembly script. Flash may only be erased in 2kB pages, and it may only be written as 32-bit words. The code that performs this is found on page 11 of SWRA124, and you'll find it in Data memory if you look hard enough after a programmer that doesn't cover its tracks.

You will find this code in the GoodFET source.
CC2430 Flash Routine

You will find the same code in RAM after programming.
CC2430 Flash Routine

Concerning the protection of Code memory, there is a lock bit in a hidden page of Flash memory. By setting the lowest configuration bit (by WR_CONFIG), the lowest 2kB of flash memory will be mapped to a special information region. Clearing the least significant bit of the first byte will lock the chip, causing it to refuse debugging after a full-power reset. Access to debugging instructions can only be regained after executing a CHIP_ERASE, which erases all of Flash memory.

At Black Hat USA in August of 2009, I presented a paper entitled Extracting Keys from Second Generation Zigbee Chips. The vulnerability, demonstrated in the image below, is that Data memory is not cleared along with Flash memory during a CHIP_ERASE. By booting a wireless sensor, then erasing it, then dumping RAM, the attacker can find any keys which are stored within the unit. This works even for constant keys, as 8051 compilers will copy them into RAM in order to make C pointers consistent.
CC2430 Vulnerability Test

In implementing a debugger, it's also necessary to watch out for a minor bug. Upon connecting, be sure to DEBUG_INSTR a NOP so as to have the lock bit checked. Failure to do so might cause the lock bit to be misrepresented when checking the device's status.

In conclusion, the protocol is blessedly simple and the 16 pages of documentation are quite complete when supplemented with the CC2430 datasheet. I hope that these notes might allow you to implement the protocol with less of a headache than I have.