예제 #1
0
파일: ctr.c 프로젝트: 03199618/linux
static int crypto_rfc3686_setkey(struct crypto_ablkcipher *parent,
				 const u8 *key, unsigned int keylen)
{
	struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(parent);
	struct crypto_ablkcipher *child = ctx->child;
	int err;

	/* the nonce is stored in bytes at end of key */
	if (keylen < CTR_RFC3686_NONCE_SIZE)
		return -EINVAL;

	memcpy(ctx->nonce, key + (keylen - CTR_RFC3686_NONCE_SIZE),
	       CTR_RFC3686_NONCE_SIZE);

	keylen -= CTR_RFC3686_NONCE_SIZE;

	crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
	crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) &
				    CRYPTO_TFM_REQ_MASK);
	err = crypto_ablkcipher_setkey(child, key, keylen);
	crypto_ablkcipher_set_flags(parent, crypto_ablkcipher_get_flags(child) &
				    CRYPTO_TFM_RES_MASK);

	return err;
}
예제 #2
0
static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
			unsigned int key_len)
{
	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
	struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base;
	int err;

	crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
	crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm)
				    & CRYPTO_TFM_REQ_MASK);
	err = crypto_ablkcipher_setkey(child, key, key_len);
	crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child)
				    & CRYPTO_TFM_RES_MASK);
	return err;
}
예제 #3
0
static int crypto_ccm_setkey(struct crypto_aead *aead, const u8 *key,
			     unsigned int keylen)
{
	struct crypto_ccm_ctx *ctx = crypto_aead_ctx(aead);
	struct crypto_ablkcipher *ctr = ctx->ctr;
	struct crypto_cipher *tfm = ctx->cipher;
	int err = 0;

	crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
	crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
				    CRYPTO_TFM_REQ_MASK);
	err = crypto_ablkcipher_setkey(ctr, key, keylen);
	crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
			      CRYPTO_TFM_RES_MASK);
	if (err)
		goto out;

	crypto_cipher_clear_flags(tfm, CRYPTO_TFM_REQ_MASK);
	crypto_cipher_set_flags(tfm, crypto_aead_get_flags(aead) &
				    CRYPTO_TFM_REQ_MASK);
	err = crypto_cipher_setkey(tfm, key, keylen);
	crypto_aead_set_flags(aead, crypto_cipher_get_flags(tfm) &
			      CRYPTO_TFM_RES_MASK);

out:
	return err;
}
예제 #4
0
파일: cryptd.c 프로젝트: 274914765/C
static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent,
                   const u8 *key, unsigned int keylen)
{
    struct cryptd_blkcipher_ctx *ctx = crypto_ablkcipher_ctx(parent);
    struct crypto_blkcipher *child = ctx->child;
    int err;

    crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
    crypto_blkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) &
                      CRYPTO_TFM_REQ_MASK);
    err = crypto_blkcipher_setkey(child, key, keylen);
    crypto_ablkcipher_set_flags(parent, crypto_blkcipher_get_flags(child) &
                        CRYPTO_TFM_RES_MASK);
    return err;
}
예제 #5
0
static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key,
				 unsigned int keylen)
{
	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk);
	struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
	unsigned long flags = to_cipher_tmpl(tfm)->alg_flags;
	int ret;

	if (!key || !keylen)
		return -EINVAL;

	if (IS_AES(flags)) {
		switch (keylen) {
		case AES_KEYSIZE_128:
		case AES_KEYSIZE_256:
			break;
		default:
			goto fallback;
		}
	} else if (IS_DES(flags)) {
		u32 tmp[DES_EXPKEY_WORDS];

		ret = des_ekey(tmp, key);
		if (!ret && crypto_ablkcipher_get_flags(ablk) &
		    CRYPTO_TFM_REQ_WEAK_KEY)
			goto weakkey;
	}

	ctx->enc_keylen = keylen;
	memcpy(ctx->enc_key, key, keylen);
	return 0;
fallback:
	ret = crypto_sync_skcipher_setkey(ctx->fallback, key, keylen);
	if (!ret)
		ctx->enc_keylen = keylen;
	return ret;
