Can I put my own crypto code into chipwhisperer for analysis?

if can, is there a doc for it?
if can’t , we can only analysis code in the project?

Thanks!

Hi,

ChipWhisperer is fully open source, so you can run any code you want on it, provided it fits onto the hardware.

Are you trying to run code on a ChipWhisperer target device? If so, you may find it easiest to start with one of our firmware projects as a base (chipwhisperer/hardware/victims/firmware). I’d recommend copying one of the folders in that directory, and modifying the makefile in that folder to include the source code of the Crypto you want to use. You can then build as you would any other ChipWhisperer firmware.

Alex

Thank you a lot.
Sorry to ask this question without many experiments.

Hi Alex.

I will need to run Kyber on ChipWhisperer. My consideration is running decryption and evaluate the power consumption using ChipWhisperer Lite at first (available with me now) and extend to Pro version if necessary (due to the limitation on number of samples) later.
Can you suggest which firmware project should I start with?
I am learning with project SCA101, labs 2 and 3 (hardware) to know how to communicate with the device / firmware for key and cyphertext sending and encrypted message receiving (but not yet really understand how the firmware get_key and get_pt by using memcpy). However, I recognized that simpleserial_addcmd has limitation in the number of bytes (64 / 192) for key and pt transfer while the key and cyphertext of Kyber512 is expected to be 768 bytes. Do you have some suggestions to overcome this problem?

Thank you very much.
Best regards,
Tuan

Hi Tuan,

I’m not sure you’ll gain much by starting with any firmware project besides simpleserial_aes in particular.

To send longer commands, you’ll need to split the key transfer into separate messages. One way you might do this is by using a different command for each part of the key. We do this in simpleserial-rsa-arm.c, as the RSA ciphertext is too large for a single simpleserial_v1 packet (though we can fit it into a single simpleserial 2 packet). There we use the 'p' command to do the encryption and to receive the first ~1/3 of the key, then use '1' for the next ~1/3, and finally '2' for the last ~1/3.

Alex

Hi Alex

Thank you very much for your reply and sorry for lack of experiments.
Is it course SCA202 (python)? If it is, the text and key in the python code is 16 bytes only.
In main in simpleserial-rsa.c (and in rsa_init in simpleserial-rsa-arm.c), I found simpleserial_addcmd(‘1’, 0, sig_chunk_1);
simpleserial_addcmd(‘2’, 0, sig_chunk_2);
simpleserial_addcmd(‘p’, 16, get_pt);
are they the functions you mentioned to?
However, sig_chunk_1 function leads to simpleserial_put function in simpleserial.c, which looks like pushing some data from device / firmware to PC.
In addition, where can I find the suitable get_pt function for rsa.

Tuan

Hi Tuan,

We don’t transfer any data from the PC to the microcontroller in the RSA demo, but the ciphertext (which is 1024 bits) is transferred back. The principle is the same - break the communication into multiple transmissions.

Alex

Hi Alex.

I extend the basic-passwdcheck project to send long message by cutting it into smaller chunks. PC sends each chunk and waits for the acknoledgement from the target before target.flush() is used and the next chunk is send.
The first chunk (which is sent right after reset_target(scope)) is correctly received and confirmed from the target side but the second chunk is not. It has the same value with the first one (and some time, an additional charactor is added to the begining). I also tried to use my_read function to read the receive buffer in the target device for few times to make sure that no unwanted data is remaining but it doesn’t work.
Can you tell me how can I “flush” the receiving buffer of the target device?

Thank you very much.
Best regards,
Anh Tuan Hoang

Hi,

The target’s receiving buffer is just passwd for that firmware if you’re using my_read(). I’m not sure I’ll be able to help much here, as all that’s used in the password check firmware is a single character blocking read - it’s up to you how you want to construct the communication between the target and the PC.

Alex

Hi Alex

I reuse my_read in the example. Is getch() the basic function for reading a byte from communication buffer (serial port) in ChipWhisperer? If it is, what should I use with getch() to remove the old data from the buffer?
I think I will need to build a protocal for sending commands and packages between PC and target. I need to work with Kyber with (at least) 756 bytes for key and another 756 bytes for cyphertext. Hence, 24 packages is required for those data transfer and is over the 16 commands of simpleserial_addcmd. Can you tell me the example that more package can be sent from PC?
Thank you very much.
Tuan

There is no buffer underneath getch() - it’s just a register storing the last received serial character. If you’re reading from getch() and getting data, it’s because that’s what you’re receiving over the serial line at that moment.

If you want to add more commands, just modify MAX_SS_CMDS in simpleserial/simpleserial.c. There isn’t any particular reason it’s 16.

Alex

Hi Alex

