summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/aead.c152
-rw-r--r--include/crypto/aead.h44
-rw-r--r--include/crypto/internal/aead.h36
3 files changed, 213 insertions, 19 deletions
diff --git a/crypto/aead.c b/crypto/aead.c
index ebc91ea89c91..d231e2837bfd 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -33,7 +33,6 @@ static int aead_null_givdecrypt(struct aead_givcrypt_request *req);
33static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key, 33static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
34 unsigned int keylen) 34 unsigned int keylen)
35{ 35{
36 struct old_aead_alg *aead = crypto_old_aead_alg(tfm);
37 unsigned long alignmask = crypto_aead_alignmask(tfm); 36 unsigned long alignmask = crypto_aead_alignmask(tfm);
38 int ret; 37 int ret;
39 u8 *buffer, *alignbuffer; 38 u8 *buffer, *alignbuffer;
@@ -46,7 +45,7 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
46 45
47 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 46 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
48 memcpy(alignbuffer, key, keylen); 47 memcpy(alignbuffer, key, keylen);
49 ret = aead->setkey(tfm, alignbuffer, keylen); 48 ret = tfm->setkey(tfm, alignbuffer, keylen);
50 memset(alignbuffer, 0, keylen); 49 memset(alignbuffer, 0, keylen);
51 kfree(buffer); 50 kfree(buffer);
52 return ret; 51 return ret;
@@ -55,7 +54,6 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
55int crypto_aead_setkey(struct crypto_aead *tfm, 54int crypto_aead_setkey(struct crypto_aead *tfm,
56 const u8 *key, unsigned int keylen) 55 const u8 *key, unsigned int keylen)
57{ 56{
58 struct old_aead_alg *aead = crypto_old_aead_alg(tfm);
59 unsigned long alignmask = crypto_aead_alignmask(tfm); 57 unsigned long alignmask = crypto_aead_alignmask(tfm);
60 58
61 tfm = tfm->child; 59 tfm = tfm->child;
@@ -63,7 +61,7 @@ int crypto_aead_setkey(struct crypto_aead *tfm,
63 if ((unsigned long)key & alignmask) 61 if ((unsigned long)key & alignmask)
64 return setkey_unaligned(tfm, key, keylen); 62 return setkey_unaligned(tfm, key, keylen);
65 63
66 return aead->setkey(tfm, key, keylen); 64 return tfm->setkey(tfm, key, keylen);
67} 65}
68EXPORT_SYMBOL_GPL(crypto_aead_setkey); 66EXPORT_SYMBOL_GPL(crypto_aead_setkey);
69 67
@@ -71,12 +69,11 @@ int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
71{ 69{
72 int err; 70 int err;
73 71
74 if (authsize > crypto_old_aead_alg(tfm)->maxauthsize) 72 if (authsize > tfm->maxauthsize)
75 return -EINVAL; 73 return -EINVAL;
76 74
77 if (crypto_old_aead_alg(tfm)->setauthsize) { 75 if (tfm->setauthsize) {
78 err = crypto_old_aead_alg(tfm)->setauthsize( 76 err = tfm->setauthsize(tfm->child, authsize);
79 tfm->child, authsize);
80 if (err) 77 if (err)
81 return err; 78 return err;
82 } 79 }
@@ -145,7 +142,7 @@ static int no_givcrypt(struct aead_givcrypt_request *req)
145 return -ENOSYS; 142 return -ENOSYS;
146} 143}
147 144
148static int crypto_aead_init_tfm(struct crypto_tfm *tfm) 145static int crypto_old_aead_init_tfm(struct crypto_tfm *tfm)
149{ 146{
150 struct old_aead_alg *alg = &tfm->__crt_alg->cra_aead; 147 struct old_aead_alg *alg = &tfm->__crt_alg->cra_aead;
151 struct crypto_aead *crt = __crypto_aead_cast(tfm); 148 struct crypto_aead *crt = __crypto_aead_cast(tfm);
@@ -153,6 +150,8 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
153 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) 150 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
154 return -EINVAL; 151 return -EINVAL;
155 152
153 crt->setkey = alg->setkey;
154 crt->setauthsize = alg->setauthsize;
156 crt->encrypt = old_encrypt; 155 crt->encrypt = old_encrypt;
157 crt->decrypt = old_decrypt; 156 crt->decrypt = old_decrypt;
158 if (alg->ivsize) { 157 if (alg->ivsize) {
@@ -164,13 +163,34 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
164 } 163 }
165 crt->child = __crypto_aead_cast(tfm); 164 crt->child = __crypto_aead_cast(tfm);
166 crt->ivsize = alg->ivsize; 165 crt->ivsize = alg->ivsize;
166 crt->maxauthsize = alg->maxauthsize;
167 crt->authsize = alg->maxauthsize; 167 crt->authsize = alg->maxauthsize;
168 168
169 return 0; 169 return 0;
170} 170}
171 171
172static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
173{
174 struct crypto_aead *aead = __crypto_aead_cast(tfm);
175 struct aead_alg *alg = crypto_aead_alg(aead);
176
177 if (crypto_old_aead_alg(aead)->encrypt)
178 return crypto_old_aead_init_tfm(tfm);
179
180 aead->setkey = alg->setkey;
181 aead->setauthsize = alg->setauthsize;
182 aead->encrypt = alg->encrypt;
183 aead->decrypt = alg->decrypt;
184 aead->child = __crypto_aead_cast(tfm);
185 aead->ivsize = alg->ivsize;
186 aead->maxauthsize = alg->maxauthsize;
187 aead->authsize = alg->maxauthsize;
188
189 return 0;
190}
191
172#ifdef CONFIG_NET 192#ifdef CONFIG_NET
173static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) 193static int crypto_old_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
174{ 194{
175 struct crypto_report_aead raead; 195 struct crypto_report_aead raead;
176 struct old_aead_alg *aead = &alg->cra_aead; 196 struct old_aead_alg *aead = &alg->cra_aead;
@@ -191,15 +211,15 @@ nla_put_failure:
191 return -EMSGSIZE; 211 return -EMSGSIZE;
192} 212}
193#else 213#else
194static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) 214static int crypto_old_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
195{ 215{
196 return -ENOSYS; 216 return -ENOSYS;
197} 217}
198#endif 218#endif
199 219
200static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 220static void crypto_old_aead_show(struct seq_file *m, struct crypto_alg *alg)
201 __attribute__ ((unused)); 221 __attribute__ ((unused));
202static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 222static void crypto_old_aead_show(struct seq_file *m, struct crypto_alg *alg)
203{ 223{
204 struct old_aead_alg *aead = &alg->cra_aead; 224 struct old_aead_alg *aead = &alg->cra_aead;
205 225
@@ -216,9 +236,9 @@ const struct crypto_type crypto_aead_type = {
216 .extsize = crypto_alg_extsize, 236 .extsize = crypto_alg_extsize,
217 .init_tfm = crypto_aead_init_tfm, 237 .init_tfm = crypto_aead_init_tfm,
218#ifdef CONFIG_PROC_FS 238#ifdef CONFIG_PROC_FS
219 .show = crypto_aead_show, 239 .show = crypto_old_aead_show,
220#endif 240#endif
221 .report = crypto_aead_report, 241 .report = crypto_old_aead_report,
222 .lookup = crypto_lookup_aead, 242 .lookup = crypto_lookup_aead,
223 .maskclear = ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV), 243 .maskclear = ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV),
224 .maskset = CRYPTO_ALG_TYPE_MASK, 244 .maskset = CRYPTO_ALG_TYPE_MASK,
@@ -227,6 +247,62 @@ const struct crypto_type crypto_aead_type = {
227}; 247};
228EXPORT_SYMBOL_GPL(crypto_aead_type); 248EXPORT_SYMBOL_GPL(crypto_aead_type);
229 249
250#ifdef CONFIG_NET
251static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
252{
253 struct crypto_report_aead raead;
254 struct aead_alg *aead = container_of(alg, struct aead_alg, base);
255
256 strncpy(raead.type, "aead", sizeof(raead.type));
257 strncpy(raead.geniv, "<none>", sizeof(raead.geniv));
258
259 raead.blocksize = alg->cra_blocksize;
260 raead.maxauthsize = aead->maxauthsize;
261 raead.ivsize = aead->ivsize;
262
263 if (nla_put(skb, CRYPTOCFGA_REPORT_AEAD,
264 sizeof(struct crypto_report_aead), &raead))
265 goto nla_put_failure;
266 return 0;
267
268nla_put_failure:
269 return -EMSGSIZE;
270}
271#else
272static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
273{
274 return -ENOSYS;
275}
276#endif
277
278static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
279 __attribute__ ((unused));
280static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
281{
282 struct aead_alg *aead = container_of(alg, struct aead_alg, base);
283
284 seq_printf(m, "type : aead\n");
285 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
286 "yes" : "no");
287 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
288 seq_printf(m, "ivsize : %u\n", aead->ivsize);
289 seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize);
290 seq_printf(m, "geniv : <none>\n");
291}
292
293static const struct crypto_type crypto_new_aead_type = {
294 .extsize = crypto_alg_extsize,
295 .init_tfm = crypto_aead_init_tfm,
296#ifdef CONFIG_PROC_FS
297 .show = crypto_aead_show,
298#endif
299 .report = crypto_aead_report,
300 .maskclear = ~CRYPTO_ALG_TYPE_MASK,
301 .maskset = CRYPTO_ALG_TYPE_MASK,
302 .type = CRYPTO_ALG_TYPE_AEAD,
303 .tfmsize = offsetof(struct crypto_aead, base),
304};
305
230static int aead_null_givencrypt(struct aead_givcrypt_request *req) 306static int aead_null_givencrypt(struct aead_givcrypt_request *req)
231{ 307{
232 return crypto_aead_encrypt(&req->areq); 308 return crypto_aead_encrypt(&req->areq);
@@ -552,5 +628,51 @@ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)
552} 628}
553EXPORT_SYMBOL_GPL(crypto_alloc_aead); 629EXPORT_SYMBOL_GPL(crypto_alloc_aead);
554 630
631static int aead_prepare_alg(struct aead_alg *alg)
632{
633 struct crypto_alg *base = &alg->base;
634
635 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
636 return -EINVAL;
637
638 base->cra_type = &crypto_new_aead_type;
639 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
640 base->cra_flags |= CRYPTO_ALG_TYPE_AEAD;
641
642 return 0;
643}
644
645int crypto_register_aead(struct aead_alg *alg)
646{
647 struct crypto_alg *base = &alg->base;
648 int err;
649
650 err = aead_prepare_alg(alg);
651 if (err)
652 return err;
653
654 return crypto_register_alg(base);
655}
656EXPORT_SYMBOL_GPL(crypto_register_aead);
657
658int crypto_unregister_aead(struct aead_alg *alg)
659{
660 return crypto_unregister_alg(&alg->base);
661}
662EXPORT_SYMBOL_GPL(crypto_unregister_aead);
663
664int aead_register_instance(struct crypto_template *tmpl,
665 struct aead_instance *inst)
666{
667 int err;
668
669 err = aead_prepare_alg(&inst->alg);
670 if (err)
671 return err;
672
673 return crypto_register_instance(tmpl, aead_crypto_instance(inst));
674}
675EXPORT_SYMBOL_GPL(aead_register_instance);
676
555MODULE_LICENSE("GPL"); 677MODULE_LICENSE("GPL");
556MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)"); 678MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");
diff --git a/include/crypto/aead.h b/include/crypto/aead.h
index aebf57dfb903..177e6f46e2bb 100644
--- a/include/crypto/aead.h
+++ b/include/crypto/aead.h
@@ -17,8 +17,6 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#define aead_alg old_aead_alg
21
22/** 20/**
23 * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API 21 * DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API
24 * 22 *
@@ -92,7 +90,48 @@ struct aead_givcrypt_request {
92 struct aead_request areq; 90 struct aead_request areq;
93}; 91};
94 92
93/**
94 * struct aead_alg - AEAD cipher definition
95 * @maxauthsize: Set the maximum authentication tag size supported by the
96 * transformation. A transformation may support smaller tag sizes.
97 * As the authentication tag is a message digest to ensure the
98 * integrity of the encrypted data, a consumer typically wants the
99 * largest authentication tag possible as defined by this
100 * variable.
101 * @setauthsize: Set authentication size for the AEAD transformation. This
102 * function is used to specify the consumer requested size of the
103 * authentication tag to be either generated by the transformation
104 * during encryption or the size of the authentication tag to be
105 * supplied during the decryption operation. This function is also
106 * responsible for checking the authentication tag size for
107 * validity.
108 * @setkey: see struct ablkcipher_alg
109 * @encrypt: see struct ablkcipher_alg
110 * @decrypt: see struct ablkcipher_alg
111 * @geniv: see struct ablkcipher_alg
112 * @ivsize: see struct ablkcipher_alg
113 *
114 * All fields except @ivsize is mandatory and must be filled.
115 */
116struct aead_alg {
117 int (*setkey)(struct crypto_aead *tfm, const u8 *key,
118 unsigned int keylen);
119 int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize);
120 int (*encrypt)(struct aead_request *req);
121 int (*decrypt)(struct aead_request *req);
122
123 const char *geniv;
124
125 unsigned int ivsize;
126 unsigned int maxauthsize;
127
128 struct crypto_alg base;
129};
130
95struct crypto_aead { 131struct crypto_aead {
132 int (*setkey)(struct crypto_aead *tfm, const u8 *key,
133 unsigned int keylen);
134 int (*setauthsize)(struct crypto_aead *tfm, unsigned int authsize);
96 int (*encrypt)(struct aead_request *req); 135 int (*encrypt)(struct aead_request *req);
97 int (*decrypt)(struct aead_request *req); 136 int (*decrypt)(struct aead_request *req);
98 int (*givencrypt)(struct aead_givcrypt_request *req); 137 int (*givencrypt)(struct aead_givcrypt_request *req);
@@ -102,6 +141,7 @@ struct crypto_aead {
102 141
103 unsigned int ivsize; 142 unsigned int ivsize;
104 unsigned int authsize; 143 unsigned int authsize;
144 unsigned int maxauthsize;
105 unsigned int reqsize; 145 unsigned int reqsize;
106 146
107 struct crypto_tfm base; 147 struct crypto_tfm base;
diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h
index 4614f795f8bc..6cd31519c4f6 100644
--- a/include/crypto/internal/aead.h
+++ b/include/crypto/internal/aead.h
@@ -19,6 +19,10 @@
19 19
20struct rtattr; 20struct rtattr;
21 21
22struct aead_instance {
23 struct aead_alg alg;
24};
25
22struct crypto_aead_spawn { 26struct crypto_aead_spawn {
23 struct crypto_spawn base; 27 struct crypto_spawn base;
24}; 28};
@@ -33,7 +37,8 @@ static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm)
33 37
34static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) 38static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm)
35{ 39{
36 return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; 40 return container_of(crypto_aead_tfm(tfm)->__crt_alg,
41 struct aead_alg, base);
37} 42}
38 43
39static inline void *crypto_aead_ctx(struct crypto_aead *tfm) 44static inline void *crypto_aead_ctx(struct crypto_aead *tfm)
@@ -47,6 +52,22 @@ static inline struct crypto_instance *crypto_aead_alg_instance(
47 return crypto_tfm_alg_instance(&aead->base); 52 return crypto_tfm_alg_instance(&aead->base);
48} 53}
49 54
55static inline struct crypto_instance *aead_crypto_instance(
56 struct aead_instance *inst)
57{
58 return container_of(&inst->alg.base, struct crypto_instance, alg);
59}
60
61static inline struct aead_instance *aead_instance(struct crypto_instance *inst)
62{
63 return container_of(&inst->alg, struct aead_instance, alg.base);
64}
65
66static inline void *aead_instance_ctx(struct aead_instance *inst)
67{
68 return crypto_instance_ctx(aead_crypto_instance(inst));
69}
70
50static inline void *aead_request_ctx(struct aead_request *req) 71static inline void *aead_request_ctx(struct aead_request *req)
51{ 72{
52 return req->__ctx; 73 return req->__ctx;
@@ -84,6 +105,12 @@ static inline struct crypto_alg *crypto_aead_spawn_alg(
84 return spawn->base.alg; 105 return spawn->base.alg;
85} 106}
86 107
108static inline struct aead_alg *crypto_spawn_aead_alg(
109 struct crypto_aead_spawn *spawn)
110{
111 return container_of(spawn->base.alg, struct aead_alg, base);
112}
113
87static inline struct crypto_aead *crypto_spawn_aead( 114static inline struct crypto_aead *crypto_spawn_aead(
88 struct crypto_aead_spawn *spawn) 115 struct crypto_aead_spawn *spawn)
89{ 116{
@@ -121,8 +148,13 @@ static inline void crypto_aead_set_reqsize(struct crypto_aead *aead,
121 148
122static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead) 149static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead)
123{ 150{
124 return crypto_old_aead_alg(aead)->maxauthsize; 151 return aead->maxauthsize;
125} 152}
126 153
154int crypto_register_aead(struct aead_alg *alg);
155int crypto_unregister_aead(struct aead_alg *alg);
156int aead_register_instance(struct crypto_template *tmpl,
157 struct aead_instance *inst);
158
127#endif /* _CRYPTO_INTERNAL_AEAD_H */ 159#endif /* _CRYPTO_INTERNAL_AEAD_H */
128 160