Lab 2_1B - Power Analysis Graph Wrong CWNano

Hello,

I am new here, so sorry if I am missing something obvious. I am using the CWNano to run though the Lab 2_1B - Power Analysis for Password Bypass.

Everything is running and completing the way I would expect, except the power graph does not look like the example and I can not get traces to overlap they way they should.

I am running the latest VM and working out of the jupyter/courses/sca101 folder.

It should look like this according to the documentation:

But this is what I get:

I even tried capturing two traces sending the same letter expecting to get overlap:

trace_h = cap_pass_trace("h\n")
trace_h2 = cap_pass_trace("h\n")
#print(trace_h)

%matplotlib notebook
import matplotlib.pylab as plt

plt.figure()
plt.plot(trace_h, 'r')
plt.plot(trace_h2, 'b')
plt.show()

But zooming in it seems there is a good bit of noise and slight trigger variance.

Image removed. (New user, can only post one image right now)

I even copied the solution exactly from here and ran it getting the same noisy graph above without the activity easily distinguishable.
https://chipwhisperer.readthedocs.io/en/latest/tutorials/courses_sca101_soln_lab%202_1b%20-cwnano-cwnano.html#tutorial-courses-sca101-soln-lab-2-1b-cwnano-cwnano

I searched through the documentation for the API on the nano, I thought I might be able to tune the gain or something that might help, but discovered the nano didn’t have the gain feature (understandably) due to the stripped down board.

Any help clearing up the traces would be greatly appreciated! Thanks :slight_smile:

Here is the zoomed in image I wanted to include in the first post but couldn’t due to being a new user.

Based on your graph, I’d definitely say something’s not running on the target side. Can you verify that the firmware works as expected:

  1. If you reset the target (set scope.io.nrst = 0, then set scope.io.nrst=None), does the target print a message on startup?
  2. If you input the correct password ('h0px3'), does the device respond with "Access granted, Welcome"?
  3. Do you get any messages about the scope timing out?

Alex

Thank you very much for the help!

Either I am failing to pull serial from the target properly to it does indeed seem to not be running properly.

Ran the following to make sure the target was successfully programmed:

SCOPETYPE = 'CWNANO'
PLATFORM = 'CWLITEARM'
SS_VER = 'SS_VER_1_1'

%run "../../Setup_Scripts/Setup_Generic.ipynb"

Output:

Serial baud rate = 38400
INFO: Found ChipWhisperer😍

Input:

%%bash -s "$PLATFORM" "$SS_VER"
cd ../../../hardware/victims/firmware/basic-passwdcheck
make PLATFORM=$1 CRYPTO_TARGET=NONE SS_VER=$2

Output:

