summaryrefslogtreecommitdiffstats
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
parent174add36f5b6592db7573145f5c59d0207856e07 (diff)
downloadcryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.tar.gz
cryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.tar.xz
cryptodev-linux-a9970bd8d7b690f03e770a16d8471924ea3ad126.zip
Separated the direct session functions.
-rw-r--r--Makefile1
-rw-r--r--ncr-sessions-direct.c405
-rw-r--r--ncr-sessions.c381
-rw-r--r--ncr-sessions.h16
4 files changed, 424 insertions, 379 deletions
diff --git a/Makefile b/Makefile
index 04f4984..2babafd 100644
--- a/Makefile
+++ b/Makefile
@@ -68,6 +68,7 @@ TOMCRYPT_OBJECTS = libtomcrypt/misc/zeromem.o libtomcrypt/misc/crypt/crypt_argch
cryptodev-objs = cryptodev_main.o cryptodev_cipher.o ncr.o \
ncr-data.o ncr-key.o ncr-limits.o ncr-sessions.o ncr-pk.o \
+ ncr-sessions-direct.o \
ncr-key-wrap.o ncr-key-storage.o $(TOMMATH_OBJECTS) \
$(TOMCRYPT_OBJECTS)
diff --git a/ncr-sessions-direct.c b/ncr-sessions-direct.c
new file mode 100644
index 0000000..aa4c756
--- /dev/null
+++ b/ncr-sessions-direct.c
@@ -0,0 +1,405 @@
+/*
+ * New driver for /dev/crypto device (aka CryptoDev)
+
+ * Copyright (c) 2010 Nikos Mavrogiannopoulos <nmav@gnutls.org>
+ *
+ * This file is part of linux cryptodev.
+ *
+ * cryptodev is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * cryptodev is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/crypto.h>
+#include "cryptodev.h"
+#include "ncr.h"
+#include "ncr_int.h"
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <ncr-sessions.h>
+
+/* 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;
+}
+
+/* Called when userspace buffers are used */
+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;
+}
+
+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;
+}
+
+
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;
diff --git a/ncr-sessions.h b/ncr-sessions.h
new file mode 100644
index 0000000..d6185aa
--- /dev/null
+++ b/ncr-sessions.h
@@ -0,0 +1,16 @@
+#ifndef NCR_SESSIONS_H
+# define NCR_SESSIONS_H
+
+int _ncr_session_direct_final(struct ncr_lists* lists, struct ncr_session_op_st* op);
+int _ncr_session_direct_update(struct ncr_lists* lists, struct ncr_session_op_st* op);
+
+int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt,
+ size_t input_size, void *output, unsigned output_cnt, size_t *output_size);
+
+int _ncr_session_decrypt(struct session_item_st* sess, const struct scatterlist* input,
+ unsigned input_cnt, size_t input_size,
+ struct scatterlist *output, unsigned output_cnt, size_t *output_size);
+
+void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc);
+
+#endif