summaryrefslogtreecommitdiff
path: root/drivers/misc/tegra-cryptodev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/tegra-cryptodev.c')
-rw-r--r--drivers/misc/tegra-cryptodev.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/misc/tegra-cryptodev.c b/drivers/misc/tegra-cryptodev.c
index 7d95fcc6f156..88c9cb217880 100644
--- a/drivers/misc/tegra-cryptodev.c
+++ b/drivers/misc/tegra-cryptodev.c
@@ -3,7 +3,7 @@
*
* crypto dev node for NVIDIA tegra aes hardware
*
- * Copyright (c) 2010-2014, NVIDIA Corporation. All Rights Reserved.
+ * Copyright (c) 2010-2017, NVIDIA Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,6 +40,10 @@
#define XBUFSIZE 8
#define RNG_DRBG 1
#define RNG 0
+#define NUM_RSA_ALGO 4
+#define ECC_MODE_MIN_INDEX 7
+#define ECC_MODE_MAX_INDEX 13
+#define MAX_RSA_MSG_LEN 256
#define TEGRA_RSA512 0
#define TEGRA_RSA1024 1
@@ -539,6 +543,11 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
unsigned long *xbuf[XBUFSIZE];
int ret = -ENOMEM;
+ if (sha_req->plaintext_sz > PAGE_SIZE) {
+ pr_err("alg:hash: invalid plaintext_sz for sha_req\n");
+ return -EINVAL;
+ }
+
tfm = crypto_alloc_ahash(sha_req->algo, 0, 0);
if (IS_ERR(tfm)) {
pr_err("alg:hash:Failed to load transform for %s:%ld\n",
@@ -653,6 +662,11 @@ static long tegra_crypto_dev_ioctl(struct file *filp,
ret = copy_from_user(&crypt_req_32, (void __user *)arg,
sizeof(crypt_req_32));
+ if (crypt_req_32.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d exceeds max value %d\n",
+ crypt_req_32.keylen, TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
crypt_req.op = crypt_req_32.op;
crypt_req.encrypt = crypt_req_32.encrypt;
crypt_req.skip_key = crypt_req_32.skip_key;
@@ -792,6 +806,11 @@ rng_out:
ret = copy_from_user(&sha_req_32, (void __user *)arg,
sizeof(sha_req_32));
+ if (sha_req_32.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d not within the range [0,%d]\n",
+ sha_req_32.keylen, TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
for (i = 0; i < sha_req_32.keylen; i++)
sha_req.key[i] = sha_req_32.key[i];
sha_req.keylen = sha_req_32.keylen;
@@ -816,7 +835,12 @@ rng_out:
__func__, ret);
return ret;
}
-
+ if (sha_req.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d out of range [0,%d]\n",
+ sha_req.keylen
+ , TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
ret = tegra_crypto_sha(&sha_req);
} else {
ret = -EINVAL;
@@ -856,7 +880,16 @@ rng_out:
pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
return ret;
}
-
+ if (rsa_req.msg_len > MAX_RSA_MSG_LEN) {
+ pr_err("Illegal message from user of length = %d\n",
+ rsa_req.msg_len);
+ return -EINVAL;
+ }
+ if (rsa_req.algo >= NUM_RSA_ALGO) {
+ pr_err("Invalid value of algo index %d\n",
+ rsa_req.algo);
+ return -EINVAL;
+ }
ret = tegra_crypt_rsa(ctx, &rsa_req);
break;