Skip to content

Glitching

Glitching

Example Glitcher:

import serial
import struct
from tqdm import tnrange, tqdm_notebook
import time


#Setup Initialization
SERIAL_DEVICE = "/dev/tty.usbserial-210328A9FDC51"

#Should the device be power cycled before the test
POWER_CYCLE_BEFORE_GLITCH = False
#The duration for which the power-cycle pulse should be send, in 100_000_000th of a second
POWER_CYCLE_PULSE = 3_000 
#The delay range start in 100_000_000th of a second
DELAY_FROM = 100_000
#The delay range end in 100_000_000th of a second
DELAY_TO = 150_000
#The duration for which the power-cycle pulse should start in 100_000_000th of a second
PULSE_FROM = 1
#The duration for which the power-cycle pulse should end in 100_000_000th of a second
PULSE_TO = 100

commands = {"CMD_TOGGLE_LED": 65,
			"CMD_POWER_CYCLE": 66,
			"CMD_SET_GLITCH_PULSE": 67, # uint32
			"CMD_SET_DELAY": 68, # uint32
			"CMD_SET_POWER_PULSE": 69, # uint32
			"CMD_GLITCH": 70,
			"CMD_READ_GPIO": 71,
			"CMD_ENABLE_GLITCH_POWER_CYCLE": 72, # bool/byte
			"CMD_GET_STATE": 73 } # Get state of device

def cmd_toggle_led(device):
	device.write(chr(commands['CMD_TOGGLE_LED']).encode("ASCII"))

def cmd(device, command):
	device.write(chr(command).encode("ASCII"))

def cmd_uint32(device, command, u32):
	device.write(chr(command).encode("ASCII"))
	data = struct.pack(">L", u32)
	device.write(data)

def cmd_uint8(device, command, u8):
	device.write(chr(command).encode("ASCII"))
	data = struct.pack("B", u8)
	device.write(data)

def cmd_read_uint8(device, command):
	device.write(chr(command).encode("ASCII"))
	return device.read(1)[0]

def parse_status(status):
	power_pulse_status = (status >> 6) & 0b11
	trigger_status = (status >> 4) & 0b11
	delay_status = (status >> 2) & 0b11
	glitch_pulse_status = status & 0b11
	print("Power pulse   : " + str(power_pulse_status))
	print("Trigger status: " + str(trigger_status))
	print("Delay status  : " + str(delay_status))
	print("Glitch pulse  : " + str(glitch_pulse_status))

def setup_chipfail(device):
	#Send the glitch parameters to the chipfail
	cmd_uint32(device, commands['CMD_SET_POWER_PULSE'], 100_000_000)
	cmd_uint32(device, commands['CMD_SET_DELAY'], 100_000_000)
	cmd_uint32(device, commands['CMD_SET_GLITCH_PULSE'], 100_000_000)
	cmd_uint8( device, commands['CMD_ENABLE_GLITCH_POWER_CYCLE'], 1)

	#Start Glitch and check the status
	cmd(device, commands['CMD_GLITCH'])
	print("Step one, power pulse:")
	status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	parse_status(status)
	time.sleep(1.1)

	#Waiting for correct timing to start
	print("Step two, trigger")
	status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	parse_status(status)
	print("\tWaiting for pin to go low...")
	while(status == 0b00010000):
		status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	print("\tWaiting for pin to go high...")
	while(status == 0b00100000):
		status = cmd_read_uint8(device, commands['CMD_GET_STATE'])

	#Check status
	print("Step three, delay:")
	status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	parse_status(status)
	time.sleep(1.1)
	print("Step four, glitch pulse:")
	status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	parse_status(status)
	while(status == 0b00000001):
		status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	print("Done, if you get here it means everything is working!")


if __name__ == '__main__':
	#Setup device
	device = serial.Serial(SERIAL_DEVICE, baudrate=115200)

	#See if device is running in normal mode
	status = cmd_read_uint8(device, commands['CMD_GET_STATE'])
	parse_status(status)

	setup_chipfail(device)

	#Do Full Glitch
	success = False
	for delay in tnrange(DELAY_FROM, DELAY_TO):
		cmd_uint32(device, CMD_SET_DELAY, delay)
		if success:
			break
		for pulse in tnrange(PULSE_FROM, PULSE_TO, leave=False):
			cmd_uint32(device, commands['CMD_SET_GLITCH_PULSE'], pulse)
			cmd(device, commands['CMD_GLITCH'])
			# Loop until the status is == 0, aka the glitch is done.
			# This avoids having to manually time the glitch :)
			while(cmd_read_uint8(device, commands['CMD_GET_STATE'])):
				pass
			# Check whether the glitch was successful!
			gpios = cmd_read_uint8(device, commands['CMD_READ_GPIO'])
			if(gpios):
				print("*** SUCCESS ***")
				print("Delay: " + str(delay))
				print("Pulse: " + str(pulse))
				success = True
				break

	# Show status of IOs
	print(format(cmd_read_uint8(device, CMD_READ_GPIO), '#010b'))