diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-12-02 02:49:21 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-10 16:16:29 -0500 |
commit | 7ba683a6deba70251756aa5a021cdaa5c875a7a2 (patch) | |
tree | 80f63039b56bef0287fdf878163a5fe109821e58 | |
parent | e29bc6ad0e84e3157e0f49130a15b278cb232c72 (diff) |
[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>
-rw-r--r-- | crypto/aead.c | 24 | ||||
-rw-r--r-- | crypto/authenc.c | 39 | ||||
-rw-r--r-- | crypto/gcm.c | 2 | ||||
-rw-r--r-- | include/linux/crypto.h | 5 |
4 files changed, 38 insertions, 32 deletions
diff --git a/crypto/aead.c b/crypto/aead.c index 84a3501fb478..f23c2b0ee009 100644 --- a/crypto/aead.c +++ b/crypto/aead.c | |||
@@ -53,6 +53,24 @@ static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) | |||
53 | return aead->setkey(tfm, key, keylen); | 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 | static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, | 74 | static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, |
57 | u32 mask) | 75 | u32 mask) |
58 | { | 76 | { |
@@ -64,14 +82,14 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
64 | struct aead_alg *alg = &tfm->__crt_alg->cra_aead; | 82 | struct aead_alg *alg = &tfm->__crt_alg->cra_aead; |
65 | struct aead_tfm *crt = &tfm->crt_aead; | 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 | return -EINVAL; | 86 | return -EINVAL; |
69 | 87 | ||
70 | crt->setkey = setkey; | 88 | crt->setkey = setkey; |
71 | crt->encrypt = alg->encrypt; | 89 | crt->encrypt = alg->encrypt; |
72 | crt->decrypt = alg->decrypt; | 90 | crt->decrypt = alg->decrypt; |
73 | crt->ivsize = alg->ivsize; | 91 | crt->ivsize = alg->ivsize; |
74 | crt->authsize = alg->authsize; | 92 | crt->authsize = alg->maxauthsize; |
75 | 93 | ||
76 | return 0; | 94 | return 0; |
77 | } | 95 | } |
@@ -85,7 +103,7 @@ static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) | |||
85 | seq_printf(m, "type : aead\n"); | 103 | seq_printf(m, "type : aead\n"); |
86 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); | 104 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); |
87 | seq_printf(m, "ivsize : %u\n", aead->ivsize); | 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 | const struct crypto_type crypto_aead_type = { | 109 | const struct crypto_type crypto_aead_type = { |
diff --git a/crypto/authenc.c b/crypto/authenc.c index 66fb2aa5c325..5df5fb169cbe 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c | |||
@@ -24,7 +24,6 @@ struct authenc_instance_ctx { | |||
24 | struct crypto_spawn auth; | 24 | struct crypto_spawn auth; |
25 | struct crypto_spawn enc; | 25 | struct crypto_spawn enc; |
26 | 26 | ||
27 | unsigned int authsize; | ||
28 | unsigned int enckeylen; | 27 | unsigned int enckeylen; |
29 | }; | 28 | }; |
30 | 29 | ||
@@ -76,8 +75,6 @@ out: | |||
76 | static int crypto_authenc_hash(struct aead_request *req) | 75 | static int crypto_authenc_hash(struct aead_request *req) |
77 | { | 76 | { |
78 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 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 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | 78 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
82 | struct crypto_hash *auth = ctx->auth; | 79 | struct crypto_hash *auth = ctx->auth; |
83 | struct hash_desc desc = { | 80 | struct hash_desc desc = { |
@@ -111,7 +108,8 @@ auth_unlock: | |||
111 | if (err) | 108 | if (err) |
112 | return err; | 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 | return 0; | 113 | return 0; |
116 | } | 114 | } |
117 | 115 | ||
@@ -147,8 +145,6 @@ static int crypto_authenc_encrypt(struct aead_request *req) | |||
147 | static int crypto_authenc_verify(struct aead_request *req) | 145 | static int crypto_authenc_verify(struct aead_request *req) |
148 | { | 146 | { |
149 | struct crypto_aead *authenc = crypto_aead_reqtfm(req); | 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 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | 148 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); |
153 | struct crypto_hash *auth = ctx->auth; | 149 | struct crypto_hash *auth = ctx->auth; |
154 | struct hash_desc desc = { | 150 | struct hash_desc desc = { |
@@ -186,7 +182,7 @@ auth_unlock: | |||
186 | if (err) | 182 | if (err) |
187 | return err; | 183 | return err; |
188 | 184 | ||
189 | authsize = ictx->authsize; | 185 | authsize = crypto_aead_authsize(authenc); |
190 | scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0); | 186 | scatterwalk_map_and_copy(ihash, src, cryptlen, authsize, 0); |
191 | return memcmp(ihash, ohash, authsize) ? -EINVAL : 0; | 187 | return memcmp(ihash, ohash, authsize) ? -EINVAL : 0; |
192 | } | 188 | } |
@@ -224,18 +220,12 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
224 | struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); | 220 | struct crypto_authenc_ctx *ctx = crypto_tfm_ctx(tfm); |
225 | struct crypto_hash *auth; | 221 | struct crypto_hash *auth; |
226 | struct crypto_ablkcipher *enc; | 222 | struct crypto_ablkcipher *enc; |
227 | unsigned int digestsize; | ||
228 | int err; | 223 | int err; |
229 | 224 | ||
230 | auth = crypto_spawn_hash(&ictx->auth); | 225 | auth = crypto_spawn_hash(&ictx->auth); |
231 | if (IS_ERR(auth)) | 226 | if (IS_ERR(auth)) |
232 | return PTR_ERR(auth); | 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 | enc = crypto_spawn_ablkcipher(&ictx->enc); | 229 | enc = crypto_spawn_ablkcipher(&ictx->enc); |
240 | err = PTR_ERR(enc); | 230 | err = PTR_ERR(enc); |
241 | if (IS_ERR(enc)) | 231 | if (IS_ERR(enc)) |
@@ -246,7 +236,7 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm) | |||
246 | tfm->crt_aead.reqsize = max_t(unsigned int, | 236 | tfm->crt_aead.reqsize = max_t(unsigned int, |
247 | (crypto_hash_alignmask(auth) & | 237 | (crypto_hash_alignmask(auth) & |
248 | ~(crypto_tfm_ctx_alignment() - 1)) + | 238 | ~(crypto_tfm_ctx_alignment() - 1)) + |
249 | digestsize * 2, | 239 | crypto_hash_digestsize(auth) * 2, |
250 | sizeof(struct ablkcipher_request) + | 240 | sizeof(struct ablkcipher_request) + |
251 | crypto_ablkcipher_reqsize(enc)); | 241 | crypto_ablkcipher_reqsize(enc)); |
252 | 242 | ||
@@ -273,7 +263,6 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
273 | struct crypto_alg *auth; | 263 | struct crypto_alg *auth; |
274 | struct crypto_alg *enc; | 264 | struct crypto_alg *enc; |
275 | struct authenc_instance_ctx *ctx; | 265 | struct authenc_instance_ctx *ctx; |
276 | unsigned int authsize; | ||
277 | unsigned int enckeylen; | 266 | unsigned int enckeylen; |
278 | int err; | 267 | int err; |
279 | 268 | ||
@@ -286,18 +275,13 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
286 | if (IS_ERR(auth)) | 275 | if (IS_ERR(auth)) |
287 | return ERR_PTR(PTR_ERR(auth)); | 276 | return ERR_PTR(PTR_ERR(auth)); |
288 | 277 | ||
289 | err = crypto_attr_u32(tb[2], &authsize); | 278 | enc = crypto_attr_alg(tb[2], CRYPTO_ALG_TYPE_BLKCIPHER, |
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, | ||
295 | CRYPTO_ALG_TYPE_BLKCIPHER_MASK); | 279 | CRYPTO_ALG_TYPE_BLKCIPHER_MASK); |
296 | inst = ERR_PTR(PTR_ERR(enc)); | 280 | inst = ERR_PTR(PTR_ERR(enc)); |
297 | if (IS_ERR(enc)) | 281 | if (IS_ERR(enc)) |
298 | goto out_put_auth; | 282 | goto out_put_auth; |
299 | 283 | ||
300 | err = crypto_attr_u32(tb[4], &enckeylen); | 284 | err = crypto_attr_u32(tb[3], &enckeylen); |
301 | if (err) | 285 | if (err) |
302 | goto out_put_enc; | 286 | goto out_put_enc; |
303 | 287 | ||
@@ -308,18 +292,17 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
308 | 292 | ||
309 | err = -ENAMETOOLONG; | 293 | err = -ENAMETOOLONG; |
310 | if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, | 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 | enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME) | 296 | enc->cra_name, enckeylen) >= CRYPTO_MAX_ALG_NAME) |
313 | goto err_free_inst; | 297 | goto err_free_inst; |
314 | 298 | ||
315 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, | 299 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
316 | "authenc(%s,%u,%s,%u)", auth->cra_driver_name, | 300 | "authenc(%s,%s,%u)", auth->cra_driver_name, |
317 | authsize, enc->cra_driver_name, enckeylen) >= | 301 | enc->cra_driver_name, enckeylen) >= |
318 | CRYPTO_MAX_ALG_NAME) | 302 | CRYPTO_MAX_ALG_NAME) |
319 | goto err_free_inst; | 303 | goto err_free_inst; |
320 | 304 | ||
321 | ctx = crypto_instance_ctx(inst); | 305 | ctx = crypto_instance_ctx(inst); |
322 | ctx->authsize = authsize; | ||
323 | ctx->enckeylen = enckeylen; | 306 | ctx->enckeylen = enckeylen; |
324 | 307 | ||
325 | err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); | 308 | err = crypto_init_spawn(&ctx->auth, auth, inst, CRYPTO_ALG_TYPE_MASK); |
@@ -337,7 +320,9 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) | |||
337 | inst->alg.cra_type = &crypto_aead_type; | 320 | inst->alg.cra_type = &crypto_aead_type; |
338 | 321 | ||
339 | inst->alg.cra_aead.ivsize = enc->cra_blkcipher.ivsize; | 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 | inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); | 327 | inst->alg.cra_ctxsize = sizeof(struct crypto_authenc_ctx); |
343 | 328 | ||
diff --git a/crypto/gcm.c b/crypto/gcm.c index ad8b8b9aeef2..5681c7957b88 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c | |||
@@ -414,7 +414,7 @@ static struct crypto_instance *crypto_gcm_alloc(struct rtattr **tb) | |||
414 | inst->alg.cra_alignmask = __alignof__(u32) - 1; | 414 | inst->alg.cra_alignmask = __alignof__(u32) - 1; |
415 | inst->alg.cra_type = &crypto_aead_type; | 415 | inst->alg.cra_type = &crypto_aead_type; |
416 | inst->alg.cra_aead.ivsize = 12; | 416 | inst->alg.cra_aead.ivsize = 12; |
417 | inst->alg.cra_aead.authsize = 16; | 417 | inst->alg.cra_aead.maxauthsize = 16; |
418 | inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx); | 418 | inst->alg.cra_ctxsize = sizeof(struct crypto_gcm_ctx); |
419 | inst->alg.cra_init = crypto_gcm_init_tfm; | 419 | inst->alg.cra_init = crypto_gcm_init_tfm; |
420 | inst->alg.cra_exit = crypto_gcm_exit_tfm; | 420 | inst->alg.cra_exit = crypto_gcm_exit_tfm; |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index f56ae8721bc9..48aa5959abbb 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -187,11 +187,12 @@ struct ablkcipher_alg { | |||
187 | struct aead_alg { | 187 | struct aead_alg { |
188 | int (*setkey)(struct crypto_aead *tfm, const u8 *key, | 188 | int (*setkey)(struct crypto_aead *tfm, const u8 *key, |
189 | unsigned int keylen); | 189 | unsigned int keylen); |
190 | int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize); | ||
190 | int (*encrypt)(struct aead_request *req); | 191 | int (*encrypt)(struct aead_request *req); |
191 | int (*decrypt)(struct aead_request *req); | 192 | int (*decrypt)(struct aead_request *req); |
192 | 193 | ||
193 | unsigned int ivsize; | 194 | unsigned int ivsize; |
194 | unsigned int authsize; | 195 | unsigned int maxauthsize; |
195 | }; | 196 | }; |
196 | 197 | ||
197 | struct blkcipher_alg { | 198 | struct blkcipher_alg { |
@@ -754,6 +755,8 @@ static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, | |||
754 | return crypto_aead_crt(tfm)->setkey(tfm, key, keylen); | 755 | return crypto_aead_crt(tfm)->setkey(tfm, key, keylen); |
755 | } | 756 | } |
756 | 757 | ||
758 | int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize); | ||
759 | |||
757 | static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) | 760 | static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) |
758 | { | 761 | { |
759 | return __crypto_aead_cast(req->base.tfm); | 762 | return __crypto_aead_cast(req->base.tfm); |