mbedTLS ECDH shared secret alignment issue

Hi @roneld01 and everyone,

I’m using the mbedtls lib’s ECDH to generate a shared secret on client and server side:

  1. Client: Ubuntu 64-bit running my c-sdk which has integrated mbedtls lib
  2. Server: Embedded microcontroller 32-bit ARM Cortex-M4 platform also running mbedtls lib

The shared secret output:


  1. Server: 5218A8E5 15F52B99 F911581C B1C37386 7BADD6E1 7200115B 42B20BF9 25B34BAE
  2. Client : 15F52B99 5218A8E5 B1C37386 F911581C 7200115B 7BADD6E1 25B34BAE 42B20BF9

As you can see, the secrets are word swapped
The above shared secrets are generated after exchanging the public keys.

The shared secret is printed from the mbedtls_ecdh_context struct which is as follows:

typedef struct
{
    mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
    mbedtls_mpi d;           /*!< The private key. */
    mbedtls_ecp_point Q;     /*!< The public key. */
    mbedtls_ecp_point Qp;    /*!< The value of the public key of the peer. */
    mbedtls_mpi z;           /*!< The shared secret. */
    int point_format;        /*!< The format of point export in TLS messages. */
    mbedtls_ecp_point Vi;    /*!< The blinding value. */
    mbedtls_ecp_point Vf;    /*!< The unblinding value. */
    mbedtls_mpi _d;          /*!< The previous \p d. */
}
mbedtls_ecdh_context;

I print out the mbedtls_mpi z object which is defined as follows:

typedef struct
{
    int s;              /*!<  integer sign      */
    size_t n;           /*!<  total # of limbs  */
    mbedtls_mpi_uint *p;          /*!<  pointer to limbs  */
}
mbedtls_mpi;

The mbedtls_mpi_uint is defined in the mbedtls lib as uin32_t for the Server side and uint64_t for the client side.

Is the word swap a bug in mbedtls library?
How should this be handled? Is there any documentation that addresses this?

Thank you,
Dhaval

Hi @dhavalhparikh26
Thank you for your question!

How are you printing the secret on your ubuntu client?
Is it possible that the issue is in the printing function?
What is the architecture of your server and client? Do they have same endianess?

Regards,
Mbed TLS Team member
Ron

Hi @roneld01
To answer your questions:

  1. I’m printing the shared secret in the following manner:
     for (uint16_t i=0; i<ctx->z.n; i++) {
         printf("%02lX", ctx->z.p[i]);
     }

Using the above method to print out shared secret would give me word-misaligned shared secret.

I also found the mbedtls_mpi_write_binary() function which would write the MPI to the buffer we provide. Should I be using that to extract the shared secret instead?
Using mbedtls_mpi_write_binary() on both client and server side actually gives the same shared secret without any issues!

  1. The server and client are both little-endian systems. The client is a 64-bit platform and server is a 32-bit ARM Cortex M4 microcontroller.

Thank you,
Dhaval

Hi @dhavalhparikh26
Thank you for your information!

Should I be using that to extract the shared secret instead?

Yes, this function is intended to take the mpi and write it to a binary buffer, in the correct format and endianity

Regards