Tampilkan postingan dengan label bsl. Tampilkan semua postingan
Tampilkan postingan dengan label bsl. Tampilkan semua postingan

Rabu, 28 Oktober 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.

Rabu, 19 Agustus 2009

Half-Blind Attacks, Source Barcelona

by Travis Goodspeed <travis at radiantmachines.com>

At the Third Usenix Workshop on Offensive Technologies, I presented Half-Blind Attacks: Mask ROM Bootloaders Are Dangerous with Aurélien Francillon. This paper describes the use of a stack overflow exploit to return into a random piece of flash memory, which often enough will elevate privileges before returning into the bootloader.

I'll be presenting the security-conference equivalent of this paper as a lecture at Source Barcelona on September 21 or 22, along with something new. I will bring both the demonstration hardware and plenty of GoodFET boards.

--Travis

Jumat, 17 April 2009

Notacon Masked ROM Challenge

Here at Notacon 6 in Cleveland, I'm having a competition involving the decoding of the MSP430F22x4's masked BSL ROM. The ROM, pictured below, begins with "0c06; 0c1e; 3fff; 40b2; a540; 012c; 90b2; ffde;" and ends with (in reverse order) "62b1; 0401; 0102; 0000; 0000; 0000; 4040; 27f2; ffff; ffff; ffff; ffff;".

MSP430F2274 BSL ROM

Begin by downloading the high resolution version of the image, then marking it like so.
BSL ROM, Marked

The first person to bring me a method for converting addresses to physical locations and back will win a Hack-A-Day Bus Pirate kit. A second kit will be given to the first person to bring me a script for generating correct bits from a binary (or Intel Hex) dump of the ROM.
Bus Pirate

Hints will be given during my lecture, "Fun with the MSP430", Saturday at noon.

--Travis Goodspeed
<travis at radiantmachines.com>

Senin, 29 September 2008

Speaking at PumpCon 2008 in Philly

Howdy Y'all,

I'll be driving to Philadelphia on Friday, October 24th to speak at this year's PumpCon. This lecture continues that of Black Hat USA, focusing on the exploitation--rather than the origin--of timing vulnerabilities that I've found in certain revisions of the MSP430's serial bootstrap loader.

--Travis Goodspeed
<travis at utk.edu>

Senin, 16 Juni 2008

MSP430 BSL Passwords: Brute Force Estimates and Defenses

by Travis Goodspeed <travis at utk.edu>
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
regarding the work of
Alexander Becher, Zinaida Benenson, and Maximillian Dornseif
with minor additions and comments.

The MSP430 microcontroller uses its 256-bit interrupt vector table (IVT) as a password for its serial bootstrap loader (BSL), which can remain activated despite a blown JTAG fuse. As code confidentiality then depends upon the BSL password, this article will make some preliminary observations as to the difficulty of guessing the password. It doesn't attempt to be terribly thorough, precise, or academic. Rather, consider this to be a few `back of the napkin' notes on breaking the password. Further, the scope of this article is limited to the brute forcing of passwords. Alternatives to brute forcing will not be discussed here.

A good starting point would be [1] Tampering with Motes: Real World Physical Attacks on Wireless Sensor Networks. It's an excellent paper, but be sure to get the 15-page version; the 4-page variant is no substitute. This article will begin by recapping their estimate of the BSL password strength, and it will conclude with the source code of a Perl script mentioned--but not included--in that paper.

The issue at hand is that the MSP430 reuses its interrupt vector table (IVT) as a password. Thus, while the password is technically 256 bits in length, many of those bits are either fixed or predictable. Further, as the BSL allows for direct memory access to the device, it might be used to compromise keys where the firmware is known.

