cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

geniv.c (3901B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * geniv: Shared IV generator code
      4 *
      5 * This file provides common code to IV generators such as seqiv.
      6 *
      7 * Copyright (c) 2007-2019 Herbert Xu <herbert@gondor.apana.org.au>
      8 */
      9
     10#include <crypto/internal/geniv.h>
     11#include <crypto/internal/rng.h>
     12#include <crypto/null.h>
     13#include <linux/err.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/rtnetlink.h>
     17#include <linux/slab.h>
     18
     19static int aead_geniv_setkey(struct crypto_aead *tfm,
     20			     const u8 *key, unsigned int keylen)
     21{
     22	struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
     23
     24	return crypto_aead_setkey(ctx->child, key, keylen);
     25}
     26
     27static int aead_geniv_setauthsize(struct crypto_aead *tfm,
     28				  unsigned int authsize)
     29{
     30	struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
     31
     32	return crypto_aead_setauthsize(ctx->child, authsize);
     33}
     34
     35static void aead_geniv_free(struct aead_instance *inst)
     36{
     37	crypto_drop_aead(aead_instance_ctx(inst));
     38	kfree(inst);
     39}
     40
     41struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
     42				       struct rtattr **tb)
     43{
     44	struct crypto_aead_spawn *spawn;
     45	struct aead_instance *inst;
     46	struct aead_alg *alg;
     47	unsigned int ivsize;
     48	unsigned int maxauthsize;
     49	u32 mask;
     50	int err;
     51
     52	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
     53	if (err)
     54		return ERR_PTR(err);
     55
     56	inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
     57	if (!inst)
     58		return ERR_PTR(-ENOMEM);
     59
     60	spawn = aead_instance_ctx(inst);
     61
     62	err = crypto_grab_aead(spawn, aead_crypto_instance(inst),
     63			       crypto_attr_alg_name(tb[1]), 0, mask);
     64	if (err)
     65		goto err_free_inst;
     66
     67	alg = crypto_spawn_aead_alg(spawn);
     68
     69	ivsize = crypto_aead_alg_ivsize(alg);
     70	maxauthsize = crypto_aead_alg_maxauthsize(alg);
     71
     72	err = -EINVAL;
     73	if (ivsize < sizeof(u64))
     74		goto err_free_inst;
     75
     76	err = -ENAMETOOLONG;
     77	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
     78		     "%s(%s)", tmpl->name, alg->base.cra_name) >=
     79	    CRYPTO_MAX_ALG_NAME)
     80		goto err_free_inst;
     81	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
     82		     "%s(%s)", tmpl->name, alg->base.cra_driver_name) >=
     83	    CRYPTO_MAX_ALG_NAME)
     84		goto err_free_inst;
     85
     86	inst->alg.base.cra_priority = alg->base.cra_priority;
     87	inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
     88	inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
     89	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
     90
     91	inst->alg.setkey = aead_geniv_setkey;
     92	inst->alg.setauthsize = aead_geniv_setauthsize;
     93
     94	inst->alg.ivsize = ivsize;
     95	inst->alg.maxauthsize = maxauthsize;
     96
     97	inst->free = aead_geniv_free;
     98
     99out:
    100	return inst;
    101
    102err_free_inst:
    103	aead_geniv_free(inst);
    104	inst = ERR_PTR(err);
    105	goto out;
    106}
    107EXPORT_SYMBOL_GPL(aead_geniv_alloc);
    108
    109int aead_init_geniv(struct crypto_aead *aead)
    110{
    111	struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead);
    112	struct aead_instance *inst = aead_alg_instance(aead);
    113	struct crypto_aead *child;
    114	int err;
    115
    116	spin_lock_init(&ctx->lock);
    117
    118	err = crypto_get_default_rng();
    119	if (err)
    120		goto out;
    121
    122	err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
    123				   crypto_aead_ivsize(aead));
    124	crypto_put_default_rng();
    125	if (err)
    126		goto out;
    127
    128	ctx->sknull = crypto_get_default_null_skcipher();
    129	err = PTR_ERR(ctx->sknull);
    130	if (IS_ERR(ctx->sknull))
    131		goto out;
    132
    133	child = crypto_spawn_aead(aead_instance_ctx(inst));
    134	err = PTR_ERR(child);
    135	if (IS_ERR(child))
    136		goto drop_null;
    137
    138	ctx->child = child;
    139	crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) +
    140				      sizeof(struct aead_request));
    141
    142	err = 0;
    143
    144out:
    145	return err;
    146
    147drop_null:
    148	crypto_put_default_null_skcipher();
    149	goto out;
    150}
    151EXPORT_SYMBOL_GPL(aead_init_geniv);
    152
    153void aead_exit_geniv(struct crypto_aead *tfm)
    154{
    155	struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
    156
    157	crypto_free_aead(ctx->child);
    158	crypto_put_default_null_skcipher();
    159}
    160EXPORT_SYMBOL_GPL(aead_exit_geniv);
    161
    162MODULE_LICENSE("GPL");
    163MODULE_DESCRIPTION("Shared IV generator code");