diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-10-29 20:08:32 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-10-29 20:08:32 +0200 |
commit | e6b6e8785e16f1c824fd1f1f333ef2591f6f0a10 (patch) | |
tree | b57fd771372d24cdcf18c8ee6e2393be3aff4ed4 | |
parent | 7241ddaa5924bc10c7a813c9163443e67b04e8d1 (diff) | |
parent | 843862b7ce325e70a0ff715006fb29fffd81e0a6 (diff) | |
download | ncrypto-e6b6e8785e16f1c824fd1f1f333ef2591f6f0a10.tar.gz ncrypto-e6b6e8785e16f1c824fd1f1f333ef2591f6f0a10.tar.xz ncrypto-e6b6e8785e16f1c824fd1f1f333ef2591f6f0a10.zip |
Merge branch 'local', port cloning to AF_ALG
Conflicts:
lib/ncrypto_local.c
-rw-r--r-- | include/ncrypto/ncrypto.h | 4 | ||||
-rw-r--r-- | lib/ncrypto_alg.c | 139 | ||||
-rw-r--r-- | tests/digests.c | 43 | ||||
-rw-r--r-- | tests/symm_signatures.c | 93 |
4 files changed, 260 insertions, 19 deletions
diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h index f82cf0e..01964f9 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. */ @@ -189,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_alg.c b/lib/ncrypto_alg.c index 8d0d900..d3a8393 100644 --- a/lib/ncrypto_alg.c +++ b/lib/ncrypto_alg.c @@ -159,6 +159,34 @@ ncr_digest_free (struct ncr_digest_session *sess) } 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; + + c->fd = accept (sess->fd, NULL, 0); + if (c->fd == -1) + { + free (c); + return ckr_errno (); + } + c->state = sess->state; + c->md_size = sess->md_size; + *clone = c; + return CKR_OK; +} + +CK_RV ncr_digest_init (struct ncr_digest_session *sess) { g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID); @@ -344,12 +372,19 @@ ncr_digest_standalone (CK_MECHANISM_TYPE mech, void *dest, slave file descriptor, but for HMAC we need the parent to be able to change the key. */ -/* Semantically, md_size_ptr should be "size_t *", but values will fit into - "int *" just as fine. */ +struct ncr_symm_signature_session +{ + int parent_fd, child_fd; + const struct sockaddr_alg *sa; + int md_size; /* size_t semantically */ + bool signing; + /* Debugging only */ + enum { NSSS_NEW, NSSS_INITIALIZED, NSSS_UPDATED, NSSS_FINISHED } state; +}; + static CK_RV -symm_signature_params_from_mech (CK_MECHANISM_TYPE mech, - const struct sockaddr_alg **sa_ptr, - int *md_size_ptr) +symm_signature_params_from_mech (struct ncr_symm_signature_session *sess, + CK_MECHANISM_TYPE mech) { const struct sockaddr_alg *sa; int md_size; @@ -377,26 +412,16 @@ symm_signature_params_from_mech (CK_MECHANISM_TYPE mech, default: g_return_val_if_reached (CKR_MECHANISM_INVALID); } - *sa_ptr = sa; - *md_size_ptr = md_size; + sess->sa = sa; + sess->md_size = md_size; return CKR_OK; } -struct ncr_symm_signature_session -{ - int parent_fd, child_fd; - int md_size; /* size_t semantically */ - bool signing; - /* Debugging only */ - enum { NSSS_NEW, NSSS_INITIALIZED, NSSS_UPDATED, NSSS_FINISHED } state; -}; - CK_RV ncr_symm_signature_alloc (struct ncr_symm_signature_session **sess, CK_MECHANISM_TYPE mech) { struct ncr_symm_signature_session *s; - const struct sockaddr_alg *sa; CK_RV res; g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD); @@ -405,7 +430,7 @@ ncr_symm_signature_alloc (struct ncr_symm_signature_session **sess, if (s == NULL) return CKR_HOST_MEMORY; - res = symm_signature_params_from_mech (mech, &sa, &s->md_size); + res = symm_signature_params_from_mech (s, mech); if (res != CKR_OK) goto err_s; @@ -415,7 +440,7 @@ ncr_symm_signature_alloc (struct ncr_symm_signature_session **sess, res = ckr_errno (); goto err_s; } - if (bind (s->parent_fd, (struct sockaddr *)sa, sizeof (*sa)) != 0) + if (bind (s->parent_fd, (struct sockaddr *)s->sa, sizeof (*s->sa)) != 0) { res = ckr_errno (); goto err_parent_fd; @@ -445,6 +470,82 @@ 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; + int new_sess_parent_fd; + CK_RV res; + + 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; + + /* This is a little complicated: parent_fd holds the "transform", which is + parametrized by the key. A mere accept () on child_fd would create two + sockets sharing a parent_fd, and reinitializing a session on one with a + different key would change the underlying key of the other. + + Therefore, create an entirely new parent_fd for _both_ clones. The + "old" parent_fd will be implicitly referred to by child_fd of both clones, + but any session reinitialization will use the new parent_fd values. */ + new_sess_parent_fd = socket (AF_ALG, SOCK_SEQPACKET, 0); + if (new_sess_parent_fd == -1) + { + res = ckr_errno (); + goto err_c; + } + if (bind (new_sess_parent_fd, (struct sockaddr *)sess->sa, + sizeof (*sess->sa)) != 0) + { + res = ckr_errno (); + goto err_new_sess_parent_fd; + } + + c->parent_fd = socket (AF_ALG, SOCK_SEQPACKET, 0); + if (c->parent_fd == -1) + { + res = ckr_errno (); + goto err_new_sess_parent_fd; + } + if (bind (c->parent_fd, (struct sockaddr *)sess->sa, sizeof (*sess->sa)) != 0) + { + res = ckr_errno (); + goto err_c_parent_fd; + } + + c->child_fd = accept (sess->child_fd, NULL, 0); + if (c->child_fd == -1) + { + res = ckr_errno (); + goto err_c_parent_fd; + } + + (void)close (sess->parent_fd); + sess->parent_fd = new_sess_parent_fd; + c->state = sess->state; + c->sa = sess->sa; + c->md_size = sess->md_size; + c->signing = sess->signing; + *clone = c; + return CKR_OK; + + err_c_parent_fd: + (void)close (c->parent_fd); + err_new_sess_parent_fd: + (void)close (new_sess_parent_fd); + err_c: + free (c); + return res; +} + static CK_RV symm_signature_init (struct ncr_symm_signature_session *sess, bool sign, struct ncr_symm_key *key) diff --git a/tests/digests.c b/tests/digests.c index 8013698..d8ca31c 100644 --- a/tests/digests.c +++ b/tests/digests.c @@ -142,6 +142,49 @@ main (void) 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); + assert (res == CKR_OK); + for (j = 0; j < 2; j++) + { res = ncr_digest_init (sess); assert (res == CKR_OK); 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); |