diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-10-29 19:52:59 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-10-29 19:52:59 +0200 |
commit | 843862b7ce325e70a0ff715006fb29fffd81e0a6 (patch) | |
tree | 5722b987a4058c65ae69c78e951b20f64f600c61 | |
parent | 79adc0a7a1c8a1817b8aea1545fd9559314f4450 (diff) | |
download | ncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.tar.gz ncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.tar.xz ncrypto-843862b7ce325e70a0ff715006fb29fffd81e0a6.zip |
Add symmetric signature session cloning
-rw-r--r-- | include/ncrypto/ncrypto.h | 2 | ||||
-rw-r--r-- | lib/ncrypto_local.c | 33 | ||||
-rw-r--r-- | tests/symm_signatures.c | 93 |
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); |