xref: /openbmc/linux/crypto/seqiv.c (revision 643d1f7f)
1 /*
2  * seqiv: Sequence Number IV Generator
3  *
4  * This generator generates an IV based on a sequence number by xoring it
5  * with a salt.  This algorithm is mainly useful for CTR and similar modes.
6  *
7  * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the Free
11  * Software Foundation; either version 2 of the License, or (at your option)
12  * any later version.
13  *
14  */
15 
16 #include <crypto/internal/aead.h>
17 #include <crypto/internal/skcipher.h>
18 #include <linux/err.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/random.h>
23 #include <linux/spinlock.h>
24 #include <linux/string.h>
25 
26 struct seqiv_ctx {
27 	spinlock_t lock;
28 	u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
29 };
30 
31 static void seqiv_complete2(struct skcipher_givcrypt_request *req, int err)
32 {
33 	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
34 	struct crypto_ablkcipher *geniv;
35 
36 	if (err == -EINPROGRESS)
37 		return;
38 
39 	if (err)
40 		goto out;
41 
42 	geniv = skcipher_givcrypt_reqtfm(req);
43 	memcpy(req->creq.info, subreq->info, crypto_ablkcipher_ivsize(geniv));
44 
45 out:
46 	kfree(subreq->info);
47 }
48 
49 static void seqiv_complete(struct crypto_async_request *base, int err)
50 {
51 	struct skcipher_givcrypt_request *req = base->data;
52 
53 	seqiv_complete2(req, err);
54 	skcipher_givcrypt_complete(req, err);
55 }
56 
57 static void seqiv_aead_complete2(struct aead_givcrypt_request *req, int err)
58 {
59 	struct aead_request *subreq = aead_givcrypt_reqctx(req);
60 	struct crypto_aead *geniv;
61 
62 	if (err == -EINPROGRESS)
63 		return;
64 
65 	if (err)
66 		goto out;
67 
68 	geniv = aead_givcrypt_reqtfm(req);
69 	memcpy(req->areq.iv, subreq->iv, crypto_aead_ivsize(geniv));
70 
71 out:
72 	kfree(subreq->iv);
73 }
74 
75 static void seqiv_aead_complete(struct crypto_async_request *base, int err)
76 {
77 	struct aead_givcrypt_request *req = base->data;
78 
79 	seqiv_aead_complete2(req, err);
80 	aead_givcrypt_complete(req, err);
81 }
82 
83 static void seqiv_geniv(struct seqiv_ctx *ctx, u8 *info, u64 seq,
84 			unsigned int ivsize)
85 {
86 	unsigned int len = ivsize;
87 
88 	if (ivsize > sizeof(u64)) {
89 		memset(info, 0, ivsize - sizeof(u64));
90 		len = sizeof(u64);
91 	}
92 	seq = cpu_to_be64(seq);
93 	memcpy(info + ivsize - len, &seq, len);
94 	crypto_xor(info, ctx->salt, ivsize);
95 }
96 
97 static int seqiv_givencrypt(struct skcipher_givcrypt_request *req)
98 {
99 	struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
100 	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
101 	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
102 	crypto_completion_t complete;
103 	void *data;
104 	u8 *info;
105 	unsigned int ivsize;
106 	int err;
107 
108 	ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
109 
110 	complete = req->creq.base.complete;
111 	data = req->creq.base.data;
112 	info = req->creq.info;
113 
114 	ivsize = crypto_ablkcipher_ivsize(geniv);
115 
116 	if (unlikely(!IS_ALIGNED((unsigned long)info,
117 				 crypto_ablkcipher_alignmask(geniv) + 1))) {
118 		info = kmalloc(ivsize, req->creq.base.flags &
119 				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
120 								  GFP_ATOMIC);
121 		if (!info)
122 			return -ENOMEM;
123 
124 		complete = seqiv_complete;
125 		data = req;
126 	}
127 
128 	ablkcipher_request_set_callback(subreq, req->creq.base.flags, complete,
129 					data);
130 	ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
131 				     req->creq.nbytes, info);
132 
133 	seqiv_geniv(ctx, info, req->seq, ivsize);
134 	memcpy(req->giv, info, ivsize);
135 
136 	err = crypto_ablkcipher_encrypt(subreq);
137 	if (unlikely(info != req->creq.info))
138 		seqiv_complete2(req, err);
139 	return err;
140 }
141 
142 static int seqiv_aead_givencrypt(struct aead_givcrypt_request *req)
143 {
144 	struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
145 	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
146 	struct aead_request *areq = &req->areq;
147 	struct aead_request *subreq = aead_givcrypt_reqctx(req);
148 	crypto_completion_t complete;
149 	void *data;
150 	u8 *info;
151 	unsigned int ivsize;
152 	int err;
153 
154 	aead_request_set_tfm(subreq, aead_geniv_base(geniv));
155 
156 	complete = areq->base.complete;
157 	data = areq->base.data;
158 	info = areq->iv;
159 
160 	ivsize = crypto_aead_ivsize(geniv);
161 
162 	if (unlikely(!IS_ALIGNED((unsigned long)info,
163 				 crypto_aead_alignmask(geniv) + 1))) {
164 		info = kmalloc(ivsize, areq->base.flags &
165 				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
166 								  GFP_ATOMIC);
167 		if (!info)
168 			return -ENOMEM;
169 
170 		complete = seqiv_aead_complete;
171 		data = req;
172 	}
173 
174 	aead_request_set_callback(subreq, areq->base.flags, complete, data);
175 	aead_request_set_crypt(subreq, areq->src, areq->dst, areq->cryptlen,
176 			       info);
177 	aead_request_set_assoc(subreq, areq->assoc, areq->assoclen);
178 
179 	seqiv_geniv(ctx, info, req->seq, ivsize);
180 	memcpy(req->giv, info, ivsize);
181 
182 	err = crypto_aead_encrypt(subreq);
183 	if (unlikely(info != areq->iv))
184 		seqiv_aead_complete2(req, err);
185 	return err;
186 }
187 
188 static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
189 {
190 	struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
191 	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
192 
193 	spin_lock_bh(&ctx->lock);
194 	if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first)
195 		goto unlock;
196 
197 	crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
198 	get_random_bytes(ctx->salt, crypto_ablkcipher_ivsize(geniv));
199 
200 unlock:
201 	spin_unlock_bh(&ctx->lock);
202 
203 	return seqiv_givencrypt(req);
204 }
205 
206 static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req)
207 {
208 	struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
209 	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
210 
211 	spin_lock_bh(&ctx->lock);
212 	if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first)
213 		goto unlock;
214 
215 	crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt;
216 	get_random_bytes(ctx->salt, crypto_aead_ivsize(geniv));
217 
218 unlock:
219 	spin_unlock_bh(&ctx->lock);
220 
221 	return seqiv_aead_givencrypt(req);
222 }
223 
224 static int seqiv_init(struct crypto_tfm *tfm)
225 {
226 	struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
227 	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
228 
229 	spin_lock_init(&ctx->lock);
230 
231 	tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);
232 
233 	return skcipher_geniv_init(tfm);
234 }
235 
236 static int seqiv_aead_init(struct crypto_tfm *tfm)
237 {
238 	struct crypto_aead *geniv = __crypto_aead_cast(tfm);
239 	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
240 
241 	spin_lock_init(&ctx->lock);
242 
243 	tfm->crt_aead.reqsize = sizeof(struct aead_request);
244 
245 	return aead_geniv_init(tfm);
246 }
247 
248 static struct crypto_template seqiv_tmpl;
249 
250 static struct crypto_instance *seqiv_ablkcipher_alloc(struct rtattr **tb)
251 {
252 	struct crypto_instance *inst;
253 
254 	inst = skcipher_geniv_alloc(&seqiv_tmpl, tb, 0, 0);
255 
256 	if (IS_ERR(inst))
257 		goto out;
258 
259 	inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt_first;
260 
261 	inst->alg.cra_init = seqiv_init;
262 	inst->alg.cra_exit = skcipher_geniv_exit;
263 
264 	inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
265 
266 out:
267 	return inst;
268 }
269 
270 static struct crypto_instance *seqiv_aead_alloc(struct rtattr **tb)
271 {
272 	struct crypto_instance *inst;
273 
274 	inst = aead_geniv_alloc(&seqiv_tmpl, tb, 0, 0);
275 
276 	if (IS_ERR(inst))
277 		goto out;
278 
279 	inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt_first;
280 
281 	inst->alg.cra_init = seqiv_aead_init;
282 	inst->alg.cra_exit = aead_geniv_exit;
283 
284 	inst->alg.cra_ctxsize = inst->alg.cra_aead.ivsize;
285 
286 out:
287 	return inst;
288 }
289 
290 static struct crypto_instance *seqiv_alloc(struct rtattr **tb)
291 {
292 	struct crypto_attr_type *algt;
293 	struct crypto_instance *inst;
294 	int err;
295 
296 	algt = crypto_get_attr_type(tb);
297 	err = PTR_ERR(algt);
298 	if (IS_ERR(algt))
299 		return ERR_PTR(err);
300 
301 	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
302 		inst = seqiv_ablkcipher_alloc(tb);
303 	else
304 		inst = seqiv_aead_alloc(tb);
305 
306 	if (IS_ERR(inst))
307 		goto out;
308 
309 	inst->alg.cra_alignmask |= __alignof__(u32) - 1;
310 	inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);
311 
312 out:
313 	return inst;
314 }
315 
316 static void seqiv_free(struct crypto_instance *inst)
317 {
318 	if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
319 		skcipher_geniv_free(inst);
320 	else
321 		aead_geniv_free(inst);
322 }
323 
324 static struct crypto_template seqiv_tmpl = {
325 	.name = "seqiv",
326 	.alloc = seqiv_alloc,
327 	.free = seqiv_free,
328 	.module = THIS_MODULE,
329 };
330 
331 static int __init seqiv_module_init(void)
332 {
333 	return crypto_register_template(&seqiv_tmpl);
334 }
335 
336 static void __exit seqiv_module_exit(void)
337 {
338 	crypto_unregister_template(&seqiv_tmpl);
339 }
340 
341 module_init(seqiv_module_init);
342 module_exit(seqiv_module_exit);
343 
344 MODULE_LICENSE("GPL");
345 MODULE_DESCRIPTION("Sequence Number IV Generator");
346