weakkey:
	crypto_ablkcipher_set_flags(ablk, CRYPTO_TFM_RES_WEAK_KEY);
	return -EINVAL;
}
예제 #6
0
파일: gcm.c 프로젝트: jtcriswell/linux256
static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
                             unsigned int keylen)
{
    struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
    struct crypto_ahash *ghash = ctx->ghash;
    struct crypto_ablkcipher *ctr = ctx->ctr;
    struct {
        be128 hash;
        u8 iv[8];

        struct crypto_gcm_setkey_result result;

        struct scatterlist sg[1];
        struct ablkcipher_request req;
    } *data;
    int err;

    crypto_ablkcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
    crypto_ablkcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
                                CRYPTO_TFM_REQ_MASK);

    err = crypto_ablkcipher_setkey(ctr, key, keylen);
    if (err)
        return err;

    crypto_aead_set_flags(aead, crypto_ablkcipher_get_flags(ctr) &
                          CRYPTO_TFM_RES_MASK);

    data = kzalloc(sizeof(*data) + crypto_ablkcipher_reqsize(ctr),
                   GFP_KERNEL);
    if (!data)
        return -ENOMEM;

    init_completion(&data->result.completion);
    sg_init_one(data->sg, &data->hash, sizeof(data->hash));
    ablkcipher_request_set_tfm(&data->req, ctr);
    ablkcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
                                    CRYPTO_TFM_REQ_MAY_BACKLOG,
                                    crypto_gcm_setkey_done,
                                    &data->result);
    ablkcipher_request_set_crypt(&data->req, data->sg, data->sg,
                                 sizeof(data->hash), data->iv);

    err = crypto_ablkcipher_encrypt(&data->req);
    if (err == -EINPROGRESS || err == -EBUSY) {
        err = wait_for_completion_interruptible(
                  &data->result.completion);
        if (!err)
            err = data->result.err;
    }

    if (err)
        goto out;

    crypto_ahash_clear_flags(ghash, CRYPTO_TFM_REQ_MASK);
    crypto_ahash_set_flags(ghash, crypto_aead_get_flags(aead) &
                           CRYPTO_TFM_REQ_MASK);
    err = crypto_ahash_setkey(ghash, (u8 *)&data->hash, sizeof(be128));
    crypto_aead_set_flags(aead, crypto_ahash_get_flags(ghash) &
                          CRYPTO_TFM_RES_MASK);

out:
    kfree(data);
    return err;
}
예제 #7
0
파일: skcipher.c 프로젝트: 020gzh/linux
static int skcipher_crypt_blkcipher(struct skcipher_request *req,
				    int (*crypt)(struct blkcipher_desc *,
						 struct scatterlist *,
						 struct scatterlist *,
						 unsigned int))
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm);
	struct blkcipher_desc desc = {
		.tfm = *ctx,
		.info = req->iv,
		.flags = req->base.flags,
	};


	return crypt(&desc, req->dst, req->src, req->cryptlen);
}

static int skcipher_encrypt_blkcipher(struct skcipher_request *req)
{
	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
	struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;

	return skcipher_crypt_blkcipher(req, alg->encrypt);
}

static int skcipher_decrypt_blkcipher(struct skcipher_request *req)
{
	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
	struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;

	return skcipher_crypt_blkcipher(req, alg->decrypt);
}

static void crypto_exit_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
{
	struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm);

	crypto_free_blkcipher(*ctx);
}

static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
{
	struct crypto_alg *calg = tfm->__crt_alg;
	struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
	struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm);
	struct crypto_blkcipher *blkcipher;
	struct crypto_tfm *btfm;

	if (!crypto_mod_get(calg))
		return -EAGAIN;

	btfm = __crypto_alloc_tfm(calg, CRYPTO_ALG_TYPE_BLKCIPHER,
					CRYPTO_ALG_TYPE_MASK);
	if (IS_ERR(btfm)) {
		crypto_mod_put(calg);
		return PTR_ERR(btfm);
	}

	blkcipher = __crypto_blkcipher_cast(btfm);
	*ctx = blkcipher;
	tfm->exit = crypto_exit_skcipher_ops_blkcipher;

	skcipher->setkey = skcipher_setkey_blkcipher;
	skcipher->encrypt = skcipher_encrypt_blkcipher;
	skcipher->decrypt = skcipher_decrypt_blkcipher;

	skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
	skcipher->keysize = calg->cra_blkcipher.max_keysize;

	return 0;
}

static int skcipher_setkey_ablkcipher(struct crypto_skcipher *tfm,
				      const u8 *key, unsigned int keylen)
{
	struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm);
	struct crypto_ablkcipher *ablkcipher = *ctx;
	int err;

	crypto_ablkcipher_clear_flags(ablkcipher, ~0);
	crypto_ablkcipher_set_flags(ablkcipher,
				    crypto_skcipher_get_flags(tfm) &
				    CRYPTO_TFM_REQ_MASK);
	err = crypto_ablkcipher_setkey(ablkcipher, key, keylen);
	crypto_skcipher_set_flags(tfm,
				  crypto_ablkcipher_get_flags(ablkcipher) &
				  CRYPTO_TFM_RES_MASK);

	return err;
}

static int skcipher_crypt_ablkcipher(struct skcipher_request *req,
				     int (*crypt)(struct ablkcipher_request *))
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm);
	struct ablkcipher_request *subreq = skcipher_request_ctx(req);

	ablkcipher_request_set_tfm(subreq, *ctx);
	ablkcipher_request_set_callback(subreq, skcipher_request_flags(req),
					req->base.complete, req->base.data);
	ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
				     req->iv);

	return crypt(subreq);
}

static int skcipher_encrypt_ablkcipher(struct skcipher_request *req)
{
	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
	struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;

	return skcipher_crypt_ablkcipher(req, alg->encrypt);
}

static int skcipher_decrypt_ablkcipher(struct skcipher_request *req)
{
	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
	struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;

	return skcipher_crypt_ablkcipher(req, alg->decrypt);
}

