jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.25k stars 1.74k forks source link

Different results on different platforms using crypto_secretbox_easy #857

Closed lucas2412 closed 5 years ago

lucas2412 commented 5 years ago

Hello,

we are trying to integrate libsodium in our Android App and this NRF Microcontroller (https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840). We succesfully integrated libsodium in our Android App and now we are trying to integrate it on the NRF Chip with C.

The problem is that we have 2 completely different results using crypto_secretbox_easy on those 2 Platforms.

Android:

    Sodium sodium = NaCl.sodium();
    String nonce = "88FDEFD7F941B63C242B7F84B3D786886340A4A8B1C1EAA0";
    String SHARED_KEY = "217FCB0F18CAF284E9BDEA0B94B83B8D10867ED706BFDEDBD2381F4CB3B8F730";
    byte[] message="test".getBytes();

    long ciphertextlen=Sodium.crypto_box_macbytes()+message.length;
    byte[] ciphertext=new byte[(int)ciphertextlen];

    int ret=Sodium.crypto_secretbox_easy(ciphertext, message, message.length, hexToBytes(nonce),hexToBytes(SHARED_KEY));

    byte[] decrypted=new byte[ciphertext.length - Sodium.crypto_box_macbytes()];
    ret=Sodium.crypto_secretbox_open_easy(decrypted, ciphertext, (int)ciphertextlen, hexToBytes(nonce),
            hexToBytes(SHARED_KEY));

Cleartext: test Encrypted (hex): 12953B678834AE08A11D2E12A064B11A63906C17 Decrypted: test

NRF Microcontroller

    sodium_init();

    #define MESSAGE ((const unsigned char *) "test")
    #define SHARED_KEY ((const char *) "217FCB0F18CAF284E9BDEA0B94B83B8D10867ED706BFDEDBD2381F4CB3B8F730")
    #define NONCE ((const char *) "88FDEFD7F941B63C242B7F84B3D786886340A4A8B1C1EAA0")
    #define MESSAGE_LEN 4
    #define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)

    unsigned char key[crypto_secretbox_KEYBYTES];
    unsigned char nonce[crypto_secretbox_NONCEBYTES];
    unsigned char ciphertext[CIPHERTEXT_LEN];

    hextobytes(SHARED_KEY, strlen(SHARED_KEY), key, sizeof(key));
    hextobytes(NONCE, strlen(NONCE), nonce, sizeof(nonce));

    int ret = crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);

    unsigned char decrypted[MESSAGE_LEN];

    int ret2 = crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key)

Cleartext: test Encrypted (hex): 3A2E66068C8A9180C2B9434079E1805BF8D701DC Decrypted: test

We also removed randombytes_stir() and _sodium_alloc_init() from sodium_init() since our microcontroller doesn't support generating random numbers (We don't need it). Could the problem be here?

For us its not possible to encrypt something on Android and decrypt it with the NRF Controller.

Thanks in advance.

jedisct1 commented 5 years ago

Running your NRF code on MacOS returns the same result as your Android code.

So, the issue is on the NRF side. This is a completely unsupported, untested platform for libsodium, so unfortunately you are on your own.

Libhydrogen may be easier and safer to use on that platform.

lucas2412 commented 5 years ago

Do you have any ideas what we could maybe try to solve this?

Are there any Libsodium encryption functions that are compatible with Libhydrogen?

jedisct1 commented 5 years ago

How do you compile it? Using the ./configure script? Were you able to run the test suite?

Libhydrogen encryption functions are not compatible with libsodium.

lucas2412 commented 5 years ago

I downloaded the latest stable version and compiled it using MSYS on Windows 10 with the ./configure script and make. After that Iimported the compiled folder into my GCC Project in VisualGDB.

jedisct1 commented 5 years ago

How did you get the DLL file to run on the microcontroller?

lucas2412 commented 5 years ago

The DLL file doesn't run on the Microcontroller. I just put the whole folder into my VisualGDB Project. When I run the project VisualGDB uses the ARM Toolchain to compile the source code for the nrf chip.

jedisct1 commented 5 years ago

If the project was configured for MingW, it is unlikely to be correct for a different platform.

You should try to cross-compile for the actual target: https://download.libsodium.org/doc/installation#cross-compiling

jedisct1 commented 5 years ago

As a side note, I would strongly recommend against using libsodium on that platform since it has no protection against side channels in the modular addition used by the Salsa20 cipher.

The nRF52840 chip has hardware support for AES, so you should really use that instead. This will also significantly improve speed and reduce power consumption.

jedisct1 commented 5 years ago

libhydrogen has Android bindings now: https://github.com/libly/hydride-android