Beispiel #1
0
 def flash(self, fw_path: str) -> bool:
     try:
         cw.program_target(self.scope, self.programmer, fw_path)
     except Exception as e:
         print(e)
         return False
     return True
Beispiel #2
0
    def programmer(
        self,
        dot_hex_path: str,
        programmer_type: str,
        reconnect: bool = True,
    ) -> None:
        self._check_connection(raise_exception=True)
        if programmer_type is None or programmer_type.lower() not in (
                'xmega', 'stm32f'):
            raise RuntimeError(
                f"'{dot_hex_path}' is unsupported programmer type. (Available: xmega, stm32f)"
            )

        if not os.path.exists(dot_hex_path):
            raise RuntimeError("The .hex file does not exist.")

        if programmer_type.lower() == "xmega":
            programmer = cw.programmers.XMEGAProgrammer
        else:
            programmer = cw.programmers.STM32FProgrammer

        cw.program_target(self._scope, programmer, dot_hex_path)
        if reconnect:
            self.reconnect()
        pass
Beispiel #3
0
def doIt(binary):
    print(f"flashing binary {binary}")
    cw.program_target(scope, prog, binary)

    # wait for all the output from the board
    print(f"output starts ({binary}):")
    while True:
        response = target.read(timeout=0)
        if response != None and response != "":
            print(response, end='', flush=True)
        if "#" in response:
            break
    print(f"{binary} done.")
Beispiel #4
0
def initialize():
    # ChipWhisperer Lite setup
    scope = cw.scope()
    scope.default_setup()

    # Program the target board
    target = cw.target(scope)
    prog = cw.programmers.XMEGAProgrammer
    cw.program_target(scope, prog, fw_path)

    # Prepare scope for capturing
    scope.gain.db = 34  # works best with this gain for some reason
    scope.adc.samples = 1700 - 170
    scope.adc.offset = 500 + 700 + 170

    # Return the scope and target handles
    return scope, target
Beispiel #5
0
def setup_device(name):
    """Convience function for setting up and programing a CW/Target pair

    Args:
        name (str): String representing the target configuration. Currently
                    supports 'STM32F3', 'CW305', 'XMEGA', 'STM32F3-mbed',
                    'K82F', 'STM32F4'

    returns:
        Setup scope and target objects
    """
    scope = cw.scope()
    if name == "CW305":
        scope.gain.db = 25
        scope.adc.samples = 129
        scope.adc.offset = 0
        scope.adc.basic_mode = "rising_edge"
        scope.clock.clkgen_freq = 7370000
        scope.clock.adc_src = "extclk_x4"
        scope.trigger.triggers = "tio4"
        scope.io.tio1 = "serial_rx"
        scope.io.tio2 = "serial_tx"
        scope.io.hs2 = "disabled"
        target = cw.target(scope, cw.targets.CW305, bsfile="cw305_top.bit", force=False)
        target.vccint_set(1.0)
        # we only need PLL1:
        target.pll.pll_enable_set(True)
        target.pll.pll_outenable_set(False, 0)
        target.pll.pll_outenable_set(True, 1)
        target.pll.pll_outenable_set(False, 2)

        # run at 10 MHz:
        target.pll.pll_outfreq_set(10E6, 1)

        # 1ms is plenty of idling time
        target.clkusbautooff = True
        target.clksleeptime = 1
    else:
        target = cw.target(scope)
        scope.default_setup()
        scope.adc.samples = 24400
    if name == "XMEGA":
        cw.program_target(scope, cw.programmers.XMEGAProgrammer, "AES-xmega.hex")
    elif name == "STM32F3":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES.hex")
    elif name == "STM32F3-mbed":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-mbed.hex")
    elif name == "K82F":
        scope.adc.samples=3500
    elif name == "STM32F4":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-f4.hex")
        scope.adc.samples=5000

    return scope,target
