Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * CTR: Counter mode
4 : : *
5 : : * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
6 : : */
7 : :
8 : : #include <crypto/algapi.h>
9 : : #include <crypto/ctr.h>
10 : : #include <crypto/internal/skcipher.h>
11 : : #include <linux/err.h>
12 : : #include <linux/init.h>
13 : : #include <linux/kernel.h>
14 : : #include <linux/module.h>
15 : : #include <linux/slab.h>
16 : :
17 : : struct crypto_rfc3686_ctx {
18 : : struct crypto_skcipher *child;
19 : : u8 nonce[CTR_RFC3686_NONCE_SIZE];
20 : : };
21 : :
22 : : struct crypto_rfc3686_req_ctx {
23 : : u8 iv[CTR_RFC3686_BLOCK_SIZE];
24 : : struct skcipher_request subreq CRYPTO_MINALIGN_ATTR;
25 : : };
26 : :
27 : 0 : static void crypto_ctr_crypt_final(struct skcipher_walk *walk,
28 : : struct crypto_cipher *tfm)
29 : : {
30 : 0 : unsigned int bsize = crypto_cipher_blocksize(tfm);
31 : 0 : unsigned long alignmask = crypto_cipher_alignmask(tfm);
32 : 0 : u8 *ctrblk = walk->iv;
33 : 0 : u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
34 : 0 : u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
35 : 0 : u8 *src = walk->src.virt.addr;
36 : 0 : u8 *dst = walk->dst.virt.addr;
37 : 0 : unsigned int nbytes = walk->nbytes;
38 : :
39 : 0 : crypto_cipher_encrypt_one(tfm, keystream, ctrblk);
40 : 0 : crypto_xor_cpy(dst, keystream, src, nbytes);
41 : :
42 : 0 : crypto_inc(ctrblk, bsize);
43 : 0 : }
44 : :
45 : 0 : static int crypto_ctr_crypt_segment(struct skcipher_walk *walk,
46 : : struct crypto_cipher *tfm)
47 : : {
48 : 0 : void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
49 : : crypto_cipher_alg(tfm)->cia_encrypt;
50 : 0 : unsigned int bsize = crypto_cipher_blocksize(tfm);
51 : 0 : u8 *ctrblk = walk->iv;
52 : 0 : u8 *src = walk->src.virt.addr;
53 : 0 : u8 *dst = walk->dst.virt.addr;
54 : 0 : unsigned int nbytes = walk->nbytes;
55 : :
56 : 0 : do {
57 : : /* create keystream */
58 : 0 : fn(crypto_cipher_tfm(tfm), dst, ctrblk);
59 : 0 : crypto_xor(dst, src, bsize);
60 : :
61 : : /* increment counter in counterblock */
62 : 0 : crypto_inc(ctrblk, bsize);
63 : :
64 : 0 : src += bsize;
65 : 0 : dst += bsize;
66 [ # # ]: 0 : } while ((nbytes -= bsize) >= bsize);
67 : :
68 : 0 : return nbytes;
69 : : }
70 : :
71 : 0 : static int crypto_ctr_crypt_inplace(struct skcipher_walk *walk,
72 : : struct crypto_cipher *tfm)
73 : : {
74 : 0 : void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
75 : : crypto_cipher_alg(tfm)->cia_encrypt;
76 : 0 : unsigned int bsize = crypto_cipher_blocksize(tfm);
77 : 0 : unsigned long alignmask = crypto_cipher_alignmask(tfm);
78 : 0 : unsigned int nbytes = walk->nbytes;
79 : 0 : u8 *ctrblk = walk->iv;
80 : 0 : u8 *src = walk->src.virt.addr;
81 : 0 : u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
82 : 0 : u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
83 : :
84 : 0 : do {
85 : : /* create keystream */
86 : 0 : fn(crypto_cipher_tfm(tfm), keystream, ctrblk);
87 : 0 : crypto_xor(src, keystream, bsize);
88 : :
89 : : /* increment counter in counterblock */
90 : 0 : crypto_inc(ctrblk, bsize);
91 : :
92 : 0 : src += bsize;
93 [ # # ]: 0 : } while ((nbytes -= bsize) >= bsize);
94 : :
95 : 0 : return nbytes;
96 : : }
97 : :
98 : 0 : static int crypto_ctr_crypt(struct skcipher_request *req)
99 : : {
100 : 0 : struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
101 : 0 : struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
102 : 0 : const unsigned int bsize = crypto_cipher_blocksize(cipher);
103 : 0 : struct skcipher_walk walk;
104 : 0 : unsigned int nbytes;
105 : 0 : int err;
106 : :
107 : 0 : err = skcipher_walk_virt(&walk, req, false);
108 : :
109 [ # # ]: 0 : while (walk.nbytes >= bsize) {
110 [ # # ]: 0 : if (walk.src.virt.addr == walk.dst.virt.addr)
111 : 0 : nbytes = crypto_ctr_crypt_inplace(&walk, cipher);
112 : : else
113 : 0 : nbytes = crypto_ctr_crypt_segment(&walk, cipher);
114 : :
115 : 0 : err = skcipher_walk_done(&walk, nbytes);
116 : : }
117 : :
118 [ # # ]: 0 : if (walk.nbytes) {
119 : 0 : crypto_ctr_crypt_final(&walk, cipher);
120 : 0 : err = skcipher_walk_done(&walk, 0);
121 : : }
122 : :
123 : 0 : return err;
124 : : }
125 : :
126 : 0 : static int crypto_ctr_create(struct crypto_template *tmpl, struct rtattr **tb)
127 : : {
128 : 0 : struct skcipher_instance *inst;
129 : 0 : struct crypto_alg *alg;
130 : 0 : int err;
131 : :
132 : 0 : inst = skcipher_alloc_instance_simple(tmpl, tb);
133 [ # # ]: 0 : if (IS_ERR(inst))
134 : 0 : return PTR_ERR(inst);
135 : :
136 [ # # ]: 0 : alg = skcipher_ialg_simple(inst);
137 : :
138 : : /* Block size must be >= 4 bytes. */
139 : 0 : err = -EINVAL;
140 [ # # ]: 0 : if (alg->cra_blocksize < 4)
141 : 0 : goto out_free_inst;
142 : :
143 : : /* If this is false we'd fail the alignment of crypto_inc. */
144 [ # # ]: 0 : if (alg->cra_blocksize % 4)
145 : 0 : goto out_free_inst;
146 : :
147 : : /* CTR mode is a stream cipher. */
148 : 0 : inst->alg.base.cra_blocksize = 1;
149 : :
150 : : /*
151 : : * To simplify the implementation, configure the skcipher walk to only
152 : : * give a partial block at the very end, never earlier.
153 : : */
154 : 0 : inst->alg.chunksize = alg->cra_blocksize;
155 : :
156 : 0 : inst->alg.encrypt = crypto_ctr_crypt;
157 : 0 : inst->alg.decrypt = crypto_ctr_crypt;
158 : :
159 : 0 : err = skcipher_register_instance(tmpl, inst);
160 [ # # ]: 0 : if (err) {
161 : 0 : out_free_inst:
162 : 0 : inst->free(inst);
163 : : }
164 : :
165 : : return err;
166 : : }
167 : :
168 : 0 : static int crypto_rfc3686_setkey(struct crypto_skcipher *parent,
169 : : const u8 *key, unsigned int keylen)
170 : : {
171 [ # # ]: 0 : struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(parent);
172 : 0 : struct crypto_skcipher *child = ctx->child;
173 : :
174 : : /* the nonce is stored in bytes at end of key */
175 [ # # ]: 0 : if (keylen < CTR_RFC3686_NONCE_SIZE)
176 : : return -EINVAL;
177 : :
178 : 0 : memcpy(ctx->nonce, key + (keylen - CTR_RFC3686_NONCE_SIZE),
179 : : CTR_RFC3686_NONCE_SIZE);
180 : :
181 : 0 : keylen -= CTR_RFC3686_NONCE_SIZE;
182 : :
183 : 0 : crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
184 : 0 : crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) &
185 : : CRYPTO_TFM_REQ_MASK);
186 : 0 : return crypto_skcipher_setkey(child, key, keylen);
187 : : }
188 : :
189 : 0 : static int crypto_rfc3686_crypt(struct skcipher_request *req)
190 : : {
191 : 0 : struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
192 : 0 : struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm);
193 : 0 : struct crypto_skcipher *child = ctx->child;
194 : 0 : unsigned long align = crypto_skcipher_alignmask(tfm);
195 : 0 : struct crypto_rfc3686_req_ctx *rctx =
196 : 0 : (void *)PTR_ALIGN((u8 *)skcipher_request_ctx(req), align + 1);
197 : 0 : struct skcipher_request *subreq = &rctx->subreq;
198 : 0 : u8 *iv = rctx->iv;
199 : :
200 : : /* set up counter block */
201 : 0 : memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE);
202 : 0 : memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE);
203 : :
204 : : /* initialize counter portion of counter block */
205 : 0 : *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
206 : : cpu_to_be32(1);
207 : :
208 : 0 : skcipher_request_set_tfm(subreq, child);
209 : 0 : skcipher_request_set_callback(subreq, req->base.flags,
210 : : req->base.complete, req->base.data);
211 : 0 : skcipher_request_set_crypt(subreq, req->src, req->dst,
212 : : req->cryptlen, iv);
213 : :
214 : 0 : return crypto_skcipher_encrypt(subreq);
215 : : }
216 : :
217 : 0 : static int crypto_rfc3686_init_tfm(struct crypto_skcipher *tfm)
218 : : {
219 : 0 : struct skcipher_instance *inst = skcipher_alg_instance(tfm);
220 : 0 : struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
221 : 0 : struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm);
222 : 0 : struct crypto_skcipher *cipher;
223 : 0 : unsigned long align;
224 : 0 : unsigned int reqsize;
225 : :
226 : 0 : cipher = crypto_spawn_skcipher(spawn);
227 [ # # ]: 0 : if (IS_ERR(cipher))
228 : 0 : return PTR_ERR(cipher);
229 : :
230 : 0 : ctx->child = cipher;
231 : :
232 : 0 : align = crypto_skcipher_alignmask(tfm);
233 : 0 : align &= ~(crypto_tfm_ctx_alignment() - 1);
234 : 0 : reqsize = align + sizeof(struct crypto_rfc3686_req_ctx) +
235 : : crypto_skcipher_reqsize(cipher);
236 : 0 : crypto_skcipher_set_reqsize(tfm, reqsize);
237 : :
238 : 0 : return 0;
239 : : }
240 : :
241 : 0 : static void crypto_rfc3686_exit_tfm(struct crypto_skcipher *tfm)
242 : : {
243 : 0 : struct crypto_rfc3686_ctx *ctx = crypto_skcipher_ctx(tfm);
244 : :
245 : 0 : crypto_free_skcipher(ctx->child);
246 : 0 : }
247 : :
248 : 0 : static void crypto_rfc3686_free(struct skcipher_instance *inst)
249 : : {
250 : 0 : struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
251 : :
252 : 0 : crypto_drop_skcipher(spawn);
253 : 0 : kfree(inst);
254 : 0 : }
255 : :
256 : 0 : static int crypto_rfc3686_create(struct crypto_template *tmpl,
257 : : struct rtattr **tb)
258 : : {
259 : 0 : struct crypto_attr_type *algt;
260 : 0 : struct skcipher_instance *inst;
261 : 0 : struct skcipher_alg *alg;
262 : 0 : struct crypto_skcipher_spawn *spawn;
263 : 0 : const char *cipher_name;
264 : 0 : u32 mask;
265 : :
266 : 0 : int err;
267 : :
268 : 0 : algt = crypto_get_attr_type(tb);
269 [ # # ]: 0 : if (IS_ERR(algt))
270 : 0 : return PTR_ERR(algt);
271 : :
272 [ # # ]: 0 : if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
273 : : return -EINVAL;
274 : :
275 : 0 : cipher_name = crypto_attr_alg_name(tb[1]);
276 [ # # ]: 0 : if (IS_ERR(cipher_name))
277 : 0 : return PTR_ERR(cipher_name);
278 : :
279 : 0 : inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
280 [ # # ]: 0 : if (!inst)
281 : : return -ENOMEM;
282 : :
283 : 0 : mask = crypto_requires_sync(algt->type, algt->mask) |
284 : : crypto_requires_off(algt->type, algt->mask,
285 : : CRYPTO_ALG_NEED_FALLBACK);
286 : :
287 : 0 : spawn = skcipher_instance_ctx(inst);
288 : :
289 : 0 : err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
290 : : cipher_name, 0, mask);
291 [ # # ]: 0 : if (err)
292 : 0 : goto err_free_inst;
293 : :
294 [ # # ]: 0 : alg = crypto_spawn_skcipher_alg(spawn);
295 : :
296 : : /* We only support 16-byte blocks. */
297 : 0 : err = -EINVAL;
298 [ # # ]: 0 : if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE)
299 : 0 : goto err_drop_spawn;
300 : :
301 : : /* Not a stream cipher? */
302 [ # # ]: 0 : if (alg->base.cra_blocksize != 1)
303 : 0 : goto err_drop_spawn;
304 : :
305 : 0 : err = -ENAMETOOLONG;
306 : 0 : if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
307 [ # # ]: 0 : "rfc3686(%s)", alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
308 : 0 : goto err_drop_spawn;
309 : 0 : if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
310 [ # # ]: 0 : "rfc3686(%s)", alg->base.cra_driver_name) >=
311 : : CRYPTO_MAX_ALG_NAME)
312 : 0 : goto err_drop_spawn;
313 : :
314 : 0 : inst->alg.base.cra_priority = alg->base.cra_priority;
315 : 0 : inst->alg.base.cra_blocksize = 1;
316 : 0 : inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
317 : :
318 : 0 : inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
319 : :
320 : 0 : inst->alg.ivsize = CTR_RFC3686_IV_SIZE;
321 : 0 : inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
322 : 0 : inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) +
323 : : CTR_RFC3686_NONCE_SIZE;
324 : 0 : inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) +
325 : : CTR_RFC3686_NONCE_SIZE;
326 : :
327 : 0 : inst->alg.setkey = crypto_rfc3686_setkey;
328 : 0 : inst->alg.encrypt = crypto_rfc3686_crypt;
329 : 0 : inst->alg.decrypt = crypto_rfc3686_crypt;
330 : :
331 : 0 : inst->alg.base.cra_ctxsize = sizeof(struct crypto_rfc3686_ctx);
332 : :
333 : 0 : inst->alg.init = crypto_rfc3686_init_tfm;
334 : 0 : inst->alg.exit = crypto_rfc3686_exit_tfm;
335 : :
336 : 0 : inst->free = crypto_rfc3686_free;
337 : :
338 : 0 : err = skcipher_register_instance(tmpl, inst);
339 [ # # ]: 0 : if (err)
340 : 0 : goto err_drop_spawn;
341 : :
342 : 0 : out:
343 : : return err;
344 : :
345 : 0 : err_drop_spawn:
346 : 0 : crypto_drop_skcipher(spawn);
347 : 0 : err_free_inst:
348 : 0 : kfree(inst);
349 : 0 : goto out;
350 : : }
351 : :
352 : : static struct crypto_template crypto_ctr_tmpls[] = {
353 : : {
354 : : .name = "ctr",
355 : : .create = crypto_ctr_create,
356 : : .module = THIS_MODULE,
357 : : }, {
358 : : .name = "rfc3686",
359 : : .create = crypto_rfc3686_create,
360 : : .module = THIS_MODULE,
361 : : },
362 : : };
363 : :
364 : 78 : static int __init crypto_ctr_module_init(void)
365 : : {
366 : 78 : return crypto_register_templates(crypto_ctr_tmpls,
367 : : ARRAY_SIZE(crypto_ctr_tmpls));
368 : : }
369 : :
370 : 0 : static void __exit crypto_ctr_module_exit(void)
371 : : {
372 : 0 : crypto_unregister_templates(crypto_ctr_tmpls,
373 : : ARRAY_SIZE(crypto_ctr_tmpls));
374 : 0 : }
375 : :
376 : : subsys_initcall(crypto_ctr_module_init);
377 : : module_exit(crypto_ctr_module_exit);
378 : :
379 : : MODULE_LICENSE("GPL");
380 : : MODULE_DESCRIPTION("CTR block cipher mode of operation");
381 : : MODULE_ALIAS_CRYPTO("rfc3686");
382 : : MODULE_ALIAS_CRYPTO("ctr");
|