static void crypto_exit_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
{
	struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm);

	crypto_free_ablkcipher(*ctx);
}

static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
{
	struct crypto_alg *calg = tfm->__crt_alg;
	struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
	struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm);
	struct crypto_ablkcipher *ablkcipher;
	struct crypto_tfm *abtfm;

	if (!crypto_mod_get(calg))
		return -EAGAIN;

	abtfm = __crypto_alloc_tfm(calg, 0, 0);
	if (IS_ERR(abtfm)) {
		crypto_mod_put(calg);
		return PTR_ERR(abtfm);
	}

	ablkcipher = __crypto_ablkcipher_cast(abtfm);
	*ctx = ablkcipher;
	tfm->exit = crypto_exit_skcipher_ops_ablkcipher;

	skcipher->setkey = skcipher_setkey_ablkcipher;
	skcipher->encrypt = skcipher_encrypt_ablkcipher;
	skcipher->decrypt = skcipher_decrypt_ablkcipher;

	skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
	skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
			    sizeof(struct ablkcipher_request);
	skcipher->keysize = calg->cra_ablkcipher.max_keysize;

	return 0;
}

static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
{
	if (tfm->__crt_alg->cra_type == &crypto_blkcipher_type)
		return crypto_init_skcipher_ops_blkcipher(tfm);

	BUG_ON(tfm->__crt_alg->cra_type != &crypto_ablkcipher_type &&
	       tfm->__crt_alg->cra_type != &crypto_givcipher_type);

	return crypto_init_skcipher_ops_ablkcipher(tfm);
}

static const struct crypto_type crypto_skcipher_type2 = {
	.extsize = crypto_skcipher_extsize,
	.init_tfm = crypto_skcipher_init_tfm,
	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
	.maskset = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
	.type = CRYPTO_ALG_TYPE_BLKCIPHER,
	.tfmsize = offsetof(struct crypto_skcipher, base),
};

struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name,
					      u32 type, u32 mask)
{
	return crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_alloc_skcipher);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Symmetric key cipher type");
예제 #8
0
static int test_acipher(const char *algo, int enc, char *data_in,
		char *data_out, size_t data_len, char *key, int keysize)
		{
	struct crypto_ablkcipher *tfm;
	struct tcrypt_result tresult;
	struct ablkcipher_request *req;
	struct scatterlist sg[TVMEMSIZE];
	unsigned int ret, i, j, iv_len;
	char iv[128];

	ret = -EAGAIN;

	init_completion(&tresult.completion);

	tfm = crypto_alloc_ablkcipher(algo, 0, 0);
	if (IS_ERR(tfm)) {
		printk(KERN_ERR "failed to load transform for %s: %ld\n",
			algo, PTR_ERR(tfm));
		return ret;
	}

	req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req) {
		printk(KERN_ERR "tcrypt: skcipher: Failed to allocate request for %s\n",
			algo);
		goto out;
	}

	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
					tcrypt_complete, &tresult);

	crypto_ablkcipher_clear_flags(tfm, ~0);

	ret = crypto_ablkcipher_setkey(tfm, key, keysize);
	if (ret) {
		printk(KERN_ERR "setkey() failed flags=%x\n",
			crypto_ablkcipher_get_flags(tfm));
		goto out_free_req;
	}

	printk(KERN_INFO "KEY:\n");
	hexdump(key, keysize);

	sg_init_table(sg, TVMEMSIZE);

	i = 0;
	j = data_len;

	while (j > PAGE_SIZE) {
		sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
		memcpy(tvmem[i], data_in + i * PAGE_SIZE, PAGE_SIZE);
		i++;
		j -= PAGE_SIZE;
	}
	sg_set_buf(sg + i, tvmem[i], j);
	memcpy(tvmem[i], data_in + i * PAGE_SIZE, j);

	iv_len = crypto_ablkcipher_ivsize(tfm);
	memcpy(iv, iv16, iv_len);

	printk(KERN_INFO "IV:\n");
	hexdump(iv, iv_len);

	ablkcipher_request_set_crypt(req, sg, sg, data_len, iv);

	printk(KERN_INFO "IN:\n");
	hexdump(data_in, data_len);

	if (enc)
		ret = do_one_acipher_op(req, crypto_ablkcipher_encrypt(req));
	else
		ret = do_one_acipher_op(req, crypto_ablkcipher_decrypt(req));

	if (ret)
		printk(KERN_ERR "failed flags=%x\n",
			crypto_ablkcipher_get_flags(tfm));
	else {
		i = 0;
		j = data_len;
		while (j > PAGE_SIZE) {
			memcpy(data_out + i * PAGE_SIZE, tvmem[i], PAGE_SIZE);
			i++;
			j -= PAGE_SIZE;
		}
		memcpy(data_out + i * PAGE_SIZE, tvmem[i], j);

		printk(KERN_INFO "OUT:\n");
		hexdump(data_out, data_len);
	}

out_free_req:
	ablkcipher_request_free(req);
out:
	crypto_free_ablkcipher(tfm);

	return ret;
}