Thank you very much for your comments on MAX_SS_CMDS for increasing the number of ‘simpleserial_addcmd’.
I follow your comments with SS_VER_2_0 and be able to send maximum 128-byte data package (192 bytes per package makes error). I also successfully use 6 packages for sending either 768-byte key or text, combine them together, modify the value (on target device) and receive them back (to PC).
However, I have problem reseting the value to 768-0x00 bytes.
I tried to reset by sending all 0x00 packages from the PC but the maximum number of zeros that can be sent is 28 (sending error occurs if the first 29 bytes of the sending package are ‘zeros’).


\targets\SimpleSerial2.py in send_cmd(self, cmd, scmd, data)
565 self.write(buf)
566 target_logger.debug(“Sending: {}”.format(bytearray(buf)))
–> 567 target_logger.debug(“Unstuffed data: {}”.format(bytearray(self._unstuff_data(buf))))
568
569 def reset_comms(self):

TypeError: ‘NoneType’ object is not iterable


Could you please tell me how can I overcome this problem?

In addition, writing 0x00 to key or text memory by a loop (value zero is a constant in C or being sent via ‘pt’) also make no effect.
#if SS_VER == SS_VER_2_0
uint8_t reset_key(uint8_t cmd, uint8_t scmd, uint8_t len, uint8_t* pt)
#else
uint8_t reset_key(uint8_t* x, uint8_t len)
#endif
{
// Reset key here if needed
for (int i = 0; i < KYBER_KEY_SIZE; i++)
{
// pt can be any 5-byte array
kyber_enckey[i] = pt[i%4]; // ->be able to reset to pt values if pt is not [0,0,0,0,x]
// only first 31 bytes change to 0x00 if pt=[0,0,0,0,x]
// OK if pt=[1,1,1,1,x]
//(also tested with kyber_enckey[i] = 0x00; but not work)
}
for (int i = 0; i < KYBER_TEXT_SIZE; i++)
retkey[i] = (kyber_enckey[i] * 3) % 256;
simpleserial_put(‘r’, reset_cmd_size, pt); // pt = ‘reset’
return 0x00;
}

Thank you very much
Tuan

Hi Tuan,

This is a bug with the 5.5.2 release of ChipWhisperer. It should be fixed on the latest develop commit, and will be fixed in the upcoming 5.6.1 release.

In the meantime, it might be good to add an additional command that just memsets your target value to 0.

Alex

Hi Alex

Some experiments shows that the filling memory (either by loop or memset) are successfully fill the memory with prefered value (zero included). The problem above causes by the returning procedure from target device to PC. If we simpleserial_put many zeros from the target device, PC will correctly receive few first tens.
Could you please check the ‘simpleserial_put’ and ‘target.simpleserial_read’ methods?

Thank you very much
Tuan

