Hello vector,
We haven’t made the modification yet as we don’t have the part and the microsoldering tool, our soldering iron is way too big for this operation right now. I’ll come back to you when we have done it!
I have now compared my traces with the traces from the “simulated” lab and found that these do not show the significant negative drops I see in my traces. See below simulated traces on the left and the measurements from my Husky on the right:
Overall signal level seems to be lower as well, but that may be related to the reduced gain I applied in order to reduce the risk of running into errors (as @Shanly described above).
Other than the gain value, I use the standard startup and solution scripts. The CW reports VCCaux error at every startup, but it can be cleared and doesn’t return until the next restart.
Any suggestions what I can do to improve my setup?
I wouldn’t recommend trying to compare to the simulated labs, as they’re done with a completely different target (the STM32F3)
Thanks @Alex_Dewar, that makes sense. Is there a possibility that the VCCaux alarm has something to do with this behavior? I get the following reported when checking print(scope.errors)
at startup
XADC errors = VCCaux alarm,
ADC errors = False
extclk error = False
trace errors = False
Clearing with scope.XADC.status = 0
as defined in the docs seems to be successful.
Would anyone be able to share settings and a plot of traces of a successful run of Lab 3_3 with a v3 Husky?
I feel I have tried every possible setting and configuration in last six weeks and would like to make sure it is not a(nother) hardware issue.
The VCCaux alarm is sticky until you clear it. When does it happen? And what is the output of this when after it’s happened:
print(scope.XADC.get_vcc('vccaux', 'current'))
print(scope.XADC.get_vcc('vccaux', 'min'))
print(scope.XADC.get_vcc('vccaux', 'max'))
It’s not likely to be the cause for the issue you’re seeing, but it is curious.
What capacitor value did you use?
Try this notebook and report what you get for sad
and std
.
notebook.zip (1.9 KB)
Thanks @jpthibault. I really appreciate your support.
I am checking the scope.errors
right before starting to capture the traces, check the current value of VCCaux and then reset the error. Running scope.XADC.get_vcc('vccaux')
with a second argument (current, min, max) doesn’t work for some Python reason, reporting that the function receives three instead of one or two arguments.
Below my output:
XADC errors = VCCaux alarm,
ADC errors = False
extclk error = False
trace errors = False
1.806884765625
Running scope.XADC.status = 0 ...
Done
XADC errors = False
ADC errors = False
extclk error = False
trace errors = False
1.808349609375
Looks stable from my perspective, min
and max
would be helpful for sure. I will try to find the issue here.
The capacitor I used is a 100pF X7R 50V from a trusted source and the improvement on the CPA lab was quite significant, while for Lab 3_3 it is not visible.
I executed the notebook (had to adjust some paths to match my installation) and received the following output:
std = 24.10216651470951, (0.06469655183900855 scaled)
0.006814599609375
sad = 25.33721142578123
std = 24.10216651470951
I would love to say that I was smart enough to understand these values and draw my conclusions… but I am not. What can you read from this?
You must be using an older release; use the develop branch.
That’s in line with what we’ve seen.
You should be able to succeed with the DPA attack. Could be a ghost peak problem; could be more traces are needed.
Thanks @jpthibault.
With all other potential issues out of the way, I finally solved it:
It was indeed a ghost peak problem. With my limited experience in power analysis, I wasn’t aware of the magnitude of ghost peaks. What I formerly though was the AES algorithm and lead to significant spikes in the plot turned out to be something completely different. The actual AES spikes where hiding somewhere in the noise (the actual peak is at sample 1900 rather than 1250 or 4300).
With the full_diffs_list
plot in the Ghost Peaks chapter
fig = cw.plot()
for subkey in range(0, 16):
fig *= cw.plot(full_diffs_list[subkey][known_key[subkey]])
fig
I finally received the following result:
zooming in on the now colorful peaks:
Setting the following parameters before sampling helped me to window the correct range:
scope.adc.offset = 1800
scope.adc.samples = 900
Big thanks to the NewAE team for the great support and patience.
I have the Husky HWREV 1.1C, and need a lot more traces on Lab 3.3, as well as 4.2 compared to what’s mentioned in the notebook. Is adding the capacitor mentioned above a recommended solution?
Edit: When I change the ADC offset and samples as per above (to 1800 and 900 respectively), it seems Lab 4.2 actually works with only 50 traces. But I’m not sure why
The capacitor improved the performance of Lab 4_2 significantly in my case. For Lab 3_3 I didn’t see any improvement.
The values for offset and no of samples, i.e. start and duration of analyzed section, in Lab 3_3 in the example above were chosen to select exactly the shown 16 peaks and filter out the much larger ghost peaks at 1300 and 4300.
I would assume that due to the very similar timing of the target firmware in Lab 3_3 and 4_2, the time window of leakage might also be similar.
Thanks! Yes, that does make a lot of sense regarding the ADC parameters. I’ll consider making the HW changes then to see if there are any changes in the performance.
Hello,
Sorry for the delayed answer, we finally managed to perform the modification.
This happened when attempting to validate the hardware:
import chipwhisperer as cw
scope = cw.scope()
(ChipWhisperer Scope ERROR|File __init__.py:389) ChipWhisperer error state detected. Resetting and retrying connection...
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\__init__.py:387, in scope(scope_type, name, sn, idProduct, bitstream, force, prog_speed, **kwargs)
386 try:
--> 387 rtn.con(**kwargs)
388 except IOError:
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\OpenADC.py:662, in OpenADC.con(self, sn, idProduct, bitstream, force, prog_speed, **kwargs)
661 self.la_mmcm = XilinxMMCMDRP(self.la_drp)
--> 662 self.clock = ChipWhispererHuskyClock.ChipWhispererHuskyClock(self.sc, \
663 self._fpga_clk, self.glitch_mmcm1, self.glitch_mmcm2)
664 self.ADS4128 = ADS4128Settings(self.sc)
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:712, in ChipWhispererHuskyClock.__init__(self, oaiface, fpga_clk_settings, mmcm1, mmcm2)
711 self.naeusb = oaiface.serial
--> 712 self.pll = CDCI6214(self.naeusb, mmcm1, mmcm2)
713 self.fpga_clk_settings = fpga_clk_settings
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:36, in CDCI6214.__init__(self, naeusb, mmcm1, mmcm2)
35 self._mmcm_vco_max = 1200e6
---> 36 self.setup()
37 self.set_pll_input()
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:144, in CDCI6214.setup(self)
143 # disable GPIO1/4 as inputs
--> 144 self.update_reg(0x00, (1 << 13) | (1 << 12), 0)
146 self.update_reg(0x04, (1 << 3) | (1 << 4), 0) # turn off outputs 2 and 4
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:119, in CDCI6214.update_reg(self, addr, bits_to_set, bits_to_clear)
118 # print(bits_to_set, bits_to_clear)
--> 119 reg_val = self.read_reg(addr, as_int=False)
120 reg_val[0] &= 0xFF - bits_to_clear[0] # the not we want ;)
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:80, in CDCI6214.read_reg(self, addr, as_int)
79 if data[0] != 2:
---> 80 raise IOError("PLL/I2C Error, got {}".format(data))
82 if as_int is True:
OSError: PLL/I2C Error, got bytearray(b'\x01\x08\x00')
During handling of the above exception, another exception occurred:
OSError Traceback (most recent call last)
Cell In[3], line 2
1 import chipwhisperer as cw
----> 2 scope = cw.scope()
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\__init__.py:393, in scope(scope_type, name, sn, idProduct, bitstream, force, prog_speed, **kwargs)
391 time.sleep(2)
392 rtn = scope_type()
--> 393 rtn.con(**kwargs)
394 return rtn
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\OpenADC.py:662, in OpenADC.con(self, sn, idProduct, bitstream, force, prog_speed, **kwargs)
660 self.glitch_mmcm2 = XilinxMMCMDRP(self.glitch_drp2)
661 self.la_mmcm = XilinxMMCMDRP(self.la_drp)
--> 662 self.clock = ChipWhispererHuskyClock.ChipWhispererHuskyClock(self.sc, \
663 self._fpga_clk, self.glitch_mmcm1, self.glitch_mmcm2)
664 self.ADS4128 = ADS4128Settings(self.sc)
665 self.XADC = XADCSettings(self.sc)
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:712, in ChipWhispererHuskyClock.__init__(self, oaiface, fpga_clk_settings, mmcm1, mmcm2)
710 self.oa = oaiface
711 self.naeusb = oaiface.serial
--> 712 self.pll = CDCI6214(self.naeusb, mmcm1, mmcm2)
713 self.fpga_clk_settings = fpga_clk_settings
714 self.fpga_clk_settings.freq_ctr_src = "extclk"
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:36, in CDCI6214.__init__(self, naeusb, mmcm1, mmcm2)
34 self._mmcm_vco_min = 600e6
35 self._mmcm_vco_max = 1200e6
---> 36 self.setup()
37 self.set_pll_input()
38 self.set_outdiv(3, 0)
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:144, in CDCI6214.setup(self)
131 """Do required initial setup.
132
133 Does the following:
(...)
141 * Use register to select PLL input instead of pin
142 """
143 # disable GPIO1/4 as inputs
--> 144 self.update_reg(0x00, (1 << 13) | (1 << 12), 0)
146 self.update_reg(0x04, (1 << 3) | (1 << 4), 0) # turn off outputs 2 and 4
148 self.update_reg(0x05, 0, 0b11111110111) # turn on power to everything
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:119, in CDCI6214.update_reg(self, addr, bits_to_set, bits_to_clear)
116 bits_to_clear = tmp
118 # print(bits_to_set, bits_to_clear)
--> 119 reg_val = self.read_reg(addr, as_int=False)
120 reg_val[0] &= 0xFF - bits_to_clear[0] # the not we want ;)
121 reg_val[1] &= 0xFF - bits_to_clear[1]
File c:\users\\chipwhisperer5_64\cw\home\portable\chipwhisperer\software\chipwhisperer\capture\scopes\cwhardware\ChipWhispererHuskyClock.py:80, in CDCI6214.read_reg(self, addr, as_int)
77 data = self.naeusb.readCtrl(0x29, dlen=3)
79 if data[0] != 2:
---> 80 raise IOError("PLL/I2C Error, got {}".format(data))
82 if as_int is True:
83 return (data[1]) | (data[2] << 8)
OSError: PLL/I2C Error, got bytearray(b'\x01\x08\x00')
The Husky was working fine before. Do you know why this is happening ? This is the part we used for our modification: https://www.mouser.se/ProductDetail/KEMET/C0402C101K5TACAUTO?qs=P%2FxahI%252BVehm4DIVfs7vRXA%3D%3D
If that can help, husky is alive and status led is blinking correctly.
Thank you so much for your support,
Shanly
That’s not a good sign: it means we’re not able to read properly from the PLL chip (U10). It’s close to C49, which suggests it may have been damaged. Here we should be reading [2, 0, 0], and you’re getting [1, 8, 0] instead.
The I2C lines which handle PLL communication are near the top right corner, on the backside, if you’re up to inspecting for damage and checking with a logic analyzer.
Hello,
We have done a optical inspection of the soldering, it seems to look fine ? Here are some picture for reference
We have tried reinstalling the drivers in the hopes of succeeding a firmware update but reinstalling the drivers did not change the issues so the CW is unavailable for any kind of firmware update.
Thank you for your suggestion. This kind of hardware debugging is really out of our competence set as it is, could you eventually please provide us with further guidance ? Is there any further output we can provide you with ?
Email sales@newae.com with a reference to this C49 modification and we’ll take the next steps from there.
Thank you for your swift support! The performances of the Husky have significantly improved.
Running the solution lab actually brings us to a output close to @vector247
The peaks are now clearly visible (solution peaks)
So, based on the precedent graph, I know that subkey 0 has a peak of around 0.4 at around 1900, which means it is the dark blue one. It stands particularly well at 2500 too.
With a brute windowing of [2500:]
Subkey 0 - most likely 0C (actual 2B)
Top 5 guesses:
0C - Diff = 0.002146
9F - Diff = 0.001743
CD - Diff = 0.001732
0B - Diff = 0.001723
26 - Diff = 0.001691
Subkey 1 - most likely 7E (actual 7E)
Top 5 guesses:
7E - Diff = 0.003172
6F - Diff = 0.001874
3F - Diff = 0.001803
19 - Diff = 0.001760
1F - Diff = 0.001724
Subkey 2 - most likely 15 (actual 15)
Top 5 guesses:
15 - Diff = 0.002919
B5 - Diff = 0.001939
DC - Diff = 0.001771
E6 - Diff = 0.001708
9A - Diff = 0.001681
Subkey 3 - most likely 16 (actual 16)
Top 5 guesses:
16 - Diff = 0.003997
AB - Diff = 0.002369
7D - Diff = 0.002168
8F - Diff = 0.002138
12 - Diff = 0.002023
Subkey 4 - most likely 17 (actual 28)
Top 5 guesses:
17 - Diff = 0.001870
8A - Diff = 0.001764
C8 - Diff = 0.001743
39 - Diff = 0.001697
20 - Diff = 0.001676
Subkey 5 - most likely AE (actual AE)
Top 5 guesses:
AE - Diff = 0.002839
BF - Diff = 0.001852
B9 - Diff = 0.001778
4B - Diff = 0.001716
3A - Diff = 0.001693
Subkey 6 - most likely D2 (actual D2)
Top 5 guesses:
D2 - Diff = 0.002999
B9 - Diff = 0.001864
BB - Diff = 0.001808
7C - Diff = 0.001801
91 - Diff = 0.001796
Subkey 7 - most likely A6 (actual A6)
Top 5 guesses:
A6 - Diff = 0.003777
4A - Diff = 0.002487
1B - Diff = 0.002405
CD - Diff = 0.002318
34 - Diff = 0.002312
Subkey 8 - most likely CC (actual AB)
Top 5 guesses:
CC - Diff = 0.002222
E0 - Diff = 0.001935
F3 - Diff = 0.001681
02 - Diff = 0.001678
EA - Diff = 0.001630
Subkey 9 - most likely F7 (actual F7)
Top 5 guesses:
F7 - Diff = 0.003574
7F - Diff = 0.002292
B5 - Diff = 0.001947
9C - Diff = 0.001926
06 - Diff = 0.001876
Subkey 10 - most likely 15 (actual 15)
Top 5 guesses:
15 - Diff = 0.003001
FB - Diff = 0.002578
35 - Diff = 0.002027
AF - Diff = 0.001811
52 - Diff = 0.001772
Subkey 11 - most likely 88 (actual 88)
Top 5 guesses:
88 - Diff = 0.003423
35 - Diff = 0.002113
E3 - Diff = 0.002094
E5 - Diff = 0.001994
7D - Diff = 0.001992
Subkey 12 - most likely 57 (actual 09)
Top 5 guesses:
57 - Diff = 0.001821
F4 - Diff = 0.001712
B1 - Diff = 0.001660
40 - Diff = 0.001632
DF - Diff = 0.001630
Subkey 13 - most likely CF (actual CF)
Top 5 guesses:
CF - Diff = 0.003567
A6 - Diff = 0.001885
72 - Diff = 0.001840
22 - Diff = 0.001680
A4 - Diff = 0.001647
Subkey 14 - most likely 4F (actual 4F)
Top 5 guesses:
4F - Diff = 0.003053
FC - Diff = 0.001882
27 - Diff = 0.001869
CF - Diff = 0.001854
2D - Diff = 0.001831
Subkey 15 - most likely 3C (actual 3C)
Top 5 guesses:
3C - Diff = 0.003877
81 - Diff = 0.002414
57 - Diff = 0.002140
C2 - Diff = 0.001997
C9 - Diff = 0.001954
We recovered almost all bytes! Except 0, 4, 8, and 12 (The +4 offset between each is intriguing aha). In those cases, the real key doesn’t make it to the top 5.
Windowing still remains quite difficult and we don’t get a perfect solution. I tried to optimize it with something like [(offset_start + cycle*subkey) : (offset_end + cycle*subkey)]
and I cannot seem to find such parameters that give me something perfect. Do you have any suggestion on how to solve this?
On the other hand, Solution Lab for 4.2 worked perfectly so the main issue have been resolved on my side. A huge thanks to @Alex_Dewar, @jpthibault and other members of the NewAE team. Thanks also to the community for contributing to this topic and helping us get to the bottom of this issue!