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:
- Generate and store a key pair (private and public).
- 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;
}