Hi Alex.
I would like to ask how can I compile the pqm4 Kyber with ChipWhisperer project?
What I did is

  • Copying simpleserial-base folder to a new one before copying crypto_kem (of pqm4) to the same folder.
  • Include (#include) all the *.h files from ./crypto_kem/kyber512/m4/ to the simpleserial-base file.
  • Call the “indcpa_dec(kyber_dec_result, kyber_text, kyber_enckey)” with the data that I successfully transfered with my previous test.
    However, doing so make an error of unknow type in ChipWhisperer project:

In file included from ./crypto_kem/kyber512/m4/verify.h:4,
from simpleserial-base_kyber512.c:35:
c:\users\3053227\chipwh~1\cw\home\portable\armgcc\gcc-arm-none-eabi-10-2020-q4-major\arm-none-eabi\include\stdio.h:46:9: error: unknown type name ‘__gnuc_va_list’
46 | typedef __gnuc_va_list va_list;
| ^~~~~~~~~~~~~~


Could you please tell me how can I compile the simpleserial-base project with pqm4 kyber included?
My system is Windows10 with ChipWhisperer installed using Chipwhisperer.v5.5.2.Setup.64-bit

Thank you very much.
Best regards,
Tuan

Does other firmware compile? If not, this may be a path length issue. Otherwise, I’m not sure what’s wrong.

Hi Alex.
I successful developed a communication program based on the simpleserial-base project (called simpleserial-base-kyber512) with coresponding folder, in which:

  1. makefile keep the same with the one from simpleserial-base except TARGET and SRC + change to “simpleserial-base_kyber512”, which is my communication project.
  2. replace the simpleserial-base.c file with the new one “simpleserial-base_kyber512.c”

I try to make a simple program to check how to include additional C program into project by:

  1. Make a folder caled “test_compile” in the folder of the project
  2. make a “test_compile.h” file:
    void sum_2uint8(uint8_t * sum, uint8_t * in1, uint8_t * in2);
  3. make a “test_compile.c” file:
    void sum_2uint8(uint8_t * sum, uint8_t * in1, uint8_t * in2) {
    sum[0] = (in1[0] + in2[0]) % 256;
    }
  4. include the additional C into the target firmware (“simpleserial-base_kyber512.c”
    ) by:
    #include “.\test_compile\test_compile.h”
  5. call the function in the target firmware by:
    sum_2uint8(kyber_dec_result, kyber_text, kyber_enckey);
    //kyber_dec_result, kyber_text, kyber_enckey are unsigned char matrixes, which work are verified with the pure communication program.

I think the manner that I include new function is completely the same with the way “aes_indep_enc” function (in “aes-independant.h”) is included in the “Lab 3_3 - DPA on Firmware Implementation of AES” project. However, when compile the new project, I received following error:


c:/users/3053227/chipwh~1/cw/home/portable/armgcc/gcc-arm-none-eabi-10-2020-q4-major/bin/…/lib/gcc/arm-none-eabi/10.2.1/…/…/…/…/arm-none-eabi/bin/ld.exe: objdir/simpleserial-base_kyber512.o: in function get_text_finished': C:\Users\3053227\CHIPWH~1\cw\home\portable\chipwhisperer\hardware\victims\firmware\simpleserial-base-kyber512/simpleserial-base_kyber512.c:523: undefined reference to sum_2uint8’
collect2.exe: error: ld returned 1 exit status
make: *** […/./Makefile.inc:462: simpleserial-base_kyber512-CWLITEARM.elf] Error 1


Can you tell me what is the missing in my trial that makes the error?
Thank you very much.
Best regards,
Anh Tuan Hoang

That error message means that the file that has sum_2uint8 hasn’t been compiled + linked. Have you modified the Makefile in the project directory to include this new file?

Alex

Hi Alex
I modified the Makefile so that I can compile the source codes of the pqm4 project in your project.
However, I have a new error with the macro. The error looks like this:


crypto_kem/kyber512/m4/macros.i:3:1: error: stray ‘#’ in program
3 | #ifndef MACROS_I
| ^
crypto_kem/kyber512/m4/macros.i:3:2: error: unknown type name ‘ifndef’
3 | #ifndef MACROS_I
| ^~~~~~
crypto_kem/kyber512/m4/macros.i:6:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘.’ token
6 | .macro load a, a0, a1, a2, a3, mem0, mem1, mem2, mem3
| ^
crypto_kem/kyber512/m4/macros.i:7:9: error: stray ‘’ in program
7 | ldr.w \a0, [\a, \mem0]
| ^
crypto_kem/kyber512/m4/macros.i:7:15: error: stray ‘’ in program
7 | ldr.w \a0, [\a, \mem0]
| ^


The macro file is:


/…/…/kyber768/m4/macros.i/

#ifndef MACROS_I
#define MACROS_I

.macro load a, a0, a1, a2, a3, mem0, mem1, mem2, mem3
ldr.w \a0, [\a, \mem0]
ldr.w \a1, [\a, \mem1]
ldr.w \a2, [\a, \mem2]
ldr.w \a3, [\a, \mem3]
.endm

.macro store a, a0, a1, a2, a3, mem0, mem1, mem2, mem3
str.w \a0, [\a, \mem0]
str.w \a1, [\a, \mem1]
str.w \a2, [\a, \mem2]
str.w \a3, [\a, \mem3]
.endm

.macro doublebarrett a, tmp, tmp2, q, barrettconst
smulbb \tmp, \a, \barrettconst
smultb \tmp2, \a, \barrettconst
asr \tmp, \tmp, #26
asr \tmp2, \tmp2, #26
smulbb \tmp, \tmp, \q
smulbb \tmp2, \tmp2, \q
pkhbt \tmp, \tmp, \tmp2, lsl#16
usub16 \a, \a, \tmp
.endm

.macro montgomery q, qinv, a, tmp
smulbt \tmp, \a, \qinv
smlabb \tmp, \q, \tmp, \a
.endm

.macro doublemontgomery a, tmp, tmp2, q, qinv, montconst
smulbb \tmp2, \a, \montconst
montgomery \q, \qinv, \tmp2, \tmp
smultb \a, \a, \montconst
montgomery \q, \qinv, \a, \tmp2
pkhtb \a, \tmp2, \tmp, asr#16
.endm

#endif /* MACROS_I */


Do you know what is the problem? Are there any additional tools that I need to add to the instalation of chipwhisperer to solve the problem?

Thank you very much.
Best regards,
Tuan

1 Like

Hi Tuan,

I think you’re trying to put asm through the C compiler. If you’re feeding in macros.i as a source file (i.e. via the SRC makefile variable), try doing ASRC+=/path/to/macros.i

Alex