Exemplo n.º 1
0
int crypto_get_default_rng(void)
{
	struct crypto_rng *rng;
	int err;

	mutex_lock(&crypto_default_rng_lock);
	if (!crypto_default_rng) {
		rng = crypto_alloc_rng("stdrng", 0, 0);
		err = PTR_ERR(rng);
		if (IS_ERR(rng))
			goto unlock;

		err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
		if (err) {
			crypto_free_rng(rng);
			goto unlock;
		}

		crypto_default_rng = rng;
	}

	crypto_default_rng_refcnt++;
	err = 0;

unlock:
	mutex_unlock(&crypto_default_rng_lock);

	return err;
}
Exemplo n.º 2
0
int cryptodev_rng_init(struct rng_data *rdata, const char *alg_name,
			void *key, size_t keylen)
{
	int ret;

	rdata->s = crypto_alloc_rng(alg_name, 0, 0);
	if (unlikely(IS_ERR(rdata->s))) {
		ddebug(1, "Failed to load transform for %s", alg_name);
		return -EINVAL;
	}

	/* Copy the key from user and set to TFM. */
	ret = crypto_rng_reset(rdata->s, key, keylen);
	if (unlikely(ret)) {
		ddebug(1, "Seeding failed for %s-%zu.",
				alg_name, keylen*8);
		ret = -EINVAL;
		goto error;
	}

	rdata->seedsize = crypto_rng_seedsize(rdata->s);
	rdata->init = 1;
	return 0;

error:
	crypto_free_rng(rdata->s);
	return ret;
}
Exemplo n.º 3
0
/*
 * Initialize big_key crypto and RNG algorithms
 */
static int __init big_key_crypto_init(void)
{
	int ret = -EINVAL;

	/* init RNG */
	big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
	if (IS_ERR(big_key_rng)) {
		big_key_rng = NULL;
		return -EFAULT;
	}

	/* seed RNG */
	ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
	if (ret)
		goto error;

	/* init block cipher */
	big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name,
						 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(big_key_skcipher)) {
		big_key_skcipher = NULL;
		ret = -EFAULT;
		goto error;
	}

	return 0;

error:
	crypto_free_rng(big_key_rng);
	big_key_rng = NULL;
	return ret;
}
Exemplo n.º 4
0
/*
 * Register key type
 */
static int __init big_key_init(void)
{
	struct crypto_skcipher *cipher;
	struct crypto_rng *rng;
	int ret;

	rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
	if (IS_ERR(rng)) {
		pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
		return PTR_ERR(rng);
	}

	big_key_rng = rng;

	/* seed RNG */
	ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
	if (ret) {
		pr_err("Can't reset rng: %d\n", ret);
		goto error_rng;
	}

	/* init block cipher */
	cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(cipher)) {
		ret = PTR_ERR(cipher);
		pr_err("Can't alloc crypto: %d\n", ret);
		goto error_rng;
	}

	big_key_skcipher = cipher;

	ret = register_key_type(&key_type_big_key);
	if (ret < 0) {
		pr_err("Can't register type: %d\n", ret);
		goto error_cipher;
	}

	return 0;

error_cipher:
	crypto_free_skcipher(big_key_skcipher);
error_rng:
	crypto_free_rng(big_key_rng);
	return ret;
}
Exemplo n.º 5
0
static long tegra_crypto_dev_ioctl(struct file *filp,
	unsigned int ioctl_num, unsigned long arg)
{
	struct tegra_crypto_ctx *ctx = filp->private_data;
	struct tegra_crypt_req crypt_req;
	struct tegra_rng_req rng_req;
	struct tegra_sha_req sha_req;
	struct tegra_rsa_req rsa_req;
	char *rng;
	int ret = 0;

	switch (ioctl_num) {

	case TEGRA_CRYPTO_IOCTL_NEED_SSK:
		ctx->use_ssk = (int)arg;
		break;

	case TEGRA_CRYPTO_IOCTL_PROCESS_REQ:
		ret = copy_from_user(&crypt_req, (void __user *)arg,
			sizeof(crypt_req));
		if (ret) {
			ret = -EFAULT;
			pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
			break;
		}

		ret = process_crypt_req(ctx, &crypt_req);
		break;

	case TEGRA_CRYPTO_IOCTL_SET_SEED:
		if (copy_from_user(&rng_req, (void __user *)arg,
			sizeof(rng_req))) {
			ret = -EFAULT;
			pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
			return ret;
		}

		memcpy(ctx->seed, rng_req.seed, TEGRA_CRYPTO_RNG_SEED_SIZE);

		if (rng_req.type == RNG_DRBG)
			ret = crypto_rng_reset(ctx->rng_drbg, ctx->seed,
				crypto_rng_seedsize(ctx->rng_drbg));
		else
			ret = crypto_rng_reset(ctx->rng, ctx->seed,
				crypto_rng_seedsize(ctx->rng));
		break;

	case TEGRA_CRYPTO_IOCTL_GET_RANDOM:
		if (copy_from_user(&rng_req, (void __user *)arg,
			sizeof(rng_req))) {
			ret = -EFAULT;
			pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
			return ret;
		}

		rng = kzalloc(rng_req.nbytes, GFP_KERNEL);
		if (!rng) {
			if (rng_req.type == RNG_DRBG)
				pr_err("mem alloc for rng_drbg fail");
			else
				pr_err("mem alloc for rng fail");

			ret = -ENODATA;
			goto rng_out;
		}

		if (rng_req.type == RNG_DRBG)
			ret = crypto_rng_get_bytes(ctx->rng_drbg, rng,
				rng_req.nbytes);
		else
			ret = crypto_rng_get_bytes(ctx->rng, rng,
				rng_req.nbytes);

		if (ret != rng_req.nbytes) {
			if (rng_req.type == RNG_DRBG)
				pr_err("rng_drbg failed");
			else
				pr_err("rng failed");
			ret = -ENODATA;
			goto rng_out;
		}

		ret = copy_to_user((void __user *)rng_req.rdata,
			(const void *)rng, rng_req.nbytes);
		if (ret) {
			ret = -EFAULT;
			pr_err("%s: copy_to_user fail(%d)\n", __func__, ret);
			return ret;
		}

rng_out:
		if (rng)
			kfree(rng);
		break;

	case TEGRA_CRYPTO_IOCTL_GET_SHA:
		if (tegra_get_chipid() != TEGRA_CHIPID_TEGRA2) {
			if (copy_from_user(&sha_req, (void __user *)arg,
				sizeof(sha_req))) {
				ret = -EFAULT;
				pr_err("%s: copy_from_user fail(%d)\n",
						__func__, ret);
				return ret;
			}

			ret = tegra_crypto_sha(&sha_req);
		} else {
			ret = -EINVAL;
		}
		break;

	case TEGRA_CRYPTO_IOCTL_RSA_REQ:
		if (copy_from_user(&rsa_req, (void __user *)arg,
			sizeof(rsa_req))) {
			ret = -EFAULT;
			pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
			return ret;
		}

		ret = tegra_crypt_rsa(ctx, &rsa_req);
		break;

	default:
		pr_debug("invalid ioctl code(%d)", ioctl_num);
		ret = -EINVAL;
	}

	return ret;
}