Commit 7ba683a6deba70251756aa5a021cdaa5c875a7a2
1 parent
e29bc6ad0e
Exists in
master
and in
20 other branches
[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>
Showing 4 changed files with 38 additions and 32 deletions Side-by-side Diff
crypto/aead.c
... | ... | @@ -53,6 +53,24 @@ |
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 | { |
59 | 77 | |
... | ... | @@ -64,14 +82,14 @@ |
64 | 82 | struct aead_alg *alg = &tfm->__crt_alg->cra_aead; |
65 | 83 | struct aead_tfm *crt = &tfm->crt_aead; |
66 | 84 | |
67 | - if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8) | |
85 | + if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) | |
68 | 86 | return -EINVAL; |
69 | 87 | |
70 | 88 | crt->setkey = setkey; |
71 | 89 | crt->encrypt = alg->encrypt; |
72 | 90 | crt->decrypt = alg->decrypt; |
73 | 91 | crt->ivsize = alg->ivsize; |
74 | - crt->authsize = alg->authsize; | |
92 | + crt->authsize = alg->maxauthsize; | |
75 | 93 | |
76 | 94 | return 0; |
77 | 95 | } |
... | ... | @@ -85,7 +103,7 @@ |
85 | 103 | seq_printf(m, "type : aead\n"); |
86 | 104 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); |
87 | 105 | seq_printf(m, "ivsize : %u\n", aead->ivsize); |
88 | - seq_printf(m, "authsize : %u\n", aead->authsize); | |
106 | + seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); | |
89 | 107 | } |
90 | 108 | |
91 | 109 | const struct crypto_type crypto_aead_type = { |
crypto/authenc.c
... | ... | @@ -24,7 +24,6 @@ |
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 | |
... | ... | @@ -76,8 +75,6 @@ |
76 | 75 | static int crypto_authenc_hash(struct aead_request *req) |
77 | 76 | { |
78 | 77 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
79 | - struct authenc_instance_ctx *ictx = | |
80 | - crypto_instance_ctx(crypto_aead_alg_instance(authenc)); | |
81 | 78 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
82 | 79 | struct crypto_hash *auth = ctx->auth; |
83 | 80 | struct hash_desc desc = { |
... | ... | @@ -111,7 +108,8 @@ |
111 | 108 | if (err) |
112 | 109 | return err; |
113 | 110 | |
114 | - scatterwalk_map_and_copy(hash, dst, cryptlen, ictx->authsize, 1); | |
111 | + scatterwalk_map_and_copy(hash, dst, cryptlen, | |
112 | + crypto_aead_authsize(authenc), 1); | |
115 | 113 | return 0; |
116 | 114 | } |
117 | 115 | |
... | ... | @@ -147,8 +145,6 @@ |
147 | 145 | static int crypto_authenc_verify(struct aead_request *req) |
148 | 146 | { |
149 | 147 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); |
150 | - struct authenc_instance_ctx *ictx = | |
151 | - crypto_instance_ctx(crypto_aead_alg_instance(authenc)); | |
152 | 148 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
153 | 149 | struct crypto_hash *auth = ctx->auth; |
154 | 150 | struct hash_desc desc = { |
... | ... | @@ -186,7 +182,7 @@ |
186 | 182 | if (err) |
187 | 183 | return err; |
188 | 184 | |
189 | - authsize = ictx->authsize; | |
185 | + authsize = crypto_aead_authsize(authenc); | |
190 | 186 | scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0); |
191 | 187 | return memcmp(ihash, ohash, authsize) ? -EINVAL : 0; |
192 | 188 | } |
193 | 189 | |
... | ... | @@ -224,18 +220,12 @@ |
224 | 220 | struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); |
225 | 221 | struct crypto_hash *auth; |
226 | 222 | struct crypto_ablkcipher *enc; |
227 | - unsigned int digestsize; | |
228 | 223 | int err; |
229 | 224 | |
230 | 225 | auth = crypto_spawn_hash(&ictx->auth); |
231 | 226 | if (IS_ERR(auth)) |
232 | 227 | return PTR_ERR(auth); |
233 | 228 | |
234 | - err = -EINVAL; | |
235 | - digestsize = crypto_hash_digestsize(auth); | |
236 | - if (ictx->authsize > digestsize) | |
237 | - goto err_free_hash; | |
238 | - | |
239 | 229 | enc = crypto_spawn_ablkcipher(&ictx->enc); |
240 | 230 | err = PTR_ERR(enc); |
241 | 231 | if (IS_ERR(enc)) |
... | ... | @@ -246,7 +236,7 @@ |
246 | 236 | tfm->crt_aead.reqsize = max_t(unsigned int, |
247 | 237 | (crypto_hash_alignmask(auth) & |
248 | 238 | ~(crypto_tfm_ctx_alignment() - 1)) + |
249 | - digestsize * 2, | |
239 | + crypto_hash_digestsize(auth) * 2, | |
250 | 240 | sizeof(struct ablkcipher_request) + |
251 | 241 | crypto_ablkcipher_reqsize(enc)); |
252 | 242 | |
... | ... | @@ -273,7 +263,6 @@ |
273 | 263 | struct crypto_alg *auth; |
274 | 264 | struct crypto_alg *enc; |
275 | 265 | struct authenc_instance_ctx *ctx; |
276 | - unsigned int authsize; | |
277 | 266 | unsigned int enckeylen; |
278 | 267 | int err; |
279 | 268 | |
280 | 269 | |
... | ... | @@ -286,18 +275,13 @@ |
286 | 275 | if (IS_ERR(auth)) |
287 | 276 | return ERR_PTR(PTR_ERR(auth)); |
288 | 277 | |
289 | - err = crypto_attr_u32(tb[2], &authsize); | |
290 | - inst = ERR_PTR(err); | |
291 | - if (err) | |
292 | - goto out_put_auth; | |
293 | - | |
294 | - enc = crypto_attr_alg(tb[3], CRYPTO_ALG_TYPE_BLKCIPHER, | |
278 | + enc = crypto_attr_alg(tb[2], CRYPTO_ALG_TYPE_BLKCIPHER, | |
295 | 279 | CRYPTO_ALG_TYPE_BLKCIPHER_MASK); |
296 | 280 | inst = ERR_PTR(PTR_ERR(enc)); |
297 | 281 | if (IS_ERR(enc)) |
298 | 282 | goto out_put_auth; |
299 | 283 | |
300 | - err = crypto_attr_u32(tb[4], &enckeylen); | |
284 | + err = crypto_attr_u32(tb[3], &enckeylen); | |
301 | 285 | if (err) |
302 | 286 | goto out_put_enc; |
303 | 287 | |
304 | 288 | |
305 | 289 | |
... | ... | @@ -308,18 +292,17 @@ |
308 | 292 | |
309 | 293 | err = -ENAMETOOLONG; |
310 | 294 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, |
311 | - "authenc(%s,%u,%s,%u)", auth->cra_name, authsize, | |
295 | + "authenc(%s,%s,%u)", auth->cra_name, | |
312 | 296 | enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME) |
313 | 297 | goto err_free_inst; |
314 | 298 | |
315 | 299 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
316 | - "authenc(%s,%u,%s,%u)", auth->cra_driver_name, | |
317 | - authsize, enc->cra_driver_name, enckeylen) >= | |
300 | + "authenc(%s,%s,%u)", auth->cra_driver_name, | |
301 | + enc->cra_driver_name, enckeylen) >= | |
318 | 302 | CRYPTO_MAX_ALG_NAME) |
319 | 303 | goto err_free_inst; |
320 | 304 | |
321 | 305 | ctx = crypto_instance_ctx(inst); |
322 | - ctx->authsize = authsize; | |
323 | 306 | ctx->enckeylen = enckeylen; |
324 | 307 | |
325 | 308 | err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); |
... | ... | @@ -337,7 +320,9 @@ |
337 | 320 | inst->alg.cra_type = &crypto_aead_type; |
338 | 321 | |
339 | 322 | inst->alg.cra_aead.ivsize = enc->cra_blkcipher.ivsize; |
340 | - inst->alg.cra_aead.authsize = authsize; | |
323 | + inst->alg.cra_aead.maxauthsize = auth->cra_type == &crypto_hash_type ? | |
324 | + auth->cra_hash.digestsize : | |
325 | + auth->cra_digest.dia_digestsize; | |
341 | 326 | |
342 | 327 | inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); |
343 | 328 |
crypto/gcm.c
... | ... | @@ -414,7 +414,7 @@ |
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; |
include/linux/crypto.h
... | ... | @@ -187,11 +187,12 @@ |
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 { |
... | ... | @@ -753,6 +754,8 @@ |
753 | 754 | { |
754 | 755 | return crypto_aead_crt(tfm)->setkey(tfm, key, keylen); |
755 | 756 | } |
757 | + | |
758 | +int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); | |
756 | 759 | |
757 | 760 | static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) |
758 | 761 | { |