Inconsistent CLK Glitching when not using GUI


#1

Hello All.

So I have been enjoying my new ChipWhisperer but I have run into an issue and I am not sure how to proceed. I am using the ChipWhisperer to clock glitch an external device. I have replaced the external device’s clock source with the HS2 pin on the ChipWhisperer. The external device sends a trigger on “tio4” back to the Chipwhisperer.

I had everything working as desired when I was using the Glitch Explorer in the GUI. I set up auxiliary scripts to iterate over the glitching parameters and it was all working according to my logic analyzer. The only problem I had was the time between traces (changing the glitching parameters) was too slow. I believe it was so slow because I am using the Glitch Explorer without capturing power traces, so the trace capture is timing out each time. So I decided to just create a script and bypass the GUI.

I created a script that is very similar to chipwhisperer/software/scripting-examples/glitch_explorer_simple_xmega.py

The major change to the script above is that I am not doing any captures (scope.capture) because I am not concerned with the power traces. I am only concerned about clock glitching and iterating over the different external offsets and other glitching parameters. Everything appears to be working as before (and it runs much faster) but I noticed that the glitch output is not consistent.

When looking at my logic analyzer the trigger (tio4) is always present but sometimes glitches are not produced on hs2. Sometimes it is only one iteration of glitch that is not produced, while other times, it will miss 3 or 4 iterations in a row but the trigger is still always present for each iteration. I switched the output from “clock_xor” to glitch only so it would be easier to debug the situation and I can clearly see that some glitches are not produced.

Any suggestions? I don’t really know how to proceed because my script doesn’t control or handle the glitch creation directly. All I am doing is setting the configuration so that it expects a trigger on “tio4” and I have verified that the trigger is being produced every time. It seemed to work fine in the GUI using the Glitch Explorer (but it was too slow!)

Any help would be greatly appreciated. Thanks!


#2

Hello,

I took a quick look at the code arming/capturing and it seems like calling scope.capture() is necessary when doing anything after arming the scope. This is speculation on my part, but I’d guess that the ChipWhisperer doesn’t disarm once it’s triggered (unless it times out). Instead, the status of the ChipWhipserer is repeatedly checked and the arm is disabled once the trigger is detected. I’d also guess that the ChipWhisperer needs to be rearmed after every glitch (so the ongoing arm will no longer react to any triggers), which would explain the inconstant behaviour you’re seeing.

There’s a few things you can try to increase the capture speed:

  • Disable display of power traces that you capture (GUI only). I believe this setting is under the Results tab in the GUI, but I don’t have ChipWhisperer 4 installed currently to check.
  • Try increasing the polling rate during capture. This can be done by navigating to line 1992 in software/chipwhisperer/capture/scopes/_OpenADCInterface.py and decreasing the sleep time on this line. For reference, this change was already made for ChipWhisperer 5 and increased capture speed by roughly x4. This will affect both the GUI and scripts.

Let me know if you have any questions,

Alex


#3

Thanks for the reply Alex.

So currently, I do not even have anything connected to the ChipWhisperer’s measure port. So if I use the GUI and disable display of power traces, will it still try to measure power traces? When I was running it in the GUI before, the glitch explorer was technically doing its job (for clock glitching), but the Multiple Trace progression bar just stayed at 0% because I was gathering no power traces. I would just have to abort it manually after it iterated enough.

So if I continue to try to achieve my results via scripts only, can I call scope.capture() without having to wait on a timeout (since I have nothing connected to measure port)? I’m just trying to come up with a way to run Glitch Explorer for clock glitching without having the need to measure power traces at all.

Is there an api call for disarming the scope?

I will try to increase the polling rate and see if that helps as well.

Again, thanks for your help.


#4

It’s been a while since I did glitching in v4, but I think the capture count should increase after each glitch. Disabling display of the power traces won’t stop the ChipWhisperer from measuring power traces, but it will stop the display of the traces, which tends to speed things up a little.

You won’t be able to call capture without a timeout. In this case, you can consider that timeout as being for the glitch trigger, not for anything related to capturing. This timeout isn’t really an issue; it doesn’t affect the speed at all. It does explain, however, why glitches are produced after the first instead of stopping entirely until the device is properly rearmed.

