summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-11-15 21:39:53 +0100
committerMiloslav Trmač <mitr@redhat.com>2010-11-15 21:39:53 +0100
commitdb7e58431d8e3265783e03eec1c05e7dfb6e34c7 (patch)
treea123d9742aff2f8e8105ab9217f82cba722b4a1f
parent3f6e9d21e4b7bf5097ee112b452fcd3acb071b0a (diff)
parent867c1257c40d8b6c2a887576f8c367bcf3df3c79 (diff)
downloadncrypto-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.h2
-rw-r--r--lib/ncrypto_alg.c44
-rw-r--r--tests/digests.c5
-rw-r--r--tests/rsa.c4
-rw-r--r--tests/symm_ciphers.c62
-rw-r--r--tests/symm_keys.c4
-rw-r--r--tests/symm_signatures.c5
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);