hc
2024-05-10 093a6c67005148ae32a5c9e4553491b9f5c2457b
kernel/crypto/aead.c
....@@ -1,30 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * AEAD: Authenticated Encryption with Associated Data
34 *
45 * This file provides API support for AEAD algorithms.
56 *
67 * Copyright (c) 2007-2015 Herbert Xu <herbert@gondor.apana.org.au>
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License as published by the Free
10
- * Software Foundation; either version 2 of the License, or (at your option)
11
- * any later version.
12
- *
138 */
149
15
-#include <crypto/internal/geniv.h>
16
-#include <crypto/internal/rng.h>
17
-#include <crypto/null.h>
18
-#include <crypto/scatterwalk.h>
19
-#include <linux/err.h>
10
+#include <crypto/internal/aead.h>
11
+#include <linux/errno.h>
2012 #include <linux/init.h>
2113 #include <linux/kernel.h>
2214 #include <linux/module.h>
23
-#include <linux/rtnetlink.h>
2415 #include <linux/slab.h>
2516 #include <linux/seq_file.h>
2617 #include <linux/cryptouser.h>
27
-#include <linux/compiler.h>
2818 #include <net/netlink.h>
2919
3020 #include "internal.h"
....@@ -75,7 +65,8 @@
7565 {
7666 int err;
7767
78
- if (authsize > crypto_aead_maxauthsize(tfm))
68
+ if ((!authsize && crypto_aead_maxauthsize(tfm)) ||
69
+ authsize > crypto_aead_maxauthsize(tfm))
7970 return -EINVAL;
8071
8172 if (crypto_aead_alg(tfm)->setauthsize) {
....@@ -88,6 +79,42 @@
8879 return 0;
8980 }
9081 EXPORT_SYMBOL_GPL(crypto_aead_setauthsize);
82
+
83
+int crypto_aead_encrypt(struct aead_request *req)
84
+{
85
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
86
+ struct crypto_alg *alg = aead->base.__crt_alg;
87
+ unsigned int cryptlen = req->cryptlen;
88
+ int ret;
89
+
90
+ crypto_stats_get(alg);
91
+ if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
92
+ ret = -ENOKEY;
93
+ else
94
+ ret = crypto_aead_alg(aead)->encrypt(req);
95
+ crypto_stats_aead_encrypt(cryptlen, alg, ret);
96
+ return ret;
97
+}
98
+EXPORT_SYMBOL_GPL(crypto_aead_encrypt);
99
+
100
+int crypto_aead_decrypt(struct aead_request *req)
101
+{
102
+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
103
+ struct crypto_alg *alg = aead->base.__crt_alg;
104
+ unsigned int cryptlen = req->cryptlen;
105
+ int ret;
106
+
107
+ crypto_stats_get(alg);
108
+ if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY)
109
+ ret = -ENOKEY;
110
+ else if (req->cryptlen < crypto_aead_authsize(aead))
111
+ ret = -EINVAL;
112
+ else
113
+ ret = crypto_aead_alg(aead)->decrypt(req);
114
+ crypto_stats_aead_decrypt(cryptlen, alg, ret);
115
+ return ret;
116
+}
117
+EXPORT_SYMBOL_GPL(crypto_aead_decrypt);
91118
92119 static void crypto_aead_exit_tfm(struct crypto_tfm *tfm)
93120 {
....@@ -121,20 +148,16 @@
121148 struct crypto_report_aead raead;
122149 struct aead_alg *aead = container_of(alg, struct aead_alg, base);
123150
124
- strncpy(raead.type, "aead", sizeof(raead.type));
125
- strncpy(raead.geniv, "<none>", sizeof(raead.geniv));
151
+ memset(&raead, 0, sizeof(raead));
152
+
153
+ strscpy(raead.type, "aead", sizeof(raead.type));
154
+ strscpy(raead.geniv, "<none>", sizeof(raead.geniv));
126155
127156 raead.blocksize = alg->cra_blocksize;
128157 raead.maxauthsize = aead->maxauthsize;
129158 raead.ivsize = aead->ivsize;
130159
131
- if (nla_put(skb, CRYPTOCFGA_REPORT_AEAD,
132
- sizeof(struct crypto_report_aead), &raead))
133
- goto nla_put_failure;
134
- return 0;
135
-
136
-nla_put_failure:
137
- return -EMSGSIZE;
160
+ return nla_put(skb, CRYPTOCFGA_REPORT_AEAD, sizeof(raead), &raead);
138161 }
139162 #else
140163 static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
....@@ -162,11 +185,6 @@
162185 {
163186 struct aead_instance *aead = aead_instance(inst);
164187
165
- if (!aead->free) {
166
- inst->tmpl->free(inst);
167
- return;
168
- }
169
-
170188 aead->free(aead);
171189 }
172190
....@@ -184,167 +202,12 @@
184202 .tfmsize = offsetof(struct crypto_aead, base),
185203 };
186204
187
-static int aead_geniv_setkey(struct crypto_aead *tfm,
188
- const u8 *key, unsigned int keylen)
189
-{
190
- struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
191
-
192
- return crypto_aead_setkey(ctx->child, key, keylen);
193
-}
194
-
195
-static int aead_geniv_setauthsize(struct crypto_aead *tfm,
196
- unsigned int authsize)
197
-{
198
- struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
199
-
200
- return crypto_aead_setauthsize(ctx->child, authsize);
201
-}
202
-
203
-struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
204
- struct rtattr **tb, u32 type, u32 mask)
205
-{
206
- const char *name;
207
- struct crypto_aead_spawn *spawn;
208
- struct crypto_attr_type *algt;
209
- struct aead_instance *inst;
210
- struct aead_alg *alg;
211
- unsigned int ivsize;
212
- unsigned int maxauthsize;
213
- int err;
214
-
215
- algt = crypto_get_attr_type(tb);
216
- if (IS_ERR(algt))
217
- return ERR_CAST(algt);
218
-
219
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
220
- return ERR_PTR(-EINVAL);
221
-
222
- name = crypto_attr_alg_name(tb[1]);
223
- if (IS_ERR(name))
224
- return ERR_CAST(name);
225
-
226
- inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
227
- if (!inst)
228
- return ERR_PTR(-ENOMEM);
229
-
230
- spawn = aead_instance_ctx(inst);
231
-
232
- /* Ignore async algorithms if necessary. */
233
- mask |= crypto_requires_sync(algt->type, algt->mask);
234
-
235
- crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
236
- err = crypto_grab_aead(spawn, name, type, mask);
237
- if (err)
238
- goto err_free_inst;
239
-
240
- alg = crypto_spawn_aead_alg(spawn);
241
-
242
- ivsize = crypto_aead_alg_ivsize(alg);
243
- maxauthsize = crypto_aead_alg_maxauthsize(alg);
244
-
245
- err = -EINVAL;
246
- if (ivsize < sizeof(u64))
247
- goto err_drop_alg;
248
-
249
- err = -ENAMETOOLONG;
250
- if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
251
- "%s(%s)", tmpl->name, alg->base.cra_name) >=
252
- CRYPTO_MAX_ALG_NAME)
253
- goto err_drop_alg;
254
- if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
255
- "%s(%s)", tmpl->name, alg->base.cra_driver_name) >=
256
- CRYPTO_MAX_ALG_NAME)
257
- goto err_drop_alg;
258
-
259
- inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
260
- inst->alg.base.cra_priority = alg->base.cra_priority;
261
- inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
262
- inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
263
- inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
264
-
265
- inst->alg.setkey = aead_geniv_setkey;
266
- inst->alg.setauthsize = aead_geniv_setauthsize;
267
-
268
- inst->alg.ivsize = ivsize;
269
- inst->alg.maxauthsize = maxauthsize;
270
-
271
-out:
272
- return inst;
273
-
274
-err_drop_alg:
275
- crypto_drop_aead(spawn);
276
-err_free_inst:
277
- kfree(inst);
278
- inst = ERR_PTR(err);
279
- goto out;
280
-}
281
-EXPORT_SYMBOL_GPL(aead_geniv_alloc);
282
-
283
-void aead_geniv_free(struct aead_instance *inst)
284
-{
285
- crypto_drop_aead(aead_instance_ctx(inst));
286
- kfree(inst);
287
-}
288
-EXPORT_SYMBOL_GPL(aead_geniv_free);
289
-
290
-int aead_init_geniv(struct crypto_aead *aead)
291
-{
292
- struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead);
293
- struct aead_instance *inst = aead_alg_instance(aead);
294
- struct crypto_aead *child;
295
- int err;
296
-
297
- spin_lock_init(&ctx->lock);
298
-
299
- err = crypto_get_default_rng();
300
- if (err)
301
- goto out;
302
-
303
- err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
304
- crypto_aead_ivsize(aead));
305
- crypto_put_default_rng();
306
- if (err)
307
- goto out;
308
-
309
- ctx->sknull = crypto_get_default_null_skcipher();
310
- err = PTR_ERR(ctx->sknull);
311
- if (IS_ERR(ctx->sknull))
312
- goto out;
313
-
314
- child = crypto_spawn_aead(aead_instance_ctx(inst));
315
- err = PTR_ERR(child);
316
- if (IS_ERR(child))
317
- goto drop_null;
318
-
319
- ctx->child = child;
320
- crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) +
321
- sizeof(struct aead_request));
322
-
323
- err = 0;
324
-
325
-out:
326
- return err;
327
-
328
-drop_null:
329
- crypto_put_default_null_skcipher();
330
- goto out;
331
-}
332
-EXPORT_SYMBOL_GPL(aead_init_geniv);
333
-
334
-void aead_exit_geniv(struct crypto_aead *tfm)
335
-{
336
- struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
337
-
338
- crypto_free_aead(ctx->child);
339
- crypto_put_default_null_skcipher();
340
-}
341
-EXPORT_SYMBOL_GPL(aead_exit_geniv);
342
-
343
-int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
344
- u32 type, u32 mask)
205
+int crypto_grab_aead(struct crypto_aead_spawn *spawn,
206
+ struct crypto_instance *inst,
207
+ const char *name, u32 type, u32 mask)
345208 {
346209 spawn->base.frontend = &crypto_aead_type;
347
- return crypto_grab_spawn(&spawn->base, name, type, mask);
210
+ return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
348211 }
349212 EXPORT_SYMBOL_GPL(crypto_grab_aead);
350213
....@@ -425,6 +288,9 @@
425288 {
426289 int err;
427290
291
+ if (WARN_ON(!inst->free))
292
+ return -EINVAL;
293
+
428294 err = aead_prepare_alg(&inst->alg);
429295 if (err)
430296 return err;