Hi, thanks for your reply.
Here is the fault attack part, excluding the normal setup code. Our hardware setup is Husky Plus + CW312 board + STM32F4 target. For compiling, the platform I select is CW308_STM32F4 and ver is SS_VER_1_1.
First, we changed gold_ct into a function, so that we can compute a separate reference ciphertext for each plaintext. In our test, we generated three reference ciphertexts for plaintexts 0, 1, and 2.
scope.clock.clkgen_src = "system"
scope.clock.adc_mul = 1
fixed_key = bytearray([0]*16)
print(fixed_key)
def get_gold_ct(pt):
reboot_flush()
# set fixed AES key
target.simpleserial_write('k', fixed_key)
target.simpleserial_wait_ack()
scope.arm()
target.simpleserial_write('p', pt)
ret = scope.capture()
wave = scope.get_last_trace()
if ret:
raise RuntimeError("Capture timeout when generating golden ciphertext")
output = target.simpleserial_read_witherrors('r', 16)
if not output['valid']:
raise RuntimeError("Invalid response when generating golden ciphertext")
return bytearray(output['payload']),wave
pt0 = bytearray([0]*16)
pt1 = bytearray([1]*16)
pt2 = bytearray([2]*16)
gold_ct0, wave0 = get_gold_ct(pt0)
gold_ct1, wave1 = get_gold_ct(pt1)
gold_ct2, wave2 = get_gold_ct(pt2)
print("gold_ct0 =", gold_ct0.hex())
print("gold_ct1 =", gold_ct1.hex())
print("gold_ct2 =", gold_ct2.hex())
print("key =", fixed_key.hex())
The output is:
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
gold_ct0 = 66e94bd4ef8a2c3b884cfa59ca342b2e
gold_ct1 = e14d5d0ee27715df08b4152ba23da8e0
gold_ct2 = 5eba73f89142c54880f68594373c5c37
key = 00000000000000000000000000000000
Then we use this setting obtained from fault101 for glitch_loc, width, offset, and ext_offset
if scope._is_husky:
scope.glitch.enabled = True
scope.glitch.clk_src = "pll"
scope.glitch.output = "clock_xor"
scope.glitch.trigger_src = "ext_single"
scope.glitch.repeat = 1
scope.io.hs2 = "glitch"
glitch_loc = range(0, 40)
scope.glitch.width = 300
scope.glitch.offset = 100
scope.glitch.ext_offset = 0
I follow the original main loop idea for 0 except use a new gold_ct0:
wave = None
logging.getLogger().setLevel(logging.ERROR)
reboot_flush()
for i in glitch_loc:
scope.adc.timeout = 0.2
scope.glitch.ext_offset = i
ack = None
while ack is None:
target.simpleserial_write('k', fixed_key)
ack = target.simpleserial_wait_ack()
if ack is None:
reboot_flush()
time.sleep(0.1)
scope.arm()
pt = bytearray([0]*16)
target.simpleserial_write('p', pt)
ret = scope.capture()
if ret:
reboot_flush() #bad if we accidentally didn't have this work
time.sleep(0.1)
print("timed out!")
continue
output = target.simpleserial_read_witherrors('r', 16, glitch_timeout = 1)
if output['valid']:
if output['payload'] != gold_ct0:
print("Glitched at {}".format(i))
wave = scope.get_last_trace()
break
else:
reboot_flush()
It shows a successful glitch and by output it shows:
glitched_ct0 = bytearray(output['payload'])
print(glitched_ct0.hex())
print(gold_ct0.hex())
b5044600f0d5ff00f042fa204600f0ce
66e94bd4ef8a2c3b884cfa59ca342b2e
Then I reuse the loop by replacing plaintext as 1 and gold_ct1,
wave = None
logging.getLogger().setLevel(logging.ERROR)
reboot_flush()
while True:
scope.adc.timeout = 0.2
scope.glitch.ext_offset = i
ack = None
while ack is None:
target.simpleserial_write('k', fixed_key)
ack = target.simpleserial_wait_ack()
if ack is None:
reboot_flush()
time.sleep(0.1)
scope.arm()
pt = bytearray([2]*16)
target.simpleserial_write('p', pt)
ret = scope.capture()
if ret:
reboot_flush() #bad if we accidentally didn't have this work
time.sleep(0.1)
print("timed out!")
continue
output = target.simpleserial_read_witherrors('r', 16, glitch_timeout = 1)
if output['valid']:
if output['payload'] != gold_ct2:
print("Glitched at {}".format(i))
wave = scope.get_last_trace()
break
else:
reboot_flush()
However, now the incorrect parts appear, as for 1, here is the fault output and correct ones:
glitched_ct2 = bytearray(output['payload'])
print(glitched_ct2.hex())
print(gold_ct2.hex())
b5044600f0d5ff00f042fa204600f0ce
3a69dc4d3eec2c4bb025b8ef40d1259e
This is incorrect, as for faulty encryption of 0 and encryption of 1 is the same. I consult GPT it suggests that this one looks not like a AES encryption but more like a error code.
P.S. What I successfully run up to now is 2.1 of RSA fault attack which shows True in the end.