def setup_device(name):
    scope = cw.scope()
    if name == "CW305":
        scope.gain.db = 25
        scope.adc.samples = 129
        scope.adc.offset = 0
        scope.adc.basic_mode = "rising_edge"
        scope.clock.clkgen_freq = 7370000
        scope.clock.adc_src = "extclk_x4"
        scope.trigger.triggers = "tio4"
        scope.io.tio1 = "serial_rx"
        scope.io.tio2 = "serial_tx"
        scope.io.hs2 = "disabled"
        target = cw.target(scope, cw.targets.CW305, bsfile="cw305_top.bit", force=False)
        target.vccint_set(1.0)
        # we only need PLL1:
        target.pll.pll_enable_set(True)
        target.pll.pll_outenable_set(False, 0)
        target.pll.pll_outenable_set(True, 1)
        target.pll.pll_outenable_set(False, 2)

        # run at 10 MHz:
        target.pll.pll_outfreq_set(10E6, 1)

        # 1ms is plenty of idling time
        target.clkusbautooff = True
        target.clksleeptime = 1
    else:
        target = cw.target(scope)
        scope.default_setup()
        scope.adc.samples = 24400
    if name == "XMEGA":
        cw.program_target(scope, cw.programmers.XMEGAProgrammer, "AES-xmega.hex")
    elif name == "STM32F3":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES.hex")
    elif name == "STM32F3-mbed":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-mbed.hex")
    elif name == "K82F":
        scope.adc.samples=3500
    elif name == "STM32F4":
        cw.program_target(scope, cw.programmers.STM32FProgrammer, "AES-f4.hex")
        scope.adc.samples=5000

    return scope,target
import os
from chipwhisperer.capture.api.programmers import STM32FProgrammer

# Initiate a new STM32F Program
# STM32 being the ARM microcontroller that we are using
# https://en.wikipedia.org/wiki/STM32#STM32_F3
program = STM32FProgrammer

# Get the path to the current folder
# Adjust accordingly
aes_firmware_dir = os.path.dirname(os.path.realpath(__file__))
aes_hex_path = os.path.join(aes_firmware_dir, r"simpleserial-target-CWLITEARM.hex")

# Apply the program to the actual target
# This allows us to run the hex code on the microcontroller
cw.program_target(scope, program, aes_hex_path)
########################################

# Capture a trace of our binary
########################################
# Define some dummy data
data = bytearray([0x42] * 16)

# Arm the capture board
scope.arm()

# Flush the UART buffer
target.flush()

