From 843862b7ce325e70a0ff715006fb29fffd81e0a6 Mon Sep 17 00:00:00 2001 From: Miloslav Trmač Date: Fri, 29 Oct 2010 19:52:59 +0200 Subject: Add symmetric signature session cloning --- include/ncrypto/ncrypto.h | 2 + lib/ncrypto_local.c | 33 +++++++++++++++++ tests/symm_signatures.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h index 367ffed..01964f9 100644 --- a/include/ncrypto/ncrypto.h +++ b/include/ncrypto/ncrypto.h @@ -191,6 +191,8 @@ struct ncr_symm_signature_session; CK_RV ncr_symm_signature_alloc (struct ncr_symm_signature_session **sess, CK_MECHANISM_TYPE mech); CK_RV ncr_symm_signature_free (struct ncr_symm_signature_session *sess); +CK_RV ncr_symm_signature_clone (struct ncr_symm_signature_session **clone, + struct ncr_symm_signature_session *sess); /* Use either ncr_symm_signature_sign_{init,update,final} (), or ncr_symm_signature_{sign_init,sign} (). After finishing such a call sequence, a new sequence can be started within the same session. Same for diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c index 15ae38c..5e0077d 100644 --- a/lib/ncrypto_local.c +++ b/lib/ncrypto_local.c @@ -788,6 +788,39 @@ ncr_symm_signature_free (struct ncr_symm_signature_session *sess) return CKR_OK; } +CK_RV +ncr_symm_signature_clone (struct ncr_symm_signature_session **clone, + struct ncr_symm_signature_session *sess) +{ + struct ncr_symm_signature_session *c; + + g_return_val_if_fail (clone != NULL, CKR_ARGUMENTS_BAD); + g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID); + g_return_val_if_fail (sess->state == NSSS_INITIALIZED + || sess->state == NSSS_UPDATED, + CKR_OPERATION_NOT_INITIALIZED); + + c = malloc (sizeof (*c)); + if (c == NULL) + return CKR_HOST_MEMORY; + + /* HMAC_CTX_copy is undocumented, and seems not to need MD_CTX_init, but + openssl internally calls HMAC_CTX_init before HMAC_CTX_copy, so we do as + well. */ + HMAC_CTX_init (&c->ctx); + if (HMAC_CTX_copy (&c->ctx, &sess->ctx) == 0) + { + free (c); + return ckr_openssl (); + } + c->state = sess->state; + c->md = sess->md; + c->md_size = sess->md_size; + c->signing = sess->signing; + *clone = c; + return CKR_OK; +} + static CK_RV symm_signature_init (struct ncr_symm_signature_session *sess, bool sign, struct ncr_symm_key *key) diff --git a/tests/symm_signatures.c b/tests/symm_signatures.c index 17ca560..003d19d 100644 --- a/tests/symm_signatures.c +++ b/tests/symm_signatures.c @@ -127,6 +127,99 @@ main (void) assert (res == CKR_OK); } + for (i = 0; i < G_N_ELEMENTS (tvs); i++) + { + res = ncr_symm_signature_alloc (&sess, tvs[i].mech); + assert (res == CKR_OK); + + res = ncr_symm_key_create (&key, CKK_GENERIC_SECRET, tvs[i].key, + tvs[i].key_size); + assert (res == CKR_OK); + + for (j = 0; j < 2; j++) + { + struct ncr_symm_signature_session *clone; + + res = ncr_symm_signature_sign_init (sess, key); + assert (res == CKR_OK); + + res = ncr_symm_signature_sign_update (sess, tvs[i].input, + tvs[i].input_size / 2); + assert (res == CKR_OK); + + res = ncr_symm_signature_clone (&clone, sess); + assert (res == CKR_OK); + + res = ncr_symm_signature_sign_update (sess, "", 1); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_signature_sign_final (sess, dest, &dest_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].output_size); + assert (memcmp (dest, tvs[i].output, dest_size) != 0); + + res = ncr_symm_signature_sign_update (clone, tvs[i].input + + tvs[i].input_size / 2, + tvs[i].input_size + - tvs[i].input_size / 2); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_signature_sign_final (clone, dest, &dest_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].output_size); + assert (memcmp (dest, tvs[i].output, dest_size) == 0); + + res = ncr_symm_signature_free (clone); + assert (res == CKR_OK); + + for (k = 0; k < 2; k++) + { + res = ncr_symm_signature_verify_init (sess, key); + assert (res == CKR_OK); + + res = ncr_symm_signature_verify_update (sess, tvs[i].input, + tvs[i].input_size / 2); + assert (res == CKR_OK); + + res = ncr_symm_signature_clone (&clone, sess); + assert (res == CKR_OK); + + res = ncr_symm_signature_verify_update (sess, "", 1); + assert (res == CKR_OK); + + res = ncr_symm_signature_verify_final (sess, tvs[i].output, + tvs[i].output_size); + assert (res == CKR_SIGNATURE_INVALID); + + res = ncr_symm_signature_verify_update (clone, tvs[i].input + + tvs[i].input_size / 2, + tvs[i].input_size + - tvs[i].input_size / 2); + assert (res == CKR_OK); + + memcpy (dest, tvs[i].output, tvs[i].output_size); + dest[0] += k; + res = ncr_symm_signature_verify_final (clone, dest, + tvs[i].output_size); + if (k == 0) + assert (res == CKR_OK); + else + assert (res == CKR_SIGNATURE_INVALID); + + res = ncr_symm_signature_free (clone); + assert (res == CKR_OK); + } + } + + res = ncr_symm_key_destroy (key); + assert (res == CKR_OK); + + res = ncr_symm_signature_free (sess); + assert (res == CKR_OK); + } + for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); -- cgit