hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/crypto/cbc.c
....@@ -1,190 +1,202 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * CBC: Cipher Block Chaining mode
34 *
45 * Copyright (c) 2006-2016 Herbert Xu <herbert@gondor.apana.org.au>
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License as published by the Free
8
- * Software Foundation; either version 2 of the License, or (at your option)
9
- * any later version.
10
- *
116 */
127
138 #include <crypto/algapi.h>
14
-#include <crypto/cbc.h>
9
+#include <crypto/internal/cipher.h>
1510 #include <crypto/internal/skcipher.h>
1611 #include <linux/err.h>
1712 #include <linux/init.h>
1813 #include <linux/kernel.h>
1914 #include <linux/log2.h>
2015 #include <linux/module.h>
21
-#include <linux/slab.h>
2216
23
-struct crypto_cbc_ctx {
24
- struct crypto_cipher *child;
25
-};
26
-
27
-static int crypto_cbc_setkey(struct crypto_skcipher *parent, const u8 *key,
28
- unsigned int keylen)
17
+static int crypto_cbc_encrypt_segment(struct skcipher_walk *walk,
18
+ struct crypto_skcipher *skcipher)
2919 {
30
- struct crypto_cbc_ctx *ctx = crypto_skcipher_ctx(parent);
31
- struct crypto_cipher *child = ctx->child;
32
- int err;
20
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
21
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
22
+ unsigned int nbytes = walk->nbytes;
23
+ u8 *src = walk->src.virt.addr;
24
+ u8 *dst = walk->dst.virt.addr;
25
+ struct crypto_cipher *cipher;
26
+ struct crypto_tfm *tfm;
27
+ u8 *iv = walk->iv;
3328
34
- crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
35
- crypto_cipher_set_flags(child, crypto_skcipher_get_flags(parent) &
36
- CRYPTO_TFM_REQ_MASK);
37
- err = crypto_cipher_setkey(child, key, keylen);
38
- crypto_skcipher_set_flags(parent, crypto_cipher_get_flags(child) &
39
- CRYPTO_TFM_RES_MASK);
40
- return err;
29
+ cipher = skcipher_cipher_simple(skcipher);
30
+ tfm = crypto_cipher_tfm(cipher);
31
+ fn = crypto_cipher_alg(cipher)->cia_encrypt;
32
+
33
+ do {
34
+ crypto_xor(iv, src, bsize);
35
+ fn(tfm, dst, iv);
36
+ memcpy(iv, dst, bsize);
37
+
38
+ src += bsize;
39
+ dst += bsize;
40
+ } while ((nbytes -= bsize) >= bsize);
41
+
42
+ return nbytes;
4143 }
4244
43
-static inline void crypto_cbc_encrypt_one(struct crypto_skcipher *tfm,
44
- const u8 *src, u8 *dst)
45
+static int crypto_cbc_encrypt_inplace(struct skcipher_walk *walk,
46
+ struct crypto_skcipher *skcipher)
4547 {
46
- struct crypto_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
48
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
49
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
50
+ unsigned int nbytes = walk->nbytes;
51
+ u8 *src = walk->src.virt.addr;
52
+ struct crypto_cipher *cipher;
53
+ struct crypto_tfm *tfm;
54
+ u8 *iv = walk->iv;
4755
48
- crypto_cipher_encrypt_one(ctx->child, dst, src);
56
+ cipher = skcipher_cipher_simple(skcipher);
57
+ tfm = crypto_cipher_tfm(cipher);
58
+ fn = crypto_cipher_alg(cipher)->cia_encrypt;
59
+
60
+ do {
61
+ crypto_xor(src, iv, bsize);
62
+ fn(tfm, src, src);
63
+ iv = src;
64
+
65
+ src += bsize;
66
+ } while ((nbytes -= bsize) >= bsize);
67
+
68
+ memcpy(walk->iv, iv, bsize);
69
+
70
+ return nbytes;
4971 }
5072
5173 static int crypto_cbc_encrypt(struct skcipher_request *req)
5274 {
53
- return crypto_cbc_encrypt_walk(req, crypto_cbc_encrypt_one);
54
-}
55
-
56
-static inline void crypto_cbc_decrypt_one(struct crypto_skcipher *tfm,
57
- const u8 *src, u8 *dst)
58
-{
59
- struct crypto_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
60
-
61
- crypto_cipher_decrypt_one(ctx->child, dst, src);
62
-}
63
-
64
-static int crypto_cbc_decrypt(struct skcipher_request *req)
65
-{
66
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
75
+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
6776 struct skcipher_walk walk;
6877 int err;
6978
7079 err = skcipher_walk_virt(&walk, req, false);
7180
7281 while (walk.nbytes) {
73
- err = crypto_cbc_decrypt_blocks(&walk, tfm,
74
- crypto_cbc_decrypt_one);
82
+ if (walk.src.virt.addr == walk.dst.virt.addr)
83
+ err = crypto_cbc_encrypt_inplace(&walk, skcipher);
84
+ else
85
+ err = crypto_cbc_encrypt_segment(&walk, skcipher);
7586 err = skcipher_walk_done(&walk, err);
7687 }
7788
7889 return err;
7990 }
8091
81
-static int crypto_cbc_init_tfm(struct crypto_skcipher *tfm)
92
+static int crypto_cbc_decrypt_segment(struct skcipher_walk *walk,
93
+ struct crypto_skcipher *skcipher)
8294 {
83
- struct skcipher_instance *inst = skcipher_alg_instance(tfm);
84
- struct crypto_spawn *spawn = skcipher_instance_ctx(inst);
85
- struct crypto_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
95
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
96
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
97
+ unsigned int nbytes = walk->nbytes;
98
+ u8 *src = walk->src.virt.addr;
99
+ u8 *dst = walk->dst.virt.addr;
86100 struct crypto_cipher *cipher;
101
+ struct crypto_tfm *tfm;
102
+ u8 *iv = walk->iv;
87103
88
- cipher = crypto_spawn_cipher(spawn);
89
- if (IS_ERR(cipher))
90
- return PTR_ERR(cipher);
104
+ cipher = skcipher_cipher_simple(skcipher);
105
+ tfm = crypto_cipher_tfm(cipher);
106
+ fn = crypto_cipher_alg(cipher)->cia_decrypt;
91107
92
- ctx->child = cipher;
93
- return 0;
108
+ do {
109
+ fn(tfm, dst, src);
110
+ crypto_xor(dst, iv, bsize);
111
+ iv = src;
112
+
113
+ src += bsize;
114
+ dst += bsize;
115
+ } while ((nbytes -= bsize) >= bsize);
116
+
117
+ memcpy(walk->iv, iv, bsize);
118
+
119
+ return nbytes;
94120 }
95121
96
-static void crypto_cbc_exit_tfm(struct crypto_skcipher *tfm)
122
+static int crypto_cbc_decrypt_inplace(struct skcipher_walk *walk,
123
+ struct crypto_skcipher *skcipher)
97124 {
98
- struct crypto_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
125
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
126
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
127
+ unsigned int nbytes = walk->nbytes;
128
+ u8 *src = walk->src.virt.addr;
129
+ u8 last_iv[MAX_CIPHER_BLOCKSIZE];
130
+ struct crypto_cipher *cipher;
131
+ struct crypto_tfm *tfm;
99132
100
- crypto_free_cipher(ctx->child);
133
+ cipher = skcipher_cipher_simple(skcipher);
134
+ tfm = crypto_cipher_tfm(cipher);
135
+ fn = crypto_cipher_alg(cipher)->cia_decrypt;
136
+
137
+ /* Start of the last block. */
138
+ src += nbytes - (nbytes & (bsize - 1)) - bsize;
139
+ memcpy(last_iv, src, bsize);
140
+
141
+ for (;;) {
142
+ fn(tfm, src, src);
143
+ if ((nbytes -= bsize) < bsize)
144
+ break;
145
+ crypto_xor(src, src - bsize, bsize);
146
+ src -= bsize;
147
+ }
148
+
149
+ crypto_xor(src, walk->iv, bsize);
150
+ memcpy(walk->iv, last_iv, bsize);
151
+
152
+ return nbytes;
101153 }
102154
103
-static void crypto_cbc_free(struct skcipher_instance *inst)
155
+static int crypto_cbc_decrypt(struct skcipher_request *req)
104156 {
105
- crypto_drop_skcipher(skcipher_instance_ctx(inst));
106
- kfree(inst);
157
+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
158
+ struct skcipher_walk walk;
159
+ int err;
160
+
161
+ err = skcipher_walk_virt(&walk, req, false);
162
+
163
+ while (walk.nbytes) {
164
+ if (walk.src.virt.addr == walk.dst.virt.addr)
165
+ err = crypto_cbc_decrypt_inplace(&walk, skcipher);
166
+ else
167
+ err = crypto_cbc_decrypt_segment(&walk, skcipher);
168
+ err = skcipher_walk_done(&walk, err);
169
+ }
170
+
171
+ return err;
107172 }
108173
109174 static int crypto_cbc_create(struct crypto_template *tmpl, struct rtattr **tb)
110175 {
111176 struct skcipher_instance *inst;
112
- struct crypto_attr_type *algt;
113
- struct crypto_spawn *spawn;
114177 struct crypto_alg *alg;
115
- u32 mask;
116178 int err;
117179
118
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER);
119
- if (err)
120
- return err;
180
+ inst = skcipher_alloc_instance_simple(tmpl, tb);
181
+ if (IS_ERR(inst))
182
+ return PTR_ERR(inst);
121183
122
- inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
123
- if (!inst)
124
- return -ENOMEM;
125
-
126
- algt = crypto_get_attr_type(tb);
127
- err = PTR_ERR(algt);
128
- if (IS_ERR(algt))
129
- goto err_free_inst;
130
-
131
- mask = CRYPTO_ALG_TYPE_MASK |
132
- crypto_requires_off(algt->type, algt->mask,
133
- CRYPTO_ALG_NEED_FALLBACK);
134
-
135
- alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, mask);
136
- err = PTR_ERR(alg);
137
- if (IS_ERR(alg))
138
- goto err_free_inst;
139
-
140
- spawn = skcipher_instance_ctx(inst);
141
- err = crypto_init_spawn(spawn, alg, skcipher_crypto_instance(inst),
142
- CRYPTO_ALG_TYPE_MASK);
143
- if (err)
144
- goto err_put_alg;
145
-
146
- err = crypto_inst_setname(skcipher_crypto_instance(inst), "cbc", alg);
147
- if (err)
148
- goto err_drop_spawn;
184
+ alg = skcipher_ialg_simple(inst);
149185
150186 err = -EINVAL;
151187 if (!is_power_of_2(alg->cra_blocksize))
152
- goto err_drop_spawn;
188
+ goto out_free_inst;
153189
154
- inst->alg.base.cra_priority = alg->cra_priority;
155
- inst->alg.base.cra_blocksize = alg->cra_blocksize;
156
- inst->alg.base.cra_alignmask = alg->cra_alignmask;
157
-
158
- inst->alg.ivsize = alg->cra_blocksize;
159
- inst->alg.min_keysize = alg->cra_cipher.cia_min_keysize;
160
- inst->alg.max_keysize = alg->cra_cipher.cia_max_keysize;
161
-
162
- inst->alg.base.cra_ctxsize = sizeof(struct crypto_cbc_ctx);
163
-
164
- inst->alg.init = crypto_cbc_init_tfm;
165
- inst->alg.exit = crypto_cbc_exit_tfm;
166
-
167
- inst->alg.setkey = crypto_cbc_setkey;
168190 inst->alg.encrypt = crypto_cbc_encrypt;
169191 inst->alg.decrypt = crypto_cbc_decrypt;
170192
171
- inst->free = crypto_cbc_free;
172
-
173193 err = skcipher_register_instance(tmpl, inst);
174
- if (err)
175
- goto err_drop_spawn;
176
- crypto_mod_put(alg);
194
+ if (err) {
195
+out_free_inst:
196
+ inst->free(inst);
197
+ }
177198
178
-out:
179199 return err;
180
-
181
-err_drop_spawn:
182
- crypto_drop_spawn(spawn);
183
-err_put_alg:
184
- crypto_mod_put(alg);
185
-err_free_inst:
186
- kfree(inst);
187
- goto out;
188200 }
189201
190202 static struct crypto_template crypto_cbc_tmpl = {
....@@ -203,9 +215,9 @@
203215 crypto_unregister_template(&crypto_cbc_tmpl);
204216 }
205217
206
-module_init(crypto_cbc_module_init);
218
+subsys_initcall(crypto_cbc_module_init);
207219 module_exit(crypto_cbc_module_exit);
208220
209221 MODULE_LICENSE("GPL");
210
-MODULE_DESCRIPTION("CBC block cipher algorithm");
222
+MODULE_DESCRIPTION("CBC block cipher mode of operation");
211223 MODULE_ALIAS_CRYPTO("cbc");