Becher et all attempted to determine the minimum keyspace, which is to say the number of bits out of 256 which are truly unpredictable in a rather small program. Beginning with 256 bits in an array of sixteen 16-bit interrupt handler function pointers, their reasoning follows: (1) As all MSP430 instructions must be even-aligned, every valid interrupt handler must have a least-significant bit of 0. Therefore, the space is reduced to 16*15=240 bits. (2) As the reset vector always points to the beginning of flash memory, the space is further reduced to 15*15=225 bits. (3) All unused interrupts point to the same address. As a worst case would have at least four distinct handlers, the keyspace will be reduced to no less than 4*15=60 bits by this observation. (4) As code is placed in a contiguous region of memory, a smaller program would have less are in which to place interrupt handlers. Supposing the program uses only 2^11=2kb of flash memory, the key domain is reduced to only 4*10=40 bits.

Note that as the intent is to come up with a reasonable minimum, claims (3) and (4) above refer only to a reasonable minimum of program security. An average, complicated ZigBee application might well have many more bits of randomness. They then measured that the speed of a brute forcing algorithm is 12 passwords/second at 9600 baud, 31p/s at 38,400 baud, and 83p/s at 38,400 baud with a modified client. They state a theoretical limit at 38,400 baud of 150p/s. Rounding off to 2^7=128 passwords per second, they conclude that brute forcing would be limited to 2^(40-7-1)=2^32 seconds, which is roughly equal to 128 years.

I'd like to briefly consider how brute forcing might be sped up beyond their estimates, even if such a speed-up is not of sufficient magnitude to make unassisted brute-forcing of the BSL feasible.

While the most recent revisions of the BSL require a password for changing the baud rate, V1.60 and V1.61 have no such requirement[2]. When using this command, the BSL client sends three bytes: D1, D2, and D3. D3 is what we would expect: 0x00 for 9600 baud, 0x01 for 19200 baud, and 0x02 for 38400 baud. D1 and D2, however, are much more interesting. They are written directly to the clock module control registers! (DCOCTL and BCSCTL1 on F1xx/F2xx; SCFI0/SCFI1 on F4xx.) These two registers control the frequency of the device, and they may be set to anything the device supports, which is in excess of the 4.2Mhz required for 38400 baud. Further, bytes are read by bit-banging, which is calibrated by the 0x80 synchronization character. By sending 0x80 too quickly and setting the microcontroller to 8 or 16mhz, it should be possible to brute force at a much faster rate. 2^9 passwords is a reasonable rough estimate; a bit more might be possible. 32 years is still too slow to be practical, but perhaps with possession of another revision of the target firmware image this speed-up might be valuable.

Suppose that you wish to maximize the security of the BSL password on your MSP430-based device, and you don't want to disable the BSL entirely. Becher's solution from [1] is a Perl script which replaces each interrupt pointer in the IVT with a pointer to another address, which contains a branch to the original address. At the cost of a few extra cycles on each interrupt, it can considerably increase the difficulty of brute-forcing a password. Most importantly, by separately randomizing the vectors of every device you ship, it is possible to defend against an attacker who has a copy of the firmware but does not have internally held keys of a device from reading those keys through the BSL.

In August at Black Hat USA 2008, I'll be presenting a timing attack which makes it possible to break some revisions of the BSL in short order.

[1] Tampering with Motes: Real World Physical Attacks on Wireless Sensor Networks
[2] SLAA089: Features of the MSP430 BSL


#!/usr/pkg/bin/perl
use warnings;
use strict;

# Use with Intel Hex files for Texas Instruments MSP430 microcontrollers.
# Replace ALL interrupt vectors with addresses generated randomly.
# Store jump instructions to the original interrupt handlers there.

# Written by Alexander Becher <alex@cyathus.de>, 2005.
# Use freely.

# $start and $end define the address range into which new vectors will point.

# The start address will be updated by the Ihex reading code below.
# It must be correctly aligned.
my $start = 0x4000;

# This is where the interrupt table starts. Addresses >= $end will not be used!
my $end = 0xffe0;

my $align = 2; # code addresses on MSP430 must be even

my %used; # will contain used memory regions

my @interrupts; # stores the original interrupt vector table