# Send a new command to trigger our code.
# Here we use scmd = 128
Beispiel #8
0
def main(argv):
    if (len(argv) != 3):
        print(
            "\nplease specify the path, type and numer of trials\npython CSIDH_glitch.py [path] [type] [ntrials]\ne.g. python CSIDH_glitch.py /home/me/chipwhisperer/hardware/victims/firmware/csidh_trace/ ATTACK1 100"
        )
        sys.exit()
    else:
        random.seed(13)
        PATH = argv[0]
        TYPE = argv[1]  # ATTACK1 or ATTACK2
        NTRIAL = int(argv[2])
        FULLPATH = PATH + BIN

        # Setup_Generic ##################################################################
        scope = cw.scope()
        target = cw.target(scope)

        if "STM" in PLATFORM or PLATFORM == "CWLITEARM" or PLATFORM == "CWNANO":
            prog = cw.programmers.STM32FProgrammer
        elif PLATFORM == "CW303" or PLATFORM == "CWLITEXMEGA":
            prog = cw.programmers.XMEGAProgrammer
        else:
            prog = None

        import time
        time.sleep(0.05)
        scope.default_setup()

        def reset_target(scope):
            if PLATFORM == "CW303" or PLATFORM == "CWLITEXMEGA":
                scope.io.pdic = 'low'
                time.sleep(0.05)
                scope.io.pdic = 'high_z'  # XMEGA doesn't like pdic driven high
                time.sleep(0.05)
            else:
                scope.io.nrst = 'low'
                time.sleep(0.05)
                scope.io.nrst = 'high'
                time.sleep(0.05)

        # Setup_Generic ##################################################################

        # create firmware
        os.chdir(PATH)
        #os.system('make clean PLATFORM=CWLITEARM CRYPTO_TARGET=NONE')
        #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=TEST OPT=0")

        if ((TYPE == "ATTACK1") or (TYPE == "ATTACK1_D")):
            if (TYPE == "ATTACK1"):
                os.system(
                    "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1 OPT=3"
                )
            else:
                os.system(
                    "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1_D OPT=3"
                )
                #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK1_D OPT=3 TYPE=CM")

            # Sets up sane capture defaults for this scope
            # 45dB gain
            # 5000 capture samples
            # 0 sample offset
            # rising edge trigger
            # 7.37MHz clock output on hs2
            # 4*7.37MHz ADC clock
            # tio1 = serial rx
            # tio2 = serial tx
            scope.default_setup()

            scope.clock.adc_src = 'clkgen_x1'

            fw_path = FULLPATH.format(PLATFORM)
            print(fw_path)

            reset_target(scope)
            target.flush()

            cw.program_target(scope, prog, fw_path)

            glitches = []
            glitches.append([
                "[scope.glitch.width", "scope.glitch.offset",
                "scope.glitch.repeat", "scope.glitch.ext_offset",
                "good/bad/crash]"
            ])

            if (GLITCH):
                setGlitch(scope)

            # The response took 1086919328 cycles
            # -O3
            ext_offset = 222534093

            wrong = 0
            crashes = 0
            for i in range(0, NTRIAL):
                if (GLITCH):
                    # scope.glitch.width = random.randint(-49, 49)

                    # scope.glitch.offset = random.randint(-49, 49)

                    # The width of a single glitch pulse, as a percentage of one period.
                    # One pulse can range from -49.8% to roughly 49.8% of a period.
                    # The system may not be reliable at 0%. Note that negative widths are allowed;
                    # these act as if they are positive widths on the other half of the clock cycle.
                    # scope.glitch.width = random.randint(-49, 49)
                    scope.glitch.width = -9

                    # The offset from a rising clock edge to a glitch pulse rising edge,
                    # as a percentage of one period.
                    # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge,
                    # allowing glitches to be swept over the entire clock cycle.
                    # scope.glitch.offset = random.randint(-49, 49)
                    scope.glitch.offset = -38.3

                    # How long the glitch module waits between a trigger and a glitch.
                    # After the glitch module is triggered, it waits for a number of clock cycles
                    # before generating glitch pulses. This delay allows the glitch to be inserted
                    # at a precise moment during the target’s execution to glitch specific instructions.
                    scope.glitch.ext_offset = random.randint(0, ext_offset)
                    # scope.glitch.ext_offset = 108466842

                    # The number of glitch pulses to generate per trigger.
                    # When the glitch module is triggered, it produces a number of pulses
                    # that can be combined with the clock signal. This setting allows for
                    # the glitch module to produce stronger glitches (especially during voltage glitching).
                    # Repeat counter must be in the range [1, 255].
                    # scope.glitch.repeat = random.randint(1, 4)
                    scope.glitch.repeat = 3

                reset_target(scope)
                target.flush()

                print("\n--------------------------------\nstarting capture " +
                      str(i) + " : " +
                      datetime.datetime.now().strftime("%H:%M:%S"))
                #scope.adc.timeout = 210
                scope.arm()
                #scope.adc.timeout = 210
                target.write("s")
                time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                time.sleep(40)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                print("<output>\n" + response + "\n</output>")

                if (GLITCH):
                    if "good" not in response:
                        # Something abnormal happened
                        if len(response) > 0:
                            # Possible glitch!
                            print(
                                "\nBad shared secret\nGlitch at offset {} and repeat = {}"
                                .format(scope.glitch.ext_offset,
                                        scope.glitch.repeat))
                            wrong = wrong + 1
                            glitches.append([
                                scope.glitch.width, scope.glitch.offset,
                                scope.glitch.repeat, scope.glitch.ext_offset,
                                "bad"
                            ])

                        else:
                            # Crash, reset and try again
                            print("\nProbably crashed at {} and repeat = {}".
                                  format(scope.glitch.ext_offset,
                                         scope.glitch.repeat))
                            crashes = crashes + 1
                            glitches.append([
                                scope.glitch.width, scope.glitch.offset,
                                scope.glitch.repeat, scope.glitch.ext_offset,
                                "crash"
                            ])
                    else:
                        print(
                            "\nGood shared secret\nGlitch at offset {} and repeat = {}"
                            .format(scope.glitch.ext_offset,
                                    scope.glitch.repeat))
                        glitches.append([
                            scope.glitch.width, scope.glitch.offset,
                            scope.glitch.repeat, scope.glitch.ext_offset,
                            "good"
                        ])

                print("end of capture " + str(i) + " : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

            glitches.append(["-----------------------------"])
            glitches.append(["ntrial, wrong, crashes"])
            glitches.append([NTRIAL, wrong, crashes])

            if (TYPE == "ATTACK1"):
                PATH = "attack1_" + datetime.datetime.now().strftime(
                    "%d%m%Y_%H%M") + ".csv"
            else:
                PATH = "attack1_D_" + datetime.datetime.now().strftime(
                    "%d%m%Y_%H%M") + ".csv"

            # save raw data as csv
            with open(PATH, mode='w') as csv_file:
                csv_writer = csv.writer(csv_file)
                for entry in glitches:
                    csv_writer.writerow(entry)

        elif (TYPE == "ATTACK2"):
            os.system(
                "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2 OPT=3"
            )

            # Sets up sane capture defaults for this scope
            # 45dB gain
            # 5000 capture samples
            # 0 sample offset
            # rising edge trigger
            # 7.37MHz clock output on hs2
            # 4*7.37MHz ADC clock
            # tio1 = serial rx
            # tio2 = serial tx
            scope.default_setup()

            scope.clock.adc_src = 'clkgen_x1'

            fw_path = FULLPATH.format(PLATFORM)
            print(fw_path)

            reset_target(scope)
            target.flush()

            cw.program_target(scope, prog, fw_path)

            glitches = []
            glitches.append([
                "[isogeny", "scope.glitch.width", "scope.glitch.offset",
                "scope.glitch.repeat", "scope.glitch.ext_offset",
                "good/bad/crash]"
            ])

            # The response took 4846257 cycles : 1. isogeny computation
            # -O0
            # ext_offset = 4846257
            # -O3
            ext_offset = 83289

            wrong = 0
            crashes = 0

            setDefault(scope)

            for i in range(0, NTRIAL):

                if (GLITCH):
                    #isogeny = random.randint(1, 2)
                    isogeny = 2

                    if (isogeny == 1):
                        setGlitch(scope)

                        # The width of a single glitch pulse, as a percentage of one period.
                        # One pulse can range from -49.8% to roughly 49.8% of a period.
                        # The system may not be reliable at 0%. Note that negative widths are allowed;
                        # these act as if they are positive widths on the other half of the clock cycle.
                        # scope.glitch.width = random.randint(-49, 49)

                        # The offset from a rising clock edge to a glitch pulse rising edge,
                        # as a percentage of one period.
                        # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge,
                        # allowing glitches to be swept over the entire clock cycle.
                        # scope.glitch.offset = random.randint(-49, 49)

                        # How long the glitch module waits between a trigger and a glitch.
                        # After the glitch module is triggered, it waits for a number of clock cycles
                        # before generating glitch pulses. This delay allows the glitch to be inserted
                        # at a precise moment during the target’s execution to glitch specific instructions.
                        scope.glitch.ext_offset = random.randint(0, ext_offset)
                        # scope.glitch.ext_offset = 108466842

                        # The number of glitch pulses to generate per trigger.
                        # When the glitch module is triggered, it produces a number of pulses
                        # that can be combined with the clock signal. This setting allows for
                        # the glitch module to produce stronger glitches (especially during voltage glitching).
                        # Repeat counter must be in the range [1, 255].
                        scope.glitch.repeat = random.randint(1, 4)
                        #scope.glitch.repeat = 1

                reset_target(scope)
                target.flush()

                print(
                    "\n--------------------------------\nstarting capture " +
                    str(i) +
                    "\n--------------------------------\ncapture of 1. isogeny  : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 180
                scope.arm()
                scope.adc.timeout = 180
                target.write("s")
                time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                #time.sleep(60)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                print("<output>\n" + response + "\n</output>")

                print("end of 1. isogeny : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                setDefault(scope)

                # The response took 3436390 cycles : 2. isogeny computation
                # -O0
                # ext_offset = 3436390
                # -O3
                ext_offset = 8580178

                if (GLITCH):

                    if (isogeny == 2):
                        setGlitch(scope)

                        # The width of a single glitch pulse, as a percentage of one period.
                        # One pulse can range from -49.8% to roughly 49.8% of a period.
                        # The system may not be reliable at 0%. Note that negative widths are allowed;
                        # these act as if they are positive widths on the other half of the clock cycle.
                        # scope.glitch.width = random.randint(-49, 49)

                        # The offset from a rising clock edge to a glitch pulse rising edge,
                        # as a percentage of one period.
                        # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge,
                        # allowing glitches to be swept over the entire clock cycle.
                        # scope.glitch.offset = random.randint(-49, 49)

                        # How long the glitch module waits between a trigger and a glitch.
                        # After the glitch module is triggered, it waits for a number of clock cycles
                        # before generating glitch pulses. This delay allows the glitch to be inserted
                        # at a precise moment during the target’s execution to glitch specific instructions.
                        scope.glitch.ext_offset = random.randint(1, ext_offset)
                        # scope.glitch.ext_offset = 108466842

                        # The number of glitch pulses to generate per trigger.
                        # When the glitch module is triggered, it produces a number of pulses
                        # that can be combined with the clock signal. This setting allows for
                        # the glitch module to produce stronger glitches (especially during voltage glitching).
                        # Repeat counter must be in the range [1, 255].
                        scope.glitch.repeat = random.randint(1, 4)
                        #scope.glitch.repeat = 1

                print(
                    "\n--------------------------------\ncapture of 2. isogeny : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 60
                scope.arm()
                scope.adc.timeout = 60
                target.write("n")
                time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                #time.sleep(10)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                print("<output>\n" + response + "\n</output>")

                print("end of 2. isogeny : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                setDefault(scope)

                print(
                    "\n--------------------------------\nstarting capture of result : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 30
                scope.arm()
                scope.adc.timeout = 30
                target.write("n")
                time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                #time.sleep(10)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                print("<output>\n" + response + "\n</output>")

                print("end of capture " + str(i) + " : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                if (GLITCH):
                    if "good" not in response:
                        # Something abnormal happened
                        if len(response) > 0:
                            # Possible glitch!
                            print(
                                "\nBad shared secret\nGlitching isogeny {} at offset {} and repeat = {}"
                                .format(isogeny, scope.glitch.ext_offset,
                                        scope.glitch.repeat))
                            wrong = wrong + 1
                            glitches.append([
                                isogeny, scope.glitch.width,
                                scope.glitch.offset, scope.glitch.repeat,
                                scope.glitch.ext_offset, "bad"
                            ])

                        else:
                            # Crash, reset and try again
                            print(
                                "\nProbably crashed at isogeny {} at {} and repeat = {}"
                                .format(isogeny, scope.glitch.ext_offset,
                                        scope.glitch.repeat))
                            crashes = crashes + 1
                            glitches.append([
                                isogeny, scope.glitch.width,
                                scope.glitch.offset, scope.glitch.repeat,
                                scope.glitch.ext_offset, "crash"
                            ])
                    else:
                        print(
                            "\nGood shared secret\nGlitching isogeny {} at offset {} and repeat = {}"
                            .format(isogeny, scope.glitch.ext_offset,
                                    scope.glitch.repeat))
                        glitches.append([
                            isogeny, scope.glitch.width, scope.glitch.offset,
                            scope.glitch.repeat, scope.glitch.ext_offset,
                            "good"
                        ])

            glitches.append(["-----------------------------"])
            glitches.append(["ntrial, wrong, crashes"])
            glitches.append([NTRIAL, wrong, crashes])

            PATH = "attack2_" + datetime.datetime.now().strftime(
                "%d%m%Y_%H%M") + ".csv"

            # save raw data as csv
            with open(PATH, mode='w') as csv_file:
                csv_writer = csv.writer(csv_file)
                for entry in glitches:
                    csv_writer.writerow(entry)

        elif (TYPE == "ATTACK2_D"):
            #os.system("make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2_D OPT=2 TYPE=CM")
            os.system(
                "make PLATFORM=CWLITEARM CRYPTO_TARGET=NONE FUNC_SEL=ATTACK2_D OPT=3"
            )

            # Sets up sane capture defaults for this scope
            # 45dB gain
            # 5000 capture samples
            # 0 sample offset
            # rising edge trigger
            # 7.37MHz clock output on hs2
            # 4*7.37MHz ADC clock
            # tio1 = serial rx
            # tio2 = serial tx
            scope.default_setup()

            scope.clock.adc_src = 'clkgen_x1'

            fw_path = FULLPATH.format(PLATFORM)
            print(fw_path)

            reset_target(scope)
            target.flush()

            cw.program_target(scope, prog, fw_path)

            glitches = []
            glitches.append([
                "[isogeny", "scope.glitch.width", "scope.glitch.offset",
                "scope.glitch.repeat", "scope.glitch.ext_offset",
                "good/bad/crash]"
            ])

            # The response took 4846257 cycles : 1. isogeny computation
            # -O0
            # ext_offset = 4846257
            # -O3
            ext_offset = 90082

            wrong = 0
            crashes = 0

            setDefault(scope)

            test = 5639046 - 10
            width = -49
            for i in range(0, NTRIAL):
                test = test + 1
                width = width + 3

                reset_target(scope)
                target.flush()

                # The response took 4846257 cycles : 1. isogeny computation
                # -O0
                # ext_offset = 4846257
                # -O3
                ext_offset = 90082

                if (GLITCH):
                    #isogeny = random.randint(1, 2)
                    isogeny = 1

                    if (isogeny == 1):
                        setGlitch(scope)

                        # The width of a single glitch pulse, as a percentage of one period.
                        # One pulse can range from -49.firmware/csidh/attack2_D_14052020_2028_m1_1.csv8% to roughly 49.8% of a period.
                        # The system may not be reliable at 0%. Note that negative widths are allowed;
                        # these act as if they are positive widths on the other half of the clock cycle.
                        # scope.glitch.width = random.randint(-49, 49)
                        scope.glitch.width = -9

                        # The offset from a rising clock edge to a glitch pulse rising edge,
                        # as a percentage of one period.
                        # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge,
                        # allowing glitches to be swept over the entire clock cycle.
                        # scope.glitch.offset = random.randint(-49, 49)
                        scope.glitch.offset = -38.3

                        # How long the glitch module waits between a trigger and a glitch.
                        # After the glitch module is triggered, it waits for a number of clock cycles
                        # before generating glitch pulses. This delay allows the glitch to be inserted
                        # at a precise moment during the target’s execution to glitch specific instructions.
                        scope.glitch.ext_offset = random.randint(1, ext_offset)
                        #scope.glitch.ext_offset = 57248

                        # The number of glitch pulses to generate per trigger.
                        # When the glitch module is triggered, it produces a number of pulses
                        # that can be combined with the clock signal. This setting allows for
                        # the glitch module to produce stronger glitches (especially during voltage glitching).
                        # Repeat counter must be in the range [1, 255].
                        #scope.glitch.repeat = random.randint(1, 5)
                        scope.glitch.repeat = 3

                print(
                    "\n--------------------------------\nstarting capture " +
                    str(i) +
                    "\n--------------------------------\ncapture of 1. isogeny  : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 10
                scope.arm()
                scope.adc.timeout = 10
                target.write("s")
                #time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                #time.sleep(5)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                #print("<output>\n" + response + "\n</output>")

                print("end of 1. isogeny : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                setDefault(scope)

                # The response took 3436390 cycles : 2. isogeny computation
                # -O0
                # response_time = 3436390
                # -O380392
                ext_offset = 60817547

                if (GLITCH):

                    if (isogeny == 2):
                        setGlitch(scope)

                        # The width of a single glitch pulse, as a percentage of one period.
                        # One pulse can range from -49.8% to roughly 49.8% of a period.
                        # The system may not be reliable at 0%. Note that negative widths are allowed;
                        # these act as if they are positive widths on the other half of the clock cycle.
                        # scope.glitch.width = random.randint(-49, 49)
                        scope.glitch.width = -9

                        # The offset from a rising clock edge to a glitch pulse rising edge,
                        # as a percentage of one period.
                        # A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge,
                        # allowing glitches to be swept over the entire clock cycle.
                        # scope.glitch.offset = random.randint(-49, 49)
                        scope.glitch.offset = -38.3

                        # How long the glitch module waits between a trigger and a glitch.
                        # After the glitch module is triggered, it waits for a number of clock cycles
                        # before generating glitch pulses. This delay allows the glitch to be inserted
                        # at a precise moment during the target’s execution to glitch specific instructions.
                        scope.glitch.ext_offset = random.randint(1, ext_offset)
                        #scope.glitch.ext_offset = 5393209 + (i*2)
                        #scope.glitch.ext_offset = 8050242

                        # The number of glitch pulses to generate per trigger.
                        # When the glitch module is triggered, it produces a number of pulses
                        # that can be combined with the clock signal. This setting allows for
                        # the glitch module to produce stronger glitches (especially during voltage glitching).
                        # Repeat counter must be in the range [1, 255].
                        #scope.glitch.repeat = random.randint(1, 5)
                        scope.glitch.repeat = 3
                        #scope.glitch.repeat = 1

                print(
                    "\n--------------------------------\ncapture of 2. isogeny : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 10
                scope.arm()
                scope.adc.timeout = 10
                target.write("n")
                #time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                time.sleep(1)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                #print("<output>\n" + response + "\n</output>")

                print("end of 2. isogeny : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                setDefault(scope)

                print(
                    "\n--------------------------------\nstarting capture of result : "
                    + datetime.datetime.now().strftime("%H:%M:%S"))
                scope.adc.timeout = 10
                scope.arm()
                scope.adc.timeout = 10
                target.write("n")
                time.sleep(0.1)

                ret = scope.capture()
                if ret:
                    print('Timeout happened during acquisition')

                #time.sleep(10)

                if SCOPETYPE == "OPENADC":
                    response_time = scope.adc.trig_count
                    print("The response took {} cycles".format(response_time))
                response = target.read(timeout=0)
                print("<output>\n" + response + "\n</output>")

                print("end of capture " + str(i) + " : " +
                      datetime.datetime.now().strftime("%H:%M:%S") +
                      "\n--------------------------------")

                if (GLITCH):
                    if "good" not in response:
                        # Something abnormal happened
                        if len(response) > 0:
                            # Possible glitch!
                            print(
                                "\nBad shared secret\nGlitching isogeny {} at offset {} and repeat = {}"
                                .format(isogeny, scope.glitch.ext_offset,
                                        scope.glitch.repeat))
                            wrong = wrong + 1
                            glitches.append([
                                isogeny, scope.glitch.width,
                                scope.glitch.offset, scope.glitch.repeat,
                                scope.glitch.ext_offset, "bad"
                            ])

                        else:
                            # Crash, reset and try again
                            print(
                                "\nProbably crashed at isogeny {} at {} and repeat = {}"
                                .format(isogeny, scope.glitch.ext_offset,
                                        scope.glitch.repeat))
                            crashes = crashes + 1
                            glitches.append([
                                isogeny, scope.glitch.width,
                                scope.glitch.offset, scope.glitch.repeat,
                                scope.glitch.ext_offset, "crash"
                            ])
                    else:
                        print(
                            "\nGood shared secret\nGlitching isogeny {} at offset {} and repeat = {}"
                            .format(isogeny, scope.glitch.ext_offset,
                                    scope.glitch.repeat))
                        glitches.append([
                            isogeny, scope.glitch.width, scope.glitch.offset,
                            scope.glitch.repeat, scope.glitch.ext_offset,
                            "good"
                        ])

            glitches.append(["-----------------------------"])
            glitches.append(["ntrial, wrong, crashes"])
            glitches.append([NTRIAL, wrong, crashes])

            PATH = "attack2_D_" + datetime.datetime.now().strftime(
                "%d%m%Y_%H%M") + ".csv"

            # save raw data as csv
            with open(PATH, mode='w') as csv_file:
                csv_writer = csv.writer(csv_file)
                for entry in glitches:
                    csv_writer.writerow(entry)

        scope.dis()
        target.dis()
Beispiel #9
0
import chipwhisperer as cw

SCOPETYPE = 'OPENADC'
PLATFORM = 'CWLITEXMEGA'
CRYPTO_TARGET = 'AVRCRYPTOLIB'

from Setup_Generic import Setup

scope, prog, target = Setup(PLATFORM)

fw_path = '../simpleserial-aes-CWLITEXMEGA.AVRLIB.hex'  #Firmware

cw.program_target(scope, prog, fw_path)

import chipwhisperer.analyzer as cwa
import matplotlib.pyplot as plt
import progressbar
from csv import writer

ktp = cw.ktp.Basic()
ktp.fixed_key = False

leak_model = cwa.leakage_models.sbox_output

num_traces = 10


def append_list_as_row(file, item):
    with open(file, 'a+', newline='') as write_obj:
        csv_writer = writer(write_obj)
        csv_writer.writerow(item)
Beispiel #10
0
import chipwhisperer as cw

scope = cw.scope()
target = cw.target(scope)
scope.default_setup()

prog = cw.programmers.STM32FProgrammer
cw.program_target(scope, prog, "image-demo-CWLITEARM.hex")

line = ""
while True:
    print(target.read(), end="")