Closed rjjrbatarao closed 2 years ago
According to the stack trace the crash is due to unaligned access - the internal structures returned by LwIP require natural alignment to work with the WireGuard library.
I suspect the root issue is that the LwIP #define MEM_ALIGNMENT is set incorrectly in your code. Try looking in your LwIP config files (normally lwipopts.h) to set, e.g. #define MEM_ALIGNMENT 4. It's probably set at 1 which is the reason for the crash.
Hm. I believe the issue is in the reference x25519 implementation, where it aliases u8 <-> u32 params and not something inside of the LWIP stack. One needs to carefully walk through the call chain to ensure those don't break the alignment up to this point (x25519.c:61) https://github.com/smartalock/wireguard-lwip/blob/4ca93fb0cd2588d4c568ed67a2b977659d5e6711/src/crypto/refc/x25519.c#L58-L64
ref. these noise-c port crash dumps, I thought this looked familiar enough https://github.com/esphome/issues/issues/2502#issuecomment-934268051 https://github.com/esphome/noise-c/blob/3e88febd5ccf024d138addab727540df3d6aa246/src/crypto/x25519/x25519.c#L263
I suspect the root issue is that the LwIP #define MEM_ALIGNMENT is set incorrectly in your code. Try looking in your LwIP config files (normally lwipopts.h) to set, e.g. #define MEM_ALIGNMENT 4. It's probably set at 1 which is the reason for the crash.
btw, Arduino pre-built lwip already sets this https://github.com/d-a-v/esp82xx-nonos-linklayer/blob/18975ca6c4facb2d57de706bec0843f286b7b0e2/glue-lwip/arduino/lwipopts.h#L292
Hm. I believe the issue is in the reference x25519 implementation, where it aliases u8 <-> u32 params and not something inside of the LWIP stack. One needs to carefully walk through the call chain to ensure those don't break the alignment up to this point (x25519.c:61)
Well spotted! That looks to be exactly the same problem. Their solution was to either compile the code in debug mode which made the compiler generate code that didn't crash, or to change to using a different crypto library that doesn't crash on ESP32
It looks like they switched to libsodium - this shouldn't be too hard to add as an option but I am unfamiliar with ESP32 on how to import this.
Maybe try changing the #define for define for wireguard_x25519 in crypto.h to use the libsodium version - e.g.
#define wireguard_x25519(a,b,c) crypto_scalarmult_curve25519(a, b, c)
You'll probably also need to call sodium_init() in your startup code as well.
@mcspr @smartalock thank you giving some insights to the problem, i will try to look on the implementation of libsodium and hope that it will work this time.
I couldn't implement the libsodium since theres no port to esp8266 arduino ide and its src files are so confusing to include in the sketch. Good news is that i've fixed the crash through libhydrogens x25519 implementation Device init and Adding peer shows up, One thing I noticed is that libhydrogen x25519 was almost identical to your x25519 with the exemption that its mostly renamed to hydrogen_ and with added typecast to some return variable, maybe thats what i missed? i never investigated much maybe someone could look on to this further. Here is the x25519 i used: https://github.com/jedisct1/libhydrogen/blob/4a477649e679aff15480f88d8dc93913540bd70e/impl/x25519.h I deleted the x25519.c since its all included in the .h from libhydrogens implementation. I also added the following on top since it shows some errors when I try to compile from arduino ide saying its missing. I dont know if its actually working lol i just fixed the crashing problem, my next step now is to test this to connect to another device.
static inline void
mem_zero(void *dst_, size_t n)
{
unsigned char *dst = (unsigned char *) dst_;
size_t i;
for (i = 0; i < n; i++) {
dst[i] = 0;
}
}
#define LOAD32_LE(SRC) load32_le(SRC)
static inline uint32_t
load32_le(const uint8_t src[4])
{
#ifdef NATIVE_LITTLE_ENDIAN
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
#else
uint32_t w = (uint32_t) src[0];
w |= (uint32_t) src[1] << 8;
w |= (uint32_t) src[2] << 16;
w |= (uint32_t) src[3] << 24;
return w;
#endif
}
#define hydro_x25519_BYTES 32
#define hydro_x25519_PUBLICKEYBYTES 32
#define hydro_x25519_SECRETKEYBYTES 32
just FYI: the original code does work with ESP8266 RTOS SDK v3.4.
I was trying to port this to esp8266, compiled and uploads fine but i get constant crash and reboot, here is the decoded stack trace, my board version 2.6.3
here is the sketch all crypto and wireguard were placed on the root of the sketch.