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) 43 : { 44 0 : struct crypto_aead_spawn *spawn; 45 0 : struct aead_instance *inst; 46 0 : struct aead_alg *alg; 47 0 : unsigned int ivsize; 48 0 : unsigned int maxauthsize; 49 0 : u32 mask; 50 0 : int err; 51 : 52 0 : err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask); 53 0 : if (err) 54 0 : return ERR_PTR(err); 55 : 56 0 : inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 57 0 : if (!inst) 58 0 : return ERR_PTR(-ENOMEM); 59 : 60 0 : spawn = aead_instance_ctx(inst); 61 : 62 0 : err = crypto_grab_aead(spawn, aead_crypto_instance(inst), 63 : crypto_attr_alg_name(tb[1]), 0, mask); 64 0 : if (err) 65 0 : goto err_free_inst; 66 : 67 0 : alg = crypto_spawn_aead_alg(spawn); 68 : 69 0 : ivsize = crypto_aead_alg_ivsize(alg); 70 0 : maxauthsize = crypto_aead_alg_maxauthsize(alg); 71 : 72 0 : err = -EINVAL; 73 0 : if (ivsize < sizeof(u64)) 74 0 : goto err_free_inst; 75 : 76 0 : err = -ENAMETOOLONG; 77 0 : if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 78 0 : "%s(%s)", tmpl->name, alg->base.cra_name) >= 79 : CRYPTO_MAX_ALG_NAME) 80 0 : goto err_free_inst; 81 0 : if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 82 0 : "%s(%s)", tmpl->name, alg->base.cra_driver_name) >= 83 : CRYPTO_MAX_ALG_NAME) 84 0 : goto err_free_inst; 85 : 86 0 : inst->alg.base.cra_priority = alg->base.cra_priority; 87 0 : inst->alg.base.cra_blocksize = alg->base.cra_blocksize; 88 0 : inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 89 0 : inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); 90 : 91 0 : inst->alg.setkey = aead_geniv_setkey; 92 0 : inst->alg.setauthsize = aead_geniv_setauthsize; 93 : 94 0 : inst->alg.ivsize = ivsize; 95 0 : inst->alg.maxauthsize = maxauthsize; 96 : 97 0 : inst->free = aead_geniv_free; 98 : 99 : out: 100 : return inst; 101 : 102 0 : err_free_inst: 103 0 : aead_geniv_free(inst); 104 0 : inst = ERR_PTR(err); 105 0 : goto out; 106 : } 107 : EXPORT_SYMBOL_GPL(aead_geniv_alloc); 108 : 109 0 : int aead_init_geniv(struct crypto_aead *aead) 110 : { 111 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead); 112 0 : struct aead_instance *inst = aead_alg_instance(aead); 113 0 : struct crypto_aead *child; 114 0 : int err; 115 : 116 0 : spin_lock_init(&ctx->lock); 117 : 118 0 : err = crypto_get_default_rng(); 119 0 : if (err) 120 0 : goto out; 121 : 122 0 : err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 123 : crypto_aead_ivsize(aead)); 124 0 : crypto_put_default_rng(); 125 0 : if (err) 126 0 : goto out; 127 : 128 0 : ctx->sknull = crypto_get_default_null_skcipher(); 129 0 : err = PTR_ERR(ctx->sknull); 130 0 : if (IS_ERR(ctx->sknull)) 131 0 : goto out; 132 : 133 0 : child = crypto_spawn_aead(aead_instance_ctx(inst)); 134 0 : err = PTR_ERR(child); 135 0 : if (IS_ERR(child)) 136 0 : goto drop_null; 137 : 138 0 : ctx->child = child; 139 0 : crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) + 140 : sizeof(struct aead_request)); 141 : 142 0 : err = 0; 143 : 144 0 : out: 145 0 : return err; 146 : 147 0 : drop_null: 148 0 : crypto_put_default_null_skcipher(); 149 0 : goto out; 150 : } 151 : EXPORT_SYMBOL_GPL(aead_init_geniv); 152 : 153 0 : void aead_exit_geniv(struct crypto_aead *tfm) 154 : { 155 0 : struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 156 : 157 0 : crypto_free_aead(ctx->child); 158 0 : crypto_put_default_null_skcipher(); 159 0 : } 160 : EXPORT_SYMBOL_GPL(aead_exit_geniv); 161 : 162 : MODULE_LICENSE("GPL"); 163 : MODULE_DESCRIPTION("Shared IV generator code");