Mistake on this page? Email us

Generating keys and CSRs

KCM provides the following APIs for generating keys and certificate signing requests (CSRs):

  • kcm_key_pair_generate_and_store() generates and stores a key pair (private and public keys).
  • kcm_csr_generate() generates a CSR using a previously generated and stored private key.
  • kcm_generate_keys_and_csr() generates a key pair, stores it, and generates a CSR using the private key.

Note: The kcm_generate_keys_and_csr() API combines the functionality of the kcm_key_pair_generate_and_store() and kcm_csr_generate() APIs.

You must allocate a buffer to hold the created CSR before using the kcm_csr_generate() or kcm_generate_keys_and_csr() APIs.

Generating and storing a key pair

The KCM API for generating and storing a key pair (private and public keys) is kcm_key_pair_generate_and_store().

You need to provide:

  • The public and private keys names and lengths, specifying whether the keys are factory items.
  • The cryptographic scheme. Currently, the API supports only the elliptic-curve cryptography (ECC) scheme.

To store only the private key, set the public_key_name parameter to NULL and the public_key_name_len parameter to 0.

Note: The public key will still be generated, but not stored.

Example of how to generate and store a key pair

kcm_status_e kcm_status;
char private_key_name[] = "priv_test_key_name";
char public_key_name[] = "pub_test_key_name";

// Generating and storing key pair
kcm_status = kcm_key_pair_generate_and_store(KCM_SCHEME_EC_SECP256R1, (uint8_t*)private_key_name, strlen(private_key_name), (uint8_t*)public_key_name, strlen(public_key_name), true, NULL);
if(kcm_status != KCM_STATUS_SUCCESS) {
    return 1;
}

Example of how to generate a key pair and store the private key

kcm_status_e kcm_status;
char private_key_name[] = "prv_sample_key";  

// Generating and storing key pair
kcm_status = kcm_key_pair_generate_and_store(KCM_SCHEME_EC_SECP256R1, (uint8_t*)private_key_name, strlen(private_key_name), NULL, 0, true, NULL);
if(kcm_status != KCM_STATUS_SUCCESS) {
    return 1;
}

Generating a CSR from a given private key

The KCM API for generating a CSR from a given (previously stored) private key is kcm_csr_generate().

You need to provide:

  • The existing private key name (and its length) that will sign the generated CSR.

  • The output CSR buffer and its size.

  • An instance of the kcm_csr_params_s structure populated with the attributes required to generate the CSR.

    The attributes are:

    • subject: Subject name of the CSR. Consists of a comma-separated list of the Object Identifier (OID) types and values; for example, "C=UK,O=ARM,CN=mbed TLS Server 1".
      See the instructions for generating a CSR for the full list of supported OIDs.
    • md_type: Message digest. Only SHA256 is currently supported.
    • key_usage: Key usage extension in integer bit-mask format, where:
      • bit 0 - Digital signature key usage extension bit.
      • bit 1 - Non-repudiation key usage extension bit.
      • bit 2 - Certificate signing key usage extension bit.
      • bit 3 - Key agreement key usage extension bit.
    • ext_key_usage: Extended key usage extension in integer bit-mask format, where:
      • bit 0 - Any extended key usage.
      • bit 1 - Server authentication.
      • bit 2 - Client authentication.
      • bit 3 - Code signing.
      • bit 4 - Email protection.
      • bit 8 - Time stamping.
      • bit 9 - OCSP signing.

Example of how to generate a CSR from a private key

kcm_status_e kcm_status;
char private_key_name[] = "priv_test_key_name";
kcm_csr_params_s csr_params = { "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd",  //subject
                                 KCM_MD_SHA256,                                     //md
                                 KCM_CSR_KU_DIGITAL_SIGNATURE,                     //Key Usage -  digital signature
                                 KCM_CSR_EKU_CLIENT_AUTH,                          // Extended Key Usage - Client Auth
                              };
uint8_t csr_buffer[1024] = { 0 };
size_t csr_act_size = 0;   

// Generating CSR from existing private key
kcm_status = kcm_csr_generate(private_key_name, strlen(private_key_name), &csr_params, csr_buffer, sizeof(csr_buffer), &csr_act_size);
if(kcm_status != KCM_STATUS_SUCCESS) {
    return 1;
}

* To calculate the approximate size of the CSR buffer size that you must allocate, take the sum of the public key size, signature size, and kcm_csr_params_s size, and add 100 extra bytes for asn.1 encoding.

Generating a key pair and creating a CSR

The KCM API for generating a key pair and CSR from a given private key is kcm_generate_keys_and_csr().

This API is a combination of the two APIs mentioned above and its signature is a superset of their parameters. You can generate a key pair and CSR signed by the generated private key by calling this single API.

This is the recommended API to use if your goal is to generate a CSR when the key pair required for its generation was not stored in KCM before.

Examples of how to generate a key pair and create a CSR

kcm_status_e kcm_status;
char private_key_name[] = "priv_test_key_name";
char public_key_name[] = "pub_test_key_name";
kcm_csr_params_s csr_params = { "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd",  //subject
                                 KCM_MD_SHA256,                                     //md
                                 KCM_CSR_KU_DIGITAL_SIGNATURE | KCM_CSR_KU_NON_REPUDIATION,  //Key Usage -  digital signature and non-repudiation extensions
                                 KCM_CSR_EKU_CLIENT_AUTH,                          // Extended Key Usage - Client Auth
                              };
uint8_t csr_buffer[1024] = { 0 };
size_t csr_act_size = 0;  

status = kcm_generate_keys_and_csr(KCM_SCHEME_EC_SECP256R1, (uint8_t*)private_key_name, strlen(private_key_name), (uint8_t*)public_key_name, strlen(public_key_name), true, &csr_params, csr_buffer, sizeof(csr_buffer), &csr_act_size, NULL);
    TEST_ASSERT_TRUE(status == KCM_STATUS_SUCCESS);

Alternatively, you can create the same CSR using the following two-step process:

  1. Generate and store a key pair (private and public).
  2. Generated a CSR from the stored private key.
kcm_status_e kcm_status;
char private_key_name[] = "priv_test_key_name";
char public_key_name[] = "pub_test_key_name";
kcm_csr_params_s csr_params = { "C=AU, ST=Some-State, O=Internet Widgits Pty Ltd",  //subject
                                 KCM_MD_SHA256,                                     //md
                                 KCM_CSR_KU_DIGITAL_SIGNATURE | KCM_CSR_KU_NON_REPUDIATION,  //digital signature and non-repudiation extensions
                                 KCM_CSR_EKU_CLIENT_AUTH,                          // Extended Key Usage - Client Auth
                              };
uint8_t csr_buffer[1024] = { 0 };
size_t csr_act_size = 0;   

// Generating and storing (new) key pair
kcm_status = kcm_key_pair_generate_and_store(KCM_SCHEME_EC_SECP256R1, (uint8_t*)private_key_name, strlen(private_key_name), (uint8_t*)public_key_name, strlen(public_key_name), true, NULL);
if(kcm_status != KCM_STATUS_SUCCESS) {
    return 1;
}

// Generating CSR from existing private key
kcm_status = kcm_csr_generate(private_key_name, strlen(private_key_name), &csr_params, csr_buffer, sizeof(csr_buffer), &csr_act_size);
if(kcm_status != KCM_STATUS_SUCCESS) {
    return 1;
}