summaryrefslogtreecommitdiffstats
path: root/ncr-sessions.c
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-08-16 22:50:56 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-08-24 23:49:09 +0200
commit7017a63132bc03462ba75e399c083e00f4e19573 (patch)
treeba790f1e3e542492640e6bf63ad1f3d6f62153e3 /ncr-sessions.c
parente536df1a394cf653ecc5964ece0551b0259abeb4 (diff)
downloadcryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.tar.gz
cryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.tar.xz
cryptodev-linux-7017a63132bc03462ba75e399c083e00f4e19573.zip
Convert *_SESSION_*
Diffstat (limited to 'ncr-sessions.c')
-rw-r--r--ncr-sessions.c514
1 files changed, 253 insertions, 261 deletions
diff --git a/ncr-sessions.c b/ncr-sessions.c
index 320a061..8f3e721 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -31,7 +31,8 @@
#include <linux/scatterlist.h>
#include <net/netlink.h>
-static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op);
+static int _ncr_session_update_key(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[]);
static void _ncr_session_remove(struct ncr_lists *lst, ncr_session_t desc);
static int session_list_deinit_fn(int id, void *item, void *unused)
@@ -222,8 +223,28 @@ const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla
return _ncr_algo_to_properties(nla_get_u32(nla));
}
-static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* session)
+static int key_item_get_nla_read(struct key_item_st **st,
+ struct ncr_lists *lists,
+ const struct nlattr *nla)
{
+ int ret;
+
+ if (nla == NULL) {
+ err();
+ return -EINVAL;
+ }
+ ret = ncr_key_item_get_read(st, lists, nla_get_u32(nla));
+ if (ret < 0) {
+ err();
+ return ret;
+ }
+ return ret;
+}
+
+static int _ncr_session_init(struct ncr_lists *lists, ncr_crypto_op_t op,
+ struct nlattr *tb[])
+{
+ const struct nlattr *nla;
struct session_item_st* ns = NULL;
int ret;
const struct algo_properties_st *sign_hash;
@@ -234,15 +255,15 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
return -ENOMEM;
}
- ns->op = session->op;
- ns->algorithm = _ncr_algo_to_properties(session->algorithm);
+ ns->op = op;
+ ns->algorithm = _ncr_nla_to_properties(tb[NCR_ATTR_ALGORITHM]);
if (ns->algorithm == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- switch(session->op) {
+ switch(op) {
case NCR_OP_ENCRYPT:
case NCR_OP_DECRYPT:
if (!ns->algorithm->can_encrypt) {
@@ -252,7 +273,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
/* read key */
- ret = ncr_key_item_get_read( &ns->key, lists, session->key);
+ ret = key_item_get_nla_read(&ns->key, lists,
+ tb[NCR_ATTR_KEY]);
if (ret < 0) {
err();
goto fail;
@@ -269,7 +291,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
if (ns->key->type == NCR_KEY_TYPE_SECRET) {
int keysize = ns->key->key.secret.size;
- if (session->algorithm == NCR_ALG_NULL)
+ if (ns->algorithm->algo == NCR_ALG_NULL)
keysize = 0;
if (ns->algorithm->kstr == NULL) {
@@ -286,16 +308,19 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
if (ns->algorithm->needs_iv) {
- if (session->params.params.cipher.iv_size > sizeof(session->params.params.cipher.iv)) {
+ nla = tb[NCR_ATTR_IV];
+ if (nla == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- cryptodev_cipher_set_iv(&ns->cipher, session->params.params.cipher.iv, session->params.params.cipher.iv_size);
+ cryptodev_cipher_set_iv(&ns->cipher,
+ nla_data(nla),
+ nla_len(nla));
}
} else if (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC) {
ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk,
- &session->params, ns->key, NULL);
+ tb, ns->key, NULL);
if (ret < 0) {
err();
goto fail;
@@ -330,7 +355,8 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
} else {
/* read key */
- ret = ncr_key_item_get_read( &ns->key, lists, session->key);
+ ret = key_item_get_nla_read(&ns->key, lists,
+ tb[NCR_ATTR_KEY]);
if (ret < 0) {
err();
goto fail;
@@ -359,10 +385,11 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
} else if (ns->algorithm->is_pk && (ns->key->type == NCR_KEY_TYPE_PRIVATE || ns->key->type == NCR_KEY_TYPE_PUBLIC)) {
- sign_hash = ncr_key_params_get_sign_hash(ns->key->algorithm, &session->params);
- if (IS_ERR(sign_hash)) {
+ nla = tb[NCR_ATTR_SIGNATURE_HASH_ALGORITHM];
+ sign_hash = _ncr_nla_to_properties(nla);
+ if (sign_hash == NULL) {
err();
- ret = PTR_ERR(sign_hash);
+ ret = -EINVAL;
goto fail;
}
@@ -379,7 +406,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
}
ret = ncr_pk_cipher_init(ns->algorithm, &ns->pk,
- &session->params, ns->key, sign_hash);
+ tb, ns->key, sign_hash);
if (ret < 0) {
err();
goto fail;
@@ -404,8 +431,7 @@ static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* ses
goto fail;
}
- ret = 0;
- session->ses = ns->desc;
+ ret = ns->desc;
fail:
if (ret < 0) {
@@ -416,29 +442,11 @@ fail:
return ret;
}
-int ncr_session_init(struct ncr_lists* lists, void __user* arg)
+int ncr_session_init(struct ncr_lists *lists,
+ const struct ncr_session_init *session,
+ struct nlattr *tb[])
{
- struct ncr_session_st session;
- int ret;
-
- if (unlikely(copy_from_user(&session, arg, sizeof(session)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_init(lists, &session);
- if (unlikely(ret)) {
- err();
- return ret;
- }
-
- ret = copy_to_user( arg, &session, sizeof(session));
- if (unlikely(ret)) {
- err();
- _ncr_session_remove(lists, session.ses);
- return -EFAULT;
- }
- return ret;
+ return _ncr_session_init(lists, session->op, tb);
}
static int _ncr_session_encrypt(struct session_item_st* sess, const struct scatterlist* input, unsigned input_cnt,
@@ -542,66 +550,64 @@ static int _ncr_session_grow_pages(struct session_item_st *ses, int pagecount)
return 0;
}
-/* Only the output buffer is given as scatterlist */
-static int get_userbuf1(struct session_item_st* ses,
- void __user * udata, size_t udata_size, struct scatterlist **dst_sg, unsigned *dst_cnt)
+/* Make NCR_ATTR_UPDATE_INPUT_DATA and NCR_ATTR_UPDATE_OUTPUT_BUFFER available
+ in scatterlists */
+static int get_userbuf2(struct session_item_st *ses, struct nlattr *tb[],
+ struct scatterlist **src_sg, unsigned *src_cnt,
+ size_t *src_size, struct ncr_session_output_buffer *dst,
+ struct scatterlist **dst_sg, unsigned *dst_cnt,
+ int compat)
{
- int pagecount = 0;
-
- if (unlikely(udata == NULL)) {
- err();
- return -EINVAL;
- }
+ const struct nlattr *src_nla, *dst_nla;
+ struct ncr_session_input_data src;
+ int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1, ret;
+ size_t input_size;
- pagecount = PAGECOUNT(udata, udata_size);
- _ncr_session_grow_pages(ses, pagecount);
+ src_nla = tb[NCR_ATTR_UPDATE_INPUT_DATA];
+ dst_nla = tb[NCR_ATTR_UPDATE_OUTPUT_BUFFER];
- if (__get_userbuf(udata, udata_size, 1,
- pagecount, ses->pages, ses->sg)) {
+ ret = ncr_session_input_data_from_nla(&src, src_nla, compat);
+ if (unlikely(ret != 0)) {
err();
- return -EINVAL;
+ return ret;
}
- (*dst_sg) = ses->sg;
- *dst_cnt = pagecount;
+ *src_size = src.data_size;
- ses->available_pages = 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;
- size_t input_size = op->data.udata.input_size;
-
- if (unlikely(op->data.udata.input == NULL)) {
- err();
- return -EINVAL;
+ if (dst_nla != NULL) {
+ ret = ncr_session_output_buffer_from_nla(dst, dst_nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ return ret;
+ }
}
- src_pagecount = PAGECOUNT(op->data.udata.input, input_size);
+ input_size = src.data_size;
+ src_pagecount = PAGECOUNT(src.data, input_size);
- if (op->data.udata.input != op->data.udata.output) { /* non-in-situ transformation */
+ if (dst_nla == NULL || src.data != dst->buffer) { /* non-in-situ transformation */
write_src = 0;
- if (op->data.udata.output != NULL) {
- dst_pagecount = PAGECOUNT(op->data.udata.output, op->data.udata.output_size);
+ if (dst_nla != NULL) {
+ dst_pagecount = PAGECOUNT(dst->buffer,
+ dst->buffer_size);
} else {
dst_pagecount = 0;
}
} else {
- src_pagecount = max((int)(PAGECOUNT(op->data.udata.output, op->data.udata.output_size)),
- src_pagecount);
- input_size = max(input_size, (size_t)op->data.udata.output_size);
+ src_pagecount = max((int)(PAGECOUNT(dst->buffer,
+ dst->buffer_size)),
+ src_pagecount);
+ input_size = max(input_size, dst->buffer_size);
}
pagecount = src_pagecount + dst_pagecount;
- _ncr_session_grow_pages(ses, pagecount);
+ ret = _ncr_session_grow_pages(ses, pagecount);
+ if (ret != 0) {
+ err();
+ return ret;
+ }
- if (__get_userbuf(op->data.udata.input, input_size, write_src,
- src_pagecount, ses->pages, ses->sg)) {
+ if (__get_userbuf((void __user *)src.data, input_size, write_src,
+ src_pagecount, ses->pages, ses->sg)) {
err();
printk("write: %d\n", write_src);
return -EINVAL;
@@ -613,14 +619,15 @@ static int get_userbuf2(struct session_item_st* ses,
*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)) {
+ if (__get_userbuf(dst->buffer, dst->buffer_size, 1,
+ dst_pagecount, ses->pages + src_pagecount,
+ *dst_sg)) {
err();
release_user_pages(ses->pages, src_pagecount);
return -EINVAL;
}
} else {
- if (op->data.udata.output != NULL) {
+ if (dst_nla != NULL) {
*dst_cnt = src_pagecount;
(*dst_sg) = (*src_sg);
} else {
@@ -635,16 +642,18 @@ static int get_userbuf2(struct session_item_st* ses,
}
/* Called when userspace buffers are used */
-static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_update(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
int ret;
struct session_item_st* sess;
- struct scatterlist *isg;
- struct scatterlist *osg;
+ struct scatterlist *isg = NULL;
+ struct scatterlist *osg = NULL;
unsigned osg_cnt=0, isg_cnt=0;
- size_t isg_size, osg_size;
+ size_t isg_size = 0, osg_size;
+ struct ncr_session_output_buffer out;
- sess = ncr_sessions_item_get(lists, op->ses);
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
@@ -656,13 +665,12 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
return -ERESTARTSYS;
}
- ret = get_userbuf2(sess, op, &isg, &isg_cnt, &osg, &osg_cnt);
+ ret = get_userbuf2(sess, tb, &isg, &isg_cnt, &isg_size, &out, &osg,
+ &osg_cnt, compat);
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:
@@ -672,6 +680,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
goto fail;
}
+ osg_size = out.buffer_size;
if (osg_size < isg_size) {
err();
ret = -EINVAL;
@@ -684,8 +693,13 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
err();
goto fail;
}
- op->data.udata.output_size = osg_size;
-
+
+ ret = ncr_session_output_buffer_set_size(&out, osg_size,
+ compat);
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
break;
case NCR_OP_DECRYPT:
if (osg == NULL) {
@@ -694,6 +708,7 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
goto fail;
}
+ osg_size = out.buffer_size;
if (osg_size < isg_size) {
err();
ret = -EINVAL;
@@ -706,8 +721,13 @@ static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st
err();
goto fail;
}
- op->data.udata.output_size = osg_size;
+ ret = ncr_session_output_buffer_set_size(&out, osg_size,
+ compat);
+ if (ret != 0) {
+ err();
+ goto fail;
+ }
break;
case NCR_OP_SIGN:
@@ -737,40 +757,34 @@ fail:
return ret;
}
-static int try_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int try_session_update(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
- if (op->type == NCR_KEY_DATA) {
- if (op->data.kdata.input != NCR_KEY_INVALID)
- return _ncr_session_update_key(lists, op);
- } else if (op->type == NCR_DIRECT_DATA) {
- if (op->data.udata.input != NULL)
- return _ncr_session_update(lists, op);
- }
+ if (tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA] != NULL)
+ return _ncr_session_update_key(lists, ses, tb);
+ else if (tb[NCR_ATTR_UPDATE_INPUT_DATA] != NULL)
+ return _ncr_session_update(lists, ses, tb, compat);
return 0;
}
-static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_final(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[], int compat)
{
+ const struct nlattr *nla;
int ret;
struct session_item_st* sess;
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;
- void __user * udata = NULL;
- size_t *udata_size;
-
- sess = ncr_sessions_item_get(lists, op->ses);
+ void *buffer = NULL;
+
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
}
- ret = try_session_update(lists, op);
+ ret = try_session_update(lists, ses, tb, compat);
if (ret < 0) {
err();
_ncr_sessions_item_put(sess);
@@ -782,129 +796,138 @@ static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st*
_ncr_sessions_item_put(sess);
return -ERESTARTSYS;
}
-
- if (op->type == NCR_DIRECT_DATA) {
- udata = op->data.udata.output;
- udata_size = &op->data.udata.output_size;
- } else if (op->type == NCR_KEY_DATA) {
- udata = op->data.kdata.output;
- udata_size = &op->data.kdata.output_size;
- } else {
- err();
- ret = -EINVAL;
- goto fail;
- }
switch(sess->op) {
- case NCR_OP_ENCRYPT:
- case NCR_OP_DECRYPT:
- break;
- case NCR_OP_VERIFY:
- ret = get_userbuf1(sess, udata, *udata_size, &osg, &osg_cnt);
+ case NCR_OP_ENCRYPT:
+ case NCR_OP_DECRYPT:
+ break;
+ case NCR_OP_VERIFY: {
+ struct ncr_session_input_data src;
+
+ nla = tb[NCR_ATTR_FINAL_INPUT_DATA];
+ ret = ncr_session_input_data_from_nla(&src, nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ goto fail;
+ }
+
+ buffer = kmalloc(src.data_size, GFP_KERNEL);
+ if (buffer == NULL) {
+ err();
+ ret = -ENOMEM;
+ goto fail;
+ }
+ if (unlikely(copy_from_user(buffer, src.data, src.data_size))) {
+ err();
+ ret = -EFAULT;
+ goto fail;
+ }
+
+ 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_pk)
+ ret = (digest_size == src.data_size
+ && memcmp(buffer, digest, digest_size) == 0);
+ else {
+ ret = ncr_pk_cipher_verify(&sess->pk, buffer,
+ src.data_size, digest,
+ digest_size);
if (ret < 0) {
err();
goto fail;
}
- orig_osg_size = osg_size = *udata_size;
+ }
+ break;
+ }
- 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) {
+ case NCR_OP_SIGN: {
+ struct ncr_session_output_buffer dst;
+ size_t output_size;
+
+ nla = tb[NCR_ATTR_FINAL_OUTPUT_BUFFER];
+ ret = ncr_session_output_buffer_from_nla(&dst, nla, compat);
+ if (unlikely(ret != 0)) {
+ err();
+ goto fail;
+ }
+
+ digest_size = sess->hash.digestsize;
+ if (digest_size == 0) {
+ err();
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ ret = cryptodev_hash_final(&sess->hash, digest);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
+ cryptodev_hash_deinit(&sess->hash);
+
+ if (!sess->algorithm->is_pk) {
+ if (dst.buffer_size < digest_size) {
err();
+ ret = -ERANGE;
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 != osg_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, udata, *udata_size, &osg, &osg_cnt);
- if (ret < 0) {
+ if (unlikely(copy_to_user(dst.buffer, digest,
+ digest_size))) {
err();
+ ret = -EFAULT;
goto fail;
}
- orig_osg_size = osg_size = *udata_size;
-
- digest_size = sess->hash.digestsize;
- if (digest_size == 0 || osg_size < digest_size) {
+ output_size = digest_size;
+ } else {
+ output_size = dst.buffer_size;
+ buffer = kmalloc(output_size, GFP_KERNEL);
+ if (buffer == NULL) {
err();
- ret = -EINVAL;
+ ret = -ENOMEM;
goto fail;
}
-
- ret = cryptodev_hash_final(&sess->hash, digest);
+ ret = ncr_pk_cipher_sign(&sess->pk, digest, digest_size,
+ buffer, &output_size);
if (ret < 0) {
err();
goto fail;
}
-
- ret = sg_copy_from_buffer(osg, osg_cnt, digest, digest_size);
- if (ret != digest_size) {
+ if (unlikely(copy_to_user(dst.buffer, buffer,
+ output_size))) {
err();
- ret = -EINVAL;
+ ret = -EFAULT;
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:
+ ret = ncr_session_output_buffer_set_size(&dst, output_size,
+ compat);
+ if (ret != 0) {
err();
- ret = -EINVAL;
goto fail;
+ }
+ break;
+ }
+ default:
+ err();
+ ret = -EINVAL;
+ goto fail;
}
-
- if (osg_size > 0)
- *udata_size = osg_size;
-
- ret = 0;
fail:
- if (sess->available_pages) {
- release_user_pages(sess->pages, sess->available_pages);
- sess->available_pages = 0;
- }
mutex_unlock(&sess->mem_mutex);
+ kfree(buffer);
cryptodev_hash_deinit(&sess->hash);
if (sess->algorithm->is_symmetric) {
@@ -914,27 +937,28 @@ fail:
}
_ncr_sessions_item_put(sess);
- _ncr_session_remove(lists, op->ses);
+ _ncr_session_remove(lists, ses);
return ret;
}
/* Direct with key: Allows to hash a key */
-/* Called when userspace buffers are used */
-static int _ncr_session_update_key(struct ncr_lists* lists, struct ncr_session_op_st* op)
+static int _ncr_session_update_key(struct ncr_lists *lists, ncr_session_t ses,
+ struct nlattr *tb[])
{
int ret;
struct session_item_st* sess;
struct key_item_st* key = NULL;
- sess = ncr_sessions_item_get(lists, op->ses);
+ sess = ncr_sessions_item_get(lists, ses);
if (sess == NULL) {
err();
return -EINVAL;
}
/* read key */
- ret = ncr_key_item_get_read( &key, lists, op->data.kdata.input);
+ ret = key_item_get_nla_read(&key, lists,
+ tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA]);
if (ret < 0) {
err();
goto fail;
@@ -976,20 +1000,16 @@ fail:
return ret;
}
-int ncr_session_update(struct ncr_lists* lists, void __user* arg)
+int ncr_session_update(struct ncr_lists *lists,
+ const struct ncr_session_update *op, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_op_st op;
int ret;
- if (unlikely(copy_from_user( &op, arg, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
- if (op.type == NCR_DIRECT_DATA)
- ret = _ncr_session_update(lists, &op);
- else if (op.type == NCR_KEY_DATA)
- ret = _ncr_session_update_key(lists, &op);
+ if (tb[NCR_ATTR_UPDATE_INPUT_DATA] != NULL)
+ ret = _ncr_session_update(lists, op->ses, tb, compat);
+ else if (tb[NCR_ATTR_UPDATE_INPUT_KEY_AS_DATA] != NULL)
+ ret = _ncr_session_update_key(lists, op->ses, tb);
else
ret = -EINVAL;
@@ -998,61 +1018,33 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg)
return ret;
}
- if (unlikely(copy_to_user(arg, &op, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
return 0;
}
-int ncr_session_final(struct ncr_lists* lists, void __user* arg)
+int ncr_session_final(struct ncr_lists *lists,
+ const struct ncr_session_final *op, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_op_st op;
- int ret;
-
- if (unlikely(copy_from_user(&op, arg, sizeof(op)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_final(lists, &op);
- if (unlikely(ret)) {
- err();
- return ret;
- }
-
- if (unlikely(copy_to_user(arg, &op, sizeof(op)))) {
- err();
- return -EFAULT;
- }
- return 0;
+ return _ncr_session_final(lists, op->ses, tb, compat);
}
-int ncr_session_once(struct ncr_lists* lists, void __user* arg)
+int ncr_session_once(struct ncr_lists *lists,
+ const struct ncr_session_once *once, struct nlattr *tb[],
+ int compat)
{
- struct ncr_session_once_op_st kop;
int ret;
- if (unlikely(copy_from_user(&kop, arg, sizeof(kop)))) {
- err();
- return -EFAULT;
- }
-
- ret = _ncr_session_init(lists, &kop.init);
+ ret = _ncr_session_init(lists, once->op, tb);
if (ret < 0) {
err();
return ret;
}
- kop.op.ses = kop.init.ses;
- ret = _ncr_session_final(lists, &kop.op);
+ ret = _ncr_session_final(lists, ret, tb, compat);
if (ret < 0) {
err();
return ret;
}
- if (unlikely(copy_to_user(arg, &kop, sizeof(kop))))
- return -EFAULT;
- return 0;
+ return ret;
}