PolarSSL is now part of ARM Official announcement and rebranded as mbed TLS.

MBEDTLS_ERR_MPI_ALLOC_FAILED from mbedtls_ecdh_gen_public()


Nov 3, 2017 12:50
Remo

Hello

We are using mbedtls on an embedded system. Always if I want to generate a ECDH public key, I get an error as return value from the mbedtls_ecdh_gen_public() function. The error is called MBEDTLS_ERR_MPI_ALLOC_FAILED. What does this error mean? The code sequence is written below. What shall I change to generate successful an ECDH key?

Thanks

mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ecdh_context ctx;
unsigned char send_buf[150] = { 0 };
static unsigned char recv_buf[150] = { 0 };
unsigned char secret_buf[150] = { 0 };
const unsigned char *p;
static size_t send_len, recv_len, secret_len;
const char pers[] = "Sample ECDH client";
static int ret;
static mbedtls_ecp_curve_info info[20];

mbedtls_ecdh_init( &ctx );
mbedtls_ctr_drbg_init( &ctr_drbg );

if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, MyRngEntropyFunc, &entropy,(unsigned char *) pers, strlen( pers ) ) ) != 0 )
{
    // Error
}

ret = mbedtls_ecp_group_load(&ctx.grp, MBEDTLS_ECP_DP_SECP192R1);
if( ret != 0 )
{
    // Error
}

ret = mbedtls_ecdh_gen_public(&ctx.grp, &ctx.d, &ctx.Q, MyRngEntropyFunc, &ctr_drbg);
if( ret != 0 )
{
    // Error
}
 
Nov 5, 2017 13:47
Ron Eldor

Hi Remo, As the documentation suggestes, the error you are receiving is failure to allocate the bignumber.
From your description, it the error is most likely returned by mbedtls_mpi_grow().:

    if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );

and

      if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
            return( MBEDTLS_ERR_MPI_ALLOC_FAILED );

Since MBEDTLS_MPI_MAX_LIMBS is defined as 10000, I assume that the error is returned by mbedtls_calloc() returning NULL, on your platform.
Note that nblimbs is determined in mbedtls_mpi_read_binary(), as how many limbs needed from the first byte in the buffer that isn't zero -> Please check your entropy function (MyRngEntropyFunc()), and check that it doesn't output only zeros, causing nblimbs to be zero.
In addition, you have a mistake in your mbedtls_ecdh_gen_public() call. The random function callback should be the random function, not the entropy function, which in your case is mbedtls_ctr_drbg_random() (as opposed to MyRngEntropyFunc() you have used).
Regards,
Mbed TLS Team member
Ron

 
Nov 7, 2017 16:16
Remo

Thank you for your help. The error returned from the mbedtls_calloc(), how you had supposed. The generation of the ECDH keys works correct.

I have further question about the implementation of the mbedtls library. I use ECDH to generate the keys. I want to make a self-signed certificate. Is it possible to make a self-signed certificate on an embedded system? Is there an example, which shows how to implement the self-signed certificate with ECDH?

I have read following link: How to generate a self-signed certificate

I have also tried to understand the examples in the mbedtls/programs/x509/ folder. Is it possible to run those examples on an embedded system?

Thanks

regards

 
Nov 7, 2017 16:44
Ron Eldor

Hi Remo,
For the benefit of the community, please create new posts on new topics next time.
I think you might have some confusion. ECDH is used for key exchange, not for signing and verifying certificates.
Are you trying to generate a self signed certificate on run-time?
The given examples, are mostly used on PC, as they use features such as file system. However, these examples use Mbed TLS API, and you could use these examples as reference for you to create the self signed certificate.
I am having a bit of trouble understanding your use case though, are you generating a key pair every run? Are you generating a certificate every run? Note that these operations are time consuming.
Regards,
Mbed TLS Team member
Ron

 
Nov 7, 2017 23:02
Remo

Hello

Sorry, I will create a new topic next time.

I guess I explained it wrong. First, I create a public and private key with ECDH. I generate the key pair one time. After that, I want to use a self signed certificiate. No, I’m not trying to generate a self signed certificate on run-time.

My questions are:

What are the next steps (after the creation of the key pair) to iplement successful a self signed certificate? Which functions are important for me?

Which example shall I read for self signed certificate on an embedded system?

Thank you

Best regards

 
Nov 8, 2017 08:26
Ron Eldor

Hi Remo,
Thank you for your explanation.
If you don't need to create the certificate in run time, can't you create it in PC and use it on your platform?
The article you referenced shows how to generate a self signed certificate. You could use this article as your basis, and adjust the functionality to work on embedded system, instead of PC, e.g. use buffers instead of files.
I hope this hint helps
Regards,
Mbed TLS Team member
Ron

 
Nov 8, 2017 09:40
Remo

Hi Ron

Thanks for your hints. As first I will try it how you have explained.

If I use a PC generated certificate on an embedded system I have always the same key pair. Am I right? If I want to use a key pair, which is generated on the embedded system, Do I need to generate the certificate also on the embedded system, right?

If I want to do it on my embedded system, which example can you recommend? I have no filesystem on my platform. Does it make sense to try it on the embedded system?

Thanks

Regards

 
Nov 8, 2017 11:57
Ron Eldor

Hi Remo,

If I use a PC generated certificate on an embedded system I have always the same key pair. Am I right?

A certificate is signed with a single private key (from a key pair), so if you use the same certificate, you would use the same key pair.

If I want to use a key pair, which is generated on the embedded system, Do I need to generate the certificate also on the embedded system, right?

If you are able to export your generated key pair into a file, (for example, by sending the output buffer through UART to your PC) , then you can still generate the certificate on your PC, but this isn't much practical in real use case.

If I want to do it on my embedded system, which example can you recommend? I have no filesystem on my platform. Does it make sense to try it on the embedded system?

You could use the existing examples described in the article, except you should modify all the functionality that writes to a file, into keeping the data in a buffer.
For example, the functionality of gen_key and cert_write could be combined into one function, makeing output of one functionality( generated key) be one of the inputs for the second functionality ( generated certificate ).
Note that gen_key is basically wrappers for mbedtls_rsa_gen_key()/mbedtls_ecp_gen_key() and mbedtls_pk_write_key_pem()/mbedtls_pk_write_key_der() and cert_write is basically a wrapper for a sequence of mbedtls_x509write_crt_set_XXXX() and mbedtls_x509write_crt_pem() at the end.
Regards,
Mbed TLS Team member
Ron

 
Nov 23, 2017 04:38
Ashwini Chandrappa

Hi, We are using mbedtls on an embedded system. we are using mbedtls_ecdsa_genkey to generate a key pair, I'm getting an error in mbedtls_calloc though the value of nlimbs is not zero and mbedtls_calloc is invoking platform_free_uninit function in platform.c and returning null. could you please help me out in solving this issue.

 
Nov 23, 2017 15:04
Ron Eldor

Hi Ashwini,
I apologize, but I am not sure what your flow is.
According to your description, I am guessing that you have MBEDTLS_PLATFORM_MEMORY defined, but you don't have MBEDTLS_PLATFORM_STD_CALLOC defined, which will define platform_calloc_uninit():

static void *platform_calloc_uninit( size_t n, size_t size )
{
    ((void) n);
    ((void) size);
    return( NULL );
}

If this is not the case, please elaborate about your use case and flow.
Regards,
Mbed TLS Team member
Ron