Blob Blame History Raw
commit 62fc2bcd98672c5d0ff8a2c926f3103110e91ed7
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date:   Thu Jul 1 13:37:04 2021 +0200

    COMMON: Perform proper context cleanup for 3DES/AES CMAC mechanisms
    
    The handling of 3DES/AES CMAC mechanisms use a complex context structure,
    that contains pointers. Such state can not be saved, and needs a custom
    context free routine to properly clean up the context.
    
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

diff --git a/usr/lib/common/mech_aes.c b/usr/lib/common/mech_aes.c
index ad6af16b..59f82482 100644
--- a/usr/lib/common/mech_aes.c
+++ b/usr/lib/common/mech_aes.c
@@ -2691,6 +2691,24 @@ CK_RV aes_mac_verify_final(STDLL_TokData_t *tokdata,
     return CKR_SIGNATURE_INVALID;
 }
 
+static void aes_cmac_cleanup(STDLL_TokData_t *tokdata, SESSION *sess,
+                             CK_BYTE *context, CK_ULONG context_len)
+{
+    UNUSED(tokdata);
+    UNUSED(sess);
+    UNUSED(context_len);
+
+    if (((AES_CMAC_CONTEXT *)context)->ctx != NULL) {
+        token_specific.t_aes_cmac(tokdata, (CK_BYTE *)"", 0, NULL,
+                                  ((AES_CMAC_CONTEXT *)context)->iv,
+                                  CK_FALSE, CK_TRUE,
+                                  ((AES_CMAC_CONTEXT *)context)->ctx);
+        ((AES_CMAC_CONTEXT *)context)->ctx = NULL;
+    }
+
+    free(context);
+}
+
 CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata,
                     SESSION *sess,
                     CK_BBOOL length_only,
@@ -2743,6 +2761,8 @@ CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata,
     if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = aes_cmac_cleanup;
+
     memcpy(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, mac_len);
     *out_data_len = mac_len;
 
@@ -2816,6 +2836,8 @@ CK_RV aes_cmac_sign_update(STDLL_TokData_t *tokdata,
 
             if (context->ctx != NULL)
                 ctx->state_unsaveable = CK_TRUE;
+
+            ctx->context_free_func = aes_cmac_cleanup;
         } else {
             TRACE_DEVEL("Token specific aes cmac failed.\n");
         }
