Random number generation in XMEGA

Is there anyway I could generate random numbers for my implementation?

I’ve developed implementations in eclipse using rand() and srand() functions, but they give me errors when I compile them into chipwhisperer. I don’t really know what are the libraries available by default or how to add any library.

I’ve seen that for the CPA analysis in the tutorials, plaintexts are randomly generated. How can I do the same? Where can I see the code that does that?

The standard C random functions are implemented in software, so I don’t think there should be any reason why they wouldn’t work. What errors do you get?

Also the plaintext is generated in Python and sent to the target over USB/Serial.

Alex

The rand() and srand() functions finally worked properly (it was only me badly coding…). However, rand() produces a too big (and long) power consumption every time is called. I’m thinking of using the imput plaintexts (their bytes) generated in Python as random values. Do you know if these are true random plaintexts? Or are they pseudo-randomly generated?

Thanks for your help,
Asier

They’re generated using the random module in Python, so they would be pseudo-random (same as rand()).

Alex

Thank you for the clarification !!
Asier

Hello again,
Do you know if I could use any system value (e.g. time, clock_cycles, program execution id,… any kind of counter) as a seed for my pseudo-random generation? I have a function that precomputes every needed random byte value before the encryption of the AES and I need different seeds in order to precompute different values in each encryption.

Anything like getpid() could work? (returns the process ID of the calling function and works with linux if i’m not mistaken)

Is it posible to install a library? <sys/time.h> has a function “gettimeofday()” that gives time in microseconds and would work prefectly.

Thanks in advance,
Asier

You won’t find anything like a PID or a system time library here - there’s no OS running on these devices. Our HALs are very basic, since all we care about is setting up UART and clock, but you can take a look at the reference manual/datasheet for your target device and implement something with one of the peripherals. Microcontrollers often have many timers usable for something like this. I believe Arm CPUs usually have a cycle counter as well.

That being said, is there any reason you need to reseed often? Even a simple PRNG like XORshift128 has a period such that you could run through every possible plaintext value in AES before you run into a repeat value.

Alex

Hello again Alex!

I am doing an analysis on software countermeasures against Side Channel Power Analysis. I took the TYNIAES128 as statrting point and have implemented many countermeasures on it already. Once the implementation is applied I attack it with a CPA and see what is the effectiveness of the countermeasure by observing how the correlations change and looking at the minimum traces needed to recover the key (when it is possible).

From what I understand, every time “cw.capture_trace(scope, target, text, key)” is called with python, the “main” in “simplelserial-aes.c” is executed once. My implementation code generates random values and I need to reseed for each new main (new trace).

I found a python library called “secrets” that generates cryptographically secure random numbers (it is probably the best PRNG possible, it uses many different system data and combines it to seed) and I would like to use it to seed my implementation.

Now the thing is that I don’t know how to send the seed from python to my target. In the code of “simplelserial-aes.c”:


#include “aes-independant.h”
#include “hal.h”
#include “simpleserial.h”
#include <stdint.h>
#include <stdlib.h>

uint8_t get_mask(uint8_t* m, uint8_t len)
{
aes_indep_mask(m, len);
return 0x00;
}

uint8_t get_key(uint8_t* k, uint8_t len)
{
aes_indep_key(k);
return 0x00;
}

uint8_t get_pt(uint8_t* pt, uint8_t len)
{
aes_indep_enc_pretrigger(pt);

trigger_high();

#ifdef ADD_JITTER
for (volatile uint8_t k = 0; k < (*pt & 0x0F); k++);
#endif

aes_indep_enc(pt); /* encrypting the data block */
trigger_low();

aes_indep_enc_posttrigger(pt);

simpleserial_put('r', 16, pt);
return 0x00;

}

uint8_t reset(uint8_t* x, uint8_t len)
{
// Reset key here if needed
return 0x00;
}

static uint16_t num_encryption_rounds = 10;

uint8_t enc_multi_getpt(uint8_t* pt, uint8_t len)
{
aes_indep_enc_pretrigger(pt);

for(unsigned int i = 0; i < num_encryption_rounds; i++){
    trigger_high();
    aes_indep_enc(pt);
    trigger_low();
}

aes_indep_enc_posttrigger(pt);
simpleserial_put('r', 16, pt);
return 0;

}

uint8_t enc_multi_setnum(uint8_t* t, uint8_t len)
{
//Assumes user entered a number like [0, 200] to mean “200”
//which is most sane looking for humans I think
num_encryption_rounds = t[1];
num_encryption_rounds |= t[0] << 8;
return 0;
}

#if SS_VER == SS_VER_2_0
uint8_t aes(uint8_t cmd, uint8_t scmd, uint8_t len, uint8_t *buf)
{
uint8_t req_len = 0;
uint8_t err = 0;
uint8_t mask_len = 0;
if (scmd & 0x04) {
// Mask has variable length. First byte encodes the length
mask_len = buf[req_len];
req_len += 1 + mask_len;
if (req_len > len) {
return SS_ERR_LEN;
}
err = get_mask(buf + req_len - mask_len, mask_len);
if (err)
return err;
}

if (scmd & 0x02) {
    req_len += 16;
    if (req_len > len) {
        return SS_ERR_LEN;
    }
    err = get_key(buf + req_len - 16, 16);
    if (err)
        return err;
}
if (scmd & 0x01) {
    req_len += 16;
    if (req_len > len) {
        return SS_ERR_LEN;
    }
    err = get_pt(buf + req_len - 16, 16);
    if (err)
        return err;
}

if (len != req_len) {
    return SS_ERR_LEN;
}

return 0x00;

}
#endif

int main(void)
{
uint8_t tmp[KEY_LENGTH] = {DEFAULT_KEY};

platform_init();
init_uart();
trigger_setup();

trigger_high();
aes_indep_init();
aes_indep_key(tmp);
trigger_low();

                                 
simpleserial_init();
#if SS_VER == SS_VER_2_0
simpleserial_addcmd(0x01, 16, aes);
#else
simpleserial_addcmd('k', 16, get_key);
simpleserial_addcmd('p', 16,  get_pt);
simpleserial_addcmd('x',  0,   reset);
simpleserial_addcmd_flags('m', 18, get_mask, CMD_FLAG_LEN);
simpleserial_addcmd('s', 2, enc_multi_setnum);
simpleserial_addcmd('f', 16, enc_multi_getpt);
#endif
while(1)
    simpleserial_get();

}

I work with SS_VER_1 and I don’t really undertand how “cw.capture_trace(scope, target, text, key)” is involved. I don’t get where “pt” comes from neither.

Any help is welcome and thanks a lo really!!.

Only the 'p' command (get_pt()) is typically called when you do a capture trace (through a 'k' get_key() command is done for the first capture to set the key). The microcontroller is typically only reset when programming firmware. pt is what is being sent to the target.

If you want to send other commands, you’ll need to recreate the steps of capture_trace(), or send the message in between traces.

I’d recommend taking a look at our document on simpleserial: https://chipwhisperer.readthedocs.io/en/latest/simpleserial.html

Alex

I can’t find where capture_trace() is defined, I think that if I undertand how it works I will get my objective.

You can find capture_trace() on our github

Alex