As of August 2020 the site you are on (wiki.newae.com) is deprecated, and content is now at rtfm.newae.com.

Difference between revisions of "Tutorial B3-1 Timing Analysis with Power for Password Bypass"

From ChipWhisperer Wiki
Jump to: navigation, search
(Basic Communications with the Target: Split up tutorial into more sections; minor edits)
 
(56 intermediate revisions by 5 users not shown)
Line 1: Line 1:
This tutorial will introduce you to breaking devices by determining when a device is performing certain operations. It will use a simple password check, and demonstrate how to perform a basic power analysis.
+
{{Warningbox|This tutorial has been updated for ChipWhisperer 5 release. If you are using 4.x.x or 3.x.x see the "V4" or "V3" link in the sidebar.}}
  
In addition this example shows you how to drive the ChipWhisperer software with a script, rather than using the GUI. This will be required when attacking new devices which you have not yet added to the core ChipWhisperer software.
+
{{Infobox tutorial
 +
|name                  = B3-1 Timing Analysis with Power for Password Bypass
 +
|image                  =
 +
|caption                =
 +
|software versions      =
 +
|capture hardware      = CW-Lite, CW-Lite 2-Part, CW-Pro
 +
|Target Device          =
 +
|Target Architecture    = XMEGA/Arm
 +
|Hardware Crypto        = No
 +
|Purchase Hardware      =
 +
}}
  
Note this is not a prerequisite to the tutorial on breaking AES. You can skip this tutorial if you wish to go ahead with the AES tutorial.
+
<!-- To edit this, edit Template:Tutorial_boilerplate -->
 +
{{Tutorial boilerplate}}
  
