summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-14 11:58:29 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-14 11:58:29 +0200
commit0201edca222dbfe408690b6b7fd0e9c34e6a02d9 (patch)
tree9370842c7c736519191ec580f4d30129b348ac96
parent7e36c5726d7ab6b41ff186fae315f039cd4a97be (diff)
downloadcryptodev-linux-0201edca222dbfe408690b6b7fd0e9c34e6a02d9.tar.gz
cryptodev-linux-0201edca222dbfe408690b6b7fd0e9c34e6a02d9.tar.xz
cryptodev-linux-0201edca222dbfe408690b6b7fd0e9c34e6a02d9.zip
Corrected RSA signature generation/verification.
Added Test for RSA and DSA signature generation and verification.
-rw-r--r--examples/ncr.c4
-rw-r--r--examples/pk.c300
-rw-r--r--ncr-key.c19
-rw-r--r--ncr-pk.c18
-rw-r--r--ncr-sessions.c57
-rw-r--r--ncr.h2
6 files changed, 352 insertions, 48 deletions
diff --git a/examples/ncr.c b/examples/ncr.c
index bb3d006..69e699a 100644
--- a/examples/ncr.c
+++ b/examples/ncr.c
@@ -1116,8 +1116,8 @@ test_ncr_hash(int cfd)
if (hash_vectors[i].key != NULL)
nop.init.params.key = key;
nop.init.op = hash_vectors[i].op;
- nop.op.data.digest.text = dd;
- nop.op.data.digest.output = dd2;
+ nop.op.data.sign.text = dd;
+ nop.op.data.sign.output = dd2;
if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
diff --git a/examples/pk.c b/examples/pk.c
index 1513d62..d35f383 100644
--- a/examples/pk.c
+++ b/examples/pk.c
@@ -204,8 +204,166 @@ int pubkey_info(void* data, int data_size)
return 0;
}
-static int
-test_ncr_rsa(int cfd)
+static int rsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey, int pss)
+{
+ struct ncr_data_init_st dinit;
+ ncr_data_t datad;
+ ncr_data_t signd;
+ struct ncr_session_once_op_st nop;
+ uint8_t data[DATA_SIZE];
+
+ fprintf(stdout, "Tests on RSA (%s) key signature:", (pss!=0)?"PSS":"PKCS V1.5");
+ fflush(stdout);
+
+ memset(data, 0x3, sizeof(data));
+
+ /* data to sign */
+ memset(&dinit, 0, sizeof(dinit));
+ dinit.max_object_size = DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+ dinit.initial_data = data;
+ dinit.initial_data_size = sizeof(data);
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+
+ datad = dinit.desc;
+
+ memset(&dinit, 0, sizeof(dinit));
+ dinit.max_object_size = DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+
+ signd = dinit.desc;
+
+ /* sign datad */
+ memset(&nop, 0, sizeof(nop));
+ nop.init.algorithm = NCR_ALG_RSA;
+ nop.init.params.key = privkey;
+ nop.init.params.params.pk.type = (pss!=0)?RSA_PKCS1_PSS:RSA_PKCS1_V1_5;
+ nop.init.params.params.pk.sign_hash = NCR_ALG_SHA1;
+
+ nop.init.op = NCR_OP_SIGN;
+ nop.op.data.sign.text = datad;
+ nop.op.data.sign.output = signd;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_SESSION_ONCE)");
+ return 1;
+ }
+
+ /* verify signature */
+ memset(&nop, 0, sizeof(nop));
+ nop.init.algorithm = NCR_ALG_RSA;
+ nop.init.params.key = pubkey;
+ nop.init.params.params.pk.type = (pss!=0)?RSA_PKCS1_PSS:RSA_PKCS1_V1_5;
+ nop.init.params.params.pk.sign_hash = NCR_ALG_SHA1;
+
+ nop.init.op = NCR_OP_VERIFY;
+ nop.op.data.verify.text = datad;
+ nop.op.data.verify.signature = signd;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_SESSION_ONCE)");
+ return 1;
+ }
+
+ fprintf(stdout, " Success\n");
+
+ return 0;
+
+}
+
+static int dsa_key_sign_verify(int cfd, ncr_key_t privkey, ncr_key_t pubkey)
+{
+ struct ncr_data_init_st dinit;
+ ncr_data_t datad;
+ ncr_data_t signd;
+ struct ncr_session_once_op_st nop;
+ uint8_t data[DATA_SIZE];
+
+ fprintf(stdout, "Tests on DSA key signature:");
+ fflush(stdout);
+
+ memset(data, 0x3, sizeof(data));
+
+ /* data to sign */
+ memset(&dinit, 0, sizeof(dinit));
+ dinit.max_object_size = DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+ dinit.initial_data = data;
+ dinit.initial_data_size = sizeof(data);
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+
+ datad = dinit.desc;
+
+ memset(&dinit, 0, sizeof(dinit));
+ dinit.max_object_size = DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+
+ signd = dinit.desc;
+
+ /* sign datad */
+ memset(&nop, 0, sizeof(nop));
+ nop.init.algorithm = NCR_ALG_DSA;
+ nop.init.params.key = privkey;
+ nop.init.params.params.pk.sign_hash = NCR_ALG_SHA1;
+
+ nop.init.op = NCR_OP_SIGN;
+ nop.op.data.sign.text = datad;
+ nop.op.data.sign.output = signd;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_SESSION_ONCE)");
+ return 1;
+ }
+
+ /* verify signature */
+ memset(&nop, 0, sizeof(nop));
+ nop.init.algorithm = NCR_ALG_DSA;
+ nop.init.params.key = pubkey;
+ nop.init.params.params.pk.sign_hash = NCR_ALG_SHA1;
+
+ nop.init.op = NCR_OP_VERIFY;
+ nop.op.data.verify.text = datad;
+ nop.op.data.verify.signature = signd;
+
+ if (ioctl(cfd, NCRIO_SESSION_ONCE, &nop)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_SESSION_ONCE)");
+ return 1;
+ }
+
+ fprintf(stdout, " Success\n");
+
+ return 0;
+
+}
+
+
+static int test_ncr_rsa(int cfd)
{
int ret;
struct ncr_data_init_st dinit;
@@ -215,7 +373,7 @@ test_ncr_rsa(int cfd)
struct ncr_data_st kdata;
uint8_t data[DATA_SIZE];
- fprintf(stdout, "Tests on RSA key generation:\n");
+ fprintf(stdout, "\n\nTests on RSA key generation:\n");
/* convert it to key */
if (ioctl(cfd, NCRIO_KEY_INIT, &privkey)) {
@@ -285,8 +443,135 @@ test_ncr_rsa(int cfd)
return 1;
}
+ /* export the public key */
+
+ memset(&keydata, 0, sizeof(keydata));
+ keydata.key = pubkey;
+ keydata.data = dinit.desc;
+
+ if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_IMPORT)");
+ return 1;
+ }
+
+ /* now read data */
+ memset(data, 0, sizeof(data));
+
+ kdata.desc = dinit.desc;
+ kdata.data = data;
+ kdata.data_size = sizeof(data);
+ kdata.append_flag = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_GET)");
+ return 1;
+ }
+
+ ret = pubkey_info(kdata.data, kdata.data_size);
+ if (ret < 0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ return 1;
+ }
+
+ ret = rsa_key_sign_verify(cfd, privkey, pubkey, 0);
+ if (ret != 0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ return 1;
+ }
+
+ ret = rsa_key_sign_verify(cfd, privkey, pubkey, 1);
+ if (ret != 0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ return 1;
+ }
+
+ return 0;
+
+}
+
+static int test_ncr_dsa(int cfd)
+{
+ int ret;
+ struct ncr_data_init_st dinit;
+ struct ncr_key_generate_st kgen;
+ ncr_key_t pubkey, privkey;
+ struct ncr_key_data_st keydata;
+ struct ncr_data_st kdata;
+ uint8_t data[DATA_SIZE];
+
+ fprintf(stdout, "\n\nTests on DSA key generation:\n");
+
+ /* convert it to key */
+ if (ioctl(cfd, NCRIO_KEY_INIT, &privkey)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_INIT)");
+ return 1;
+ }
+
+ if (ioctl(cfd, NCRIO_KEY_INIT, &pubkey)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_INIT)");
+ return 1;
+ }
+
+ memset(&kgen, 0, sizeof(kgen));
+ kgen.desc = privkey;
+ kgen.desc2 = pubkey;
+ kgen.params.algorithm = NCR_ALG_DSA;
+ kgen.params.keyflags = NCR_KEY_FLAG_EXPORTABLE|NCR_KEY_FLAG_WRAPPABLE;
+ kgen.params.params.dsa.q_bits = 160;
+ kgen.params.params.dsa.p_bits = 1024;
+
+ if (ioctl(cfd, NCRIO_KEY_GENERATE_PAIR, &kgen)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_GENERATE_PAIR)");
+ return 1;
+ }
+
+ /* export the private key */
+ dinit.max_object_size = DATA_SIZE;
+ dinit.flags = NCR_DATA_FLAG_EXPORTABLE;
+ dinit.initial_data = NULL;
+ dinit.initial_data_size = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_INIT)");
+ return 1;
+ }
+ memset(&keydata, 0, sizeof(keydata));
+ keydata.key = privkey;
+ keydata.data = dinit.desc;
+ if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_KEY_EXPORT)");
+ return 1;
+ }
+
+ /* now read data */
+ memset(data, 0, sizeof(data));
+
+ kdata.desc = dinit.desc;
+ kdata.data = data;
+ kdata.data_size = sizeof(data);
+ kdata.append_flag = 0;
+
+ if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ perror("ioctl(NCRIO_DATA_GET)");
+ return 1;
+ }
+
+ ret = privkey_info(kdata.data, kdata.data_size);
+ if (ret != 0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ return 1;
+ }
+
/* export the public key */
memset(&keydata, 0, sizeof(keydata));
@@ -319,6 +604,12 @@ test_ncr_rsa(int cfd)
return 1;
}
+ ret = dsa_key_sign_verify(cfd, privkey, pubkey);
+ if (ret != 0) {
+ fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__);
+ return 1;
+ }
+
return 0;
}
@@ -340,6 +631,9 @@ main()
return 1;
}
+ if (test_ncr_dsa(fd))
+ return 1;
+
if (test_ncr_rsa(fd))
return 1;
diff --git a/ncr-key.c b/ncr-key.c
index ff5af6c..b12f3a0 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -273,8 +273,6 @@ int ret;
}
break;
-
-
default:
err();
ret = -EINVAL;
@@ -446,13 +444,13 @@ size_t size;
goto fail;
}
- _ncr_key_item_put( item);
-
- return 0;
+ ret = 0;
fail:
- if (item)
+ if (item) {
+ if (ret < 0) item->type = NCR_KEY_TYPE_INVALID;
_ncr_key_item_put(item);
+ }
return ret;
}
@@ -520,7 +518,6 @@ int ret;
if (public->type == NCR_KEY_TYPE_PUBLIC) {
ret = ncr_pk_generate(gen.params.algorithm, &gen.params, private, public);
-
if (ret < 0) {
err();
goto fail;
@@ -533,10 +530,14 @@ int ret;
ret = 0;
fail:
- if (public)
+ if (public) {
+ if (ret < 0) public->type = NCR_KEY_TYPE_INVALID;
_ncr_key_item_put(public);
- if (private)
+ }
+ if (private) {
+ if (ret < 0) private->type = NCR_KEY_TYPE_INVALID;
_ncr_key_item_put(private);
+ }
return ret;
}
diff --git a/ncr-pk.c b/ncr-pk.c
index 31bad73..9033d6f 100644
--- a/ncr-pk.c
+++ b/ncr-pk.c
@@ -220,19 +220,22 @@ static void keygen_handler(struct work_struct *instance)
if (cret != CRYPT_OK) {
err();
st->ret = tomerr(cret);
- }
-
- st->ret = 0;
+ } else
+ st->ret = 0;
break;
case NCR_ALG_DSA:
+ if (st->params->params.dsa.q_bits==0)
+ st->params->params.dsa.q_bits = 160;
+ if (st->params->params.dsa.p_bits==0)
+ st->params->params.dsa.p_bits = 1024;
+
cret = dsa_make_key(st->params->params.dsa.q_bits/8,
st->params->params.dsa.p_bits/8, &st->private->key.pk.dsa);
if (cret != CRYPT_OK) {
err();
st->ret = tomerr(cret);
- }
-
- st->ret = 0;
+ } else
+ st->ret = 0;
break;
default:
err();
@@ -268,10 +271,9 @@ struct keygen_st st;
}
wait_for_completion(&st.completed);
-
if (st.ret < 0) {
err();
- return ret;
+ return st.ret;
}
ret = ncr_pk_make_public_and_id(private, public);
diff --git a/ncr-sessions.c b/ncr-sessions.c
index b61879c..834fd3d 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -277,13 +277,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
{
struct session_item_st* ns = NULL;
int ret;
- const char* str;
-
- str = _ncr_algo_to_str(session->algorithm);
- if (str == NULL) {
- err();
- return -EINVAL;
- }
+ const char* str = NULL;
ns = ncr_session_new(&lists->sessions);
if (ns == NULL) {
@@ -310,6 +304,12 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
if (ns->key->type == NCR_KEY_TYPE_SECRET) {
+ str = _ncr_algo_to_str(session->algorithm);
+ if (str == NULL) {
+ err();
+ return -EINVAL;
+ }
+
ret = cryptodev_cipher_init(&ns->cipher, str,
ns->key->key.secret.data, ns->key->key.secret.size);
if (ret < 0) {
@@ -355,6 +355,12 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
if (ns->key->type == NCR_KEY_TYPE_SECRET) {
+ str = _ncr_algo_to_str(session->algorithm);
+ if (str == NULL) {
+ err();
+ return -EINVAL;
+ }
+
ret = cryptodev_hash_init(&ns->hash, str, 1,
ns->key->key.secret.data, ns->key->key.secret.size);
if (ret < 0) {
@@ -427,6 +433,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
fail:
if (ret < 0) {
if (ns->key) _ncr_key_item_put(ns->key);
+ ns->key = NULL;
ncr_pk_cipher_deinit(&ns->pk);
cryptodev_cipher_deinit(&ns->cipher);
@@ -555,7 +562,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
case NCR_OP_SIGN:
case NCR_OP_DIGEST:
/* obtain data item */
- data = ncr_data_item_get( &lists->data, op->data.digest.text);
+ data = ncr_data_item_get( &lists->data, op->data.sign.text);
if (data == NULL) {
err();
ret = -EINVAL;
@@ -659,17 +666,11 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
op->data.cipher.ciphertext != NCR_DATA_INVALID) {
_ncr_session_update(lists, op);
}
-
- if (algo_is_symmetric(sess->algorithm)) {
- cryptodev_cipher_deinit(&sess->cipher);
- } else {
- ncr_pk_cipher_deinit(&sess->pk);
- }
break;
case NCR_OP_VERIFY:
/* obtain data item */
- if (op->data.digest.text != NCR_DATA_INVALID) {
+ if (op->data.sign.text != NCR_DATA_INVALID) {
_ncr_session_update(lists, op);
}
@@ -680,16 +681,18 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
goto fail;
}
- digest_size = _ncr_algo_digest_size(sess->algorithm);
+ digest_size = sess->hash.digestsize;
if (digest_size == 0 || sizeof(digest) < digest_size) {
err();
ret = -EINVAL;
goto fail;
}
ret = cryptodev_hash_final(&sess->hash, digest);
- odata->data_size = digest_size;
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
- cryptodev_hash_deinit(&sess->hash);
if (algo_is_hmac(sess->algorithm)) {
if (digest_size != odata->data_size ||
@@ -707,25 +710,23 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
err();
goto fail;
}
-
- ncr_pk_cipher_deinit(&sess->pk);
}
break;
case NCR_OP_SIGN:
case NCR_OP_DIGEST:
/* obtain data item */
- if (op->data.digest.text != NCR_DATA_INVALID) {
+ if (op->data.sign.text != NCR_DATA_INVALID) {
_ncr_session_update(lists, op);
}
- odata = ncr_data_item_get( &lists->data, op->data.digest.output);
+ odata = ncr_data_item_get( &lists->data, op->data.sign.output);
if (odata == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- digest_size = _ncr_algo_digest_size(sess->algorithm);
+ digest_size = sess->hash.digestsize;
if (digest_size == 0 || odata->max_data_size < digest_size) {
err();
ret = -EINVAL;
@@ -745,8 +746,7 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
err();
goto fail;
}
-
- ncr_pk_cipher_deinit(&sess->pk);
+ odata->data_size = new_size;
}
break;
default:
@@ -760,6 +760,13 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
fail:
if (odata) _ncr_data_item_put(odata);
if (data) _ncr_data_item_put(data);
+ cryptodev_hash_deinit(&sess->hash);
+ if (algo_is_symmetric(sess->algorithm)) {
+ cryptodev_cipher_deinit(&sess->cipher);
+ } else {
+ ncr_pk_cipher_deinit(&sess->pk);
+ }
+
_ncr_sessions_item_put(sess);
_ncr_session_remove(&lists->sessions, op->ses);
diff --git a/ncr.h b/ncr.h
index 0576c62..82b1dc8 100644
--- a/ncr.h
+++ b/ncr.h
@@ -276,7 +276,7 @@ struct ncr_session_op_st {
struct {
ncr_data_t text;
ncr_data_t output;
- } digest; /* mac/hash/sign */
+ } sign; /* mac/hash/sign */
struct {
ncr_data_t text;
ncr_data_t signature;