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!!.