You can also view a 53-min [https://www.youtube.com/watch?v=h4eAU6vEONs&hd=1 Video Version on YouTube]:
+
* Jupyter file: '''PA_SPA_1-Timing_Analysis_with_Power_for_Password_Bypass.ipynb'''
  
= Prerequisites =
 
  
You should have already completed tutorialtimingsimple to gain a better understanding of the ChipWhisperer interface.
+
== XMEGA Target ==
  
= Building the Target Firmware =
+
See the following for using:
 +
* ChipWhisperer-Lite Classic (XMEGA)
 +
* ChipWhisperer-Lite Capture + XMEGA Target on UFO Board (including NAE-SCAPACK-L1/L2 users)
 +
* ChipWhisperer-Pro + XMEGA Target on UFO Board
  
The target firmware is located in the directory <code>chipwhisperer\hardware\victims\firmware\basic-passwdcheck</code>. Build the firmware using <code>make</code>, once again being careful to ensure you have modified the <code>makefile</code> to select the correct target. You should end up with something like this being printed:
+
https://chipwhisperer.readthedocs.io/en/latest/tutorials/pa_spa_1-openadc-cwlitexmega.html#tutorial-pa-spa-1-openadc-cwlitexmega
  
<pre>Creating Symbol Table: basic-passwdcheck.sym
+
== ChipWhisperer-Lite ARM / STM32F3 Target ==
avr-nm -n basic-passwdcheck.elf &gt; basic-passwdcheck.sym
+
  
Size after:
+
See the following for using:
AVR Memory Usage
+
* ChipWhisperer-Lite 32-bit (STM32F3 Target)
----------------
+
* ChipWhisperer-Lite Capture + STM32F3 Target on UFO Board (including NAE-SCAPACK-L1/L2 users)
Device: atxmega128d3
+
* ChipWhisperer-Pro + STM32F3 Target on UFO Board
  
Program:   5400 bytes (3.9% Full)
+
https://chipwhisperer.readthedocs.io/en/latest/tutorials/pa_spa_1-openadc-cwlitearm.html#tutorial-pa-spa-1-openadc-cwlitearm
(.text + .data + .bootloader)
+
  
Data:        524 bytes (6.4% Full)
+
== ChipWhisperer Nano Target ==
(.data + .bss + .noinit)
+
  
 +
See the following for using:
 +
* ChipWhisperer-Nano
  
Built for platform CW-Lite XMEGA
+
https://chipwhisperer.readthedocs.io/en/latest/tutorials/pa_spa_1-cwnano-cwnano.html#tutorial-pa-spa-1-cwnano-cwnano
 
+
-------- end --------</pre>
+
= Manual Communications with the Target =
+
 
+
At this point, you should be able to configure the target as in the previous tutorials. Rather than tediously going through the setup process again, we'll simply use one of the scripts built into the ChipWhisperer-Capture software. This will demonstrate how we can use a script as a starting point to simplify our setup.
+
 
+
<ol style="list-style-type: decimal;">
+
<li>Connect your target hardware (ChipWhisperer-Lite or ChipWhisperer-Capture Rev 2 with target board).</li>
+
<li>Open the ChipWhisperer-Capture software.</li>
+
<li>From the ''Example Scripts'', select one which most closely matches your hardware. For example here I'm using a ChipWhisperer-Lite with the XMEGA target, so will select that script. Note I'm ''NOT'' attacking AES, so will need to make some adjustments later. .. image:: /images/tutorials/basic/timingpowerbasic/scriptexample.png</li>
+
<li>The system should connect to your hardware. Remember you have not yet reprogrammed the target so won't be communicating with the target program.</li>
+
<li>Using the programming tool (such as XMEGA programming dialog), program the file <code>basic-passwdcheck.hex</code> into the target device. This file is located where you ran <code>make</code> previously.</li>
+
<li><p>Select ''Tools --&gt; Open Terminal'', and press ''Connect''. You should see a window such as this:</p>
+
<blockquote><p>[[File:Termconn.png|image]]</p></blockquote></li>
+
<li><p>At this point we need to reset the target device. The easiest way to do this is use the programmer interface, and press the ''Check Signature'' or ''Read Signature'' button. This will reset the target device as part of the signature read operation. You should see some messages come across the terminal emulator window:</p>
+
<blockquote><p>[[File:Checksig_print.png|image]]</p></blockquote>
+
<dl>
+
<dt>Note a few warnings about the terminal emulator:</dt>
+
<dd><ul>
+
<li>The on-board buffer is fairly small, and can be easily overflowed. You may notice a few longer lines become trunicated if printing is too fast!</li>
+
<li>You can uncheck the &quot;Show non-ASCII as hex&quot; to avoid having the <code>0a</code> printed in red. The <code>0a</code> is the hex character for a newline. Many protocols use non-ASCII characters, so to help with debugging it is left enabled by default.</li></ul>
+
</dd></dl>
+
</li>
+
<li><p>We've now got some super-secure system! Let's begin with some exploratory tests - in this case I happened to know the correct password is <code>h0px3</code>.</p>
+
<blockquote><p>'''tip'''</p>
+
<p>In real systems, you may often know ''one'' of the passwords, which is sufficient to investigate the password checking routines as we will do. You also normally have an ability to reset passwords to default. While the reset procedure would erase any data you care about, the attacker will be able to use this 'sacrificial' device to learn about possible vulnerabilites. So the assumption that we have access to the password is really just saying we have access to ''a'' password, and will use that knowledge to break the system in general.</p></blockquote></li>
+
<li><p>Using the terminal emulator, write the correct password in, and press <code>&lt;enter&gt;</code>. You should be greeted by a welcome message, and if using the CW-Lite XMEGA target the green LED will illuminate:</p>
+
<p>[[File:Passok.png|image]]</p></li>
+
<li>The system enters an infinite loop for any password entry. Thus you must reset the system, use the ''Programmer Window'' to again perform a ''Check Signature'' or ''Read Signature'' operation.</li>
+
<li>Enter an incorrect password - notice a different message is printed, and if using the CW-Lite XMEGA target the red LED will come on.</li></ol>
+
 
+
 
+
= Recording Power Traces =
+
Now that we can communicate with our super-secure system, our next goal is to get a power trace while the target is running. To do this, we'll get the power measurements to trigger after we send our password to the target.
+
 
+
<ol style="list-style-type: decimal;">
+
<li><p>We'll make some changes to the trigger setup of the ChipWhisperer. In particular, ensure you set the following:</p>
+
<blockquote><ul>
+
<li>Offset = 0</li>
+
<li>Timeout set to 5 seconds or greater (to give yourself time when manually testing)</li></ul>
+
 
+
<p>[[File:Timeout_offset.png|image]]</p></blockquote></li>
+
<li><p>Change to the ''Target Settings'' tab, and delete the ''Command'' strings. Those strings are used in the AES attack to send a specific command to the target device, for now we will be manually sending data:</p>
+
<blockquote><p>[[File:Text_targetsettings.png|image]]</p></blockquote></li>
+
 
+
<li><p>Perform the following actions:</p>
+
<blockquote><ol style="list-style-type: lower-roman;">
+
<li>Reset the target device (e.g. by performing the signature check).</li>
+
<li>Enter the password <code>h0px3</code> in the terminal window, but ''do not'' yet hit enter.</li>
+
<li>Press the ''Capture 1'' button, and immediately switch to the terminal emulator window and press <code>&lt;enter&gt;</code> to send the password.</li></ol>
+
</blockquote>
+
<p>You must send the password before the timeout occurs -- you can increase the length of the timeout if needed to give yourself more time! If this works you should see the power consumption displayed in the GUI:</p>
+
<blockquote><p>[[File:Trace_manual_pass.png|image]]</p></blockquote></li>
+
 
+
<li><p>Rather than using the manual terminal, let's now use the GUI to automatically send a password try. Switching back to the ''Target Settings'' tab, write <code>h0px3\n</code> into the ''Go Command'' option:</p>
+
<blockquote><p>[[File:Gocorrect.png|image]]</p></blockquote>
+
<p>The ''Go Command'' is sent right after the scope is armed. In this example it means we can capture the power consumption during the password entry phase.</p></li>
+
<li><p>Now perform the following actions:</p>
+
<blockquote><ol style="list-style-type: lower-roman;">
+
<li>Reset the target device (e.g. by performing the signature check).</li>
+
<li>Press the ''Capture 1'' button.</li></ol>
+
</blockquote>
+
<p>Hopefully this resulted in the same waveform as before! Note the device takes around 1 second to 'boot', so if you are too lightning fast after resetting the device it won't actually be ready to accept the password. You can keep the terminal emulator window open to view the output data.</p></li>
+
<li><p>Play around with the password entered on the ''Go Command'' - try all of the following:</p>
+
<ul>
+
<li><code>h0px3\n</code></li>
+
<li><code>h0px4\n</code></li>
+
<li><code>h0paa\n</code></li>
+
<li><code>haaaa\n</code></li>
+
<li><code>a\n</code></li></ul>
+
 
+
<p>You should notice a distinct change in the password depending how many characters were correct. For example the following shows the difference between passwords of <code>h0px4</code> (which has 4 correct characters) and <code>h0paa</code> (which has 3 correct characters):</p>
+
<blockquote><p>[[File:3vs4.png|image]]</p></blockquote></li></ol>
+
 
+
 
+
 
+
= Automatic Resets =
+
The last step before scripting an entire attack is to figure out how to automatically reset the target device before (or after) each capture. There are two ways to do this, and the following steps take you through two examples of how to accomplish this goal.
+
 
+
== Reset via Spare IO Lines ==
+
 
+
TODO - see reset via programming interface for now
+
 
+
== Reset via Programming Interface ==
+
 
+
The following example targets the ChipWhisperer-Lite XMEGA target. You can modify it for ChipWhisperer-Lite AVR target by replacing <code>XMEGA</code> with <code>AVR</code> in the function calls. We'll first learn how to recreate the process of pressing the ''Check Signature'' button via the API. This isn't normally exposed, but we can explore that using the Python Console.
+
 
+
<ol style="list-style-type: decimal;">
+
<li><p>Type <code>self</code> into the Python console, the output will look like this:</p>
+
<pre>&gt;&gt;&gt; self
+
&lt;__main__.ChipWhispererCapture object at 0x072F25F8&gt;</pre>
+
<p>This tells us that the class type of this opject is <code>ChipWhispererCapture</code>. We can open the source code for that class, and determine where the &quot;scope&quot; is stored. This takes some effort the first time through, but eventually you would discover there is a <code>self.scope</code>.</p>
+
<p>Type <code>self.scope</code> into the Python console:</p>
+
<pre>&gt;&gt;&gt; self.scope
+
&lt;chipwhisperer.capture.scopes.OpenADC.OpenADCInterface object at 0x0D4986C0&gt;</pre>
+
<p>Opening the file <code>chipwhisperer\capture\scopes\OpenADC.py</code> would tell us that <code>.scopetype</code> is used to store the next level of the interface. We want to reach very far down to get to the AVR/XMEGA programmer interface, so will continue down the rabbit hole:</p>
+
<pre>&gt;&gt;&gt; self.scope.scopetype 
+
&lt;chipwhisperer.capture.scopes.OpenADC.OpenADCInterface_NAEUSBChip object at 0x0D5BC4B8&gt;</pre>
+
<p>Finally, checking the source for the <code>OpenADCInterface_NAEUSBChip</code> class in that same file gives us this source code:</p>
+
<pre>...code...
+
self.cwliteXMEGA = XMEGAProgrammerDialog(global_mod.main_window)
+
 
+
self.xmegaProgramAct = QAction('CW-Lite XMEGA Programmer', self,
+
                              statusTip='Open XMEGA Programmer (ChipWhisperer-Lite Only)',
+
                              triggered=self.cwliteXMEGA.show)
+
 
+
self.cwliteAVR = AVRProgrammerDialog(global_mod.main_window)
+
...code...</pre>
+
<p>We can finally try reaching out and touching the XMEGA or AVR programmer:</p>
+
<pre>&gt;&gt;&gt; self.scope.scopetype.cwliteXMEGA
+
&lt;chipwhisperer.capture.utils.XMEGAProgrammer.XMEGAProgrammerDialog object at 0x0D5BC670&gt;</pre>
+
<p>This allows us to touch the XMEGA programmer dialog directly. At this point you can refer to the file <code>chipwhisperer\capture\utils\XMEGAProgrammer.py</code> to confirm the class interface. Part of this will be the <code>readSignature()</code> function, which we can try running:</p>
+
<pre>&gt;&gt;&gt; self.scope.scopetype.cwliteXMEGA.readSignature()</pre>
+
<p>Success! You should see the terminal emulator print the startup message, indicating the target was rebooted.</p></li>
+
<li><p>Now we need to understand how to force this to be called. This can be done via the ''Auxiliary Modules'', which we used in the previous part to toggle an IO line. Instead we will define one through the command prompt, before finally using it in a custom script.</p>
+
<p>At the console, type the following to import some require modules (ignore the &gt;&gt;&gt; which just indicate the console prompt):</p>
+
<pre>&gt;&gt;&gt; from time import sleep
+
&gt;&gt;&gt; from chipwhisperer.capture.auxiliary.AuxiliaryTemplate import AuxiliaryTemplate</pre></li>
+
<li><p>We will now define a simple <code>reset_device()</code> function. You will do this interactively at the console, the objective being to enter the following chunk of code:</p>
+
<pre>def reset_device():
+
    self.scope.scopetype.cwliteXMEGA.readSignature()
+
    sleep(0.8)</pre>
+
<p>Remember Python is ''whitespace sensitive'', so you'll have to be careful with indents in use. To being with, simply type <code>def reset_device():</code> at the console and press enter. You'll notice the <code>&gt;&gt;&gt;</code> changes to <code>...</code> at the console prompt:</p>
+
<blockquote><p>[[File:Consoledotdot.png|image]]</p></blockquote>
+
<p>Now you will enter the next two lines. Remember you must insert at least one space before each line, and it must be consistent between the two lines entered. Once you enter the last line, press enter and the <code>...</code> should change back to <code>&gt;&gt;&gt;</code></p>
+
<blockquote><p>[[File:Consolespace.png|image]]</p></blockquote></li>
+
<li>Check you can run <code>reset_device()</code> at the console and the device resets. If there is an error check you've run the import statements previously and for other typos. Re-run the <code>def reset_device():</code> step if required.</li>
+
<li><p>Now we need to define the class which links the function to a step in the capture. To do so, we want to define the following:</p>
+
<pre>class resetClass(AuxiliaryTemplate):
+
  def traceDone(self):
+
  reset_device()</pre>
+
<p>Pay very careful attention to the indentation -- when entering via the command line, we need to ensure <code>def traceDone(self):</code> has one level of indents, and <code>reset_device()</code> has additional indent. You can use a single space if you want for one-level, and two spaces for two-levels for example:</p>
+
<pre>&gt;&gt;&gt; class resetClass(AuxiliaryTemplate):
+
...  def traceDone(self):
+
...  reset_device()</pre></li>
+
<li><p>Finally, generate an object using that class, and confirm it again resets the device:</p>
+
<pre>&gt;&gt;&gt; rc = resetClass()
+
&gt;&gt;&gt; rc.traceDone()</pre></li>
+
<li><p>Now all that is left is to link this class into the Auxiliary interface. This is done simply with the following call:</p>
+
<pre>&gt;&gt;&gt; self.auxChanged(rc)</pre>
+
<p><code>auxChanged()</code> is called with the new Auxiliary module to be loaded (or list of modules). The <code>traceDone()</code> method will be called once a single trace is done.</p></li>
+
<li>Confirm you can press ''Capture 1'' in the GUI without needing to manually reset the XMEGA target device. Play around with the password to again see the effect of changing password length. In particular, start to consider where you might look for an indicator about how far in the loop you can go? Play around with 0 correct digits, 1 correct digits, etc.</li></ol>
+
 
+
= Scripting Communications =
+
 
+
<ol style="list-style-type: decimal;">
+
<li>Make a copy of the existing script. You can find it at <code>chipwhisperer\software\chipwhisperer\capture\scripts</code>, for example the default one is called <code>cwlite-simpleserialxmega.py</code> for the XMEGA device. Copy this to another directory that you will use for the attack.</li>
+
<li><p>Rename the script something else - for example <code>cwlite-passwordcrack.py</code>, and open it for editing. You'll notice the following is a main chunk of the code, where the parameters are set:</p>
+
<pre>#Example of using a list to set parameters. Slightly easier to copy/paste in this format
+
lstexample = [['CW Extra', 'CW Extra Settings', 'Trigger Pins', 'Target IO4 (Trigger Line)', True],
+
              ['CW Extra', 'CW Extra Settings', 'Target IOn Pins', 'Target IO1', 'Serial RXD'],
+
              ['CW Extra', 'CW Extra Settings', 'Target IOn Pins', 'Target IO2', 'Serial TXD'],
+
              ['OpenADC', 'Clock Setup', 'CLKGEN Settings', 'Desired Frequency', 7370000.0],
+
              ['CW Extra', 'CW Extra Settings', 'Target HS IO-Out', 'CLKGEN'],
+
              ['OpenADC', 'Clock Setup', 'ADC Clock', 'Source', 'CLKGEN x4 via DCM'],
+
              ['OpenADC', 'Trigger Setup', 'Total Samples', 3000],
+
              ['OpenADC', 'Trigger Setup', 'Offset', 1500],
+
              ['OpenADC', 'Gain Setting', 'Setting', 45],
+
              ['OpenADC', 'Trigger Setup', 'Mode', 'rising edge'],
+
              #Final step: make DCMs relock in case they are lost
+
              ['OpenADC', 'Clock Setup', 'ADC Clock', 'Reset ADC DCM', None],
+
              ]</pre>
+
<p>Those parameters come from the ''Scripting Parameters'' tab. Switch over to it and notice how when you change the text for example, it tells you the required parameter name to do this via the API call:</p>
+
<blockquote><p>[[File:Scriptcommands.png|image]]</p></blockquote>
+
<p>Note that commands run via the script are also printed, so you can see where the values being set are coming from too. At this point close the ''ChipWhisperer-Capture'' window, as we will confirm the script still works.</p></li>
+
<li><p>Run the new script (which doesn't have any changes yet). You may have to open a console with Python in the path:</p>
+
<blockquote><ol style="list-style-type: lower-roman;">
+
<li>If you installed WinPython, run the ''WinPython Console'' from your WinPython installation directory.</li>
+
<li>If using the VMWare image of a Linux machine, this should just be a regular console</li></ol>
+
</blockquote></li></ol>
+
 
+
<blockquote>Run the script with <code>python cwlite-passwordcrack.py</code>. If the script errors out, it might be that the location of the FPGA bitstream is stored in relative terms. To fix this perform the following:
+
 
+
<blockquote><ol style="list-style-type: lower-roman;">
+
<li>Open ChipWhisperer-Capture regularly.</li>
+
<li>Run the ChipWhisperer script that you used previously.</li>
+
<li>Select ''Tools--&gt;Config CW Firmware''</li>
+
<li>Under the &quot;FPGA .zip (Release)&quot;, hit the &quot;Find&quot; button. Point the system to the file <code>chipwhisperer/hardware/capture/chipwhisperer-lite/cwlite_firmware.zip</code> on your filesystem. Note by default there is a relative path.</li></ol>
+
</blockquote></blockquote>
+
<ol start="4" style="list-style-type: decimal;">
+
<li>Once again on the ''Target Settings'' tab, delete the various commands. Note the resulting ''Script Commands'' which you will need to enter to achieve this same goal.</li>
+
<li>Close ChipWhisperer-Capture.</li>
+
<li><p>Edit the script, first find the line setting the Trigger Offset:</p>
+
<pre>['OpenADC', 'Trigger Setup', 'Offset', 1500],</pre>
+
<p>And set this to 0, which we were using previously:</p>
+
<pre>['OpenADC', 'Trigger Setup', 'Offset', 0],</pre></li>
+
<li><p>Next, append the required commands to clear the simpleserial commands:</p>
+
<pre>#Example of using a list to set parameters. Slightly easier to copy/paste in this format
+
lstexample = [['CW Extra', 'CW Extra Settings', 'Trigger Pins', 'Target IO4 (Trigger Line)', True],
+
              ...BUNCH MORE COMMANDS HERE HAVE BEEN REMOVED...
+
              #Final step: make DCMs relock in case they are lost
+
              ['OpenADC', 'Clock Setup', 'ADC Clock', 'Reset ADC DCM', None],
+
 
+
              #Append your commands here
+
              ['Target Connection', 'Load Key Command', u''],
+
              ['Target Connection', 'Go Command', u''],
+
              ['Target Connection', 'Output Format', u''],                     
+
              ]</pre></li>
+
<li><p>Next, we are going to &quot;hack in&quot; the Auxiliary module. While the following isn't great Python code, the idea is to demonstrate how we can rapidly iterate with the combination of GUI to explore options, and the script to write them into place. First, add the imports to the start of the Python script:</p>
+
<pre>from time import sleep
+
from chipwhisperer.capture.auxiliary.AuxiliaryTemplate import AuxiliaryTemplate</pre>
+
<p>Find the section of the file that sends the previous commands to the hardware. You will see a line like the following:</p>
+
<pre>#Download all hardware setup parameters
+
for cmd in lstexample: cap.setParameter(cmd)</pre>
+
<p>We will then hack in the script we tested previously, which will insert our custom Auxiliary module:</p>
+
<pre>#Download all hardware setup parameters
+
for cmd in lstexample: cap.setParameter(cmd)
+
 
+
def reset_device():
+
    cap.scope.scopetype.cwliteXMEGA.readSignature()
+
    sleep(0.8)
+
 
+
class resetClass(AuxiliaryTemplate):
+
  def traceDone(self):
+
  reset_device()
+
 
+
rc = resetClass()
+
cap.auxChanged(rc)</pre>
+
<p>Note we changed the references to &quot;self&quot; to &quot;cap&quot;, as we are no longer running from within the Capture environment. Otherwise we have used the ability of Python to declare classes inside of functions to avoid needing to think about how to properly declare everything.</p></li>
+
<li><p>Finally, we will set the password. You can enter the password in the Capture ''Target Settings'' tab, and see the following sort of call would set the appropriate password:</p>
+
<pre>cap.setParameter(['Target Connection', 'Go Command', u'h0px3\\n'])</pre>
+
<p>Note the newline is actually escaped, to set the text equivalent of what will be printed. This will result in an actual newline going out across the serial port.</p>
+
<p>Set that command at some point after your call to <code>cap.auxChanged()</code>. Close any open ChipWhisperer-Capture windows, and run the script as before. You should connect to the target, and be able to press ''Capture 1'' and see the correct waveform.</p></li>
+
<li><p>Next, we will automatically start attacking the system. You needed to figure out where we will look to determine if the password check is working. Looking at an example of the power when 0 and 1 bytes are correct, we can see a good point that appears to shift forward in time:</p>
+
<blockquote><p>[[File:Passwordcrackerpts.png|image]]</p></blockquote>
+
<p>This point corresponds to an offset of 153 samples, and a delta for each character of 72 points. Note the specific point will change for different hardware, and may also change if you use different versions of avr-gcc to compile the target code. The example code here was compiled with WinAVR 20100110, which has avr-gcc 4.3.3. If you view the video version of this tutorial the point numbers are different for example, so be sure to check what they are for your specific system.</p>
+
<p>Let's start with cracking just the first character, assuming it's a lowercase alphanumeric character:</p>
+
<pre>trylist = &quot;abcdefghijklmnopqrstuvwyx0123456789&quot;
+
 
+
for c in trylist:
+
    cap.setParameter(['Target Connection', 'Go Command', u'%c\\n'%c])
+
    cap.capture1()
+
 
+
    #TODO: Check data to see if successful??
+
    print &quot;Try = %c&quot;%c
+
 
+
    #Call to pe() causes GUI to process outstanding events, useful if you are calling API directly
+
    pe()</pre></li>
+
<li>We haven't yet pragmatically tested the results, but run the script anyway (to kill it, you'll have to use Ctrl-C on the terminal window). You should notice a distinct change of the power signature when it runs through &quot;Try = h&quot;.</li>
+
<li><p>We can access <code>cap.scope.datapoints</code> to get the data points. Let's print that point of interest (again change the point for your specific setup):</p>
+
<pre>for c in trylist:
+
    cap.setParameter(['Target Connection', 'Go Command', u'%c\\n'%c])
+
    cap.capture1()
+
 
+
    #TODO: Check data to see if successful??
+
    print &quot;Try = %c&quot;%c
+
    print cap.scope.datapoints[153]
+
 
+
    #Call to pe() causes GUI to process outstanding events, useful if you are calling API directly
+
    pe()</pre></li>
+
<li><p>Running that example, you can see we can use a simple threshold to detect the correct password. Finally use the following paying careful attention that you first:</p>
+
<blockquote><ul>
+
<li>Check the offset and delta values (here they are 153 and 72)</li>
+
<li>Note that the &quot;Go Command&quot; has been modified to send the known password characters, otherwise it won't work in a progressive manner.</li></ul>
+
</blockquote>
+
<p>The following is a sample code you can replace the previous with:</p>
+
<pre>password = &quot;&quot;
+
 
+
for i in range(0,5):
+
    print &quot;***CHARACTER %d***&quot;%i
+
    for c in trylist:
+
        cap.setParameter(['Target Connection', 'Go Command', password + &quot;%c\\n&quot;%c])
+
        cap.capture1()
+
 
+
        print &quot;Try = %c&quot;%c
+
        #print cap.scope.datapoints[153 + i*72]
+
        if cap.scope.datapoints[153 + i*72] &gt; -0.2:
+
            print &quot;****CHARACTER %d = %c****&quot;%(i, c)
+
            password += c
+
            break
+
 
+
        elif c == &quot;9&quot;:
+
            print &quot;****CHARACTER %d FAILED****&quot;%(i)
+
            password += &quot;?&quot;
+
 
+
        #Call to pe() causes GUI to process outstanding events, useful if you are calling API directly
+
        pe()   
+
 
+
print password</pre></li></ol>
+
 
+
That's it! You should have successfully cracked a password using the timing attack. Some notes on this method:
+
 
+
<blockquote>* The target device has a finite start-up time, which slows down the attack. If you wish, remove some of the printf()'s from the target code, recompile and reprogram, and see how quickly you can do this attack.
+
* The current script doesn't look for the &quot;WELCOME&quot; message when the password is OK. That is an extension that allows it to crack any size password.
+
* If there was a lock-out on a wrong password, the system would ignore it, as it resets the target after every attempt.
+
</blockquote>
+
= Conclusion =
+
 
+
This tutorial has demonstrated the use of the power side-channel for performing timing attacks. A target with a simple password-based security system is broken. In addition you have learned about the scripting support in the ChipWhisperer-Capture software.
+
 
+
[[Category:Tutorial]]
+

Latest revision as of 05:08, 29 July 2019

This tutorial has been updated for ChipWhisperer 5 release. If you are using 4.x.x or 3.x.x see the "V4" or "V3" link in the sidebar.

B3-1 Timing Analysis with Power for Password Bypass
Target Architecture XMEGA/Arm
Hardware Crypto No
Software Release V3 / V4 / V5

This tutorial will introduce you to measuring the power consumption of a device under attack. It will demonstrate how you can view the difference between assembly instructions. In ChipWhisperer 5 Release, the software documentation is now held outside the wiki. See links below.

To see background on the tutorials see the Tutorial Introduction on ReadTheDocs, which explains what the links below mean. These wiki pages (that you are reading right now) only hold the hardware setup required, and you have to run the Tutorial via the Jupyter notebook itself. The links below take you to the expected Jupyter output from each tutorial, so you can compare your results to the expected/known-good results.

Running the tutorial uses the referenced Jupyter notebook file.

  • Jupyter file: PA_SPA_1-Timing_Analysis_with_Power_for_Password_Bypass.ipynb


XMEGA Target

See the following for using:

  • ChipWhisperer-Lite Classic (XMEGA)
  • ChipWhisperer-Lite Capture + XMEGA Target on UFO Board (including NAE-SCAPACK-L1/L2 users)
  • ChipWhisperer-Pro + XMEGA Target on UFO Board

https://chipwhisperer.readthedocs.io/en/latest/tutorials/pa_spa_1-openadc-cwlitexmega.html#tutorial-pa-spa-1-openadc-cwlitexmega

ChipWhisperer-Lite ARM / STM32F3 Target

See the following for using:

  • ChipWhisperer-Lite 32-bit (STM32F3 Target)
  • ChipWhisperer-Lite Capture + STM32F3 Target on UFO Board (including NAE-SCAPACK-L1/L2 users)
  • ChipWhisperer-Pro + STM32F3 Target on UFO Board

https://chipwhisperer.readthedocs.io/en/latest/tutorials/pa_spa_1-openadc-cwlitearm.html#tutorial-pa-spa-1-openadc-cwlitearm