@@ -2882,6 +2904,8 @@ CK_RV aes_cmac_sign_final(STDLL_TokData_t *tokdata,
     if (context->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = aes_cmac_cleanup;
+
     memcpy(out_data, context->iv, mac_len);
     *out_data_len = mac_len;
 
@@ -2941,6 +2965,8 @@ CK_RV aes_cmac_verify(STDLL_TokData_t *tokdata,
     if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = aes_cmac_cleanup;
+
     if (CRYPTO_memcmp(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv,
                       out_data_len) == 0) {
         return CKR_OK;
@@ -3012,6 +3038,8 @@ CK_RV aes_cmac_verify_update(STDLL_TokData_t *tokdata,
 
             if (context->ctx != NULL)
                 ctx->state_unsaveable = CK_TRUE;
+
+            ctx->context_free_func = aes_cmac_cleanup;
         } else {
             TRACE_DEVEL("Token specific aes cmac failed.\n");
         }
@@ -3070,6 +3098,8 @@ CK_RV aes_cmac_verify_final(STDLL_TokData_t *tokdata,
     if (context->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = aes_cmac_cleanup;
+
     if (rc != CKR_OK) {
         TRACE_DEVEL("Token specific aes mac failed.\n");
         return rc;
diff --git a/usr/lib/common/mech_des3.c b/usr/lib/common/mech_des3.c
index be8d6075..591ad3fa 100644
--- a/usr/lib/common/mech_des3.c
+++ b/usr/lib/common/mech_des3.c
@@ -2334,6 +2334,24 @@ CK_RV des3_mac_verify_final(STDLL_TokData_t *tokdata,
     return CKR_SIGNATURE_INVALID;
 }
 
+static void des3_cmac_cleanup(STDLL_TokData_t *tokdata, SESSION *sess,
+                              CK_BYTE *context, CK_ULONG context_len)
+{
+    UNUSED(tokdata);
+    UNUSED(sess);
+    UNUSED(context_len);
+
+    if (((DES_CMAC_CONTEXT *)context)->ctx != NULL) {
+        token_specific.t_tdes_cmac(tokdata, (CK_BYTE *)"", 0, NULL,
+                                   ((DES_CMAC_CONTEXT *)context)->iv,
+                                   CK_FALSE, CK_TRUE,
+                                   ((DES_CMAC_CONTEXT *)context)->ctx);
+        ((DES_CMAC_CONTEXT *)context)->ctx = NULL;
+    }
+
+    free(context);
+}
+
 CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata,
                      SESSION *sess,
                      CK_BBOOL length_only,
@@ -2383,6 +2401,8 @@ CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata,
     if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = des3_cmac_cleanup;
+
     memcpy(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, mac_len);
 
     *out_data_len = mac_len;
@@ -2456,6 +2476,8 @@ CK_RV des3_cmac_sign_update(STDLL_TokData_t *tokdata,
 
             if (context->ctx != NULL)
                 ctx->state_unsaveable = CK_TRUE;
+
+            ctx->context_free_func = des3_cmac_cleanup;
         } else {
             TRACE_DEVEL("Token specific des3 cmac failed.\n");
         }
@@ -2521,6 +2543,8 @@ CK_RV des3_cmac_sign_final(STDLL_TokData_t *tokdata,
     if (context->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = des3_cmac_cleanup;
+
     memcpy(out_data, context->iv, mac_len);
 
     *out_data_len = mac_len;
@@ -2577,6 +2601,8 @@ CK_RV des3_cmac_verify(STDLL_TokData_t *tokdata,
     if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = des3_cmac_cleanup;
+
     if (CRYPTO_memcmp(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv,
                       out_data_len) == 0) {
         return CKR_OK;
@@ -2646,6 +2672,8 @@ CK_RV des3_cmac_verify_update(STDLL_TokData_t *tokdata,
 
             if (context->ctx != NULL)
                 ctx->state_unsaveable = CK_TRUE;
+
+            ctx->context_free_func = des3_cmac_cleanup;
         } else {
             TRACE_DEVEL("Token specific des3 cmac failed.\n");
         }
@@ -2709,6 +2737,8 @@ CK_RV des3_cmac_verify_final(STDLL_TokData_t *tokdata,
     if (context->ctx != NULL)
         ctx->state_unsaveable = CK_TRUE;
 
+    ctx->context_free_func = des3_cmac_cleanup;
+
     if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0)
         return CKR_OK;
 
diff --git a/usr/lib/ica_s390_stdll/ica_specific.c b/usr/lib/ica_s390_stdll/ica_specific.c
index 77876467..881a430c 100644
--- a/usr/lib/ica_s390_stdll/ica_specific.c
+++ b/usr/lib/ica_s390_stdll/ica_specific.c
@@ -713,6 +713,9 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
     UNUSED(tokdata);
     UNUSED(ctx);
 
+    if (key == NULL)
+        return CKR_ARGUMENTS_BAD;
+
     // get the key type
     rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
     if (rc != CKR_OK) {
@@ -3621,6 +3624,9 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
     UNUSED(tokdata);
     UNUSED(ctx);
 
+    if (key == NULL)
+        return CKR_ARGUMENTS_BAD;
+
     rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
     if (rc != CKR_OK) {
         TRACE_ERROR("Could not find CKA_VALUE for the key.\n");
diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c
index aeff39a9..5ca22693 100644
--- a/usr/lib/soft_stdll/soft_specific.c
+++ b/usr/lib/soft_stdll/soft_specific.c
@@ -3994,6 +3994,9 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
     UNUSED(tokdata);
 
     if (first) {
+        if (key == NULL)
+            return CKR_ARGUMENTS_BAD;
+
         // get the key type
         rv = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype);
         if (rv != CKR_OK) {
@@ -4194,6 +4197,9 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message,
     UNUSED(tokdata);
 
     if (first) {
+        if (key == NULL)
+            return CKR_ARGUMENTS_BAD;
+
         // get the key value
         rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr);
         if (rc != CKR_OK) {