The actual call for disabling the arm is a few objects deep (scope.qtadc.sc should be the right object), but you’d need to reimplement part of the capture call to avoid changing settings during an important operation. It might be worth adding this as a callable method in the future, but I’d need to check that transferring the scope data actually takes a decent chunk of the capture time.

Alex


#5

Update:

I changed the sleep time from time.sleep(0.05) to time.sleep(0.02)

I put scope.scapture() back into the script. After doing so, my while loop slowed down due to the timeouts and it prints out this message:

WARNING:root:Timeout in OpenADC capture(), trigger FORCED

This is the same message that I receive in the Debug Logging in the GUI except I also receive this message in the GUI:

INFO - Previous trace failed. Redoing with same pair.

I think this is why the Capture Progess does not progress/move on from 0%. However the Glitch Explorer is working and changing the clock glitching parameters and the external device is being reset each time, as desired.

Using my Logic Analyzer, it looks like even with scope.capture() added to the script, the glitch output is still inconsistent and is being missed every so often. This is not the case in the GUI. But the GUI is being slowed down by the warning message above (script also is being slowed down if I add the scope.capture())

So now I am back to the same position I started in…I suppose. If it helps, here is the relevant parts of the script that I am running:

scope.glitch.clk_src = 'clkgen'
scope.glitch.trigger_src = 'ext_single'
scope.glitch.output = 'glitch_only'

scope.gain.gain = 45
scope.adc.samples = 500
scope.adc.offset = 0
scope.adc.basic_mode = 'rising_edge'
scope.clock.clkgen_freq = 9600000
scope.clock.adc_src = 'clkgen_x4'
scope.trigger.triggers = 'tio4'
scope.io.tio1 = 'serial_rx'
scope.io.tio2 = 'serial_tx'
scope.io.hs2 = 'glitch'
target.init()
while scope.glitch.offset < offset_range.max:
    scope.glitch.ext_offset = ext_offset_range.min
    while scope.glitch.ext_offset < ext_offset_range.max:
        # call before trace things here

        # flush the garbage from the computer's target read buffer
        target.ser.flush()

        # target enters reset mode
        scope.io.nrst = 'low'

        # run aux stuff that should run before the scope arms here

        scope.arm()

        # run aux stuff that should run after the scope arms here

        # target exits reset mode
        scope.io.nrst = 'high'

        #timeout = 50
        # wait for target to finish
        #while target.isDone() is False and timeout:
        #     timeout -= 1
        #     time.sleep(0.01)

        # Try adding scope.capture() back into script
        #scope.capture()

        #try:
        #    ret = scope.capture()
        #    if ret:
        #        logging.warning('Timeout happened during acquisition')
        #except IOError as e:
        #    logging.error('IOError: %s' % str(e))

        # get the results from the scope
        #trace = scope.getLastTrace()
        # read from the targets buffer
        output = target.ser.read(10, timeout=0)
        #traces.append(trace)
        outputs.append(output)
        widths.append(scope.glitch.width)
        offsets.append(scope.glitch.width)
        ext_offsets.append(scope.glitch.ext_offset)

        # for table display purposes
        success = '1234' in repr(output) # check for glitch success (depends on targets active firmware)
        data = [repr(output), scope.glitch.width, scope.glitch.offset, scope.glitch.ext_offset, success]
        print(data)
        #glitch_display.add_data(data)
        #writer.writerow(data)

        # run aux stuff that should happen after trace here
        scope.glitch.ext_offset += ext_offset_range.step
    scope.glitch.offset += offset_range.step
#f.close()
#traces = np.asarray(traces)
# the rest of the data is available with the outputs, widths, and offsets lists
#glitch_display.display_table()
print('Done')

This is the way the code is written with the scope.capture() commented out. Both versions of the code produce inconsistent/missing glitch output. The scope.capture() version is just slower because of timeouts.

Any more ideas, would be much appreciated!


#6

Update to Update:

So apparently the glitch output was working consistently after all. I turned up the Sample Rate on my Saleae Logic and it was able to see each glitch. I had thought I had the sample rate fast enough, but somehow it got switched to lower so it was only able to see some of the glitches. Well, at least I know that you can do clock glitching without the scope.capture() call.

I feel like a moron.

Alex, I apologize for wasting your time, but I appreciate all of the help and feedback that you have given me.

Happy glitching everyone!


#7

Good to hear you got it working! Let me know if you have any more questions and I’d be happy to help out.

Alex