summaryrefslogtreecommitdiffstats
path: root/ncr-sessions.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-25 20:48:26 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-25 21:34:37 +0200
commita9970bd8d7b690f03e770a16d8471924ea3ad126 (patch)
tree2281fec02d8f185f5ca843b001aff239fe10d48b /ncr-sessions.c
parent174add36f5b6592db7573145f5c59d0207856e07 (diff)
downloadcryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.tar.gz
cryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.tar.xz
cryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.zip
Separated the direct session functions.
Diffstat (limited to 'ncr-sessions.c')
-rw-r--r--ncr-sessions.c381
1 files changed, 2 insertions, 379 deletions
diff --git a/ncr-sessions.c b/ncr-sessions.c
index fb9fe4f..8137276 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -25,8 +25,7 @@
#include "ncr_int.h"
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
-
-static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc);
+#include <ncr-sessions.h>
void ncr_sessions_list_deinit(struct list_sem_st* lst)
{
@@ -565,120 +564,7 @@ fail:
return ret;
}
-/* Only the output buffer is given as scatterlist */
-static int get_userbuf1(struct session_item_st* ses,
- struct ncr_session_op_st* op, struct scatterlist **dst_sg, unsigned *dst_cnt)
-{
- int pagecount = 0;
-
- if (op->data.udata.output == NULL) {
- return -EINVAL;
- }
-
- pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size);
-
-
- ses->available_pages = pagecount;
-
- if (pagecount > ses->array_size) {
- while (ses->array_size < pagecount)
- ses->array_size *= 2;
-
- dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
- __func__, ses->array_size);
- ses->pages = krealloc(ses->pages, ses->array_size *
- sizeof(struct page *), GFP_KERNEL);
- ses->sg = krealloc(ses->sg, ses->array_size *
- sizeof(struct scatterlist), GFP_KERNEL);
-
- if (ses->sg == NULL || ses->pages == NULL) {
- return -ENOMEM;
- }
- }
-
- if (__get_userbuf(op->data.udata.output, op->data.udata.output_size, 1,
- pagecount, ses->pages, ses->sg)) {
- dprintk(1, KERN_ERR, "failed to get user pages for data input\n");
- return -EINVAL;
- }
- (*dst_sg) = ses->sg;
- *dst_cnt = pagecount;
-
- return 0;
-}
-
-/* make op->data.udata.input and op->data.udata.output available in scatterlists */
-static int get_userbuf2(struct session_item_st* ses,
- struct ncr_session_op_st* op, struct scatterlist **src_sg,
- unsigned *src_cnt, struct scatterlist **dst_sg, unsigned *dst_cnt)
-{
- int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1;
-
- if (op->data.udata.input == NULL) {
- return -EINVAL;
- }
-
- src_pagecount = PAGECOUNT(op->data.udata.input, op->data.udata.input_size);
-
- if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */
- if (op->data.udata.output != NULL) {
- dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size);
- write_src = 0;
- } else {
- dst_pagecount = 0;
- }
- }
-
- ses->available_pages = pagecount = src_pagecount + dst_pagecount;
-
- if (pagecount > ses->array_size) {
- while (ses->array_size < pagecount)
- ses->array_size *= 2;
-
- dprintk(2, KERN_DEBUG, "%s: reallocating to %d elements\n",
- __func__, ses->array_size);
- ses->pages = krealloc(ses->pages, ses->array_size *
- sizeof(struct page *), GFP_KERNEL);
- ses->sg = krealloc(ses->sg, ses->array_size *
- sizeof(struct scatterlist), GFP_KERNEL);
-
- if (ses->sg == NULL || ses->pages == NULL) {
- return -ENOMEM;
- }
- }
-
- if (__get_userbuf(op->data.udata.input, op->data.udata.input_size, write_src,
- src_pagecount, ses->pages, ses->sg)) {
- dprintk(1, KERN_ERR, "failed to get user pages for data input\n");
- return -EINVAL;
- }
- (*src_sg) = ses->sg;
- *src_cnt = src_pagecount;
-
- if (dst_pagecount) {
- *dst_cnt = dst_pagecount;
- (*dst_sg) = ses->sg + src_pagecount;
-
- if (__get_userbuf(op->data.udata.output, op->data.udata.output_size, 1, dst_pagecount,
- ses->pages + src_pagecount, *dst_sg)) {
- dprintk(1, KERN_ERR, "failed to get user pages for data output\n");
- release_user_pages(ses->pages, src_pagecount);
- return -EINVAL;
- }
- } else {
- if (op->data.udata.output != NULL) {
- *dst_cnt = src_pagecount;
- (*dst_sg) = (*src_sg);
- } else {
- *dst_cnt = 0;
- *dst_sg = NULL;
- }
- }
-
- return 0;
-}
-
-static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
+void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
{
struct session_item_st * item, *tmp;
@@ -824,269 +710,6 @@ fail:
return ret;
}
-/* Called when userspace buffers are used */
-static int _ncr_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
-{
- int ret;
- struct session_item_st* sess;
- struct scatterlist *isg;
- struct scatterlist *osg;
- unsigned osg_cnt=0, isg_cnt=0;
- size_t isg_size, osg_size;
-
- sess = ncr_sessions_item_get( &lists->sessions, op->ses);
- if (sess == NULL) {
- err();
- return -EINVAL;
- }
-
- if (down_interruptible(&sess->mem_mutex)) {
- err();
- _ncr_sessions_item_put(sess);
- return -ERESTARTSYS;
- }
-
- ret = get_userbuf2(sess, op, &isg, &isg_cnt, &osg, &osg_cnt);
- if (ret < 0) {
- err();
- goto fail;
- }
- isg_size = op->data.udata.input_size;
- osg_size = op->data.udata.output_size;
-
- switch(sess->op) {
- case NCR_OP_ENCRYPT:
- if (osg == NULL) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = _ncr_session_encrypt(sess, isg, isg_cnt, isg_size,
- osg, osg_cnt, &osg_size);
- if (ret < 0) {
- err();
- goto fail;
- }
- op->data.udata.output_size = osg_size;
-
- break;
- case NCR_OP_DECRYPT:
- if (osg == NULL) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- if (osg_size < isg_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = _ncr_session_decrypt(sess, isg, isg_cnt, isg_size,
- osg, osg_cnt, &osg_size);
- if (ret < 0) {
- err();
- goto fail;
- }
- op->data.udata.output_size = osg_size;
-
- break;
-
- case NCR_OP_SIGN:
- case NCR_OP_VERIFY:
- ret = cryptodev_hash_update(&sess->hash, isg, isg_size);
- if (ret < 0) {
- err();
- goto fail;
- }
- break;
- default:
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = 0;
-
-fail:
- if (sess->available_pages) {
- release_user_pages(sess->pages, sess->available_pages);
- sess->available_pages = 0;
- }
- up(&sess->mem_mutex);
- _ncr_sessions_item_put(sess);
-
- return ret;
-}
-
-static int try_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
-{
- if (op->data.udata.input != NULL) {
- return _ncr_session_direct_update(lists, op);
- }
-
- return 0;
-}
-
-static int _ncr_session_direct_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
-{
- int ret;
- struct session_item_st* sess;
- struct data_item_st* odata = NULL;
- int digest_size;
- uint8_t digest[NCR_HASH_MAX_OUTPUT_SIZE];
- uint8_t vdigest[NCR_HASH_MAX_OUTPUT_SIZE];
- struct scatterlist *osg;
- unsigned osg_cnt=0;
- size_t osg_size = 0;
- size_t orig_osg_size;
-
- sess = ncr_sessions_item_get( &lists->sessions, op->ses);
- if (sess == NULL) {
- err();
- return -EINVAL;
- }
-
- ret = try_session_direct_update(lists, op);
- if (ret < 0) {
- err();
- _ncr_sessions_item_put(sess);
- return ret;
- }
-
- if (down_interruptible(&sess->mem_mutex)) {
- err();
- _ncr_sessions_item_put(sess);
- return -ERESTARTSYS;
- }
-
- switch(sess->op) {
- case NCR_OP_ENCRYPT:
- case NCR_OP_DECRYPT:
- break;
- case NCR_OP_VERIFY:
- ret = get_userbuf1(sess, op, &osg, &osg_cnt);
- if (ret < 0) {
- err();
- goto fail;
- }
- orig_osg_size = osg_size = op->data.udata.output_size;
-
- 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);
- if (ret < 0) {
- err();
- goto fail;
- }
-
- if (sess->algorithm->is_hmac) {
- ret = sg_copy_to_buffer(osg, osg_cnt, vdigest, digest_size);
- if (ret != digest_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- if (digest_size != odata->data_size ||
- memcmp(vdigest, digest, digest_size) != 0) {
-
- op->err = NCR_VERIFICATION_FAILED;
- } else {
- op->err = NCR_SUCCESS;
- }
- } else {
- /* PK signature */
- ret = ncr_pk_cipher_verify(&sess->pk, osg, osg_cnt, osg_size,
- digest, digest_size, &op->err);
- if (ret < 0) {
- err();
- goto fail;
- }
- }
- break;
-
- case NCR_OP_SIGN:
- ret = get_userbuf1(sess, op, &osg, &osg_cnt);
- if (ret < 0) {
- err();
- goto fail;
- }
- orig_osg_size = osg_size = op->data.udata.output_size;
-
- digest_size = sess->hash.digestsize;
- if (digest_size == 0 || osg_size < digest_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- ret = cryptodev_hash_final(&sess->hash, digest);
- if (ret < 0) {
- err();
- goto fail;
- }
-
- ret = sg_copy_from_buffer(osg, osg_cnt, digest, digest_size);
- if (ret != digest_size) {
- err();
- ret = -EINVAL;
- goto fail;
- }
- osg_size = digest_size;
-
- cryptodev_hash_deinit(&sess->hash);
-
- if (sess->algorithm->is_pk) {
- /* PK signature */
-
- ret = ncr_pk_cipher_sign(&sess->pk, osg, osg_cnt, osg_size,
- osg, osg_cnt, &orig_osg_size);
- if (ret < 0) {
- err();
- goto fail;
- }
- osg_size = orig_osg_size;
- }
- break;
- default:
- err();
- ret = -EINVAL;
- goto fail;
- }
-
- if (osg_size > 0)
- op->data.udata.output_size = osg_size;
-
- ret = 0;
-
-fail:
- if (sess->available_pages) {
- release_user_pages(sess->pages, sess->available_pages);
- sess->available_pages = 0;
- }
- up(&sess->mem_mutex);
-
- cryptodev_hash_deinit(&sess->hash);
- if (sess->algorithm->is_symmetric) {
- cryptodev_cipher_deinit(&sess->cipher);
- } else {
- ncr_pk_cipher_deinit(&sess->pk);
- }
-
- _ncr_sessions_item_put(sess);
- _ncr_session_remove(&lists->sessions, op->ses);
-
- return ret;
-}
-
-
int ncr_session_update(struct ncr_lists* lists, void __user* arg)
{
struct ncr_session_op_st op;