1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
8 #include <crypto/algapi.h>
9 #include <crypto/ctr.h>
10 #include <crypto/internal/cipher.h>
11 #include <crypto/internal/skcipher.h>
12 #include <linux/err.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
18 struct crypto_rfc3686_ctx
{
19 struct crypto_skcipher
*child
;
20 u8 nonce
[CTR_RFC3686_NONCE_SIZE
];
23 struct crypto_rfc3686_req_ctx
{
24 u8 iv
[CTR_RFC3686_BLOCK_SIZE
];
25 struct skcipher_request subreq CRYPTO_MINALIGN_ATTR
;
28 static void crypto_ctr_crypt_final(struct skcipher_walk
*walk
,
29 struct crypto_cipher
*tfm
)
31 unsigned int bsize
= crypto_cipher_blocksize(tfm
);
32 unsigned long alignmask
= crypto_cipher_alignmask(tfm
);
33 u8
*ctrblk
= walk
->iv
;
34 u8 tmp
[MAX_CIPHER_BLOCKSIZE
+ MAX_CIPHER_ALIGNMASK
];
35 u8
*keystream
= PTR_ALIGN(tmp
+ 0, alignmask
+ 1);
36 u8
*src
= walk
->src
.virt
.addr
;
37 u8
*dst
= walk
->dst
.virt
.addr
;
38 unsigned int nbytes
= walk
->nbytes
;
40 crypto_cipher_encrypt_one(tfm
, keystream
, ctrblk
);
41 crypto_xor_cpy(dst
, keystream
, src
, nbytes
);
43 crypto_inc(ctrblk
, bsize
);
46 static int crypto_ctr_crypt_segment(struct skcipher_walk
*walk
,
47 struct crypto_cipher
*tfm
)
49 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
50 crypto_cipher_alg(tfm
)->cia_encrypt
;
51 unsigned int bsize
= crypto_cipher_blocksize(tfm
);
52 u8
*ctrblk
= walk
->iv
;
53 u8
*src
= walk
->src
.virt
.addr
;
54 u8
*dst
= walk
->dst
.virt
.addr
;
55 unsigned int nbytes
= walk
->nbytes
;
58 /* create keystream */
59 fn(crypto_cipher_tfm(tfm
), dst
, ctrblk
);
60 crypto_xor(dst
, src
, bsize
);
62 /* increment counter in counterblock */
63 crypto_inc(ctrblk
, bsize
);
67 } while ((nbytes
-= bsize
) >= bsize
);
72 static int crypto_ctr_crypt_inplace(struct skcipher_walk
*walk
,
73 struct crypto_cipher
*tfm
)
75 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
76 crypto_cipher_alg(tfm
)->cia_encrypt
;
77 unsigned int bsize
= crypto_cipher_blocksize(tfm
);
78 unsigned long alignmask
= crypto_cipher_alignmask(tfm
);
79 unsigned int nbytes
= walk
->nbytes
;
80 u8
*ctrblk
= walk
->iv
;
81 u8
*src
= walk
->src
.virt
.addr
;
82 u8 tmp
[MAX_CIPHER_BLOCKSIZE
+ MAX_CIPHER_ALIGNMASK
];
83 u8
*keystream
= PTR_ALIGN(tmp
+ 0, alignmask
+ 1);
86 /* create keystream */
87 fn(crypto_cipher_tfm(tfm
), keystream
, ctrblk
);
88 crypto_xor(src
, keystream
, bsize
);
90 /* increment counter in counterblock */
91 crypto_inc(ctrblk
, bsize
);
94 } while ((nbytes
-= bsize
) >= bsize
);
99 static int crypto_ctr_crypt(struct skcipher_request
*req
)
101 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
102 struct crypto_cipher
*cipher
= skcipher_cipher_simple(tfm
);
103 const unsigned int bsize
= crypto_cipher_blocksize(cipher
);
104 struct skcipher_walk walk
;
108 err
= skcipher_walk_virt(&walk
, req
, false);
110 while (walk
.nbytes
>= bsize
) {
111 if (walk
.src
.virt
.addr
== walk
.dst
.virt
.addr
)
112 nbytes
= crypto_ctr_crypt_inplace(&walk
, cipher
);
114 nbytes
= crypto_ctr_crypt_segment(&walk
, cipher
);
116 err
= skcipher_walk_done(&walk
, nbytes
);
120 crypto_ctr_crypt_final(&walk
, cipher
);
121 err
= skcipher_walk_done(&walk
, 0);
127 static int crypto_ctr_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
129 struct skcipher_instance
*inst
;
130 struct crypto_alg
*alg
;
133 inst
= skcipher_alloc_instance_simple(tmpl
, tb
);
135 return PTR_ERR(inst
);
137 alg
= skcipher_ialg_simple(inst
);
139 /* Block size must be >= 4 bytes. */
141 if (alg
->cra_blocksize
< 4)
144 /* If this is false we'd fail the alignment of crypto_inc. */
145 if (alg
->cra_blocksize
% 4)
148 /* CTR mode is a stream cipher. */
149 inst
->alg
.base
.cra_blocksize
= 1;
152 * To simplify the implementation, configure the skcipher walk to only
153 * give a partial block at the very end, never earlier.
155 inst
->alg
.chunksize
= alg
->cra_blocksize
;
157 inst
->alg
.encrypt
= crypto_ctr_crypt
;
158 inst
->alg
.decrypt
= crypto_ctr_crypt
;
160 err
= skcipher_register_instance(tmpl
, inst
);
169 static int crypto_rfc3686_setkey(struct crypto_skcipher
*parent
,
170 const u8
*key
, unsigned int keylen
)
172 struct crypto_rfc3686_ctx
*ctx
= crypto_skcipher_ctx(parent
);
173 struct crypto_skcipher
*child
= ctx
->child
;
175 /* the nonce is stored in bytes at end of key */
176 if (keylen
< CTR_RFC3686_NONCE_SIZE
)
179 memcpy(ctx
->nonce
, key
+ (keylen
- CTR_RFC3686_NONCE_SIZE
),
180 CTR_RFC3686_NONCE_SIZE
);
182 keylen
-= CTR_RFC3686_NONCE_SIZE
;
184 crypto_skcipher_clear_flags(child
, CRYPTO_TFM_REQ_MASK
);
185 crypto_skcipher_set_flags(child
, crypto_skcipher_get_flags(parent
) &
186 CRYPTO_TFM_REQ_MASK
);
187 return crypto_skcipher_setkey(child
, key
, keylen
);
190 static int crypto_rfc3686_crypt(struct skcipher_request
*req
)
192 struct crypto_skcipher
*tfm
= crypto_skcipher_reqtfm(req
);
193 struct crypto_rfc3686_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
194 struct crypto_skcipher
*child
= ctx
->child
;
195 unsigned long align
= crypto_skcipher_alignmask(tfm
);
196 struct crypto_rfc3686_req_ctx
*rctx
=
197 (void *)PTR_ALIGN((u8
*)skcipher_request_ctx(req
), align
+ 1);
198 struct skcipher_request
*subreq
= &rctx
->subreq
;
201 /* set up counter block */
202 memcpy(iv
, ctx
->nonce
, CTR_RFC3686_NONCE_SIZE
);
203 memcpy(iv
+ CTR_RFC3686_NONCE_SIZE
, req
->iv
, CTR_RFC3686_IV_SIZE
);
205 /* initialize counter portion of counter block */
206 *(__be32
*)(iv
+ CTR_RFC3686_NONCE_SIZE
+ CTR_RFC3686_IV_SIZE
) =
209 skcipher_request_set_tfm(subreq
, child
);
210 skcipher_request_set_callback(subreq
, req
->base
.flags
,
211 req
->base
.complete
, req
->base
.data
);
212 skcipher_request_set_crypt(subreq
, req
->src
, req
->dst
,
215 return crypto_skcipher_encrypt(subreq
);
218 static int crypto_rfc3686_init_tfm(struct crypto_skcipher
*tfm
)
220 struct skcipher_instance
*inst
= skcipher_alg_instance(tfm
);
221 struct crypto_skcipher_spawn
*spawn
= skcipher_instance_ctx(inst
);
222 struct crypto_rfc3686_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
223 struct crypto_skcipher
*cipher
;
225 unsigned int reqsize
;
227 cipher
= crypto_spawn_skcipher(spawn
);
229 return PTR_ERR(cipher
);
233 align
= crypto_skcipher_alignmask(tfm
);
234 align
&= ~(crypto_tfm_ctx_alignment() - 1);
235 reqsize
= align
+ sizeof(struct crypto_rfc3686_req_ctx
) +
236 crypto_skcipher_reqsize(cipher
);
237 crypto_skcipher_set_reqsize(tfm
, reqsize
);
242 static void crypto_rfc3686_exit_tfm(struct crypto_skcipher
*tfm
)
244 struct crypto_rfc3686_ctx
*ctx
= crypto_skcipher_ctx(tfm
);
246 crypto_free_skcipher(ctx
->child
);
249 static void crypto_rfc3686_free(struct skcipher_instance
*inst
)
251 struct crypto_skcipher_spawn
*spawn
= skcipher_instance_ctx(inst
);
253 crypto_drop_skcipher(spawn
);
257 static int crypto_rfc3686_create(struct crypto_template
*tmpl
,
260 struct skcipher_instance
*inst
;
261 struct crypto_skcipher_spawn
*spawn
;
262 struct skcipher_alg_common
*alg
;
266 err
= crypto_check_attr_type(tb
, CRYPTO_ALG_TYPE_SKCIPHER
, &mask
);
270 inst
= kzalloc(sizeof(*inst
) + sizeof(*spawn
), GFP_KERNEL
);
274 spawn
= skcipher_instance_ctx(inst
);
276 err
= crypto_grab_skcipher(spawn
, skcipher_crypto_instance(inst
),
277 crypto_attr_alg_name(tb
[1]), 0, mask
);
281 alg
= crypto_spawn_skcipher_alg_common(spawn
);
283 /* We only support 16-byte blocks. */
285 if (alg
->ivsize
!= CTR_RFC3686_BLOCK_SIZE
)
288 /* Not a stream cipher? */
289 if (alg
->base
.cra_blocksize
!= 1)
293 if (snprintf(inst
->alg
.base
.cra_name
, CRYPTO_MAX_ALG_NAME
,
294 "rfc3686(%s)", alg
->base
.cra_name
) >= CRYPTO_MAX_ALG_NAME
)
296 if (snprintf(inst
->alg
.base
.cra_driver_name
, CRYPTO_MAX_ALG_NAME
,
297 "rfc3686(%s)", alg
->base
.cra_driver_name
) >=
301 inst
->alg
.base
.cra_priority
= alg
->base
.cra_priority
;
302 inst
->alg
.base
.cra_blocksize
= 1;
303 inst
->alg
.base
.cra_alignmask
= alg
->base
.cra_alignmask
;
305 inst
->alg
.ivsize
= CTR_RFC3686_IV_SIZE
;
306 inst
->alg
.chunksize
= alg
->chunksize
;
307 inst
->alg
.min_keysize
= alg
->min_keysize
+ CTR_RFC3686_NONCE_SIZE
;
308 inst
->alg
.max_keysize
= alg
->max_keysize
+ CTR_RFC3686_NONCE_SIZE
;
310 inst
->alg
.setkey
= crypto_rfc3686_setkey
;
311 inst
->alg
.encrypt
= crypto_rfc3686_crypt
;
312 inst
->alg
.decrypt
= crypto_rfc3686_crypt
;
314 inst
->alg
.base
.cra_ctxsize
= sizeof(struct crypto_rfc3686_ctx
);
316 inst
->alg
.init
= crypto_rfc3686_init_tfm
;
317 inst
->alg
.exit
= crypto_rfc3686_exit_tfm
;
319 inst
->free
= crypto_rfc3686_free
;
321 err
= skcipher_register_instance(tmpl
, inst
);
324 crypto_rfc3686_free(inst
);
329 static struct crypto_template crypto_ctr_tmpls
[] = {
332 .create
= crypto_ctr_create
,
333 .module
= THIS_MODULE
,
336 .create
= crypto_rfc3686_create
,
337 .module
= THIS_MODULE
,
341 static int __init
crypto_ctr_module_init(void)
343 return crypto_register_templates(crypto_ctr_tmpls
,
344 ARRAY_SIZE(crypto_ctr_tmpls
));
347 static void __exit
crypto_ctr_module_exit(void)
349 crypto_unregister_templates(crypto_ctr_tmpls
,
350 ARRAY_SIZE(crypto_ctr_tmpls
));
353 subsys_initcall(crypto_ctr_module_init
);
354 module_exit(crypto_ctr_module_exit
);
356 MODULE_LICENSE("GPL");
357 MODULE_DESCRIPTION("CTR block cipher mode of operation");
358 MODULE_ALIAS_CRYPTO("rfc3686");
359 MODULE_ALIAS_CRYPTO("ctr");
360 MODULE_IMPORT_NS("CRYPTO_INTERNAL");