diff options
-rw-r--r-- | cryptodev_main.c | 45 | ||||
-rw-r--r-- | ncr-data.c | 65 | ||||
-rw-r--r-- | ncr-key-wrap.c | 24 | ||||
-rw-r--r-- | ncr-key.c | 36 | ||||
-rw-r--r-- | ncr-sessions.c | 132 | ||||
-rw-r--r-- | ncr.c | 7 |
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)); } @@ -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(); |