This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ECC create key, sign and verify sample code

Hi everybody

I want to implement the ECC creation key, sign and verify purpose. But I didn't find sample code in google or in the renesas website.

Does some people who already implement these things ?

Someone have a small example code to start ?

Thanks

  • Hi Tomtom,

     

    Here is an example of how to use the HAL layer ECC to generate keys then sign and verify.

    /* HAL-only entry function */
    #include "hal_data.h"
    #include "string.h"

    /* Recommended Parameters secp256k1
    *
    * Curve E: y^2 = x^3 +ax + b
    *
    */
    uint8_t domain[ECC_256_DOMAIN_PARAMETER_WITH_ORDER_LENGTH_WORDS * sizeof(uint32_t)] =
    {
    /* a */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    /* b */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
    /* p = 2^192-2^64-1 */
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
    /* n */
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
    0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
    };
    /*
    *
    * Base Point G (uncompressed)
    *
    */
    uint8_t generator_point[ECC_256_GENERATOR_POINT_LENGTH_WORDS * sizeof(uint32_t)] =
    {
    /* x */
    0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95,
    0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9,
    0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98,
    /* y */
    0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc,
    0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19,
    0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8,
    };

    static uint8_t public_key[ECC_256_PUBLIC_KEY_LENGTH_WORDS * sizeof(uint32_t)]; // plain text key
    static uint8_t wrapped_private_key[ECC_256_PRIVATE_KEY_HRK_LENGTH_WORDS * sizeof(uint32_t)]; // wrapped key


    void hal_entry(void)
    {
    ssp_err_t status;
    /*
    * Create the data handles that the crypto layer uses to access the data
    */
    r_crypto_data_handle_t domain_handle = {(uint32_t *) domain, sizeof(domain)/sizeof(uint32_t)};
    r_crypto_data_handle_t generator_point_handle ={(uint32_t *) generator_point, sizeof(generator_point)/sizeof(uint32_t)};
    r_crypto_data_handle_t public_key_handle = {(uint32_t *) public_key, sizeof(public_key)/sizeof(uint32_t)};
    r_crypto_data_handle_t wrapped_private_key_handle = {(uint32_t *) wrapped_private_key, sizeof(wrapped_private_key)/sizeof(uint32_t)};


    /*
    * We must open the SCE common driver before any crypto operations
    */
    status = g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg);
    if (status)
    __BKPT();

    /*
    * Open the ECC driver
    */
    status = g_sce_ecc_0.p_api->open( g_sce_ecc_0.p_ctrl, g_sce_ecc_0.p_cfg);
    if (status)
    __BKPT();

    /*
    * Create the key pair
    */
    status = g_sce_ecc_0.p_api->keyCreate(g_sce_ecc_0.p_ctrl, &domain_handle, &generator_point_handle, &wrapped_private_key_handle, &public_key_handle);
    if (status)
    __BKPT();

    /*
    * Sign the message digest (hash of a data message)
    *
    * This is a common use case to verify the identity of the sender of a blob of data if we know the public key of the sender
    * The sender would generate a hash over the blob of data and then sign the hash with the private key. The recipient of the blob & the signed hash
    * would then use the public key to verify the signature of the hash and then use the hash to verify the blob of data is correct.
    *
    */
    uint8_t message_digest [ECC_256_MESSAGE_DIGEST_LENGTH_WORDS * sizeof(uint32_t)] = {
    0x7f, 0xed, 0x57, 0x68, 0xb2, 0x85, 0xc9, 0xa2, 0x5b, 0xf0, 0x07, 0xf7, 0x9d, 0x32, 0x48, 0xb5,
    0x5e, 0xba, 0x61, 0x8d, 0xfa, 0x40, 0x52, 0x7d, 0xda, 0x58, 0x0a, 0x32, 0x55, 0x56, 0xcd, 0x10
    };

    uint8_t sign_r[ECC_256_SIGNATURE_R_LENGTH_WORDS * sizeof(uint32_t)];
    uint8_t sign_s[ECC_256_SIGNATURE_S_LENGTH_WORDS * sizeof(uint32_t)];

    /*
    * Create the data handles that the crypto layer uses to access the data
    */
    r_crypto_data_handle_t message_digest_handle = {(uint32_t *) message_digest, ECC_256_MESSAGE_DIGEST_LENGTH_WORDS};
    r_crypto_data_handle_t sign_r_handle = {(uint32_t *) sign_r, ECC_256_SIGNATURE_R_LENGTH_WORDS};
    r_crypto_data_handle_t sign_s_handle = {(uint32_t *) sign_s, ECC_256_SIGNATURE_S_LENGTH_WORDS};

    status = g_sce_ecc_0.p_api->sign(g_sce_ecc_0.p_ctrl, &domain_handle, &generator_point_handle, &wrapped_private_key_handle, &message_digest_handle, &sign_r_handle, &sign_s_handle);
    if (status)
    __BKPT();

    /*
    * Verify the signature
    *
    * This would normally be on a different system...
    *
    */
    status = g_sce_ecc_0.p_api->verify(g_sce_ecc_0.p_ctrl, &domain_handle, &generator_point_handle, &public_key_handle, &message_digest_handle, &sign_r_handle, &sign_s_handle);
    if (status)
    __BKPT();

    }

     

    -Gary

  • Hello,

    Following up on this thread.

    My team is looking into using ECDSA for signing and verifying our S5D9 applications, using the SCE7 HAL drivers. I started with a feasibility test using the secp256k1 parameters and Gary's sample code. We're using a bootloader plus two application images built for MMF, and the testing has been successful.

    One of the secure signing servers we are looking at doesn't support secp256k1, so we changed the algorithm to use secp256r1. So far so good. But that has led us to ask a question on the security of our private keys.

    Say our private key is stolen and a bad actor wants to build his own image, sign it, and have it accepted as authentic by our bootloader (using our public key). If he does steal the private key, doesn't he also have to know the underlying ECC curve we are using? Otherwise how can he sign his image so our bootloader will successfully verify it? Is there some way of inferring the EC parameters if you only know the private key?

    tom

  • Hello ! This is a really old post, and will be locked. So I'll encourage you to create a new post explaining the issue.

    Thank you,
    Jayesh

    If this response, or one provided by another user, answers your question, please verify the answer. Thank you!
    Renesas Engineering Community Moderators
    https://community.renesas.com/
    https://academy.renesas.com/
    en-support.renesas.com/.../