kmackay / micro-ecc

ECDH and ECDSA for 8-bit, 32-bit, and 64-bit processors.
BSD 2-Clause "Simplified" License
1.26k stars 459 forks source link

Miscompilation #186

Open JKBert opened 3 years ago

JKBert commented 3 years ago

Hello, I'm using this library on an ATmega 1284 CPU and it only runs as expected if I define uECC_arch_other. When library is built with uECC_avr, all tests fail.

For example, I have written this simple test:

#include <stdio.h>
void stty_print(unsigned char *);
#include "crypto/ecc/uECC.h"
#define F_CPU   16000000
#include "multitasking/mutex.h"

uint8_t uECC_public_key[64];
uint8_t uECC_private_key[32];

mutex_t mutex_stty;

const struct uECC_Curve_t  *curve;

int random_ecc(uint8_t *dest, unsigned size);

long
alea()
{
    static uint8_t  init = 0;

    if (init == 0)
    {
        stty_print("Init alea\r\n");
        srandom(1);
        init = 1;
    }

    if (uECC_get_rng() == NULL)
    {
        stty_print("Init random_ecc\r\n");
        uECC_set_rng(&random_ecc);
    }

    return(random());
}

int
random_ecc(uint8_t *dest, unsigned size)
{
    while(size)
    {
        (*dest) = (uint8_t) (alea() & 0x000000FF);
        dest++;
        size--;
    }

    return(1);
}

int
main()
{
    mutex_init(&mutex_stty, MUTEX_FAST);

    stty_print("Init\r\n");
    alea();

    curve = uECC_secp256r1();
    uECC_make_key(uECC_public_key, uECC_private_key, curve);

    for(uint8_t i = 0; i < 64; i++)
    {
        unsigned char t[4];
        snprintf(t, 4, "%02X", uECC_public_key[i]);
        stty_print(t);
    }
    stty_print("\r\n");

    if (uECC_valid_public_key(uECC_public_key, curve) == 0)
    {
        stty_print("Invalid key\r\n");
    }
    else
    {
        stty_print("Valid key\r\n");
    }

    stty_print("Done\r\n");

    for(;;);
}

Build options are: -mmcu=atmega1284 -O2 with avr-gcc 11.1.0.

With uECC_PLATFORM set to uECC_avr, my test returns:

Init alea..
Init random_ecc..
445D739B4727C8701BB99221404EB89DC09A8FC7F11F5BCA501E2DDE07BB953BF77E6EEA558E9234DC9431893EC60271700571E23F5D34BABC9856F3BC876B62..
Invalid key..
Done..

With uECC_PLATFORM set to uECC_arch_other (thus, without assembly optimization):

Init alea..
Init random_ecc..
93A980352F127448C19FB0213622B13D5FEFC07CA4E6EA3A22234E7F0D9634FF8F2854B25A6E70F9E2063AB47040A341B54D39FD4845FB6D86CA33C8CFB5E308..
Valid key..
Done..

I have checked return of asmb subroutines and they return faulty values. I suppose I have done a mistake in compilation stage but I'm unable to find my mistake.

Best regards,

JB

JKBert commented 3 years ago

Some news.

I remember I have used uECC without this kind of bug. I have rebuilt the same code (with uECC_avr defined), but I have compiled this library not with gcc 11.1.0, but with 5.4.0.

And I obtain :

Loaded 18710 .text at address 0x0
Loaded 416 .data
Init...
Init alea...
Init random_ecc...
93A980352F127448C19FB0213622B13D5FEFC07CA4E6EA3A22234E7F0D9634FF8F2854B25A6E70F9E2063AB47040A341B54D39FD4845FB6D86CA33C8CFB5E308...
93A980352F127448C19FB0213622B13D5FEFC07CA4E6EA3A22234E7F0D9634FF8F2854B25A6E70F9E2063AB47040A341B54D39FD4845FB6D86CA33C8CFB5E308...
Done...

Now the question ;-) Did I find a bug or does gcc 11 need a special build option to compile uECC ?