Dumping Calypso DSP ROM for archiving

Mychaela Falconia mychaela.falconia at gmail.com
Tue Oct 29 02:50:19 UTC 2019


Hello FC community,

We all know that our beloved Calypso chip contains two processor cores
inside: the ARM7TDMI core where our regular firmwares run, and a C54x
DSP core performing less glamorous signal processing and codec tasks.
We also know that the DSP runs mostly mask ROM code that is hard-cast
in the silicon, with a limited patching capability: while it is said
that the DSP ROM code is structured in such a way that allows any part
of it to be overridden by RAM-loaded patches, the patching capability
is limited by the small RAM space available to hold these patches.

If we are going to take over the moral ownership of the Calypso chip
itself from TI, on the basis of TI's abandonment of and total
disinterest in this product, we need to take moral ownership of the
DSP ROM code among other parts.  At the minimum we need to have
complete dumps of this mask ROM published on our FTP site, and if we
never succeed in recovering the source from TI, then at some point we
will also need to do a thorough reverse engineering job on it.

The Calypso chip itself was made in several different evolutionary
versions over the course of its first life at TI (prior to its second
life with FreeCalypso), and there were 3 different versions of the DSP
ROM that made their way into mass-produced chips: version 3311 used in
Calypso C05 (both A and B, supposedly no DSP ROM change between these
two), version 3416 used in early Calypso C035 chips (F751774), and the
final version 3606 used in the final Calypso C035 chips which both FC
and OBB generally work with.

A dump of Calypso DSP ROM version 3606 (the final and most commonly
encountered one) has been posted on ftp.freecalypso.org since the
summer of 2017, and even prior to that date it was very easily
accessible to anyone willing to go through the minor pain of compiling
and running OsmocomBB - OBB features a misnamed "Compal" (really all
OBB-supported targets, not just Compal) DSP dump tool, and because all
OBB-supported phones and modems feature Calypso chips with DSP ROM
version 3606 in them, that OBB tool will always produce exactly the
same output no matter what phone or board target it is run on.  By
publishing that output on our FTP site, I have simply eliminated the
need to run alien-to-us OBB software.

But that is just version 3606 - what about the other two versions?  I
have a historical TI D-Sample board featuring Calypso chip version
F741979B, and that one has DSP ROM version 3311 in it.  And just
recently I have bought some D751774AGHH chips from my trusty supplier,
that is the chip that should have DSP ROM version 3416 in it, and last
Friday I gave these chips to my friends at Technotronix with
instructions to populate them on two FCDEV3B boards.  Thus hopefully
later this week I will have a board or two with this rare Calypso DSP
ROM version for experimentation.

Clearly we need to make DSP ROM dumps from these D-Sample C05 and
FCDEV3B-751774 boards featuring these earlier Calypso chip versions,
but how can it be done?  OBB's tool built in their framework won't
work, as these exotic boards obviously aren't OBB-supported targets.
Toward this end I have put together a dspdump program in our FC
target-utils suite, and a host-side fc-dspromdump front end to it.  It
is exactly the same sequence of operations for dumping the DSP ROM as
performed by OBB's "Compal" DSP dumper tool, but reimplemented in our
own FreeCalypso framework instead of OBB.  Our framework is more
orthogonal than OBB's in this regard: in OBB each target application
is built in different board-specific versions, and each resulting
loadable image contains highly board-specific code that must be
customized for every board target.  But in FreeCalypso we don't take
the same approach: in our universe only the main operational firmware
images need to be built differently for each target and contain highly
custom board-specific bits, whereas most of the auxiliary programs in
the target-utils suite are common across all Calypso targets.

Earlier today I got this new fc-dspromdump tool finished, I tested it
on a familiar DSP 36 target to make sure that it produces exactly the
same output as OBB's old tool (it does), and then I promptly ran it on
my D-Sample C05 board with DSP ROM version 3311.  And it worked!  Now
we have fully published Calypso DSP ROM dumps of both versions:

ftp://ftp.freecalypso.org/pub/GSM/Calypso/dsp-rom-3311-dump.txt
ftp://ftp.freecalypso.org/pub/GSM/Calypso/dsp-rom-3606-dump.txt

ROM version 3416 will hopefully be joining this collection very soon,
as soon as I get those reworked FCDEV3B-751774 boards back from
Technotronix, and assuming that at least one of them will be working.

It needs to be noted that reading out the DSP ROM content on a Calypso
chip (any version) is a non-trivial task because that ROM is protected
against reading.  We can get code execution on the DSP by feeding our
own RAM code to the DSP's ROM bootloader in the same way how official
patches are applied at boot time (there is no cryptographic restricted
boot on Calypso, neither on the ARM nor on the DSP), but the hardware
ROM protection scheme works as follows: whenever code executes out of
RAM rather than ROM, reads from the ROM are blocked.  Instead the way
OBB's DSP dumper tool works (what we have now replicated in our own FC
framework) is through an exploit.  Whoever did that work in the OBB
camp (was it Sylvain Munaut?) found these two exploitable instruction
sequences in the ROM:

    7213:	7e92 	reada  *ar2+
    7214:	f000 	add    #1,a
    7215:	0001
    7216:	fc00 	ret

    e4b8:	e598 	mvdd   *ar3+,*ar2+
    e4b9:	fc00 	ret

