From 79adc0a7a1c8a1817b8aea1545fd9559314f4450 Mon Sep 17 00:00:00 2001 From: Miloslav Trmač Date: Wed, 27 Oct 2010 18:12:02 +0200 Subject: Add digest session cloning --- include/ncrypto/ncrypto.h | 2 ++ lib/ncrypto_local.c | 29 +++++++++++++++++++++++++++++ tests/digests.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h index f82cf0e..367ffed 100644 --- a/include/ncrypto/ncrypto.h +++ b/include/ncrypto/ncrypto.h @@ -124,6 +124,8 @@ struct ncr_digest_session; CK_RV ncr_digest_alloc (struct ncr_digest_session **sess, CK_MECHANISM_TYPE mech); CK_RV ncr_digest_free (struct ncr_digest_session *sess); +CK_RV ncr_digest_clone (struct ncr_digest_session **clone, + struct ncr_digest_session *sess); /* Use either ncr_digest_{init,update*,final} (), or ncr_{digest_init,digest} (). After finishing such a call sequence, a new sequence can be started within the same session. */ diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c index 16bd781..15ae38c 100644 --- a/lib/ncrypto_local.c +++ b/lib/ncrypto_local.c @@ -268,6 +268,35 @@ ncr_digest_free (struct ncr_digest_session *sess) return CKR_OK; } +CK_RV +ncr_digest_clone (struct ncr_digest_session **clone, + struct ncr_digest_session *sess) +{ + struct ncr_digest_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 == NDS_INITIALIZED + || sess->state == NDS_UPDATED, + CKR_OPERATION_NOT_INITIALIZED); + + c = malloc (sizeof (*c)); + if (c == NULL) + return CKR_HOST_MEMORY; + + EVP_MD_CTX_init (&c->ctx); + if (EVP_MD_CTX_copy_ex (&c->ctx, &sess->ctx) == 0) + { + free (c); + return ckr_openssl (); + } + c->state = sess->state; + c->md = sess->md; + c->md_size = sess->md_size; + *clone = c; + return CKR_OK; +} + CK_RV ncr_digest_init (struct ncr_digest_session *sess) { diff --git a/tests/digests.c b/tests/digests.c index 8013698..d8ca31c 100644 --- a/tests/digests.c +++ b/tests/digests.c @@ -136,6 +136,49 @@ main (void) assert (res == CKR_OK); } + for (i = 0; i < G_N_ELEMENTS (tvs); i++) + { + res = ncr_digest_alloc (&sess, tvs[i].mech); + assert (res == CKR_OK); + for (j = 0; j < 2; j++) + { + struct ncr_digest_session *clone; + + res = ncr_digest_init (sess); + assert (res == CKR_OK); + + res = ncr_digest_update (sess, tvs[i].input, tvs[i].input_size / 2); + assert (res == CKR_OK); + + res = ncr_digest_clone (&clone, sess); + assert (res == CKR_OK); + + res = ncr_digest_update (sess, "", 1); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_digest_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_digest_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_digest_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_digest_free (clone); + assert (res == CKR_OK); + } + res = ncr_digest_free (sess); + assert (res == CKR_OK); + } + for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_digest_alloc (&sess, tvs[i].mech); -- cgit