summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-10-29 19:52:59 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-10-29 19:52:59 +0200
commit843862b7ce325e70a0ff715006fb29fffd81e0a6 (patch)
tree5722b987a4058c65ae69c78e951b20f64f600c61
parent79adc0a7a1c8a1817b8aea1545fd9559314f4450 (diff)
downloadncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.tar.gz
ncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.tar.xz
ncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.zip
Add symmetric signature session cloning
-rw-r--r--include/ncrypto/ncrypto.h2
-rw-r--r--lib/ncrypto_local.c33
-rw-r--r--tests/symm_signatures.c93
3 files changed, 128 insertions, 0 deletions
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
@@ -138,6 +138,99 @@ main (void)
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);
+ 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++)
+ {
res = ncr_symm_signature_sign_init (sess, key);
assert (res == CKR_OK);