Making a UART controlled glitch on an iCE40 icestick FPGA board.
So, let's pick up
where we left off... This is our setup - we have an STM32F103 target,
and we're going to see how accurately we can glitch this IC by
manipulating the power supply on the GND side using a MOSFET triggered
by an FPGA. We had this running on an AVR before, but...
please take my
word for it, the code from last time will work on this chip. So, first,
we make some modifications and remove the power line filter caps from
the PCB. Here's the view after some minor surgery and a meditation with a
hot air reflow gun:
(NB - I try to
avoid removing ALL the caps off a board. Some are needed by the crystal
to filter the clock signal or for other parts of the PCB that won't
affect what I'm looking at - so these few are enough for me for now, I
think... if I'm wrong, do tell!)
So, with that
done, it's time to 'mangle' the verilog. I'm not a great coder, so this
is very much 'hacked together until it works' but that's all I need for
this. I want very precise glitches, and control over the built in UART
ideally. The iceStick has 2 UART ports, one for...
programming, and one as an interface (handy dandy FTDI IC t the rescue). So, I found some example code here:
(props to cyrozap on github) and used that as my UART library, because I can't be bothered to write my own. So, now we're set - compile and...
(props to cyrozap on github) and used that as my UART library, because I can't be bothered to write my own. So, now we're set - compile and...
...test the
example code and make sure it works (it does) and then we're done for
this little bit. We can read a byte over UART and sort this out. Now,
onto clocking...
I want to
generate very accurate glitches, so having a clock available that is at
the clock speed of my target (72MHz) would be ace. But my FPGA only has
12MHz clock?! NEVER FEAR!!
This is what a PLL
(Phase Locked Loop) is handy for - we can use it to divide the clock up
to 72MHz by this kinda magic;
So, we have our clocks setup, here's how we'll do the glitch - read the comments in red for more info:
So, now, we have a
basic bit of UART control, both the _when_ and the _how long_ we
glitch. This is important! We can now use this control stuff by just
sending a few bytes over UART from, for example, a PySerial script to
affect our target.
So, first up,
here's me triggering a glitch using a keyboard... this is the basic
first step. Once this is sorted, using the value we sent over UART is
relatively straightforward (see code a tweet or so back)
So, this requires
a bit of careful inspection, but notice that the second glitch signal
is quite a bit wider than the first. This is a comparison from sending
an 'a' to sending a 'z'. Our bitshift of 8 to the left (multiply by 256
effectively) makes this quite a bit bolder for...
every +1 in our
UART input. I've also clocked up the UART from 9600bd in the example to
115200 - this means I can get in more glitch 'requests' in per second,
effectively. I could ramp this right up to get very fine glitches, but
there's a problem in the code that prevents this
(the why I'm not certain on, but it's not really critical - this is control enough, if I'm honest)
NB - the code on
the STM32F103 is mine - it's from this example I wrote of an IRQ-driven
UART on the STM32F103 chip. It was a tw to get working. Here's the
link:
So, now we want to test it... Here's the test code being sent from within python from pyserial:
Note, in this
code, I'm creating 'wait' glitches by sending '\x01' - glitches of one
clock cycle - that will not affect the uC. This is a dirty hack, and
there are better ways to do it, but it is handy for my by-hand testing
:P Yes, delays are usually enough! :P
so, here's the effect it is having on our IC:
Notice, I have
enough control by adding '\x01' bytes when sending a payload, that I can
glitch backwards across the opening UART printf to affect each
character with very-nearly pinpoint accuracy. :P This is a good sign! :D
not bad for a dirty hack on a Sat Afternoon X-P
So, here is the scope trace for one of the instances of what you just saw:
Note that the
'furry' bit on the trace, just after the reset glitch (initiated by a
'z' being sent in this case) is the UART sending of hte 'Reboot has
occurred' message. So, you can see the minor glitches not affecting
stuff, and then the major glitch at the end kicking in...
(though the larger glitch isn't really visible here... but you can try it for yourself! :P )
Here are a few
final shots of the test setup. This works surprisingly well - though
I've not had a chance to test it against actual targets where I have
something I want to glitch. But I'll hopefully be able to do some work
with it soon :D
PPS - one last thing - this setup is of minimal cost - that's why I did it!
IceStick FPGA board: £25
2N7000 MOSFET - £0.10
Breadboard - £5?
cables - free with any densely populated hackspace
STM32F103 'bluepill' target - £3-4
IceStick FPGA board: £25
2N7000 MOSFET - £0.10
Breadboard - £5?
cables - free with any densely populated hackspace
STM32F103 'bluepill' target - £3-4
Comments
Post a Comment