This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf_crypto_ecdsa_sign_hash() returns internal error, but signature is verified by nrf_crypto_ecdsa_verify_hash()

Hi,

I am using microecc to create a ecdsa signature and verifying with my public key. When calling nrf_crypto_ecdsa_sign_hash() to sign the hash it returns with NRF_ERROR_INTERNAL, if i ignore this error and verify the signature, hash by calling nrf_crypto_ecdsa_verify_hash() it says it is correct. If i change any of the inputs for nrf_crypto_ecdsa_verify_hash(), it results in verification failed. It shows nrf_crypto_ecdsa_verify_hash() is working correctly. So my question is do we ignore nrf_crypto_ecdsa_sign_hash() when it returns NRF_ERROR_INTERNAL?

Please advice. Thanks in advance.

code:

NRF_CRYPTO_HASH_CREATE(init_hash, SHA256);

NRF_CRYPTO_ECDSA_SIGNATURE_CREATE(crypto_sig, SECP256R1);
NRF_CRYPTO_ECC_PUBLIC_KEY_RAW_CREATE(crypto_key_pk, SECP256R1);

const nrf_crypto_signature_info_t sig_info_p256 =
{
    .curve_type     = NRF_CRYPTO_CURVE_SECP256R1,
    .hash_type      = NRF_CRYPTO_HASH_TYPE_SHA256,
    .endian_type    = NRF_CRYPTO_ENDIAN_BE
};
const nrf_crypto_curve_info_t curve_info_p256 =
{
    .curve_type     = NRF_CRYPTO_CURVE_SECP256R1,
    .endian_type    = NRF_CRYPTO_ENDIAN_BE
};
const nrf_crypto_hash_info_t hash_info_sha256 =
{
    .hash_type = NRF_CRYPTO_HASH_TYPE_SHA256,
    .endian_type = NRF_CRYPTO_ENDIAN_BE
};
{
 err_code = nrf_crypto_hash_compute(hash_info_sha256, msg, 16, hash);
        private_key.p_value = (uint8_t *)crypto_key_sk;
        private_key.length = 32;
        err_code =  nrf_crypto_ecdsa_sign_hash(sig_info_p256,
                                            &private_key,
                                            &init_hash,
                                            &crypto_sig);
           NRF_LOG_INFO("err %d .\r\n",err_code);

           err_code =  nrf_crypto_ecc_public_key_calculate(curve_info_p256,
                                                           &private_key,
                                                        &crypto_key_pk);

             // crypto_key_pk.p_value[1] = 0x00;
         if( (nrf_crypto_ecdsa_verify_hash(sig_info_p256, &crypto_key_pk, &init_hash, &crypto_sig)) !=NRF_SUCCESS )
         {
             NRF_LOG_INFO("verification failed %d .\r\n",err_code);
         }
         else
         {
             NRF_LOG_INFO("Signature verified \r\n");
         }
}
  • How do you initialize the crypto library, and what configuration have you set in sdk_config.h?

  • I just call nrf_crypto_init() and sdk_config.h

    //==========================================================
    
    // <h> nRF_Crypto 
    
    //==========================================================
    // <e> NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library
    //==========================================================
    #ifndef NRF_CRYPTO_ENABLED
    #define NRF_CRYPTO_ENABLED 1
    #endif
    #if  NRF_CRYPTO_ENABLED
    // <q> NRF_CRYPTO_BACKEND_CC310_LIB  - Enables the ARM Cryptocell CC310 backend
     
    
    // <i> The hardware-accelerated cryptography backend is available only on nRF52840.
    
    #ifndef NRF_CRYPTO_BACKEND_CC310_LIB
    #define NRF_CRYPTO_BACKEND_CC310_LIB 0
    #endif
    
    // <e> NRF_CRYPTO_BACKEND_MICRO_ECC - Enables the micro-ecc software backend
    
    // <i> The micro-ecc library provides a software implementation of ECC cryptography for nRF5 Series devices.
    //==========================================================
    #ifndef NRF_CRYPTO_BACKEND_MICRO_ECC
    #define NRF_CRYPTO_BACKEND_MICRO_ECC 1
    #endif
    #if  NRF_CRYPTO_BACKEND_MICRO_ECC
    // <q> NRF_CRYPTO_BACKEND_SW  - Enables hashing
     
    
    // <i> If enabled, the cryptography library supports hashing (needed for signing).
    
    #ifndef NRF_CRYPTO_BACKEND_SW
    #define NRF_CRYPTO_BACKEND_SW 1
    #endif
    
    // <q> NRF_CRYPTO_SUPPORTS_RNG  - Enables RNG
     
    
    // <i> If enabled, the cryptography library supports random number generation (needed for key generation).
    
    #ifndef NRF_CRYPTO_SUPPORTS_RNG
    #define NRF_CRYPTO_SUPPORTS_RNG 1
    #endif
    
  • nrf_crypto_ecdsa_sign_hash() calls uECC_sign() calls uECC_sign_with_k() returning 1, uECC_sign() is returning with 1 but in micro_ecc_lib_ecdsa.c

    if(uECC_sign(p_private_key->p_value, p_hash->p_value, p_hash->length, p_signature->p_value, p_curve))
    {
        return NRF_ERROR_INTERNAL;
    }
    

    It looks like you are just returning NRF_ERROR_INTERNAL for a valid signature.

  • You are correct, the line should be changed to:

    if (uECC_sign(p_private_key->p_value, p_hash->p_value, p_hash->length, p_signature->p_value, p_curve) == 0)
    

    This have already been reported internally and should be fixed in future SDK versions.

Related