summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptodev_main.c45
-rw-r--r--ncr-data.c65
-rw-r--r--ncr-key-wrap.c24
-rw-r--r--ncr-key.c36
-rw-r--r--ncr-sessions.c132
-rw-r--r--ncr.c7
6 files changed, 221 insertions, 88 deletions
diff --git a/cryptodev_main.c b/cryptodev_main.c
index 5abd4c708a7..6c897c8195b 100644
--- a/cryptodev_main.c
+++ b/cryptodev_main.c
@@ -206,7 +206,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
ret = -EINVAL;
goto error;
}
- copy_from_user(keyp, sop->key, sop->keylen);
+
+ ret = copy_from_user(keyp, sop->key, sop->keylen);
+ if (unlikely(ret)) {
+ goto error;
+ }
ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keyp, sop->keylen);
if (ret < 0) {
@@ -226,7 +230,11 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
ret = -EINVAL;
goto error;
}
- copy_from_user(keyp, sop->mackey, sop->mackeylen);
+
+ ret = copy_from_user(keyp, sop->mackey, sop->mackeylen);
+ if (unlikely(ret)) {
+ goto error;
+ }
ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode, keyp, sop->mackeylen);
if (ret != 0) {
@@ -431,7 +439,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
while(nbytes > 0) {
size_t current_len = nbytes > bufsize ? bufsize : nbytes;
- if (unlikely(copy_from_user(data, src, current_len)))
+ ret = copy_from_user(data, src, current_len);
+ if (unlikely(ret))
goto out;
sg_init_one(&sg, data, current_len);
@@ -454,7 +463,9 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
goto out;
}
- if (unlikely(copy_to_user(dst, data, current_len)))
+
+ ret = copy_to_user(dst, data, current_len);
+ if (unlikely(ret))
goto out;
dst += current_len;
}
@@ -466,7 +477,9 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
goto out;
}
- if (unlikely(copy_to_user(dst, data, current_len)))
+
+ ret = copy_to_user(dst, data, current_len);
+ if (unlikely(ret))
goto out;
dst += current_len;
@@ -492,7 +505,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
goto out;
}
- if (unlikely(copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize)))
+ ret = copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize);
+ if (unlikely(ret))
goto out;
}
@@ -597,7 +611,10 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
return 0;
case CIOCGSESSION:
ret = copy_from_user(&sop, (void*)arg, sizeof(sop));
- ret |= crypto_create_session(fcr, &sop);
+ if (unlikely(ret))
+ return ret;
+
+ ret = crypto_create_session(fcr, &sop);
if (unlikely(ret))
return ret;
return copy_to_user((void*)arg, &sop, sizeof(sop));
@@ -607,7 +624,10 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
return ret;
case CIOCCRYPT:
ret = copy_from_user(&cop, (void*)arg, sizeof(cop));
- ret |= crypto_run(fcr, &cop);
+ if (unlikely(ret))
+ return ret;
+
+ ret = crypto_run(fcr, &cop);
if (unlikely(ret))
return ret;
return copy_to_user((void*)arg, &cop, sizeof(cop));
@@ -697,8 +717,10 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = copy_from_user(&compat_sop,
(void *)arg, sizeof(compat_sop));
compat_to_session_op(&compat_sop, &sop);
+ if (unlikely(ret))
+ return ret;
- ret |= crypto_create_session(fcr, &sop);
+ ret = crypto_create_session(fcr, &sop);
if (unlikely(ret))
return ret;
@@ -709,9 +731,12 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case COMPAT_CIOCCRYPT:
ret = copy_from_user(&compat_cop,
(void*)arg, sizeof(compat_cop));
+
compat_to_crypt_op(&compat_cop, &cop);
+ if (unlikely(ret))
+ return ret;
- ret |= crypto_run(fcr, &cop);
+ ret = crypto_run(fcr, &cop);
if (unlikely(ret))
return ret;
diff --git a/ncr-data.c b/ncr-data.c
index a0d7ca9dea4..27aadd5565b 100644
--- a/ncr-data.c
+++ b/ncr-data.c
@@ -110,7 +110,11 @@ int ncr_data_init(struct list_sem_st* lst, void __user* arg)
return ret;
}
- copy_from_user( &init, arg, sizeof(init));
+ ret = copy_from_user( &init, arg, sizeof(init));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) {
@@ -135,7 +139,13 @@ int ncr_data_init(struct list_sem_st* lst, void __user* arg)
data->max_data_size = init.max_object_size;
if (init.initial_data != NULL) {
- copy_from_user(data->data, init.initial_data, init.initial_data_size);
+ ret = copy_from_user(data->data, init.initial_data, init.initial_data_size);
+ if (unlikely(ret)) {
+ err();
+ kfree(data->data);
+ kfree(data);
+ return ret;
+ }
data->data_size = init.initial_data_size;
}
@@ -148,9 +158,7 @@ int ncr_data_init(struct list_sem_st* lst, void __user* arg)
up(&lst->sem);
init.desc = data->desc;
- copy_to_user(arg, &init, sizeof(init));
-
- return 0;
+ return copy_to_user(arg, &init, sizeof(init));
}
@@ -158,9 +166,13 @@ int ncr_data_deinit(struct list_sem_st* lst, void __user* arg)
{
ncr_data_t desc;
struct data_item_st * item, *tmp;
+ int ret;
- copy_from_user( &desc, arg, sizeof(desc));
-
+ ret = copy_from_user( &desc, arg, sizeof(desc));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
down(&lst->sem);
list_for_each_entry_safe(item, tmp, &lst->list, list) {
@@ -183,7 +195,11 @@ int ncr_data_get(struct list_sem_st* lst, void __user* arg)
size_t len;
int ret;
- copy_from_user( &get, arg, sizeof(get));
+ ret = copy_from_user( &get, arg, sizeof(get));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
data = ncr_data_item_get( lst, get.desc);
@@ -202,12 +218,11 @@ int ncr_data_get(struct list_sem_st* lst, void __user* arg)
/* update length */
get.data_size = len;
- copy_to_user(arg, &get, sizeof(get));
-
- if (len > 0)
- copy_to_user(get.data, data->data, len);
+
+ ret = copy_to_user(arg, &get, sizeof(get));
- ret = 0;
+ if (ret == 0 && len > 0)
+ ret = copy_to_user(get.data, data->data, len);
cleanup:
_ncr_data_item_put( data);
@@ -221,7 +236,11 @@ int ncr_data_set(struct list_sem_st* lst, void __user* arg)
struct data_item_st * data;
int ret;
- copy_from_user( &get, arg, sizeof(get));
+ ret = copy_from_user( &get, arg, sizeof(get));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
data = ncr_data_item_get( lst, get.desc);
@@ -238,8 +257,13 @@ int ncr_data_set(struct list_sem_st* lst, void __user* arg)
}
if (!get.append_flag) {
- if (get.data != NULL)
- copy_from_user(data->data, get.data, get.data_size);
+ if (get.data != NULL) {
+ ret = copy_from_user(data->data, get.data, get.data_size);
+ if (unlikely(ret)) {
+ err();
+ goto cleanup;
+ }
+ }
data->data_size = get.data_size;
} else {
if (get.data_size+data->data_size > data->max_data_size) {
@@ -247,8 +271,13 @@ int ncr_data_set(struct list_sem_st* lst, void __user* arg)
ret = -EINVAL;
goto cleanup;
}
- if (get.data != NULL)
- copy_from_user(&data->data[data->data_size], get.data, get.data_size);
+ if (get.data != NULL) {
+ ret = copy_from_user(&data->data[data->data_size], get.data, get.data_size);
+ if (unlikely(ret)) {
+ err();
+ goto cleanup;
+ }
+ }
data->data_size += get.data_size;
}
ret = 0;
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c
index aa46df0a3bb..5fda82cb686 100644
--- a/ncr-key-wrap.c
+++ b/ncr-key-wrap.c
@@ -422,7 +422,11 @@ struct key_item_st* key = NULL;
struct data_item_st * data = NULL;
int ret;
- copy_from_user( &wrap, arg, sizeof(wrap));
+ ret = copy_from_user( &wrap, arg, sizeof(wrap));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
if (wkey == NULL) {
@@ -482,7 +486,11 @@ struct key_item_st* key = NULL;
struct data_item_st * data = NULL;
int ret;
- copy_from_user( &wrap, arg, sizeof(wrap));
+ ret = copy_from_user( &wrap, arg, sizeof(wrap));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
if (wkey == NULL) {
@@ -540,7 +548,11 @@ int ret;
return ENOKEY;
}
- copy_from_user( &wrap, arg, sizeof(wrap));
+ ret = copy_from_user( &wrap, arg, sizeof(wrap));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
if (wkey == NULL) {
@@ -595,7 +607,11 @@ int ret;
return ENOKEY;
}
- copy_from_user( &wrap, arg, sizeof(wrap));
+ ret = copy_from_user( &wrap, arg, sizeof(wrap));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
wkey = ncr_key_item_get( key_lst, wrap.keytowrap);
if (wkey == NULL) {
diff --git a/ncr-key.c b/ncr-key.c
index 4c4694874d8..daf77bf5263 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -118,9 +118,7 @@ int ncr_key_init(struct list_sem_st* lst, void __user* arg)
up(&lst->sem);
desc = key->desc;
- copy_to_user(arg, &desc, sizeof(desc));
-
- return 0;
+ return copy_to_user(arg, &desc, sizeof(desc));
}
@@ -128,8 +126,13 @@ int ncr_key_deinit(struct list_sem_st* lst, void __user* arg)
{
ncr_key_t desc;
struct key_item_st * item, *tmp;
+ int ret;
- copy_from_user( &desc, arg, sizeof(desc));
+ ret = copy_from_user( &desc, arg, sizeof(desc));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
down(&lst->sem);
@@ -157,7 +160,11 @@ struct key_item_st* item = NULL;
struct data_item_st* ditem = NULL;
int ret;
- copy_from_user( &data, arg, sizeof(data));
+ ret = copy_from_user( &data, arg, sizeof(data));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
item = ncr_key_item_get( key_lst, data.key);
if (item == NULL) {
@@ -221,7 +228,11 @@ struct key_item_st* item = NULL;
struct data_item_st* ditem = NULL;
int ret;
- copy_from_user( &data, arg, sizeof(data));
+ ret = copy_from_user( &data, arg, sizeof(data));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
item = ncr_key_item_get( key_lst, data.key);
if (item == NULL) {
@@ -297,7 +308,11 @@ struct key_item_st* item = NULL;
int ret;
size_t size;
- copy_from_user( &gen, arg, sizeof(gen));
+ ret = copy_from_user( &gen, arg, sizeof(gen));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
item = ncr_key_item_get( lst, gen.desc);
if (item == NULL) {
@@ -345,8 +360,13 @@ int ncr_key_info(struct list_sem_st* lst, void __user* arg)
{
struct ncr_key_info_st info;
struct key_item_st* item = NULL;
+int ret;
- copy_from_user( &info, arg, sizeof(info));
+ ret = copy_from_user( &info, arg, sizeof(info));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
item = ncr_key_item_get( lst, info.key);
if (item == NULL) {
diff --git a/ncr-sessions.c b/ncr-sessions.c
index ca2f8a5cb26..7ae96c0cbad 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -177,17 +177,14 @@ int i = 0;
return 0;
}
-int ncr_session_init(struct ncr_lists* lists, void __user* arg)
+static int _ncr_session_init(struct ncr_lists* lists, struct ncr_session_st* session)
{
- struct ncr_session_st session;
struct session_item_st* ns = NULL;
struct key_item_st *key = NULL;
int ret;
const char* str;
- copy_from_user( &session, arg, sizeof(session));
-
- str = algo2str(session.algorithm);
+ str = algo2str(session->algorithm);
if (str == NULL) {
err();
return NCR_SESSION_INVALID;
@@ -199,13 +196,13 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg)
return -EINVAL;
}
- ns->op = session.op;
- ns->algo = session.algorithm;
- switch(session.op) {
+ ns->op = session->op;
+ ns->algo = session->algorithm;
+ switch(session->op) {
case NCR_OP_ENCRYPT:
case NCR_OP_DECRYPT:
/* read key */
- key = ncr_key_item_get( &lists->key, session.params.key);
+ key = ncr_key_item_get( &lists->key, session->params.key);
if (key == NULL) {
err();
ret = -EINVAL;
@@ -224,19 +221,19 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg)
goto fail;
}
- if (algo_needs_iv(session.algorithm)) {
- if (session.params.params.cipher.iv_size > sizeof(session.params.params.cipher.iv)) {
+ if (algo_needs_iv(session->algorithm)) {
+ if (session->params.params.cipher.iv_size > sizeof(session->params.params.cipher.iv)) {
err();
ret = -EINVAL;
goto fail;
}
- cryptodev_cipher_set_iv(&ns->ctx, session.params.params.cipher.iv, session.params.params.cipher.iv_size);
+ cryptodev_cipher_set_iv(&ns->ctx, session->params.params.cipher.iv, session->params.params.cipher.iv_size);
}
break;
case NCR_OP_MAC:
/* read key */
- key = ncr_key_item_get( &lists->key, session.params.key);
+ key = ncr_key_item_get( &lists->key, session->params.key);
if (key == NULL) {
err();
ret = -EINVAL;
@@ -281,11 +278,9 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg)
ret = -EINVAL;
goto fail;
}
-
+
ret = 0;
-
- session.ses = ns->desc;
- copy_to_user( arg, &session, sizeof(session));
+ session->ses = ns->desc;
fail:
if (key) _ncr_key_item_put(key);
@@ -300,18 +295,35 @@ fail:
return ret;
}
-int ncr_session_update(struct ncr_lists* lists, void __user* arg)
+int ncr_session_init(struct ncr_lists* lists, void __user* arg)
+{
+ struct ncr_session_st session;
+ int ret;
+
+ ret = copy_from_user( &session, arg, sizeof(session));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
+
+ ret = _ncr_session_init(lists, &session);
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
+
+ return copy_to_user( arg, &session, sizeof(session));
+}
+
+static int _ncr_session_update(struct ncr_lists* lists, struct ncr_session_op_st* op)
{
- struct ncr_session_op_st op;
struct key_item_st *key = NULL;
int ret;
struct session_item_st* sess;
struct data_item_st* data = NULL;
struct data_item_st* odata = NULL;
- copy_from_user( &op, arg, sizeof(op));
-
- sess = ncr_sessions_item_get( &lists->sessions, op.ses);
+ sess = ncr_sessions_item_get( &lists->sessions, op->ses);
if (sess == NULL) {
err();
return -EINVAL;
@@ -320,14 +332,14 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg)
switch(sess->op) {
case NCR_OP_ENCRYPT:
/* obtain data item */
- data = ncr_data_item_get( &lists->data, op.data.cipher.plaintext);
+ data = ncr_data_item_get( &lists->data, op->data.cipher.plaintext);
if (data == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- odata = ncr_data_item_get( &lists->data, op.data.cipher.ciphertext);
+ odata = ncr_data_item_get( &lists->data, op->data.cipher.ciphertext);
if (odata == NULL) {
err();
ret = -EINVAL;
@@ -352,14 +364,14 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg)
break;
case NCR_OP_DECRYPT:
/* obtain data item */
- data = ncr_data_item_get( &lists->data, op.data.cipher.ciphertext);
+ data = ncr_data_item_get( &lists->data, op->data.cipher.ciphertext);
if (data == NULL) {
err();
ret = -EINVAL;
goto fail;
}
- odata = ncr_data_item_get( &lists->data, op.data.cipher.plaintext);
+ odata = ncr_data_item_get( &lists->data, op->data.cipher.plaintext);
if (odata == NULL) {
err();
ret = -EINVAL;
@@ -386,7 +398,7 @@ int ncr_session_update(struct ncr_lists* lists, void __user* arg)
case NCR_OP_MAC:
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.digest.text);
if (data == NULL) {
err();
ret = -EINVAL;
@@ -416,6 +428,20 @@ fail:
return ret;
}
+int ncr_session_update(struct ncr_lists* lists, void __user* arg)
+{
+ struct ncr_session_op_st op;
+ int ret;
+
+ ret = copy_from_user( &op, arg, sizeof(op));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
+
+ return _ncr_session_update(lists, &op);
+}
+
static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
{
struct session_item_st * item, *tmp;
@@ -435,9 +461,8 @@ static void _ncr_session_remove(struct list_sem_st* lst, ncr_session_t desc)
return;
}
-int ncr_session_final(struct ncr_lists* lists, void __user* arg)
+static int _ncr_session_final(struct ncr_lists* lists, struct ncr_session_op_st* op)
{
- struct ncr_session_op_st op;
struct key_item_st *key = NULL;
int ret;
struct session_item_st* sess;
@@ -445,9 +470,7 @@ int ncr_session_final(struct ncr_lists* lists, void __user* arg)
struct data_item_st* odata = NULL;
int digest_size;
- copy_from_user( &op, arg, sizeof(op));
-
- sess = ncr_sessions_item_get( &lists->sessions, op.ses);
+ sess = ncr_sessions_item_get( &lists->sessions, op->ses);
if (sess == NULL) {
err();
return -EINVAL;
@@ -457,19 +480,19 @@ int ncr_session_final(struct ncr_lists* lists, void __user* arg)
case NCR_OP_ENCRYPT:
case NCR_OP_DECRYPT:
/* obtain data item */
- if (op.data.cipher.plaintext != NCR_DATA_INVALID &&
- op.data.cipher.ciphertext != NCR_DATA_INVALID) {
- ncr_session_update(lists, arg);
+ if (op->data.cipher.plaintext != NCR_DATA_INVALID &&
+ op->data.cipher.ciphertext != NCR_DATA_INVALID) {
+ _ncr_session_update(lists, op);
}
cryptodev_cipher_deinit(&sess->ctx);
break;
case NCR_OP_MAC:
case NCR_OP_DIGEST:
/* obtain data item */
- if (op.data.digest.text != NCR_DATA_INVALID) {
- ncr_session_update(lists, arg);
+ if (op->data.digest.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.digest.output);
if (odata == NULL) {
err();
ret = -EINVAL;
@@ -500,33 +523,48 @@ fail:
if (odata) _ncr_data_item_put(odata);
if (data) _ncr_data_item_put(data);
_ncr_sessions_item_put(sess);
- _ncr_session_remove(&lists->sessions, op.ses);
+ _ncr_session_remove(&lists->sessions, op->ses);
return ret;
}
+int ncr_session_final(struct ncr_lists* lists, void __user* arg)
+{
+ struct ncr_session_op_st op;
+ int ret;
+
+ ret = copy_from_user( &op, arg, sizeof(op));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
+
+ return _ncr_session_final(lists, &op);
+}
+
int ncr_session_once(struct ncr_lists* lists, void __user* arg)
{
- struct __user ncr_session_once_op_st* op = arg;
struct ncr_session_once_op_st kop;
int ret;
- ret = ncr_session_init(lists, &op->init);
- if (ret < 0) {
+ ret = copy_from_user(&kop, arg, sizeof(kop));
+ if (unlikely(ret)) {
err();
return ret;
}
- copy_from_user(&kop, arg, sizeof(kop));
- kop.op.ses = kop.init.ses;
- copy_to_user(arg, &kop, sizeof(kop));
+ ret = _ncr_session_init(lists, &kop.init);
+ if (ret < 0) {
+ err();
+ return ret;
+ }
- ret = ncr_session_final(lists, &op->op);
+ ret = _ncr_session_final(lists, &kop.op);
if (ret < 0) {
err();
return ret;
}
- return 0;
+ return copy_to_user(arg, &kop, sizeof(kop));
}
diff --git a/ncr.c b/ncr.c
index 352e0edf0a0..abdad6d0a7a 100644
--- a/ncr.c
+++ b/ncr.c
@@ -78,13 +78,18 @@ void ncr_master_key_reset(void)
static int ncr_master_key_set(void* __user arg)
{
struct ncr_master_key_st st;
+int ret;
if (current_euid() != 0 && !capable(CAP_SYS_ADMIN)) {
err();
return -EPERM;
}
- copy_from_user(&st, arg, sizeof(st));
+ ret = copy_from_user(&st, arg, sizeof(st));
+ if (unlikely(ret)) {
+ err();
+ return ret;
+ }
if (st.key_size > sizeof(master_key.key.secret.data)) {
err();