Skip to content

Commit 63293c6

Browse files
committed
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 <[email protected]>
1 parent 56fcf73 commit 63293c6

File tree

3 files changed

+213
-19
lines changed

3 files changed

+213
-19
lines changed

crypto/aead.c

Lines changed: 137 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ static int aead_null_givdecrypt(struct aead_givcrypt_request *req);
3333
static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
3434
unsigned int keylen)
3535
{
36-
struct old_aead_alg *aead = crypto_old_aead_alg(tfm);
3736
unsigned long alignmask = crypto_aead_alignmask(tfm);
3837
int ret;
3938
u8 *buffer, *alignbuffer;
@@ -46,7 +45,7 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
4645

4746
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
4847
memcpy(alignbuffer, key, keylen);
49-
ret = aead->setkey(tfm, alignbuffer, keylen);
48+
ret = tfm->setkey(tfm, alignbuffer, keylen);
5049
memset(alignbuffer, 0, keylen);
5150
kfree(buffer);
5251
return ret;
@@ -55,28 +54,26 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
5554
int crypto_aead_setkey(struct crypto_aead *tfm,
5655
const u8 *key, unsigned int keylen)
5756
{
58-
struct old_aead_alg *aead = crypto_old_aead_alg(tfm);
5957
unsigned long alignmask = crypto_aead_alignmask(tfm);
6058

6159
tfm = tfm->child;
6260

6361
if ((unsigned long)key & alignmask)
6462
return setkey_unaligned(tfm, key, keylen);
6563

66-
return aead->setkey(tfm, key, keylen);
64+
return tfm->setkey(tfm, key, keylen);
6765
}
6866
EXPORT_SYMBOL_GPL(crypto_aead_setkey);
6967

7068
int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
7169
{
7270
int err;
7371

74-
if (authsize > crypto_old_aead_alg(tfm)->maxauthsize)
72+
if (authsize > tfm->maxauthsize)
7573
return -EINVAL;
7674

77-
if (crypto_old_aead_alg(tfm)->setauthsize) {
78-
err = crypto_old_aead_alg(tfm)->setauthsize(
79-
tfm->child, authsize);
75+
if (tfm->setauthsize) {
76+
err = tfm->setauthsize(tfm->child, authsize);
8077
if (err)
8178
return err;
8279
}
@@ -145,14 +142,16 @@ static int no_givcrypt(struct aead_givcrypt_request *req)
145142
return -ENOSYS;
146143
}
147144

148-
static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
145+
static int crypto_old_aead_init_tfm(struct crypto_tfm *tfm)
149146
{
150147
struct old_aead_alg *alg = &tfm->__crt_alg->cra_aead;
151148
struct crypto_aead *crt = __crypto_aead_cast(tfm);
152149

153150
if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8)
154151
return -EINVAL;
155152

153+
crt->setkey = alg->setkey;
154+
crt->setauthsize = alg->setauthsize;
156155
crt->encrypt = old_encrypt;
157156
crt->decrypt = old_decrypt;
158157
if (alg->ivsize) {
@@ -164,13 +163,34 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm)
164163
}
165164
crt->child = __crypto_aead_cast(tfm);
166165
crt->ivsize = alg->ivsize;
166+
crt->maxauthsize = alg->maxauthsize;
167167
crt->authsize = alg->maxauthsize;
168168

169169
return 0;
170170
}
171171

172+
static 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+
172192
#ifdef CONFIG_NET
173-
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
193+
static int crypto_old_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
174194
{
175195
struct crypto_report_aead raead;
176196
struct old_aead_alg *aead = &alg->cra_aead;
@@ -191,15 +211,15 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
191211
return -EMSGSIZE;
192212
}
193213
#else
194-
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
214+
static int crypto_old_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
195215
{
196216
return -ENOSYS;
197217
}
198218
#endif
199219

