diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-11-15 21:39:53 +0100 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-11-15 21:39:53 +0100 |
commit | db7e58431d8e3265783e03eec1c05e7dfb6e34c7 (patch) | |
tree | a123d9742aff2f8e8105ab9217f82cba722b4a1f | |
parent | 3f6e9d21e4b7bf5097ee112b452fcd3acb071b0a (diff) | |
parent | 867c1257c40d8b6c2a887576f8c367bcf3df3c79 (diff) | |
download | ncrypto-db7e58431d8e3265783e03eec1c05e7dfb6e34c7.tar.gz ncrypto-db7e58431d8e3265783e03eec1c05e7dfb6e34c7.tar.xz ncrypto-db7e58431d8e3265783e03eec1c05e7dfb6e34c7.zip |
Merge branch 'local', port IV change to AF_ALG
Conflicts:
lib/ncrypto_local.c
-rw-r--r-- | include/ncrypto/ncrypto.h | 2 | ||||
-rw-r--r-- | lib/ncrypto_alg.c | 44 | ||||
-rw-r--r-- | tests/digests.c | 5 | ||||
-rw-r--r-- | tests/rsa.c | 4 | ||||
-rw-r--r-- | tests/symm_ciphers.c | 62 | ||||
-rw-r--r-- | tests/symm_keys.c | 4 | ||||
-rw-r--r-- | tests/symm_signatures.c | 5 |
7 files changed, 125 insertions, 1 deletions
diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h index 024d5a7..a09d451 100644 --- a/include/ncrypto/ncrypto.h +++ b/include/ncrypto/ncrypto.h @@ -158,6 +158,8 @@ struct ncr_symm_cipher_session; CK_RV ncr_symm_cipher_alloc (struct ncr_symm_cipher_session **sess, CK_MECHANISM_TYPE mech); CK_RV ncr_symm_cipher_free (struct ncr_symm_cipher_session *sess); +CK_RV ncr_symm_cipher_change_iv (struct ncr_symm_cipher_session *sess, + const void *iv, size_t iv_size); /* Use either ncr_symm_cipher_encrypt_{init,update,final} (), or ncr_symm_cipher_{encrypt_init,encrypt} (). 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 7d91b40..dcb6e02 100644 --- a/lib/ncrypto_alg.c +++ b/lib/ncrypto_alg.c @@ -902,6 +902,50 @@ ncr_symm_cipher_free (struct ncr_symm_cipher_session *sess) return CKR_OK; } +CK_RV +ncr_symm_cipher_change_iv (struct ncr_symm_cipher_session *sess, const void *iv, + size_t iv_size) +{ + uint8_t cmsg_buf[4096]; /* The size is arbitrary. */ + size_t cmsg_space; + struct msghdr msg; + struct cmsghdr *cmsg; + struct af_alg_iv iv_header; + + g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID); + g_return_val_if_fail (sess->state == NSCS_INITIALIZED + || sess->state == NSCS_UPDATED, + CKR_OPERATION_NOT_INITIALIZED); + g_return_val_if_fail (iv != NULL || iv_size == 0, CKR_ARGUMENTS_BAD); + /* Implicitly restricts iv_size so that it fits into iv_header.ivlen */ + cmsg_space = CMSG_SPACE (sizeof (iv_header) + iv_size); + g_return_val_if_fail (cmsg_space <= sizeof (cmsg_buf), + CKR_MECHANISM_PARAM_INVALID); + + /* The IV might be left pending until the first actual data arrives, saving + one system call, but we prefer reporting invalid IV immediately. */ + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = NULL; + msg.msg_iovlen = 0; + msg.msg_control = cmsg_buf; + msg.msg_controllen = cmsg_space; + + iv_header.ivlen = iv_size; + cmsg = CMSG_FIRSTHDR (&msg); + g_return_val_if_fail (cmsg != NULL, CKR_GENERAL_ERROR); /* What? */ + cmsg->cmsg_len = CMSG_LEN (sizeof (iv_header) + iv_size); + cmsg->cmsg_level = SOL_ALG; + cmsg->cmsg_type = ALG_SET_IV; + memcpy (CMSG_DATA (cmsg), &iv_header, sizeof (iv_header)); + memcpy (CMSG_DATA (cmsg) + sizeof (iv_header), iv, iv_size); + + if (sendmsg (sess->child_fd, &msg, MSG_MORE) != 0) + return ckr_errno (); + + return CKR_OK; +} + static CK_RV symm_cipher_init (struct ncr_symm_cipher_session *sess, bool encrypt, struct ncr_symm_key *key, const void *param, diff --git a/tests/digests.c b/tests/digests.c index 19e54cd..e771d12 100644 --- a/tests/digests.c +++ b/tests/digests.c @@ -107,6 +107,7 @@ main (void) void *large; CK_RV res; + /* Test standalone digests. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { dest_size = sizeof (dest); @@ -117,6 +118,7 @@ main (void) assert (memcmp (dest, tvs[i].output, dest_size) == 0); } + /* Test init + update + final. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_digest_alloc (&sess, tvs[i].mech); @@ -139,6 +141,7 @@ main (void) assert (res == CKR_OK); } + /* Test session cloning. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_digest_alloc (&sess, tvs[i].mech); @@ -182,6 +185,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + digest. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_digest_alloc (&sess, tvs[i].mech); @@ -202,6 +206,7 @@ main (void) assert (res == CKR_OK); } + /* Test very large input. */ res = ncr_digest_alloc (&sess, CKM_SHA256); assert (res == CKR_OK); res = ncr_digest_init (sess); diff --git a/tests/rsa.c b/tests/rsa.c index 224f5c1..d14e05c 100644 --- a/tests/rsa.c +++ b/tests/rsa.c @@ -53,7 +53,7 @@ main (void) size_t src_size, dest_size; CK_RV res; - /* Test the generic version as well? */ + /* Test key loading. Should we test the generic version as well? */ res = ncr_public_key_create_rsa (&public, modulus, sizeof (modulus), public_exponent, sizeof (public_exponent)); assert (res == CKR_OK); @@ -68,6 +68,7 @@ main (void) assert (res == CKR_OK); + /* Test encryption */ dest_size = sizeof (dest); res = ncr_public_key_encrypt (CKM_RSA_PKCS, public, dest, &dest_size, input, sizeof (input)); @@ -81,6 +82,7 @@ main (void) assert (dest_size == sizeof (input)); assert (memcmp (dest, input, dest_size) == 0); + /* Test signatures */ dest_size = sizeof (dest); res = ncr_private_key_sign (CKM_RSA_PKCS, private, dest, &dest_size, input, sizeof (input)); diff --git a/tests/symm_ciphers.c b/tests/symm_ciphers.c index a6f3570..892cfed 100644 --- a/tests/symm_ciphers.c +++ b/tests/symm_ciphers.c @@ -108,6 +108,7 @@ main (void) void *large_src, *large_dest; CK_RV res; + /* Test init + update + final. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_cipher_alloc (&sess, tvs[i].mech); @@ -163,6 +164,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + {en,de}crypt. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_cipher_alloc (&sess, tvs[i].mech); @@ -204,6 +206,64 @@ main (void) assert (res == CKR_OK); } + /* Test changing of the IV. */ + for (i = 0; i < G_N_ELEMENTS (tvs); i++) + { + res = ncr_symm_cipher_alloc (&sess, tvs[i].mech); + assert (res == CKR_OK); + + res = ncr_symm_key_create (&key, tvs[i].key_type, true, tvs[i].key, + tvs[i].key_size); + assert (res == CKR_OK); + + res = ncr_symm_cipher_encrypt_init (sess, key, tvs[i].iv, tvs[i].iv_size); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_cipher_encrypt_update (sess, dest, &dest_size, + tvs[i].input, tvs[i].input_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].output_size); + assert (memcmp (dest, tvs[i].output, dest_size) == 0); + + res = ncr_symm_cipher_change_iv (sess, tvs[i].iv, tvs[i].iv_size); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_cipher_encrypt_final (sess, dest, &dest_size, tvs[i].input, + tvs[i].input_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].output_size); + assert (memcmp (dest, tvs[i].output, dest_size) == 0); + + res = ncr_symm_cipher_decrypt_init (sess, key, tvs[i].iv, tvs[i].iv_size); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_cipher_decrypt_update (sess, dest, &dest_size, + tvs[i].output, tvs[i].output_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].input_size); + assert (memcmp (dest, tvs[i].input, dest_size) == 0); + + res = ncr_symm_cipher_change_iv (sess, tvs[i].iv, tvs[i].iv_size); + assert (res == CKR_OK); + + dest_size = sizeof (dest); + res = ncr_symm_cipher_decrypt_final (sess, dest, &dest_size, + tvs[i].output, tvs[i].output_size); + assert (res == CKR_OK); + assert (dest_size == tvs[i].input_size); + assert (memcmp (dest, tvs[i].input, dest_size) == 0); + + res = ncr_symm_key_destroy (key); + assert (res == CKR_OK); + + res = ncr_symm_cipher_free (sess); + assert (res == CKR_OK); + } + + /* Test init + update + final with a random key. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_cipher_alloc (&sess, tvs[i].mech); @@ -257,6 +317,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + {en,de}crypt with a random key. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_cipher_alloc (&sess, tvs[i].mech); @@ -297,6 +358,7 @@ main (void) assert (res == CKR_OK); } + /* Test very large input. */ res = ncr_symm_cipher_alloc (&sess, CKM_AES_CBC); assert (res == CKR_OK); diff --git a/tests/symm_keys.c b/tests/symm_keys.c index aee5396..3f5aed0 100644 --- a/tests/symm_keys.c +++ b/tests/symm_keys.c @@ -74,6 +74,7 @@ main (void) struct ncr_symm_key *key; CK_RV res; + /* Test handling of loaded, non-sensitive keys. */ res = ncr_symm_key_create (&key, CKK_AES, false, input, sizeof (input)); assert (res == CKR_OK); @@ -95,6 +96,7 @@ main (void) assert (res == CKR_OK); + /* Test handling of loaded, sensitive keys. */ res = ncr_symm_key_create (&key, CKK_AES, true, input, sizeof (input)); assert (res == CKR_OK); @@ -104,6 +106,7 @@ main (void) assert (res == CKR_OK); + /* Test handling of generated, non-sensitive keys. */ res = ncr_symm_key_generate (&key, CKM_AES_KEY_GEN, false, sizeof (input)); assert (res == CKR_OK); @@ -124,6 +127,7 @@ main (void) assert (res == CKR_OK); + /* Test handling of generated, sensitive keys. */ res = ncr_symm_key_generate (&key, CKM_AES_KEY_GEN, true, sizeof (input)); assert (res == CKR_OK); diff --git a/tests/symm_signatures.c b/tests/symm_signatures.c index d53eeef..fa672fd 100644 --- a/tests/symm_signatures.c +++ b/tests/symm_signatures.c @@ -77,6 +77,7 @@ main (void) size_t i, j, k, dest_size; CK_RV res; + /* Test init + update + final. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); @@ -128,6 +129,7 @@ main (void) assert (res == CKR_OK); } + /* Test session cloning. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); @@ -221,6 +223,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + {sign,verify}. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); @@ -265,6 +268,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + update + final with a random key. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); @@ -314,6 +318,7 @@ main (void) assert (res == CKR_OK); } + /* Test init + {sign,verify} with a random key. */ for (i = 0; i < G_N_ELEMENTS (tvs); i++) { res = ncr_symm_signature_alloc (&sess, tvs[i].mech); |