diff options
Diffstat (limited to 'drivers/misc/tegra-cryptodev.c')
-rw-r--r-- | drivers/misc/tegra-cryptodev.c | 39 |
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; |