From 761ed24142854383f5f95ae65aa6571c1f3e477c Mon Sep 17 00:00:00 2001 From: Marouene Boubakri Date: Fri, 24 Nov 2023 17:20:48 +0100 Subject: [PATCH] ta: pkcs11: processing.c: calculate KCV on key generation Modify generate_random_key_value() to fill in the CKA_CHECK_VALUE with the key check value (KCV) after CKA_VALUE is filled. The template passed to C_GenerateKey() can set CKA_CHECK_VALUE attribute. In which case we should not omit it but ensure it complies with a valid value, that is either a zero-sized value or the value the pkcs11 TA also computes. Other values for this attribute should error with return code CKR_ATTRIBUTE_VALUE_INVALID. Signed-off-by: Marouene Boubakri --- ta/pkcs11/src/processing.c | 61 +++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/ta/pkcs11/src/processing.c b/ta/pkcs11/src/processing.c index 6be34829db2..a3ba2fbdab1 100644 --- a/ta/pkcs11/src/processing.c +++ b/ta/pkcs11/src/processing.c @@ -166,10 +166,12 @@ size_t get_object_key_bit_size(struct pkcs11_object *obj) static enum pkcs11_rc generate_random_key_value(struct obj_attrs **head) { enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; - void *data = NULL; uint32_t data_size = 0; uint32_t value_len = 0; + uint32_t kcv_len = 0; void *value = NULL; + void *data = NULL; + void *kcv = NULL; if (!*head) return PKCS11_CKR_TEMPLATE_INCONSISTENT; @@ -195,8 +197,65 @@ static enum pkcs11_rc generate_random_key_value(struct obj_attrs **head) TEE_GenerateRandom(value, value_len); rc = add_attribute(head, PKCS11_CKA_VALUE, value, value_len); + if (rc != PKCS11_CKR_OK) + goto out; + + /* Get key check value size */ + rc = aes_get_check_value_size(value, value_len, &kcv_len); + if (rc) + goto out; + + kcv = TEE_Malloc(kcv_len, TEE_MALLOC_FILL_ZERO); + if (!kcv) { + rc = PKCS11_CKR_DEVICE_MEMORY; + goto out; + } + + /* Compute and add the key check sum value*/ + rc = aes_compute_check_value(value, value_len, kcv, &kcv_len); + if (rc) + goto out; + /* Check whether CKA_CHECK_VALUE has been provided in the template */ + data = NULL; + data_size = 0; + rc = get_attribute_ptr(*head, PKCS11_CKA_CHECK_VALUE, + &data, &data_size); + if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) { + rc = PKCS11_CKR_GENERAL_ERROR; + goto out; + } + + /* + * The generation of the KCV may be prevented by the application + * supplying the attribute in the template as a no-value (0 length) + * entry. + */ + if (rc == PKCS11_CKR_OK) { + if (data_size == 0) + goto out; + + if (data_size != kcv_len) { + rc = PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; + goto out; + } + + /* + * If the computed KCV does not match the provided one + * then return CKR_ATTRIBUTE_VALUE_INVALID + */ + if (TEE_MemCompare(data, kcv, kcv_len)) { + EMSG("@@@@@ KCV does not match the provided ! @@@@"); + rc = PKCS11_CKR_ATTRIBUTE_VALUE_INVALID; + goto out; + } + } + + rc = add_attribute(head, PKCS11_CKA_CHECK_VALUE, kcv, kcv_len); + +out: TEE_Free(value); + TEE_Free(kcv); return rc; }