summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-05-21 03:11:08 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-21 23:25:54 -0400
commit63293c61133447249d7e5b49d333f68825d30e43 (patch)
tree5525d14473d05acf8eb38b8f8e0b8f33acec399f
parent56fcf73a29007aa7bec2e3fc5da2962f3f72d610 (diff)
crypto: aead - Add support for new AEAD implementations
This patch adds the basic structure of the new AEAD type. Unlike the current version, there is no longer any concept of geniv. IV generation will still be carried out by wrappers but they will be normal AEAD algorithms that simply take the IPsec sequence number as the IV. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-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