{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Upgrade your firmware (to do only once per CWlite target)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the following code, and wait until you see \"Bootloader disabled. Please power cycle device\". Then unplug your CW then plug it again. The CWlite should then visible again in the VM (USB port)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "ERROR:ChipWhisperer Scope:ChipWhisperer error state detected. Resetting and retrying connection...\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Entering bootloader mode...\n", " Please wait until the ChipWhisperer shows up as a serial port. Once it has, call\n", " the program(COMPORT, FWPATH) to program the ChipWhisperer\n", "\n", " Default firmware can be found at chipwhisperer/hardware/capture/chipwhisperer-lite/sam3u_fw/SAM3U_VendorExample/Debug/SAM3U_CW1173.bin\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mscope\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcw\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscope\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mprog\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcw\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSAMFWLoader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mscope\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mscope\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauto_program\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/work/projects/chipwhisperer/software/chipwhisperer/capture/scopes/cwhardware/ChipWhispererSAM3Update.py\u001b[0m in \u001b[0;36mauto_program\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 196\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcandidate\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 198\u001b[0;31m \u001b[0mafter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mserial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlist_ports\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcomports\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 199\u001b[0m \u001b[0mafter\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mafter\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[0mcandidate\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbefore\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m^\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mafter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m&\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mafter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# make sure we only grab the serial ports from after\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/pyserial-3.5-py3.7.egg/serial/tools/list_ports_linux.py\u001b[0m in \u001b[0;36mcomports\u001b[0;34m(include_links)\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0mdevices\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_ports_common\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlist_links\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevices\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 101\u001b[0m return [info\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mSysFS\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0md\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdevices\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 103\u001b[0m if info.subsystem != \"platform\"] # hide non-present internal serial ports\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/pyserial-3.5-py3.7.egg/serial/tools/list_ports_linux.py\u001b[0m in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0mdevices\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_ports_common\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlist_links\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevices\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 101\u001b[0m return [info\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mSysFS\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0md\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdevices\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 103\u001b[0m if info.subsystem != \"platform\"] # hide non-present internal serial ports\n\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/pyserial-3.5-py3.7.egg/serial/tools/list_ports_linux.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, device)\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 22\u001b[0;31m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSysFS\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 23\u001b[0m \u001b[0;31m# special handling for links\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdevice\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mislink\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/pyserial-3.5-py3.7.egg/serial/tools/list_ports_common.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, device, skip_link_detection)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterface\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0;31m# special handling for links\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mskip_link_detection\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mdevice\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mislink\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 53\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhwid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'LINK={}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrealpath\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/lib/python3.7/posixpath.py\u001b[0m in \u001b[0;36mislink\u001b[0;34m(path)\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[0;34m\"\"\"Test whether a path is a symbolic link\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 170\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 171\u001b[0;31m \u001b[0mst\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlstat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 172\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mOSError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 173\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "import chipwhisperer as cw\n", "scope = cw.scope()\n", "prog = cw.SAMFWLoader(scope=scope)\n", "prog.auto_program()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If your upgrade did not work (or seems to), you can run the following block. \n", "Do not forget to unplug the CWlite and plug it again, it should b" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Auto scan for device failed\n", "Try specifying a serial port with the '-p' option\n" ] }, { "ename": "CalledProcessError", "evalue": "Command 'b'cd ../../../../BOSSA\\nsudo bin/bossac -e -w -v -b ../work/projects/chipwhisperer/hardware/capture/chipwhisperer-lite/sam3u_fw/SAM3U_VendorExample/Debug/SAM3U_CW1173.bin\\n'' returned non-zero exit status 1.", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mCalledProcessError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mget_ipython\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_cell_magic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'bash'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'cd ../../../../BOSSA\\nsudo bin/bossac -e -w -v -b ../work/projects/chipwhisperer/hardware/capture/chipwhisperer-lite/sam3u_fw/SAM3U_VendorExample/Debug/SAM3U_CW1173.bin\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_cell_magic\u001b[0;34m(self, magic_name, line, cell)\u001b[0m\n\u001b[1;32m 2397\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuiltin_trap\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2398\u001b[0m \u001b[0margs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mmagic_arg_s\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2399\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2400\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2401\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/IPython/core/magics/script.py\u001b[0m in \u001b[0;36mnamed_script_magic\u001b[0;34m(line, cell)\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 141\u001b[0m \u001b[0mline\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mscript\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 142\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshebang\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 143\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 144\u001b[0m \u001b[0;31m# write a basic docstring:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/decorator.py\u001b[0m in \u001b[0;36mfun\u001b[0;34m(*args, **kw)\u001b[0m\n\u001b[1;32m 230\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mkwsyntax\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkw\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkw\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 232\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcaller\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mextras\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 233\u001b[0m \u001b[0mfun\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 234\u001b[0m \u001b[0mfun\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__doc__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__doc__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/IPython/core/magic.py\u001b[0m in \u001b[0;36m\u001b[0;34m(f, *a, **k)\u001b[0m\n\u001b[1;32m 185\u001b[0m \u001b[0;31m# but it's overkill for just that one bit of state.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 186\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmagic_deco\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 187\u001b[0;31m \u001b[0mcall\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 188\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.pyenv/versions/3.7.7/envs/cw/lib/python3.7/site-packages/IPython/core/magics/script.py\u001b[0m in \u001b[0;36mshebang\u001b[0;34m(self, line, cell)\u001b[0m\n\u001b[1;32m 243\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflush\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 244\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_error\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreturncode\u001b[0m\u001b[0;34m!=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 245\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mCalledProcessError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreturncode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstderr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 246\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 247\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_run_script\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mto_close\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mCalledProcessError\u001b[0m: Command 'b'cd ../../../../BOSSA\\nsudo bin/bossac -e -w -v -b ../work/projects/chipwhisperer/hardware/capture/chipwhisperer-lite/sam3u_fw/SAM3U_VendorExample/Debug/SAM3U_CW1173.bin\\n'' returned non-zero exit status 1." ] } ], "source": [ "%%bash \n", "cd ../../../../BOSSA\n", "sudo bin/bossac -e -w -v -b ../work/projects/chipwhisperer/hardware/capture/chipwhisperer-lite/sam3u_fw/SAM3U_VendorExample/Debug/SAM3U_CW1173.bin" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Firmware Build Setup\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial will introduce you to the software side of ChipWhisperer, including the tutorials themselves. It will also show you how to perform different operations on data based on input from the ChipWhisperer software. This can be used for building your own system which you wish to 'break'. All the `%%bash` blocks can be run either in Jupyter or in your favourite command line environment (note that Jupyter resets your path between blocks).\n", "\n", "If you haven't run through `TME1_preliminaries_introduction_to_Jupyter.ipynb` do that now.\n", "\n", "Assuming you've done that, we can get started on the tutorial." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "SCOPETYPE = 'OPENADC'\n", "PLATFORM = 'CWLITEXMEGA'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What is SimpleSerial" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SimpleSerial is the communications protocol used for almost all of the ChipWhisperer demo project. It's a very basic serial protocol which can be easily implemented on most systems. This system communicates using a standard asyncronous serial protocol, 38400 baud, 8-N-1.\n", "\n", "All messages are sent in ASCII-text, and are normally terminated with a line-feed (`'\\n'`). This allows you to interact with the simpleserial system over a standard terminal emulator.\n", "\n", "`x`\n", "\n", "> Sending a 'x' resets the buffers. This does not require a line-feed termination. It is suggested to always send a stream of x's to initilize the system in case the device was already in some other mode due to noise/corruption.\n", "\n", "`k00112233445566778899AABBCCDDEEFF\\n`\n", "\n", "> Loads the encryption key `00112233445566778899AABBCCDDEEFF` into the system. If not called the system may use some default key.\n", "\n", "`pAABBCCDDEEFF00112233445566778899\\n`\n", "\n", "> Encrypts the data `AABBCCDDEEFF00112233445566778899` with the last key loaded with the 'k' command. The system will respond with a string starting with r, as shown next.\n", "\n", "`rCBBD4A2B34F2571758FF6A797E09859D\\n`\n", "\n", "> This is the response from the target system. If data encryption has been required with a 'p', the target system will respond with the 'r' sequence after the encryption has been done. So sending the earlier example means the result of the encryption was `cbbd4a2b34f2571758ff6a797e09859d`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Building the Basic Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To bulid the basic example, you'll need an appropriate compiler for your target. For the ChipWhisperer Lite/Xmega platform, you'll need `avr-gcc` and `avr-libc`. If you're unsure that it is installed, you can run the block below: if it is correctly installed, you should see some version and copyright info printed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%bash\n", "#check for avr-gcc\n", "avr-gcc --version" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that you have the relevant toolchain installed, you should be able to build firmware for your platform. We'll begin by creating a new project based on simpleserial-base by making a new firmware and copying the files from the project we want to work on:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%bash\n", "cd ../hardware/victims/firmware/\n", "mkdir -p simpleserial-base-lab1 && cp -r simpleserial-base/* $_\n", "cd simpleserial-base-lab1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we'll build the firmware. You'll need to specify the `PLATFORM` and `CRYPTO_TARGET` for your target to the `make` command.\n", "\n", "This tutorial doesn't use any crypto, so we can leave `CRYPTO_TARGET` as `NONE`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "CRYPTO_TARGET = \"NONE\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You should be able to successfully run the block below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%bash -s \"$PLATFORM\" \"$CRYPTO_TARGET\"\n", "cd ../hardware/victims/firmware/simpleserial-base-lab1\n", "make PLATFORM=$1 CRYPTO_TARGET=$2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Modifying the Basic Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At this point we want to modify the system to perform 'something' with the data, such that we can confirm the system is working. To do so, open the file `simpleserial-base.c` in the `simpleserial-base-lab1` folder with a code editor of your choice, you can also edit it in your navigator since all the files from the directory read by jupyter notebook are avaibable. However, in this last case, pay attention that you have saved your changes !\n", "\n", "Find the following code block towards the end of the file:\n", "\n", "```C\n", "/**********************************\n", " * Start user-specific code here. */\n", "trigger_high();\n", "\n", "//16 hex bytes held in 'pt' were sent\n", "//from the computer. Store your response\n", "//back into 'pt', which will send 16 bytes\n", "//back to computer. Can ignore of course if\n", "//not needed\n", "\n", "trigger_low();\n", "/* End user-specific code here. *\n", "```\n", "\n", "Now modify the code to increment the value of each data byte:\n", "\n", "```C\n", "/**********************************\n", " * Start user-specific code here. */\n", "trigger_high();\n", "\n", "//16 hex bytes held in 'pt' were sent\n", "//from the computer. Store your response\n", "//back into 'pt', which will send 16 bytes\n", "//back to computer. Can ignore of course if\n", "//not needed\n", "\n", "for(int i = 0; i < 16; i++){\n", " pt[i]++;\n", "}\n", "\n", "trigger_low();\n", "/* End user-specific code here. *\n", " ********************************/\n", "```\n", "\n", "Then rebuild the file with `make`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%bash -s \"$PLATFORM\" \"$CRYPTO_TARGET\"\n", "cd ../hardware/victims/firmware/simpleserial-base-lab1\n", "make PLATFORM=$1 CRYPTO_TARGET=$2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python Script" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll end by uploading the firmware onto the target and communicating with it via a python script. Depending on your target, uploading firmware will be different. For the XMega target, you can use the ChipWhisperer's interface. After running the final block, you should see two sets of hexadecimal numbers, with the second having values one higher than the first." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll begin by importing the ChipWhisperer module. This will allow us to connect to and communicate with the ChipWhisperer hardware. The ChipWhisperer module also includes analysis software, which we'll be looking at in later tutorials." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import chipwhisperer as cw" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Documentation is available on [ReadtheDocs](https://chipwhisperer.readthedocs.io/en/latest/api.html) or by calling `help()` on the module, submodule, function, etc.:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "help(cw)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we'll need to connect to the scope end of the hardware. Starting with ChipWhisperer 5.1, `cw.scope` will attempt to autodetect which scope type you have (though if you have multiple ChipWhisperers connected, you'll need to specify the serial number). If you'd like, you can still specify the scope type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scope = cw.scope()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "help(scope)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll also need to setup the interface to the target (typically what we want to attack). Like with scopes, there's a few different interfaces we can use, which are available through `scope.targets.`. The default, SimpleSerial, communicates over UART and is almost always the correct choice." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "target = cw.target(scope, cw.targets.SimpleSerial)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we'll do some basic setup. Most of these settings don't matter for now, but take note of the `scope.clock` and `scope.io`, which setup the clock and serial io lines, which needs to be done before programming the target. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# setup scope parameters\n", "scope.gain.db = 45\n", "scope.adc.samples = 3000\n", "scope.adc.offset = 1250\n", "scope.adc.basic_mode = \"rising_edge\"\n", "scope.clock.clkgen_freq = 7370000\n", "scope.clock.adc_src = \"clkgen_x4\"\n", "scope.trigger.triggers = \"tio4\"\n", "scope.io.tio1 = \"serial_rx\"\n", "scope.io.tio2 = \"serial_tx\"\n", "scope.io.hs2 = \"clkgen\"\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or, more simply:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scope.default_setup()\n", "print(scope.connectStatus)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that the clock and IO lines are setup, we can program the target. ChipWhisperer includes a generic programming function, `cw.program_target(scope, type, fw_path)`. Here `type` is one of the programmers available in the cw.programmers submodule (`help(cw.programmers)` for more information). `fw_path` is the path to the hex file that you want to flash onto the device.\n", "\n", "The final part of the binary path should match your platform (`/simpleserial-base-CWLITEXMEGA.hex`)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prog = cw.programmers.XMEGAProgrammer\n", " \n", "fw_path = '../hardware/victims/firmware/simpleserial-base-lab1/simpleserial-base-{}.hex'.format(PLATFORM)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And finally actually programming the device:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cw.program_target(scope, prog, fw_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we'll load some text, send it to the target, and read it back. We also capture a trace here, but don't do anything with it yet (that will come in later tutorials). You should see your original text with the received text below it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ktp = cw.ktp.Basic() # object to generate fixed/random key and text (default fixed key, random text)\n", "key, text = ktp.next() # get our fixed key and random text as bytearrays as used by SimpleSerial protocol\n", "\n", "target.simpleserial_write('k', key)\n", "target.simpleserial_wait_ack()\n", "scope.arm()\n", "\n", "target.simpleserial_write('p', text)\n", " \n", "ret = scope.capture()\n", "trace = scope.get_last_trace()\n", "output = target.simpleserial_read('r', 16)\n", "print(\"output: \", output) # print output which is a byte array\n", "print(\"send text: \", text) # print text which is a byte array\n", "print(\"captured trace of \", len(trace), \" samples\", trace) # print trace which is a ndarray\n", "\n", "print(\"send text:\", text.hex()) # print as a text string\n", "print(\"send key:\", key.hex()) # print as a text string\n", "print(\"received data:\", output.hex())\n", "\n", "from binascii import hexlify # print hexadecimal representation of the binary data.\n", "print(\"text:\" , hexlify(text))\n", "print(\"output:\", hexlify(output)) \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also just run the following code and use the \"trace\" returned by `capture_trace()` which is different from the one we get using `scope.get_last_trace()`. It contains all the data (`textin`, `textout`, `key` and also the `wave` than contains the measurements) :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ret = cw.capture_trace(scope, target, text, key) \n", "if ret:\n", " trace = ret\n", " print(\"key: \", hexlify(trace.key))\n", " print(\"textin: \", hexlify(trace.textin))\n", " print(\"textout: \" ,hexlify(trace.textout))\n", " print(\"trace: \" , trace.wave)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can change the text sent by generating a new one without changing the key :" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "key, text = ktp.next() # keep our fixed key and generate new random text as bytearrays as used by SimpleSerial protocol\n", "ret = cw.capture_trace(scope, target, text, key)\n", "if ret:\n", " trace = ret\n", " print(\"key: \", hexlify(trace.key))\n", " print(\"textin: \", hexlify(trace.textin))\n", " print(\"textout: \" ,hexlify(trace.textout))\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can plot the trace using matplotlib: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib notebook\n", "import matplotlib.pyplot as plt\n", "plt.figure()\n", "plt.plot(trace.wave)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can you identify the 16 iterations of the loop ? if not, declare you iteration variable as volatile in the C code and follow the different steps until here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we're done with this tutorial, we'll need to disconnect from the ChipWhisperer. This will prevent this session from interferening from later ones (most notably with a `USB can't claim interface` error). Don't worry if you forget, unplugging and replugging the ChipWhipserer should fix it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scope.dis()\n", "target.dis()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Future Tutorials" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next tutorials that you run will start using helper scripts to make setup a little faster and more consistent between tutorials. Those scripts run mostly the same setup code that we did here, but if you'd like to see exactly what they're doing, they're all included in the `Helper_Scripts` folder.\n", "\n", "For example, the scope setup (gain, clock, etc) is taken care of by `Helper Scripts/Setup_Generic.ipynb`." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }