CWNano unknown state

Hi,
I have recently bought a ChipWhisperer Nano to try some basic stuff about capture and glitch. I was able to finish the major tutorials with not much problems.
It’s been 2 days, the CW Nano stopped to work 99% of the time. If i try to launch the past tutorials, i have a failure at the moment to capture the trace. USB Error (Errno 110 ‘No Error’) or USB Error (Errno None 'error sending control message: Broken pipe). Another bug pop at the connection to the CW Nano, USB Error (Errno None 'error sending control message: No such device).
I have a 1% of the time, the CW Nano lets me capture some traces.
I tried to use the CW Nano through VirtualBox on MacOS and Windows host, and on MacOS, natively. Each time, the same errors. I also flash the CW Nano with several versions but nothing has changed.
I’m wondering if i broke something :confused:

Hi,

I’ve typically seen that broken pipe error when Python gets interrupted when sending/receiving data from the ChipWhisperer, though there could be other things that could put the ChipWhipserer in that state. If you see an error like that, often the best method to fix it is to unplug+replug.

You said you’ve flashed the Nano with new firmware. Which firmware version is that (you should be able to tell by calling scope.fw_version)? Additionally, you said you’ve tried using the ChipWhisperer via VirtualBox. Are you using the VM image from our Github? If so, which version of the VM image are you using?

Alex

Hi Alex,
Thanks for the answer. The scope.fw_version of my Nano is 0.23.0 and i’m using the VM image from the ChipWhisperer Github. It’s the latest version 5.4.

Hi,

Can you post a stack trace of these various errors?

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)
~/work/projects/chipwhisperer/jupyter/courses/sca101/Lab 2_1B - Power Analysis for Password Bypass (HARDWARE).ipynb in
1 #Example - capture ‘h’ - end with newline ‘\n’ as serial protocol expects that
----> 2 trace_h = cap_pass_trace(“h\n”)
3
4 print(trace_h)
5

~/work/projects/chipwhisperer/jupyter/courses/sca101/Lab 2_1B - Power Analysis for Password Bypass (HARDWARE).ipynb 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


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)
in
1 if VERSION == ‘HARDWARE’:
----> 2 get_ipython().run_line_magic(‘run’, ‘“Lab 2_1B - Power Analysis for Password Bypass (HARDWARE).ipynb”’)
3 elif VERSION == ‘SIMULATED’:
4 get_ipython().run_line_magic(‘run’, ‘“Lab 2_1B - Power Analysis for Password Bypass (SIMULATED).ipynb”’)

~/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/IPython/core/interactiveshell.py in run_line_magic(self, magic_name, line, _stack_depth)
2324 kwargs[‘local_ns’] = sys._getframe(stack_depth).f_locals
2325 with self.builtin_trap:
-> 2326 result = fn(*args, **kwargs)
2327 return result
2328

in run(self, parameter_s, runner, file_finder)

~/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/IPython/core/magic.py in (f, *a, **k)
185 # but it’s overkill for just that one bit of state.
186 def magic_deco(arg):
–> 187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):

~/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/IPython/core/magics/execution.py in run(self, parameter_s, runner, file_finder)
716 with preserve_keys(self.shell.user_ns, ‘file’):
717 self.shell.user_ns[‘file’] = filename
–> 718 self.shell.safe_execfile_ipy(filename, raise_exceptions=True)
719 return
720

~/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/IPython/core/interactiveshell.py in safe_execfile_ipy(self, fname, shell_futures, raise_exceptions)
2801 result = self.run_cell(cell, silent=True, shell_futures=shell_futures)
2802 if raise_exceptions:
-> 2803 result.raise_error()
2804 elif not result.success:
2805 break

~/.pyenv/versions/3.6.7/envs/cw/lib/python3.6/site-packages/IPython/core/interactiveshell.py in raise_error(self)
329 raise self.error_before_exec
330 if self.error_in_exec is not None:
–> 331 raise self.error_in_exec
332
333 def repr(self):

[... skipping hidden 1 frame]

in
1 #Example - capture ‘h’ - end with newline ‘\n’ as serial protocol expects that
----> 2 trace_h = cap_pass_trace(“h\n”)
3
4 print(trace_h)
5

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

Alright, I think what’s happening here is that PyUSB is using the wrong USB backend library. Can you run the following before the problem lines?

import logging
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)

then send the example.log?

Alex

Actually, I think even better here would be to go into the VM and run:

sudo apt install libusb-1.0.0-dev

It appears that Debian comes with libusb0, but not libusb1.

Alex

I’ve found a workaround for the issue:

Go to hardware/victims/firmware/basic-passwdcheck/basic-passwdcheck.c and remove the print statements from the beginning of main().

Alex

It turns out the response buffer on the nano only was fixed at 128 bytes instead of being determined by the uart buffer size. A workaround is now in the newest ChipWhisperer, limiting nano serial reads to 128 bytes. The issue will be fixed on the nano in a future firmware update.

The USB lib didn’t fix the problem but remove the print statements does. Thanks a lot !