# Read an Intel hex file. With much help from BFD.
while (<>) {
my ($len, $addr, $data, $checksum)
= (/^:([[:xdigit:]]{2})([[:xdigit:]]{4})00([[:xdigit:]]*)([[:xdigit:]]{2})\cM?$/);

## Does not work? What did I do wrong??
# if (m/^: # colon
# ([[:xdigit:]]{2}) # data length
# ([[:xdigit:]]{4}) # address
# 00 # record type
# ([[:xdigit:]]*) # data
# ([[:xdigit:]]{2}) # checksum
# \cM?$/x # CRLF
# ) {

if (!defined $addr || ($addr ne "FFE0" && $addr ne "FFF0")) {
# update start of unused address region
# assume ascending order of addresses
# (i.e. it is not the case that there is a line in the hex file
# which contains code for address 0x4242 which is followed by a
# line which contains code for address 0x2323)

# assume all data first, then interrupts, then trailing stuff
if (defined $addr && defined $len) {
$start = align(hex($addr) + $len);
}

print;
next;
}

# If we reach this point, we are reading the first or the second
# line of the interrupt vector table.

# Attention: MSP430 is little endian!
while ($data =~ /([[:xdigit:]]{2})([[:xdigit:]]{2})/g) {
push @interrupts, hex "$2$1";
}

# If this is the second line, do The Real Work[tm].
if (@interrupts && $addr eq "FFF0") {
replace_interrupts(@interrupts);
}
}

#
# Why this program exists ;->
#
sub replace_interrupts {
my (@interrupts) = @_;

foreach my $addr (@interrupts) {
# Create a branch instruction to the original address of the handler
my $instr = br($addr);

# Get a new, unused address, using key material
my $new_addr = new_addr(length $instr);

# write a branch instruction there, mark appropriate addresses as used.
code($new_addr, $instr);

# point interrupt vector to new address (use Perl's loop aliasing)
$addr = $new_addr;
}

print ihex(0xFFE0, map { rep_16bit_le($_) } @interrupts);
}

#
# Returns a new random unused address suitable for putting code of
# $length bytes there. Return value will be aligned.
#
sub new_addr {
my ($length) = @_;

my ($addr, $diff);

$diff = ($end - $start) / $align;

# create a new random address until an unused region of the desired
# length is found
do {
my $n = int rand $diff;
$addr = $start + $n * $align;
} while (grep { $_ } map { isused($addr+$_) } (0..$length-1));
# Woohoo, Perl's list processing rocks. ;-> The above was a crude
# form of "Is any address in the region [$addr, $addr+$length) used?".

return $addr;
}

sub isused { $used{shift()} }

sub mark_used {
my ($addr, $len) = @_;

foreach ($addr .. $addr + $len) {
$used{$_} = 1;
}
}

#
# Place $code at $addr (which must be aligned). Outputs an ihex line
# which says just that, and marks the memory area as used.
#
sub code {
my ($addr, $code) = @_;

my $l = length $code;
mark_used($addr, $l);

print ihex($addr, $code);
}

# MSP 430 branch instruction
sub br { "\x30\x40" . rep_16bit_le(@_) }

# 16 bit little endian representation
sub rep_16bit_le { pack("v", @_) }

# ihex($addr, @data)
# write an ihex line, saying that $addr contains bytes @data
# @data should contain "\xXX" binary data
sub ihex {
my ($addr, @data) = @_;

@data = split //, join("", @data);

my $type = 0; # data

my $ret = "";

while (@data) {
my @bytes = @data >= 16 ? (splice @data, 0, 16) : (splice @data);

my $c = @bytes;

# XXX pack?
my $data = join("", map { sprintf "%02X", ord $_ } @bytes);

# checksum computation from GNU binutils bfd/ihex.c
my $checksum = $c + $addr + ($addr >> 8) + $type;
foreach (@bytes) {
$checksum += ord;
}
$checksum = (- $checksum) & 0xff;

$ret .= sprintf(":%02X%04X%02X%s%02X\cM\cJ",
$c, $addr, $type, $data, $checksum);

$addr += 16; # wrong for last iteration, but irrelevant then
}

return $ret;
}

# round up to the nearest multiple of $align
sub align {
my ($n) = @_;
if ($n % $align != 0) {
$n += $align - ($n % $align);
}
return $n;
}

Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor

  Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor Halo, para pecinta judi online! Apakah Anda sedang mencari car...