Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[CRYPTO] aead: Make authsize a run-time parameter

As it is authsize is an algorithm paramter which cannot be changed at
run-time. This is inconvenient because hardware that implements such
algorithms would have to register each authsize that they support
separately.

Since authsize is a property common to all AEAD algorithms, we can add
a function setauthsize that sets it at run-time, just like setkey.

This patch does exactly that and also changes authenc so that authsize
is no longer a parameter of its template.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+38 -32
+21 -3
crypto/aead.c
··· 53 53 return aead->setkey(tfm, key, keylen); 54 54 } 55 55 56 + int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) 57 + { 58 + int err; 59 + 60 + if (authsize > crypto_aead_alg(tfm)->maxauthsize) 61 + return -EINVAL; 62 + 63 + if (crypto_aead_alg(tfm)->setauthsize) { 64 + err = crypto_aead_alg(tfm)->setauthsize(tfm, authsize); 65 + if (err) 66 + return err; 67 + } 68 + 69 + crypto_aead_crt(tfm)->authsize = authsize; 70 + return 0; 71 + } 72 + EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); 73 + 56 74 static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, 57 75 u32 mask) 58 76 { ··· 82 64 struct aead_alg *alg = &tfm->__crt_alg->cra_aead; 83 65 struct aead_tfm *crt = &tfm->crt_aead; 84 66 85 - if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8) 67 + if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) 86 68 return -EINVAL; 87 69 88 70 crt->setkey = setkey; 89 71 crt->encrypt = alg->encrypt; 90 72 crt->decrypt = alg->decrypt; 91 73 crt->ivsize = alg->ivsize; 92 - crt->authsize = alg->authsize; 74 + crt->authsize = alg->maxauthsize; 93 75 94 76 return 0; 95 77 } ··· 103 85 seq_printf(m, "type : aead\n"); 104 86 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 105 87 seq_printf(m, "ivsize : %u\n", aead->ivsize); 106 - seq_printf(m, "authsize : %u\n", aead->authsize); 88 + seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); 107 89 } 108 90 109 91 const struct crypto_type crypto_aead_type = {
+12 -27
crypto/authenc.c
··· 24 24 struct crypto_spawn auth; 25 25 struct crypto_spawn enc; 26 26 27 - unsigned int authsize; 28 27 unsigned int enckeylen; 29 28 }; 30 29 ··· 75 76 static int crypto_authenc_hash(struct aead_request *req) 76 77 { 77 78 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 78 - struct authenc_instance_ctx *ictx = 79 - crypto_instance_ctx(crypto_aead_alg_instance(authenc)); 80 79 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 81 80 struct crypto_hash *auth = ctx->auth; 82 81 struct hash_desc desc = { ··· 108 111 if (err) 109 112 return err; 110 113 111 - scatterwalk_map_and_copy(hash, dst, cryptlen, ictx->authsize, 1); 114 + scatterwalk_map_and_copy(hash, dst, cryptlen, 115 + crypto_aead_authsize(authenc), 1); 112 116 return 0; 113 117 } 114 118 ··· 145 147 static int crypto_authenc_verify(struct aead_request *req) 146 148 { 147 149 struct crypto_aead *authenc = crypto_aead_reqtfm(req); 148 - struct authenc_instance_ctx *ictx = 149 - crypto_instance_ctx(crypto_aead_alg_instance(authenc)); 150 150 struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); 151 151 struct crypto_hash *auth = ctx->auth; 152 152 struct hash_desc desc = { ··· 182 186 if (err) 183 187 return err; 184 188 185 - authsize = ictx->authsize; 189 + authsize = crypto_aead_authsize(authenc); 186 190 scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0); 187 191 return memcmp(ihash, ohash, authsize) ? -EINVAL : 0; 188 192 } ··· 220 224 struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); 221 225 struct crypto_hash *auth; 222 226 struct crypto_ablkcipher *enc; 223 - unsigned int digestsize; 224 227 int err; 225 228 226 229 auth = crypto_spawn_hash(&ictx->auth); 227 230 if (IS_ERR(auth)) 228 231 return PTR_ERR(auth); 229 - 230 - err = -EINVAL; 231 - digestsize = crypto_hash_digestsize(auth); 232 - if (ictx->authsize > digestsize) 233 - goto err_free_hash; 234 232 235 233 enc = crypto_spawn_ablkcipher(&ictx->enc); 236 234 err = PTR_ERR(enc); ··· 236 246 tfm->crt_aead.reqsize = max_t(unsigned int, 237 247 (crypto_hash_alignmask(auth) & 238 248 ~(crypto_tfm_ctx_alignment() - 1)) + 239 - digestsize * 2, 249 + crypto_hash_digestsize(auth) * 2, 240 250 sizeof(struct ablkcipher_request) + 241 251 crypto_ablkcipher_reqsize(enc)); 242 252 ··· 263 273 struct crypto_alg *auth; 264 274 struct crypto_alg *enc; 265 275 struct authenc_instance_ctx *ctx; 266 - unsigned int authsize; 267 276 unsigned int enckeylen; 268 277 int err; 269 278 ··· 275 286 if (IS_ERR(auth)) 276 287 return ERR_PTR(PTR_ERR(auth)); 277 288 278 - err = crypto_attr_u32(tb[2], &authsize); 279 - inst = ERR_PTR(err); 280 - if (err) 281 - goto out_put_auth; 282 - 283 - enc = crypto_attr_alg(tb[3], CRYPTO_ALG_TYPE_BLKCIPHER, 289 + enc = crypto_attr_alg(tb[2], CRYPTO_ALG_TYPE_BLKCIPHER, 284 290 CRYPTO_ALG_TYPE_BLKCIPHER_MASK); 285 291 inst = ERR_PTR(PTR_ERR(enc)); 286 292 if (IS_ERR(enc)) 287 293 goto out_put_auth; 288 294 289 - err = crypto_attr_u32(tb[4], &enckeylen); 295 + err = crypto_attr_u32(tb[3], &enckeylen); 290 296 if (err) 291 297 goto out_put_enc; 292 298 ··· 292 308 293 309 err = -ENAMETOOLONG; 294 310 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, 295 - "authenc(%s,%u,%s,%u)", auth->cra_name, authsize, 311 + "authenc(%s,%s,%u)", auth->cra_name, 296 312 enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME) 297 313 goto err_free_inst; 298 314 299 315 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 300 - "authenc(%s,%u,%s,%u)", auth->cra_driver_name, 301 - authsize, enc->cra_driver_name, enckeylen) >= 316 + "authenc(%s,%s,%u)", auth->cra_driver_name, 317 + enc->cra_driver_name, enckeylen) >= 302 318 CRYPTO_MAX_ALG_NAME) 303 319 goto err_free_inst; 304 320 305 321 ctx = crypto_instance_ctx(inst); 306 - ctx->authsize = authsize; 307 322 ctx->enckeylen = enckeylen; 308 323 309 324 err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); ··· 320 337 inst->alg.cra_type = &crypto_aead_type; 321 338 322 339 inst->alg.cra_aead.ivsize = enc->cra_blkcipher.ivsize; 323 - inst->alg.cra_aead.authsize = authsize; 340 + inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? 341 + auth->cra_hash.digestsize : 342 + auth->cra_digest.dia_digestsize; 324 343 325 344 inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); 326 345
+1 -1
crypto/gcm.c
··· 414 414 inst->alg.cra_alignmask = __alignof__(u32) - 1; 415 415 inst->alg.cra_type = &crypto_aead_type; 416 416 inst->alg.cra_aead.ivsize = 12; 417 - inst->alg.cra_aead.authsize = 16; 417 + inst->alg.cra_aead.maxauthsize = 16; 418 418 inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx); 419 419 inst->alg.cra_init = crypto_gcm_init_tfm; 420 420 inst->alg.cra_exit = crypto_gcm_exit_tfm;
+4 -1
include/linux/crypto.h
··· 187 187 struct aead_alg { 188 188 int (*setkey)(struct crypto_aead *tfm, const u8 *key, 189 189 unsigned int keylen); 190 + int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); 190 191 int (*encrypt)(struct aead_request *req); 191 192 int (*decrypt)(struct aead_request *req); 192 193 193 194 unsigned int ivsize; 194 - unsigned int authsize; 195 + unsigned int maxauthsize; 195 196 }; 196 197 197 198 struct blkcipher_alg { ··· 754 753 { 755 754 return crypto_aead_crt(tfm)->setkey(tfm, key, keylen); 756 755 } 756 + 757 + int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); 757 758 758 759 static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) 759 760 {