summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptodev_cipher.c14
-rw-r--r--cryptodev_int.h2
-rw-r--r--cryptodev_main.c48
3 files changed, 35 insertions, 29 deletions
diff --git a/cryptodev_cipher.c b/cryptodev_cipher.c
index 25ef44e..2f52f46 100644
--- a/cryptodev_cipher.c
+++ b/cryptodev_cipher.c
@@ -64,7 +64,10 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t
return -EINVAL;
}
/* Copy the key from user and set to TFM. */
- copy_from_user(keyp, key, keylen);
+ if (unlikely(copy_from_user(keyp, key, keylen))) {
+ dprintk(1, KERN_DEBUG, "copy_from_user() failed for key\n");
+ return -EINVAL;
+ }
out->async.s = crypto_alloc_ablkcipher(alg_name, 0, 0);
if (unlikely(IS_ERR(out->async.s))) {
@@ -135,9 +138,9 @@ void cryptodev_cipher_deinit(struct cipher_data* cdata)
cdata->init = 0;
}
-void cryptodev_cipher_set_iv(struct cipher_data* cdata, void __user* iv, size_t iv_size)
+int cryptodev_cipher_set_iv(struct cipher_data* cdata, void __user* iv, size_t iv_size)
{
- copy_from_user(cdata->async.iv, iv, min(iv_size,sizeof(cdata->async.iv)));
+ return copy_from_user(cdata->async.iv, iv, min(iv_size,sizeof(cdata->async.iv)));
}
static inline int waitfor (struct cryptodev_result* cr, ssize_t ret)
@@ -205,7 +208,10 @@ uint8_t hkeyp[CRYPTO_HMAC_MAX_KEY_LEN];
alg_name, mackeylen*8);
return -EINVAL;
}
- copy_from_user(hkeyp, mackey, mackeylen);
+ if (unlikely(copy_from_user(hkeyp, mackey, mackeylen))) {
+ dprintk(1, KERN_DEBUG, "copy_from_user() failed for mackey\n");
+ return -EINVAL;
+ }
hdata->async.s = crypto_alloc_ahash(alg_name, 0, 0);
if (unlikely(IS_ERR(hdata->async.s))) {
diff --git a/cryptodev_int.h b/cryptodev_int.h
index 8e3059a..408f1f9 100644
--- a/cryptodev_int.h
+++ b/cryptodev_int.h
@@ -40,7 +40,7 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, __user
void cryptodev_cipher_deinit(struct cipher_data* cdata);
ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len);
ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len);
-void cryptodev_cipher_set_iv(struct cipher_data* cdata, void* iv, size_t iv_size);
+int cryptodev_cipher_set_iv(struct cipher_data* cdata, void* iv, size_t iv_size);
/* hash stuff */
struct hash_data
diff --git a/cryptodev_main.c b/cryptodev_main.c
index 9fac1e6..35feefd 100644
--- a/cryptodev_main.c
+++ b/cryptodev_main.c
@@ -405,7 +405,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
while(nbytes > 0) {
size_t current_len = nbytes > bufsize ? bufsize : nbytes;
- copy_from_user(data, src, current_len);
+ if (unlikely(copy_from_user(data, src, current_len)))
+ goto out;
sg_init_one(&sg, data, current_len);
@@ -427,7 +428,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
goto out;
}
- copy_to_user(dst, data, current_len);
+ if (unlikely(copy_to_user(dst, data, current_len)))
+ goto out;
dst += current_len;
}
} else {
@@ -438,7 +440,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
goto out;
}
- copy_to_user(dst, data, current_len);
+ if (unlikely(copy_to_user(dst, data, current_len)))
+ goto out;
dst += current_len;
}
@@ -463,7 +466,8 @@ crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
goto out;
}
- copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize);
+ if (unlikely(copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize)))
+ goto out;
}
#if defined(CRYPTODEV_STATS)
@@ -557,12 +561,11 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
return 0;
case CIOCGSESSION:
- copy_from_user(&sop, (void*)arg, sizeof(sop));
- ret = crypto_create_session(fcr, &sop);
+ ret = copy_from_user(&sop, (void*)arg, sizeof(sop));
+ ret |= crypto_create_session(fcr, &sop);
if (unlikely(ret))
return ret;
- copy_to_user((void*)arg, &sop, sizeof(sop));
- return 0;
+ return copy_to_user((void*)arg, &sop, sizeof(sop));
case CIOCFSESSION:
get_user(ses, (uint32_t*)arg);
@@ -570,12 +573,11 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
return ret;
case CIOCCRYPT:
- copy_from_user(&cop, (void*)arg, sizeof(cop));
- ret = crypto_run(fcr, &cop);
+ ret = copy_from_user(&cop, (void*)arg, sizeof(cop));
+ ret |= crypto_run(fcr, &cop);
if (unlikely(ret))
return ret;
- copy_to_user((void*)arg, &cop, sizeof(cop));
- return 0;
+ return copy_to_user((void*)arg, &cop, sizeof(cop));
default:
return -EINVAL;
@@ -645,32 +647,30 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return cryptodev_ioctl(NULL, file, cmd, arg);
case COMPAT_CIOCGSESSION:
- copy_from_user(&compat_sop, (void *)arg,
- sizeof(compat_sop));
+ ret = copy_from_user(&compat_sop,
+ (void *)arg, sizeof(compat_sop));
compat_to_session_op(&compat_sop, &sop);
- ret = crypto_create_session(fcr, &sop);
+ ret |= crypto_create_session(fcr, &sop);
if (unlikely(ret))
return ret;
session_op_to_compat(&sop, &compat_sop);
- copy_to_user((void*)arg, &compat_sop,
- sizeof(compat_sop));
- return 0;
+ return copy_to_user((void*)arg,
+ &compat_sop, sizeof(compat_sop));
case COMPAT_CIOCCRYPT:
- copy_from_user(&compat_cop, (void*)arg,
- sizeof(compat_cop));
+ ret = copy_from_user(&compat_cop,
+ (void*)arg, sizeof(compat_cop));
compat_to_crypt_op(&compat_cop, &cop);
- ret = crypto_run(fcr, &cop);
+ ret |= crypto_run(fcr, &cop);
if (unlikely(ret))
return ret;
crypt_op_to_compat(&cop, &compat_cop);
- copy_to_user((void*)arg, &compat_cop,
- sizeof(compat_cop));
- return 0;
+ return copy_to_user((void*)arg,
+ &compat_cop, sizeof(compat_cop));
default:
return -EINVAL;