As of August 2020 the site you are on (wiki.newae.com) is deprecated, and content is now at rtfm.newae.com. |
Tutorial A5-Bonus Breaking AES-256 Bootloader
From ChipWhisperer Wiki
This tutorial is an add-on to Tutorial A5 Breaking AES-256 Bootloader. It continues working on the same firmware, showing how to obtain the hidden IV and signature in the bootloader. It is not possible to do this bonus tutorial without first completing the regular tutorial, so please finish Tutorial A5 first.
This tutorial is under construction! Check back in a few days.
Contents
Background
AES in CBC Mode
- Repeat of theory from tutorial
The IV
- Suggest some ideas
The Signature
- Timing attack
- Show firmware
Attacking the IV
Steps:
- Investigation
- Look at bootloader code
- Move trigger
- Record 1
- Show different instructions in trace
- Making the attack feasible
- Capture a bunch (500?)
- Apply decryption
- Look at one bit
- Find means + plot
- Find differences + plot
- Automating the attack
- Finding the attack points
- Getting a single bit
- Building the IV bytes
- Full script in appendix
Example:
#Imports for IV Attack from Crypto.Cipher import AES def initPreprocessing(self): self.preProcessingResyncSAD0 = preprocessing.ResyncSAD.ResyncSAD(self.parent) self.preProcessingResyncSAD0.setEnabled(True) self.preProcessingResyncSAD0.setReference(rtraceno=0, refpoints=(6300,6800), inputwindow=(6000,7200)) self.preProcessingResyncSAD1 = preprocessing.ResyncSAD.ResyncSAD(self.parent) self.preProcessingResyncSAD1.setEnabled(True) self.preProcessingResyncSAD1.setReference(rtraceno=0, refpoints=(4800,5100), inputwindow=(4700,5200)) self.preProcessingList = [self.preProcessingResyncSAD0,self.preProcessingResyncSAD1,] return self.preProcessingList class AESIVAttack(object): numSubKeys = 16 @staticmethod def leakage(textin, textout, guess, bnum, setting, state): knownkey = [0x94, 0x28, 0x5D, 0x4D, 0x6D, 0xCF, 0xEC, 0x08, 0xD8, 0xAC, 0xDD, 0xF6, 0xBE, 0x25, 0xA4, 0x99, 0xC4, 0xD9, 0xD0, 0x1E, 0xC3, 0x40, 0x7E, 0xD7, 0xD5, 0x28, 0xD4, 0x09, 0xE9, 0xF0, 0x88, 0xA1] knownkey = str(bytearray(knownkey)) ct = str(bytearray(textin)) aes = AES.new(knownkey, AES.MODE_ECB) pt = aes.decrypt(ct) return getHW(bytearray(pt)[bnum] ^ guess)
Appendix D AES-256 IV Attack Script
NB: This script works for 0.10 release or later, see local copy in doc/html directory of chipwhisperer release if you need earlier versions
Full attack script, copy/paste into a file then add as active attack script:
#IV Attack Script from chipwhisperer.common.autoscript import AutoScriptBase #Imports from Preprocessing import chipwhisperer.analyzer.preprocessing as preprocessing #Imports from Capture from chipwhisperer.analyzer.attacks.CPA import CPA from chipwhisperer.analyzer.attacks.CPAProgressive import CPAProgressive import chipwhisperer.analyzer.attacks.models.AES128_8bit # Imports from utilList # Imports for AES256 Attack from chipwhisperer.analyzer.attacks.models.AES128_8bit import getHW #Imports for IV Attack from Crypto.Cipher import AES class AESIVAttack(object): numSubKeys = 16 @staticmethod def leakage(textin, textout, guess, bnum, setting, state): knownkey = [0x94, 0x28, 0x5D, 0x4D, 0x6D, 0xCF, 0xEC, 0x08, 0xD8, 0xAC, 0xDD, 0xF6, 0xBE, 0x25, 0xA4, 0x99, 0xC4, 0xD9, 0xD0, 0x1E, 0xC3, 0x40, 0x7E, 0xD7, 0xD5, 0x28, 0xD4, 0x09, 0xE9, 0xF0, 0x88, 0xA1] knownkey = str(bytearray(knownkey)) ct = str(bytearray(textin)) aes = AES.new(knownkey, AES.MODE_ECB) pt = aes.decrypt(ct) return getHW(bytearray(pt)[bnum] ^ guess) class userScript(AutoScriptBase): preProcessingList = [] def initProject(self): pass def initPreprocessing(self): self.preProcessingResyncSAD0 = preprocessing.ResyncSAD.ResyncSAD(self.parent) self.preProcessingResyncSAD0.setEnabled(True) self.preProcessingResyncSAD0.setReference(rtraceno=0, refpoints=(6300,6800), inputwindow=(6000,7200)) self.preProcessingResyncSAD1 = preprocessing.ResyncSAD.ResyncSAD(self.parent) self.preProcessingResyncSAD1.setEnabled(True) self.preProcessingResyncSAD1.setReference(rtraceno=0, refpoints=(4800,5100), inputwindow=(4700,5200)) self.preProcessingList = [self.preProcessingResyncSAD0,self.preProcessingResyncSAD1,] return self.preProcessingList def initAnalysis(self): self.attack = CPA(self.parent, console=self.console, showScriptParameter=self.showScriptParameter) self.attack.setAnalysisAlgorithm(CPAProgressive, AESIVAttack, None) self.attack.setTraceStart(0) self.attack.setTracesPerAttack(100) self.attack.setIterations(1) self.attack.setReportingInterval(25) self.attack.setTargetBytes([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) self.attack.setTraceManager(self.traceManager()) self.attack.setProject(self.project()) self.attack.setPointRange((4800,6500)) return self.attack def initReporting(self, results): results.setAttack(self.attack) results.setTraceManager(self.traceManager()) self.results = results def doAnalysis(self): self.attack.doAttack()