Neither of these sequences was meant to be a function in its own right,
instead they are tail ends of longer functions - but we can call them
at these addresses, an exploit similar to return-oriented programming.
The first sequence is abused as a function that copies one word from
program ROM to RAM, and the second sequence is abused as a function
that copies one word from data ROM to RAM.  (The C54x DSP is a true
Harvard architecture, thus separate program and data ROMs.)  Because
these "functions" themselves execute from ROM, reading from ROM becomes
allowed during their execution - voila!  OBB's DSP dumper which we
have replicated in our dspdump utility feeds a piece of agent code
(built with GNU Binutils for the tic54x-coff target) to the DSP's ROM
bootloader, and this agent code calls the two exploit functions in the
ROM at hard-coded magic addresses.

But it is a chicken-and-egg problem: if you can't read the ROM, how do
you find these exploitable functions?  There is a video of Sylvain's
29C3 talk about the CalypsoBTS hack which involved a lot of DSP
patching, and in that talk Sylvain said that the exploitable functions
were found by trying every possible ROM address and looking for one
that didn't cause a crash.  At first I was thinking that I would have
to recreate that search procedure in order to find the presumably-
different location of these exploitable instruction sequences in
different DSP ROM versions, but then I got a totally unexpected but
very helpful surprise: these exploitable instruction sequences appear
to be at the same location in all versions of interest!

Our beloved Calypso was not TI's first DBB (digital baseband) chip for
GSM, instead it was a successor to a long line of predecessors.
Apparently some of those predecessors had RAM instead of ROM for the
DSP - it appears that Samson was the name of TI's chip that preceded
Calypso and had RAM instead of ROM - although I suspect that this
Samson chip may have been produced only as a very small run for
internal development use at TI, and was never mass-produced like its
ROM-based close relatives Ulysse and Calypso.  In any case, TI's ARM
firmware architecture includes a provision for RAM-based DSPs where
the entire body of DSP code needs to be loaded by the ARM on boot, not
just an optional patch, and the famous TSM30 source find includes two
hex char array C files named Dsp_Code.c and Dsp_Data.c, containing a
complete DSP code image of some unknown version for some unknown chip.
(There is no version ID included, and it is too difficult to tell what
the target chip is - but the memory map is different from what we have
on our familiar Calypso.)

There is a dump2coff.py script in the OsmocomBB source tree that can
convert a dump like dsp-rom-????-dump.txt above to a COFF image.
Sylvain used proprietary IDA software for further analysis, but I have
a principled personal policy against investing my time and energy into
proprietary sw.  Getting a cracked pirate copy or even buying a
legitimate copy of IDA wouldn't be a problem, instead the part which I
absolutely refuse to do is to invest any time or energy into learning
it - making a personal investment into proprietary sw is a big no-no
for me.  But fortunately there is a FOSS alternative: GNU Binutils
configured for the tic54x-coff target, giving us tic54x-coff-objdump
which reads COFF files produced by Sylvain's dump2coff.py just fine.
I have used it to take a little peek inside that DSP code.

Recently I wrote a companion utility which I named char2coff, a C
program living in the freecalypso-reveng repository.  My char2coff
utility reads hex char array C files as found in ARM-side firmware
sources and turns them into the same kind of COFF as Sylvain's
dump2coff.py script.  I used this char2coff tool to convert those
mysterious Dsp_Code.c and Dsp_Data.c images from the TSM30 source, and
I looked at the resulting COFF with tic54x-coff-objdump.  Lo and
behold: the lovely exploitable instruction sequences at 0x7213 and
0xE4B8 are exactly the same in this ancient Samson(?) DSP image as in
our familiar Calypso 3606!  Chronologically this finding happened
before I started putting together our FreeCalypso dspdump target
program, i.e., our FC port of OBB's DSP dumper, and it gave me the
confidence boost I needed.  I then put together our FC repackaging of
OBB's dumper which critically depends on these two magic instruction
sequences being at these very specific ROM locations, and the effort
paid off - it worked successfully against DSP ROM version 3311 in
Calypso chip version F741979B on our D-Sample C05 board.

Doing a diff between dsp-rom-3311-dump.txt and dsp-rom-3606-dump.txt,
one can see that some parts of the ROM are almost unchanged, with just
a few individual word changes here and there but no code shifting, and
the exploited instruction sequences happen to be in this stable region.
Other parts of the ROM differ beyond any recognition between the two
versions, as one would naturally expect given the significant
evolutionary and functional differences between them.

Thus we conclude the story of how I was able to repurpose Sylvain's
Calypso DSP dumper from 10 y ago (it was already included in OBB's
initial git commit dated 2010-02-18) for a totally different purpose
than anything ever imagined by Sylvain or by anyone else in the OBB
camp: not hacking Calypso phones to shreds, but archiving different
versions of the DSP ROM for posterity as part of the ongoing eminent
domain proceedings to make all Calypso IP the national property of
the Women's Republic of Themyscira, a proto-nation I am working on.

Hasta la Victoria, Siempre,
Mychaela aka The Mother


More information about the Community mailing list