Branch data Line data Source code
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 : : 19 : 0 : static int aead_geniv_setkey(struct crypto_aead *tfm, 20 : : const u8 *key, unsigned int keylen) 21 : : { 22 : 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 23 : : 24 : 0 : return crypto_aead_setkey(ctx->child, key, keylen); 25 : : } 26 : : 27 : 0 : static int aead_geniv_setauthsize(struct crypto_aead *tfm, 28 : : unsigned int authsize) 29 : : { 30 : 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 31 : : 32 : 0 : return crypto_aead_setauthsize(ctx->child, authsize); 33 : : } 34 : : 35 : 0 : static void aead_geniv_free(struct aead_instance *inst) 36 : : { 37 : 0 : crypto_drop_aead(aead_instance_ctx(inst)); 38 : 0 : kfree(inst); 39 : 0 : } 40 : : 41 : 0 : struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl, 42 : : struct rtattr **tb, u32 type, u32 mask) 43 : : { 44 : 0 : const char *name; 45 : 0 : struct crypto_aead_spawn *spawn; 46 : 0 : struct crypto_attr_type *algt; 47 : 0 : struct aead_instance *inst; 48 : 0 : struct aead_alg *alg; 49 : 0 : unsigned int ivsize; 50 : 0 : unsigned int maxauthsize; 51 : 0 : int err; 52 : : 53 : 0 : algt = crypto_get_attr_type(tb); 54 [ # # ]: 0 : if (IS_ERR(algt)) 55 : : return ERR_CAST(algt); 56 : : 57 [ # # ]: 0 : if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) 58 : : return ERR_PTR(-EINVAL); 59 : : 60 : 0 : name = crypto_attr_alg_name(tb[1]); 61 [ # # ]: 0 : if (IS_ERR(name)) 62 : : return ERR_CAST(name); 63 : : 64 : 0 : inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 65 [ # # ]: 0 : if (!inst) 66 : : return ERR_PTR(-ENOMEM); 67 : : 68 : 0 : spawn = aead_instance_ctx(inst); 69 : : 70 : : /* Ignore async algorithms if necessary. */ 71 : 0 : mask |= crypto_requires_sync(algt->type, algt->mask); 72 : : 73 : 0 : err = crypto_grab_aead(spawn, aead_crypto_instance(inst), 74 : : name, type, mask); 75 [ # # ]: 0 : if (err) 76 : 0 : goto err_free_inst; 77 : : 78 [ # # ]: 0 : alg = crypto_spawn_aead_alg(spawn); 79 : : 80 [ # # ]: 0 : ivsize = crypto_aead_alg_ivsize(alg); 81 [ # # ]: 0 : maxauthsize = crypto_aead_alg_maxauthsize(alg); 82 : : 83 : 0 : err = -EINVAL; 84 [ # # ]: 0 : if (ivsize < sizeof(u64)) 85 : 0 : goto err_drop_alg; 86 : : 87 : 0 : err = -ENAMETOOLONG; 88 : 0 : if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 89 [ # # ]: 0 : "%s(%s)", tmpl->name, alg->base.cra_name) >= 90 : : CRYPTO_MAX_ALG_NAME) 91 : 0 : goto err_drop_alg; 92 : 0 : if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 93 [ # # ]: 0 : "%s(%s)", tmpl->name, alg->base.cra_driver_name) >= 94 : : CRYPTO_MAX_ALG_NAME) 95 : 0 : goto err_drop_alg; 96 : : 97 : 0 : inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; 98 : 0 : inst->alg.base.cra_priority = alg->base.cra_priority; 99 : 0 : inst->alg.base.cra_blocksize = alg->base.cra_blocksize; 100 : 0 : inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 101 : 0 : inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); 102 : : 103 : 0 : inst->alg.setkey = aead_geniv_setkey; 104 : 0 : inst->alg.setauthsize = aead_geniv_setauthsize; 105 : : 106 : 0 : inst->alg.ivsize = ivsize; 107 : 0 : inst->alg.maxauthsize = maxauthsize; 108 : : 109 : 0 : inst->free = aead_geniv_free; 110 : : 111 : : out: 112 : : return inst; 113 : : 114 : 0 : err_drop_alg: 115 : 0 : crypto_drop_aead(spawn); 116 : 0 : err_free_inst: 117 : 0 : kfree(inst); 118 : 0 : inst = ERR_PTR(err); 119 : 0 : goto out; 120 : : } 121 : : EXPORT_SYMBOL_GPL(aead_geniv_alloc); 122 : : 123 : 0 : int aead_init_geniv(struct crypto_aead *aead) 124 : : { 125 : 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead); 126 : 0 : struct aead_instance *inst = aead_alg_instance(aead); 127 : 0 : struct crypto_aead *child; 128 : 0 : int err; 129 : : 130 : 0 : spin_lock_init(&ctx->lock); 131 : : 132 : 0 : err = crypto_get_default_rng(); 133 [ # # ]: 0 : if (err) 134 : 0 : goto out; 135 : : 136 : 0 : err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 137 : : crypto_aead_ivsize(aead)); 138 : 0 : crypto_put_default_rng(); 139 [ # # ]: 0 : if (err) 140 : 0 : goto out; 141 : : 142 : 0 : ctx->sknull = crypto_get_default_null_skcipher(); 143 [ # # ]: 0 : err = PTR_ERR(ctx->sknull); 144 [ # # ]: 0 : if (IS_ERR(ctx->sknull)) 145 : 0 : goto out; 146 : : 147 : 0 : child = crypto_spawn_aead(aead_instance_ctx(inst)); 148 [ # # ]: 0 : err = PTR_ERR(child); 149 [ # # ]: 0 : if (IS_ERR(child)) 150 : 0 : goto drop_null; 151 : : 152 : 0 : ctx->child = child; 153 : 0 : crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) + 154 : : sizeof(struct aead_request)); 155 : : 156 : 0 : err = 0; 157 : : 158 : 0 : out: 159 : 0 : return err; 160 : : 161 : : drop_null: 162 : 0 : crypto_put_default_null_skcipher(); 163 : 0 : goto out; 164 : : } 165 : : EXPORT_SYMBOL_GPL(aead_init_geniv); 166 : : 167 : 0 : void aead_exit_geniv(struct crypto_aead *tfm) 168 : : { 169 : 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 170 : : 171 : 0 : crypto_free_aead(ctx->child); 172 : 0 : crypto_put_default_null_skcipher(); 173 : 0 : } 174 : : EXPORT_SYMBOL_GPL(aead_exit_geniv); 175 : : 176 : : MODULE_LICENSE("GPL"); 177 : : MODULE_DESCRIPTION("Shared IV generator code");