SS_VER set to SS_VER_1_1
rm -f -- basic-passwdcheck-CWLITEARM.hex
rm -f -- basic-passwdcheck-CWLITEARM.eep
rm -f -- basic-passwdcheck-CWLITEARM.cof
rm -f -- basic-passwdcheck-CWLITEARM.elf
rm -f -- basic-passwdcheck-CWLITEARM.map
rm -f -- basic-passwdcheck-CWLITEARM.sym
rm -f -- basic-passwdcheck-CWLITEARM.lss
rm -f -- objdir/*.o
rm -f -- objdir/*.lst
rm -f -- basic-passwdcheck.s simpleserial.s stm32f3_hal.s stm32f3_hal_lowlevel.s stm32f3_sysmem.s
rm -f -- basic-passwdcheck.d simpleserial.d stm32f3_hal.d stm32f3_hal_lowlevel.d stm32f3_sysmem.d
rm -f -- basic-passwdcheck.i simpleserial.i stm32f3_hal.i stm32f3_hal_lowlevel.i stm32f3_sysmem.i
.
Welcome to another exciting ChipWhisperer target build!!
arm-none-eabi-gcc (15:5.4.1+svn241155-1) 5.4.1 20160919
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

.
Compiling C: basic-passwdcheck.c
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/basic-passwdcheck.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/basic-passwdcheck.o.d basic-passwdcheck.c -o objdir/basic-passwdcheck.o 
.
Compiling C: .././simpleserial/simpleserial.c
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/simpleserial.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/simpleserial.o.d .././simpleserial/simpleserial.c -o objdir/simpleserial.o 
.
Compiling C: .././hal/stm32f3/stm32f3_hal.c
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/stm32f3_hal.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/stm32f3_hal.o.d .././hal/stm32f3/stm32f3_hal.c -o objdir/stm32f3_hal.o 
.
Compiling C: .././hal/stm32f3/stm32f3_hal_lowlevel.c
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/stm32f3_hal_lowlevel.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/stm32f3_hal_lowlevel.o.d .././hal/stm32f3/stm32f3_hal_lowlevel.c -o objdir/stm32f3_hal_lowlevel.o 
.
Compiling C: .././hal/stm32f3/stm32f3_sysmem.c
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/stm32f3_sysmem.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/stm32f3_sysmem.o.d .././hal/stm32f3/stm32f3_sysmem.c -o objdir/stm32f3_sysmem.o 
.
Assembling: .././hal/stm32f3/stm32f3_startup.S
arm-none-eabi-gcc -c -mcpu=cortex-m4 -I. -x assembler-with-cpp -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -DF_CPU=7372800 -Wa,-gstabs,-adhlns=objdir/stm32f3_startup.lst -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ .././hal/stm32f3/stm32f3_startup.S -o objdir/stm32f3_startup.o
.
Linking: basic-passwdcheck-CWLITEARM.elf
arm-none-eabi-gcc -mcpu=cortex-m4 -I. -mthumb -mfloat-abi=soft -fmessage-length=0 -ffunction-sections -gdwarf-2 -DSS_VER=SS_VER_1_1 -DSTM32F303xC -DSTM32F3 -DSTM32 -DDEBUG -DHAL_TYPE=HAL_stm32f3 -DPLATFORM=CWLITEARM -DF_CPU=7372800UL -DSS_VER_2_0=2 -DSS_VER_1_1=1 -DSS_VER_1_0=0 -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/basic-passwdcheck.o -I.././simpleserial/ -I.././hal -I.././hal/stm32f3 -I.././hal/stm32f3/CMSIS -I.././hal/stm32f3/CMSIS/core -I.././hal/stm32f3/CMSIS/device -I.././hal/stm32f4/Legacy -I.././crypto/ -std=gnu99  -MMD -MP -MF .dep/basic-passwdcheck-CWLITEARM.elf.d objdir/basic-passwdcheck.o objdir/simpleserial.o objdir/stm32f3_hal.o objdir/stm32f3_hal_lowlevel.o objdir/stm32f3_sysmem.o objdir/stm32f3_startup.o --output basic-passwdcheck-CWLITEARM.elf --specs=nano.specs --specs=nosys.specs -T .././hal/stm32f3/LinkerScript.ld -Wl,--gc-sections -lm -Wl,-Map=basic-passwdcheck-CWLITEARM.map,--cref   -lm  
.
Creating load file for Flash: basic-passwdcheck-CWLITEARM.hex
arm-none-eabi-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature basic-passwdcheck-CWLITEARM.elf basic-passwdcheck-CWLITEARM.hex
.
Creating load file for EEPROM: basic-passwdcheck-CWLITEARM.eep
arm-none-eabi-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex basic-passwdcheck-CWLITEARM.elf basic-passwdcheck-CWLITEARM.eep || exit 0
.
Creating Extended Listing: basic-passwdcheck-CWLITEARM.lss
arm-none-eabi-objdump -h -S -z basic-passwdcheck-CWLITEARM.elf > basic-passwdcheck-CWLITEARM.lss
.
Creating Symbol Table: basic-passwdcheck-CWLITEARM.sym
arm-none-eabi-nm -n basic-passwdcheck-CWLITEARM.elf > basic-passwdcheck-CWLITEARM.sym
Size after:
   text	   data	    bss	    dec	    hex	filename
   5672	    108	   1188	   6968	   1b38	basic-passwdcheck-CWLITEARM.elf
+--------------------------------------------------------
+ Default target does full rebuild each time.
+ Specify buildtarget == allquick == to avoid full rebuild
+--------------------------------------------------------
+--------------------------------------------------------
+ Built for platform CW-Lite Arm \(STM32F3\) with:
+ CRYPTO_TARGET = NONE
+ CRYPTO_OPTIONS = AES128C
+--------------------------------------------------------

Input:

cw.program_target(scope, prog, "../../../hardware/victims/firmware/basic-passwdcheck/basic-passwdcheck-{}.hex".format(PLATFORM))

Output:

Serial baud rate = 115200
Detected known STMF32: STM32F03xx4/03xx6
Extended erase (0x44), this can take ten seconds or more
Attempting to program 5779 bytes at 0x8000000
STM32F Programming flash...
STM32F Reading flash...
Verified flash OK, 5779 bytes
Serial baud rate = 38400

I continued with defining the cap_pass_trace and testing just to verify:

def cap_pass_trace(pass_guess):
    reset_target(scope)
    num_char = target.in_waiting()
    while num_char > 0:
        target.read(num_char, 10)
        time.sleep(0.01)
        num_char = target.in_waiting()

    scope.arm()
    target.write(pass_guess)
    ret = scope.capture()
    if ret:
        print('Timeout happened during acquisition')

    trace = scope.get_last_trace()
    return trace

scope.adc.samples = 3000

trace_test = cap_pass_trace("h\n")

#Basic sanity check
assert(len(trace_test) == 3000)
print("✔️ OK to continue!")

Output:

✔️ OK to continue!

Then I ran the reset and tried to pull the serial

scope.io.nrst = 0
scope.io.nrst=None
recv_msg = ""
recv_msg += target.read()
print(recv_msg)

I got no response. I also tried running the target.read() several times after the reset just in case there was a delay that I was missing by doing the read right away. Still nothing.

Then I tried sending the correct password as you suggested with the following:

reset_target(scope)
target.write("h0px3\n")
time.sleep(0.01)
num_char = target.in_waiting()
recv_msg = ""
while num_char > 0:
    recv_msg += target.read(num_char, 10)
    time.sleep(0.01)
    num_char = target.in_waiting()
    
print(recv_msg)

Again no response. I even tried waiting a full second after sending the password and trying to read the response, still nothing.

The interesting thing is I did run though the hardware setup test notebook. I was able to program it and do the simple serial test, and got the mirror commands back. So I know I can program and pull serial from the target.

Maybe there is an issue with the firmware or the way I compiled it? I didn’t dig into the target code. I could start debugging it. I assumed since I didn’t change anything there, the firmware shipped with the course was fine and the problem must be on my side.

Thank you for the help! :slight_smile:

The issue here is that you need to set PLATFORM='CWNANO' instead of 'CWLITEARM'.

Alex

I thought that might have been the issue! I tried compiling and uploading with CWNANO for the platform but then the target wouldn’t connect and I was getting errors.

I think it may just be that it was in a weird state or I had another error somewhere.

After work today I will go back, start clean with the correct platform and report back.

Thank you for the help! I knew I was just doing something dumb! :slight_smile:

1 Like

Things are looking much better! Thank you!

I ran the following two traces to see how well they overlap and it’s looking good!

import time
trace_h = cap_pass_trace("h\n")
trace_h2 = cap_pass_trace("h\n")
#print(trace_h)

%matplotlib notebook
import matplotlib.pylab as plt

plt.figure()
plt.plot(trace_h, 'r')
plt.plot(trace_h2, 'b')
plt.show()

I figured out a workaround for the errors I am seeing, and I think it’s because I have to do something extra to reset the target each time I send it the password.

The following error is what I kept running into before and what keeps coming up if I try to communicate with the target a second time. For instance, if I send the above block of code a second time.

Traceback (most recent call last):
  File "/home/vagrant/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py", line 296, in txrx
    response = self.usbdev().ctrl_transfer(payload[0], payload[1], payload[2], payload[3], payload[4], timeout=self._timeout)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 1077, in ctrl_transfer
    self.__get_timeout(timeout))
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb0.py", line 609, in ctrl_transfer
    timeout
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb0.py", line 447, in _check
    raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] b'error sending control message: Broken pipe'
---------------------------------------------------------------------------
USBError                                  Traceback (most recent call last)
~/work/projects/chipwhisperer/software/chipwhisperer/capture/targets/SimpleSerial.py in read(self, num_char, timeout)
    239                 num_char = self.ser.inWaiting()
--> 240             return self.ser.read(num_char, timeout)
    241         except USBError:

~/work/projects/chipwhisperer/software/chipwhisperer/capture/targets/simpleserial_readers/_base.py in read(self, num, timeout)
    133         # If we didn't get enough data, try to read more from the hardware
--> 134         data = bytearray(self.hardware_read(num, timeout=timeout)).decode('latin-1')
    135         for c in data:

~/work/projects/chipwhisperer/software/chipwhisperer/capture/targets/simpleserial_readers/cwlite.py in hardware_read(self, num, timeout)
     80     def hardware_read(self, num, timeout=250):
---> 81         return self.cwlite_usart.read(num, timeout)

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/serial.py in read(self, dlen, timeout)
    185             if waiting > 0:
--> 186                 newdata = self._usb.readCtrl(self.CMD_USART0_DATA, 0, min(waiting, dlen))
    187                 resp.extend(newdata)

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in readCtrl(self, cmd, value, dlen)
    701         # Vendor-specific, IN, interface control transfer
--> 702         return self.usbseralizer.readCtrl(cmd, value, dlen)
    703 

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in readCtrl(self, cmd, value, dlen)
    187         cmdpacket = self.make_cmd(self.READ_CTRL, cmdpacket)
--> 188         return self.process_rx(self.txrx(tx=cmdpacket))
    189 

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in process_rx(self, inp)
    153         if resp == self.ERROR:
--> 154             raise payload
    155 

USBError: [Errno None] None

During handling of the above exception, another exception occurred:

Warning                                   Traceback (most recent call last)
<ipython-input-128-a9fa5eb8e085> in <module>
      2 
      3 import time
----> 4 trace_h = cap_pass_trace("h\n")
      5 trace_h2 = cap_pass_trace("h\n")
      6 #print(trace_h)

<ipython-input-119-addfe96922f3> in cap_pass_trace(pass_guess)
      3     num_char = target.in_waiting()
      4     while num_char > 0:
----> 5         target.read(num_char, 10)
      6         time.sleep(0.01)
      7         num_char = target.in_waiting()

~/work/projects/chipwhisperer/software/chipwhisperer/capture/targets/SimpleSerial.py in read(self, num_char, timeout)
    241         except USBError:
    242             self.dis()
--> 243             raise Warning("Error in target. It may have been disconnected")
    244         except Exception as e:
    245             self.dis()

Warning: Error in target. It may have been disconnected

Just by chance I realized if I rerun the setup script it will communicate again.

%run "../../Setup_Scripts/Setup_Generic.ipynb"

It was so very confusing because I would run the check block:

#
# DEFINE THE cap_pass_trace() function - either using a hardware connection or the file read-out.
#


trace_test = cap_pass_trace("h\n")

#Basic sanity check
assert(len(trace_test) == 3000)
print("✔️ OK to continue!")

And it would complete perfectly with no errors. Then I would go to run my capture code:

import time
trace_h = cap_pass_trace("h\n")
trace_h2 = cap_pass_trace("h\n")
#print(trace_h)

%matplotlib notebook
import matplotlib.pylab as plt

plt.figure()
plt.plot(trace_h, 'r')
plt.plot(trace_h2, 'b')
plt.show()

And get that error every time. I will continue investigating why it seems to stop responding. The cap_pass_trace calls reset_target(scope) in it but obviously the Setup_generic.ipynb script is doing more. I will keep debugging and figure out what the difference is and why it’s locking.

Thank you very much for the help! I am excited to continue learning and move forward with the courses!

Hello,

I have exactly the same problems with my nano.
The connection to the target gets lost each time.
Tought it would be a problem with the computer so I installed it on another one.
But get exactly the same error messages on it.

Did you find a solution?
I think there are more people strugeling with this issue!!

Thanks

I haven’t quite figured it out yet myself either. I have played around with a few things but nothing has been reliable yet.

I updated my capture function to print out what’s received:

def cap_pass_trace(pass_guess):
    reset_target(scope)
    num_char = target.in_waiting()
    recv_msg = ""
    while num_char > 0:
        recv_msg += target.read(num_char, 10)
        time.sleep(0.01)
        num_char = target.in_waiting()
    print("Received: ")
    print(recv_msg)

    scope.arm()
    target.write(pass_guess)
    ret = scope.capture()
    if ret:
        print('Timeout happened during acquisition')

    trace = scope.get_last_trace()
    return trace

trace_test = cap_pass_trace("h\n")

And then I get:

Received: 
*****Safe-o-matic 3000 Booting...
Aligning bits........[DONE]
Checking Cesium RNG..[DONE]
Masquerading flash...[DONE]
Decrypting database..[DONE]


WARNING: UNAUTHORIZED ACCESS WILL BE PUNISHED
Please enter password to continue: 
Traceback (most recent call last):
  File "/home/vagrant/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py", line 304, in txrx
    response = self.cmdReadMem(addr, dlen)
  File "/home/vagrant/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py", line 510, in cmdReadMem
    data = self.usbdev().read(self.rep, dlen, timeout=self._timeout)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 1009, in read
    intf, ep = self._ctx.setup_request(self, endpoint)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 113, in wrapper
    return f(self, *args, **kwargs)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 227, in setup_request
    self.managed_claim_interface(device, intf)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 113, in wrapper
    return f(self, *args, **kwargs)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 178, in managed_claim_interface
    self.backend.claim_interface(self.handle, i)
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb0.py", line 537, in claim_interface
    _check(_lib.usb_claim_interface(dev_handle, intf))
  File "/home/vagrant/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb0.py", line 447, in _check
    raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] b'could not claim interface 0: Device or resource busy'
---------------------------------------------------------------------------
USBError                                  Traceback (most recent call last)
<ipython-input-85-9b66d1a2bb4e> in <module>
      4 
      5 
----> 6 trace_test = cap_pass_trace("h\n")
      7 
      8 #Basic sanity check

<ipython-input-84-31de05ee44af> in cap_pass_trace(pass_guess)
     12     scope.arm()
     13     target.write(pass_guess)
---> 14     ret = scope.capture()
     15     if ret:
     16         print('Timeout happened during acquisition')

~/work/projects/chipwhisperer/software/chipwhisperer/capture/scopes/cwnano.py in capture(self)
    652                     return True
    653 
--> 654             self._lasttrace = self._cwusb.cmdReadMem(0, self.adc.samples)
    655 
    656             # can just keep rerunning this until it works I think

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in cmdReadMem(self, addr, dlen)
    708         """
    709 
--> 710         return self.usbseralizer.cmdReadMem(addr, dlen)
    711 
    712     def cmdWriteMem(self, addr, data):

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in cmdReadMem(self, addr, dlen)
    199         cmdpacket = self.make_cmd(self.CMD_READ_MEM, payload)
    200 
--> 201         return self.process_rx(self.txrx(tx=cmdpacket))
    202 
    203     def cmdWriteMem(self, addr, data):

~/work/projects/chipwhisperer/software/chipwhisperer/hardware/naeusb/naeusb.py in process_rx(self, inp)
    152 
    153         if resp == self.ERROR:
--> 154             raise payload
    155 
    156         return payload

USBError: [Errno None] None

Also, I never have issues when I program the wrong target. I think there is something weird going on when the target is responding.

There is a delay in the target code:

if (passbad){
            //Stop them fancy timing attacks
             int wait = rand() % 100000; //% 100000 can be removed for xmega
            for(volatile int i = 0; i < wait; i++){
                ;
            }
            delay_2_ms();
            delay_2_ms();
            my_puts("PASSWORD FAIL\n");
            led_error(1);
        } else {
            my_puts("Access granted, Welcome!\n");
            led_ok(1);
        }

But I am assuming that reset_target(scope) should be doing a hard reset of the target. Perhaps it’s not resetting correctly?

I think my next step is to hook up a scope and logic analyzer and see what is actually happening on the board. Only being able to monitor comms through the API is a bit frustrating, I would love to have had a terminal to monitor the target output.

I will update here though if I find any new insights.

This looks to be an issue reading ADC data back from the ChipWhisperer, so it shouldn’t have anything to do with the target.

How long does it take to program the target here, roughly? If it’s taking a long time (more than a minute), it might be due to a VirtualBox bug.

Alex

Hello Alex,

Programming the target takes only 5 to 6 seconds in my case.
For sure no more than a minute.

The only way that I sometimes succeed (1/10 chance) to get a trace is by putting the program in one straight line.
And not use the reset_target(scope) routine to reset but put the reset in the cap_pass_trace() routine like below. Because if there is a slight more delay between the reset and the capturing then there 0/10 chance.

%run "../../Setup_Scripts/Setup_Generic.ipynb

def cap_pass_trace(pass_guess):
    scope.io.nrst = 'low'
    time.sleep(0.05)
    scope.io.nrst = 'high_z'
    time.sleep(0.05)
    num_char = target.in_waiting()
    while num_char > 0:
        target.read(num_char, 10)
        time.sleep(0.01)
        num_char = target.in_waiting()

    scope.arm()
    target.write(pass_guess)
    ret = scope.capture()
    if ret:
        print('Timeout happened during acquisition')

    trace = scope.get_last_trace()
    return trace

scope.adc.samples = 5000

from tqdm.notebook import tqdm
plt.figure()
for c in tqdm('abcdefghijklmnopqrstuvwxyz0123456789'):
    trace = cap_pass_trace("h" + c + "\n")
    plt.plot(trace[0:500])"

Can you try changing the delay in https://github.com/newaetech/chipwhisperer/blob/develop/software/chipwhisperer/capture/scopes/cwnano.py#L649 (chipwhisperer/software/chipwhisperer/capture/scopes/cwnano.py line 649, in capture()) to a longer value (say 0.05) and seeing if that fixes things?

Alex

For that I need to be able to recompile and reprogram the capture side isn’t it?
I’m not capable yet to do that form out of jupyter! Just starting with it.
Just succeeded to bring the board in bootloader mode inside jupyter and update with the “cw_firmware_updater_5_4_0.exe” routine.
Was’nt able to find the right com port in Linux!

Nope, that’s just Python, so you just need to change the file, restart Python/Jupyter, and it should take effect.

I tried with 0.001 / 0.005 / 0.05 / 0.1 and restarted the VM each time.
But the result stays the same.


Warning Traceback (most recent call last)
in
----> 1 trace_test = cap_pass_trace(“h\n”)
2
3 #Basic sanity check
4 assert(len(trace_test) == 3000)
5 print(“:heavy_check_mark: OK to continue!”)

in cap_pass_trace(pass_guess)
3 num_char = target.in_waiting()
4 while num_char > 0:
----> 5 target.read(num_char, 10)
6 time.sleep(0.01)
7 num_char = target.in_waiting()

~/work/projects/chipwhisperer/software/chipwhisperer/capture/targets/SimpleSerial.py in read(self, num_char, timeout)
234 “”"
235 if not self.connectStatus:
–> 236 raise Warning(“Target not connected”)
237 try:
238 if num_char == 0:

Warning: Target not connected

I use Firefox 84.0.2 (64-bits) can that have to do something with it?

It’s very unlikely that firefox has anything to do with this. If you get the target disconnected error, it’s likely that there was a previous error that caused it to disconnect. Do you get another error message here as well?

Alex

No, there are no other error messages.
And if all is put in one straight line as mentioned above it sometimes works.
Seems like a timing problem between the reset and the capturing.
Short after the reset there is only a fraction of time before the connection gets lost.
If the capture starts in this fraction of time, it succeeds.

I’m guessing the issue here is that

Target not connected here doesn’t actually have anything to do with connections - it’s just a boolean that gets set to true when “connecting” to the target (which again doesn’t have anything to do with connections) and gets set to false for errors/calling target.dis(). I’m guessing the issue here is that you’re rerunning that block after the target has reported an error.

If you run into a target error, try calling target.con() before rerunning a block that uses the target. At the very least, it should give you a better error message

Alex