200-
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
220+
static void crypto_old_aead_show(struct seq_file *m, struct crypto_alg *alg)
201221
__attribute__ ((unused));
202-
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
222+
static void crypto_old_aead_show(struct seq_file *m, struct crypto_alg *alg)
203223
{
204224
struct old_aead_alg *aead = &alg->cra_aead;
205225

@@ -216,9 +236,9 @@ const struct crypto_type crypto_aead_type = {
216236
.extsize = crypto_alg_extsize,
217237
.init_tfm = crypto_aead_init_tfm,
218238
#ifdef CONFIG_PROC_FS
219-
.show = crypto_aead_show,
239+
.show = crypto_old_aead_show,
220240
#endif
221-
.report = crypto_aead_report,
241+
.report = crypto_old_aead_report,
222242
.lookup = crypto_lookup_aead,
223243
.maskclear = ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV),
224244
.maskset = CRYPTO_ALG_TYPE_MASK,
@@ -227,6 +247,62 @@ const struct crypto_type crypto_aead_type = {
227247
};
228248
EXPORT_SYMBOL_GPL(crypto_aead_type);
229249

250+
#ifdef CONFIG_NET
251+
static 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+
268+
nla_put_failure:
269+
return -EMSGSIZE;
270+
}
271+
#else
272+
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
273+
{
274+
return -ENOSYS;
275+
}
276+
#endif
277+
278+
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
279+
__attribute__ ((unused));
280+
static 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+
293+
static 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+
230306
static int aead_null_givencrypt(struct aead_givcrypt_request *req)
231307
{
232308
return crypto_aead_encrypt(&req->areq);
@@ -552,5 +628,51 @@ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)
552628
}
553629
EXPORT_SYMBOL_GPL(crypto_alloc_aead);
554630

631+
static 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+
645+
int 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+
}
656+
EXPORT_SYMBOL_GPL(crypto_register_aead);
657+
658+
int crypto_unregister_aead(struct aead_alg *alg)
659+
{
660+
return crypto_unregister_alg(&alg->base);
661+
}
662+
EXPORT_SYMBOL_GPL(crypto_unregister_aead);
663+
664+
int 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+
}
675+
EXPORT_SYMBOL_GPL(aead_register_instance);
676+
555677
MODULE_LICENSE("GPL");
556678
MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");

include/crypto/aead.h

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include <linux/kernel.h>
1818
#include <linux/slab.h>
1919

20-
#define aead_alg old_aead_alg
21-
2220
/**
2321
* DOC: Authenticated Encryption With Associated Data (AEAD) Cipher API
2422
*
@@ -92,7 +90,48 @@ struct aead_givcrypt_request {
9290
struct aead_request areq;
9391
};
9492

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+
*/
116+
struct 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+
95131
struct 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);
96135
int (*encrypt)(struct aead_request *req);
97136
int (*decrypt)(struct aead_request *req);
98137
int (*givencrypt)(struct aead_givcrypt_request *req);
@@ -102,6 +141,7 @@ struct crypto_aead {
102141

103142
unsigned int ivsize;
104143
unsigned int authsize;
144+
unsigned int maxauthsize;
105145
unsigned int reqsize;
106146

107147
struct crypto_tfm base;

include/crypto/internal/aead.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
struct rtattr;
2121

22+
struct aead_instance {
23+
struct aead_alg alg;
24+
};
25+
2226
struct crypto_aead_spawn {
2327
struct crypto_spawn base;
2428
};
@@ -33,7 +37,8 @@ static inline struct old_aead_alg *crypto_old_aead_alg(struct crypto_aead *tfm)
3337

3438
static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm)
3539
{
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);
3742
}
3843

3944
static inline void *crypto_aead_ctx(struct crypto_aead *tfm)
@@ -47,6 +52,22 @@ static inline struct crypto_instance *crypto_aead_alg_instance(
4752
return crypto_tfm_alg_instance(&aead->base);
4853
}
4954

55+
static 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+
61+
static inline struct aead_instance *aead_instance(struct crypto_instance *inst)
62+
{
63+
return container_of(&inst->alg, struct aead_instance, alg.base);
64+
}
65+
66+
static inline void *aead_instance_ctx(struct aead_instance *inst)
67+
{
68+
return crypto_instance_ctx(aead_crypto_instance(inst));
69+
}
70+
5071
static inline void *aead_request_ctx(struct aead_request *req)
5172
{
5273
return req->__ctx;
@@ -84,6 +105,12 @@ static inline struct crypto_alg *crypto_aead_spawn_alg(
84105
return spawn->base.alg;
85106
}
86107

108+
static 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+
87114
static inline struct crypto_aead *crypto_spawn_aead(
88115
struct crypto_aead_spawn *spawn)
89116
{
@@ -121,8 +148,13 @@ static inline void crypto_aead_set_reqsize(struct crypto_aead *aead,
121148

122149
static inline unsigned int crypto_aead_maxauthsize(struct crypto_aead *aead)
123150
{
124-
return crypto_old_aead_alg(aead)->maxauthsize;
151+
return aead->maxauthsize;
125152
}
126153

154+
int crypto_register_aead(struct aead_alg *alg);
155+
int crypto_unregister_aead(struct aead_alg *alg);
156+
int aead_register_instance(struct crypto_template *tmpl,
157+
struct aead_instance *inst);
158+
127159
#endif /* _CRYPTO_INTERNAL_AEAD_H */
128160

0 commit comments

Comments
 (0)