Blame view

crypto/rsa-pkcs1pad.c 17.3 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
2
3
4
5
  /*
   * RSA padding templates.
   *
   * Copyright (c) 2015  Intel Corporation
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
6
7
8
9
10
   */
  
  #include <crypto/algapi.h>
  #include <crypto/akcipher.h>
  #include <crypto/internal/akcipher.h>
a1180cffe   Eric Biggers   crypto: rsa-pkcs1...
11
  #include <crypto/internal/rsa.h>
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
12
13
14
15
16
  #include <linux/err.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/random.h>
0c3dc787a   Herbert Xu   crypto: algapi - ...
17
  #include <linux/scatterlist.h>
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
18

a49de377e   Tadeusz Struk   crypto: Add hash ...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  /*
   * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
   */
  static const u8 rsa_digest_info_md5[] = {
  	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
  	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
  	0x05, 0x00, 0x04, 0x10
  };
  
  static const u8 rsa_digest_info_sha1[] = {
  	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
  	0x2b, 0x0e, 0x03, 0x02, 0x1a,
  	0x05, 0x00, 0x04, 0x14
  };
  
  static const u8 rsa_digest_info_rmd160[] = {
  	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
  	0x2b, 0x24, 0x03, 0x02, 0x01,
  	0x05, 0x00, 0x04, 0x14
  };
  
  static const u8 rsa_digest_info_sha224[] = {
  	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
  	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
  	0x05, 0x00, 0x04, 0x1c
  };
  
  static const u8 rsa_digest_info_sha256[] = {
  	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
  	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
  	0x05, 0x00, 0x04, 0x20
  };
  
  static const u8 rsa_digest_info_sha384[] = {
  	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
  	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
  	0x05, 0x00, 0x04, 0x30
  };
  
  static const u8 rsa_digest_info_sha512[] = {
  	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
  	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
  	0x05, 0x00, 0x04, 0x40
  };
  
  static const struct rsa_asn1_template {
  	const char	*name;
  	const u8	*data;
  	size_t		size;
  } rsa_asn1_templates[] = {
  #define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
  	_(md5),
  	_(sha1),
  	_(rmd160),
  	_(sha256),
  	_(sha384),
  	_(sha512),
  	_(sha224),
  	{ NULL }
  #undef _
  };
  
  static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name)
  {
  	const struct rsa_asn1_template *p;
  
  	for (p = rsa_asn1_templates; p->name; p++)
  		if (strcmp(name, p->name) == 0)
  			return p;
  	return NULL;
  }
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
90
91
  struct pkcs1pad_ctx {
  	struct crypto_akcipher *child;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
92
93
  	unsigned int key_size;
  };
a49de377e   Tadeusz Struk   crypto: Add hash ...
94
95
  struct pkcs1pad_inst_ctx {
  	struct crypto_akcipher_spawn spawn;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
96
  	const struct rsa_asn1_template *digest_info;
a49de377e   Tadeusz Struk   crypto: Add hash ...
97
  };
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
98
  struct pkcs1pad_request {
0f2c83190   Herbert Xu   crypto: rsa-pkcs1...
99
  	struct scatterlist in_sg[2], out_sg[1];
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
100
  	uint8_t *in_buf, *out_buf;
a6d7bfd0f   Tadeusz Struk   crypto: rsa-pkcs1...
101
  	struct akcipher_request child_req;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
102
103
104
105
106
107
  };
  
  static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
  		unsigned int keylen)
  {
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
108
109
110
  	int err;
  
  	ctx->key_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
111
112
  
  	err = crypto_akcipher_set_pub_key(ctx->child, key, keylen);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
113
114
  	if (err)
  		return err;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
115

73f791896   Herbert Xu   crypto: rsa-pkcs1...
116
117
  	/* Find out new modulus size from rsa implementation */
  	err = crypto_akcipher_maxsize(ctx->child);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
118
119
  	if (err > PAGE_SIZE)
  		return -ENOTSUPP;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
120

73f791896   Herbert Xu   crypto: rsa-pkcs1...
121
122
  	ctx->key_size = err;
  	return 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
123
124
125
126
127
128
  }
  
  static int pkcs1pad_set_priv_key(struct crypto_akcipher *tfm, const void *key,
  		unsigned int keylen)
  {
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
129
130
131
  	int err;
  
  	ctx->key_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
132
133
  
  	err = crypto_akcipher_set_priv_key(ctx->child, key, keylen);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
134
135
  	if (err)
  		return err;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
136

73f791896   Herbert Xu   crypto: rsa-pkcs1...
137
138
  	/* Find out new modulus size from rsa implementation */
  	err = crypto_akcipher_maxsize(ctx->child);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
139
140
  	if (err > PAGE_SIZE)
  		return -ENOTSUPP;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
141

73f791896   Herbert Xu   crypto: rsa-pkcs1...
142
143
  	ctx->key_size = err;
  	return 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
144
  }
543de102e   Tudor-Dan Ambarus   crypto: pkcs1pad ...
145
  static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
146
147
148
149
150
151
152
153
  {
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  
  	/*
  	 * The maximum destination buffer size for the encrypt/sign operations
  	 * will be the same as for RSA, even though it's smaller for
  	 * decrypt/verify.
  	 */
543de102e   Tudor-Dan Ambarus   crypto: pkcs1pad ...
154
  	return ctx->key_size;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
155
156
157
158
159
  }
  
  static void pkcs1pad_sg_set_buf(struct scatterlist *sg, void *buf, size_t len,
  		struct scatterlist *next)
  {
0f2c83190   Herbert Xu   crypto: rsa-pkcs1...
160
161
162
163
  	int nsegs = next ? 2 : 1;
  
  	sg_init_table(sg, nsegs);
  	sg_set_buf(sg, buf, len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
164
165
166
167
168
169
170
171
172
173
  
  	if (next)
  		sg_chain(sg, nsegs, next);
  }
  
  static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
174
175
176
177
178
179
180
181
182
183
184
185
186
  	unsigned int pad_len;
  	unsigned int len;
  	u8 *out_buf;
  
  	if (err)
  		goto out;
  
  	len = req_ctx->child_req.dst_len;
  	pad_len = ctx->key_size - len;
  
  	/* Four billion to one */
  	if (likely(!pad_len))
  		goto out;
1ca280989   Jia-Ju Bai   crypto: rsa-pkcs1...
187
  	out_buf = kzalloc(ctx->key_size, GFP_KERNEL);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
188
189
190
191
192
193
194
195
196
  	err = -ENOMEM;
  	if (!out_buf)
  		goto out;
  
  	sg_copy_to_buffer(req->dst, sg_nents_for_len(req->dst, len),
  			  out_buf + pad_len, len);
  	sg_copy_from_buffer(req->dst,
  			    sg_nents_for_len(req->dst, ctx->key_size),
  			    out_buf, ctx->key_size);
453431a54   Waiman Long   mm, treewide: ren...
197
  	kfree_sensitive(out_buf);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
198
199
  
  out:
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
200
201
202
  	req->dst_len = ctx->key_size;
  
  	kfree(req_ctx->in_buf);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  
  	return err;
  }
  
  static void pkcs1pad_encrypt_sign_complete_cb(
  		struct crypto_async_request *child_async_req, int err)
  {
  	struct akcipher_request *req = child_async_req->data;
  	struct crypto_async_request async_req;
  
  	if (err == -EINPROGRESS)
  		return;
  
  	async_req.data = req->base.data;
  	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
  	async_req.flags = child_async_req->flags;
  	req->base.complete(&async_req,
  			pkcs1pad_encrypt_sign_complete(req, err));
  }
  
  static int pkcs1pad_encrypt(struct akcipher_request *req)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
  	int err;
  	unsigned int i, ps_end;
  
  	if (!ctx->key_size)
  		return -EINVAL;
  
  	if (req->src_len > ctx->key_size - 11)
  		return -EOVERFLOW;
  
  	if (req->dst_len < ctx->key_size) {
  		req->dst_len = ctx->key_size;
  		return -EOVERFLOW;
  	}
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
241
  	req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len,
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
242
  				  GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
243
244
245
246
247
248
249
250
251
252
253
  	if (!req_ctx->in_buf)
  		return -ENOMEM;
  
  	ps_end = ctx->key_size - req->src_len - 2;
  	req_ctx->in_buf[0] = 0x02;
  	for (i = 1; i < ps_end; i++)
  		req_ctx->in_buf[i] = 1 + prandom_u32_max(255);
  	req_ctx->in_buf[ps_end] = 0x00;
  
  	pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
  			ctx->key_size - 1 - req->src_len, req->src);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
254
255
256
  	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
  	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
  			pkcs1pad_encrypt_sign_complete_cb, req);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
257
258
259
  	/* Reuse output buffer */
  	akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
  				   req->dst, ctx->key_size - 1, req->dst_len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
260
  	err = crypto_akcipher_encrypt(&req_ctx->child_req);
4e5b0ad58   Gilad Ben-Yossef   crypto: remove re...
261
  	if (err != -EINPROGRESS && err != -EBUSY)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
262
263
264
265
266
267
268
269
270
271
  		return pkcs1pad_encrypt_sign_complete(req, err);
  
  	return err;
  }
  
  static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
272
  	unsigned int dst_len;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
273
  	unsigned int pos;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
274
  	u8 *out_buf;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
275
276
277
  
  	if (err)
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
278
279
280
  	err = -EINVAL;
  	dst_len = req_ctx->child_req.dst_len;
  	if (dst_len < ctx->key_size - 1)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
281
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
282
283
284
285
286
287
288
289
290
  
  	out_buf = req_ctx->out_buf;
  	if (dst_len == ctx->key_size) {
  		if (out_buf[0] != 0x00)
  			/* Decrypted value had no leading 0 byte */
  			goto done;
  
  		dst_len--;
  		out_buf++;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
291
  	}
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
292
  	if (out_buf[0] != 0x02)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
293
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
294
295
296
  
  	for (pos = 1; pos < dst_len; pos++)
  		if (out_buf[pos] == 0x00)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
297
  			break;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
298
  	if (pos < 9 || pos == dst_len)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
299
  		goto done;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
300
  	pos++;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
301
302
303
  	err = 0;
  
  	if (req->dst_len < dst_len - pos)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
304
  		err = -EOVERFLOW;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
305
  	req->dst_len = dst_len - pos;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
306
307
308
309
  
  	if (!err)
  		sg_copy_from_buffer(req->dst,
  				sg_nents_for_len(req->dst, req->dst_len),
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
310
  				out_buf + pos, req->dst_len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
311
312
  
  done:
453431a54   Waiman Long   mm, treewide: ren...
313
  	kfree_sensitive(req_ctx->out_buf);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  
  	return err;
  }
  
  static void pkcs1pad_decrypt_complete_cb(
  		struct crypto_async_request *child_async_req, int err)
  {
  	struct akcipher_request *req = child_async_req->data;
  	struct crypto_async_request async_req;
  
  	if (err == -EINPROGRESS)
  		return;
  
  	async_req.data = req->base.data;
  	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
  	async_req.flags = child_async_req->flags;
  	req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err));
  }
  
  static int pkcs1pad_decrypt(struct akcipher_request *req)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
  	int err;
  
  	if (!ctx->key_size || req->src_len != ctx->key_size)
  		return -EINVAL;
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
342
  	req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
343
344
345
346
  	if (!req_ctx->out_buf)
  		return -ENOMEM;
  
  	pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
6f0904ada   Tadeusz Struk   crypto: rsa-pkcs1...
347
  			    ctx->key_size, NULL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
348
349
350
351
  
  	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
  	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
  			pkcs1pad_decrypt_complete_cb, req);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
352
353
354
355
  	/* Reuse input buffer, output to a new buffer */
  	akcipher_request_set_crypt(&req_ctx->child_req, req->src,
  				   req_ctx->out_sg, req->src_len,
  				   ctx->key_size);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
356
  	err = crypto_akcipher_decrypt(&req_ctx->child_req);
4e5b0ad58   Gilad Ben-Yossef   crypto: remove re...
357
  	if (err != -EINPROGRESS && err != -EBUSY)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
358
359
360
361
362
363
364
365
366
367
  		return pkcs1pad_decrypt_complete(req, err);
  
  	return err;
  }
  
  static int pkcs1pad_sign(struct akcipher_request *req)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
368
369
370
  	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
  	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
  	const struct rsa_asn1_template *digest_info = ictx->digest_info;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
371
  	int err;
a49de377e   Tadeusz Struk   crypto: Add hash ...
372
  	unsigned int ps_end, digest_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
373
374
375
  
  	if (!ctx->key_size)
  		return -EINVAL;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
376
377
  	if (digest_info)
  		digest_size = digest_info->size;
a49de377e   Tadeusz Struk   crypto: Add hash ...
378
379
  
  	if (req->src_len + digest_size > ctx->key_size - 11)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
380
381
382
383
384
385
  		return -EOVERFLOW;
  
  	if (req->dst_len < ctx->key_size) {
  		req->dst_len = ctx->key_size;
  		return -EOVERFLOW;
  	}
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
386
  	req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len,
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
387
  				  GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
388
389
  	if (!req_ctx->in_buf)
  		return -ENOMEM;
a49de377e   Tadeusz Struk   crypto: Add hash ...
390
  	ps_end = ctx->key_size - digest_size - req->src_len - 2;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
391
392
393
  	req_ctx->in_buf[0] = 0x01;
  	memset(req_ctx->in_buf + 1, 0xff, ps_end - 1);
  	req_ctx->in_buf[ps_end] = 0x00;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
394
395
396
  	if (digest_info)
  		memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
  		       digest_info->size);
a49de377e   Tadeusz Struk   crypto: Add hash ...
397

3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
398
399
  	pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf,
  			ctx->key_size - 1 - req->src_len, req->src);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
400
401
402
  	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
  	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
  			pkcs1pad_encrypt_sign_complete_cb, req);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
403
404
405
  	/* Reuse output buffer */
  	akcipher_request_set_crypt(&req_ctx->child_req, req_ctx->in_sg,
  				   req->dst, ctx->key_size - 1, req->dst_len);
3ecc97259   Vitaly Chikunov   crypto: rsa - uni...
406
  	err = crypto_akcipher_decrypt(&req_ctx->child_req);
4e5b0ad58   Gilad Ben-Yossef   crypto: remove re...
407
  	if (err != -EINPROGRESS && err != -EBUSY)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
408
409
410
411
412
413
414
415
416
417
  		return pkcs1pad_encrypt_sign_complete(req, err);
  
  	return err;
  }
  
  static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
418
419
420
  	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
  	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
  	const struct rsa_asn1_template *digest_info = ictx->digest_info;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
421
  	unsigned int dst_len;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
422
  	unsigned int pos;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
423
  	u8 *out_buf;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
424
425
426
  
  	if (err)
  		goto done;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
427
428
429
  	err = -EINVAL;
  	dst_len = req_ctx->child_req.dst_len;
  	if (dst_len < ctx->key_size - 1)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
430
  		goto done;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
431
432
433
434
435
436
437
438
439
  
  	out_buf = req_ctx->out_buf;
  	if (dst_len == ctx->key_size) {
  		if (out_buf[0] != 0x00)
  			/* Decrypted value had no leading 0 byte */
  			goto done;
  
  		dst_len--;
  		out_buf++;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
440
  	}
a49de377e   Tadeusz Struk   crypto: Add hash ...
441
  	err = -EBADMSG;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
442
  	if (out_buf[0] != 0x01)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
443
  		goto done;
a49de377e   Tadeusz Struk   crypto: Add hash ...
444

27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
445
446
  	for (pos = 1; pos < dst_len; pos++)
  		if (out_buf[pos] != 0xff)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
447
  			break;
a49de377e   Tadeusz Struk   crypto: Add hash ...
448

27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
449
  	if (pos < 9 || pos == dst_len || out_buf[pos] != 0x00)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
450
  		goto done;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
451
  	pos++;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
452
453
454
455
  	if (digest_info) {
  		if (crypto_memneq(out_buf + pos, digest_info->data,
  				  digest_info->size))
  			goto done;
a49de377e   Tadeusz Struk   crypto: Add hash ...
456

b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
457
458
  		pos += digest_info->size;
  	}
a49de377e   Tadeusz Struk   crypto: Add hash ...
459
460
  
  	err = 0;
c7381b012   Vitaly Chikunov   crypto: akcipher ...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  	if (req->dst_len != dst_len - pos) {
  		err = -EKEYREJECTED;
  		req->dst_len = dst_len - pos;
  		goto done;
  	}
  	/* Extract appended digest. */
  	sg_pcopy_to_buffer(req->src,
  			   sg_nents_for_len(req->src,
  					    req->src_len + req->dst_len),
  			   req_ctx->out_buf + ctx->key_size,
  			   req->dst_len, ctx->key_size);
  	/* Do the actual verification step. */
  	if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos,
  		   req->dst_len) != 0)
  		err = -EKEYREJECTED;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
476
  done:
453431a54   Waiman Long   mm, treewide: ren...
477
  	kfree_sensitive(req_ctx->out_buf);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  
  	return err;
  }
  
  static void pkcs1pad_verify_complete_cb(
  		struct crypto_async_request *child_async_req, int err)
  {
  	struct akcipher_request *req = child_async_req->data;
  	struct crypto_async_request async_req;
  
  	if (err == -EINPROGRESS)
  		return;
  
  	async_req.data = req->base.data;
  	async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req));
  	async_req.flags = child_async_req->flags;
  	req->base.complete(&async_req, pkcs1pad_verify_complete(req, err));
  }
  
  /*
   * The verify operation is here for completeness similar to the verification
   * defined in RFC2313 section 10.2 except that block type 0 is not accepted,
   * as in RFC2437.  RFC2437 section 9.2 doesn't define any operation to
   * retrieve the DigestInfo from a signature, instead the user is expected
   * to call the sign operation to generate the expected signature and compare
   * signatures instead of the message-digests.
   */
  static int pkcs1pad_verify(struct akcipher_request *req)
  {
  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
  	int err;
c7381b012   Vitaly Chikunov   crypto: akcipher ...
511
512
513
  	if (WARN_ON(req->dst) ||
  	    WARN_ON(!req->dst_len) ||
  	    !ctx->key_size || req->src_len < ctx->key_size)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
514
  		return -EINVAL;
c7381b012   Vitaly Chikunov   crypto: akcipher ...
515
  	req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
516
517
518
519
  	if (!req_ctx->out_buf)
  		return -ENOMEM;
  
  	pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
6f0904ada   Tadeusz Struk   crypto: rsa-pkcs1...
520
  			    ctx->key_size, NULL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
521
522
523
524
  
  	akcipher_request_set_tfm(&req_ctx->child_req, ctx->child);
  	akcipher_request_set_callback(&req_ctx->child_req, req->base.flags,
  			pkcs1pad_verify_complete_cb, req);
d858b0713   Herbert Xu   crypto: rsa-pkcs1...
525
526
527
528
  	/* Reuse input buffer, output to a new buffer */
  	akcipher_request_set_crypt(&req_ctx->child_req, req->src,
  				   req_ctx->out_sg, req->src_len,
  				   ctx->key_size);
3ecc97259   Vitaly Chikunov   crypto: rsa - uni...
529
  	err = crypto_akcipher_encrypt(&req_ctx->child_req);
4e5b0ad58   Gilad Ben-Yossef   crypto: remove re...
530
  	if (err != -EINPROGRESS && err != -EBUSY)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
531
532
533
534
535
536
537
538
  		return pkcs1pad_verify_complete(req, err);
  
  	return err;
  }
  
  static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm)
  {
  	struct akcipher_instance *inst = akcipher_alg_instance(tfm);
a49de377e   Tadeusz Struk   crypto: Add hash ...
539
  	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
540
541
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct crypto_akcipher *child_tfm;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
542
  	child_tfm = crypto_spawn_akcipher(&ictx->spawn);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
543
544
545
546
  	if (IS_ERR(child_tfm))
  		return PTR_ERR(child_tfm);
  
  	ctx->child = child_tfm;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
547
548
549
550
551
552
553
554
555
556
557
558
  	return 0;
  }
  
  static void pkcs1pad_exit_tfm(struct crypto_akcipher *tfm)
  {
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  
  	crypto_free_akcipher(ctx->child);
  }
  
  static void pkcs1pad_free(struct akcipher_instance *inst)
  {
a49de377e   Tadeusz Struk   crypto: Add hash ...
559
560
  	struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
  	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
561
562
  
  	crypto_drop_akcipher(spawn);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
563
564
565
566
567
  	kfree(inst);
  }
  
  static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
  {
73bed26f7   Eric Biggers   crypto: akcipher ...
568
  	u32 mask;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
569
  	struct akcipher_instance *inst;
a49de377e   Tadeusz Struk   crypto: Add hash ...
570
  	struct pkcs1pad_inst_ctx *ctx;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
571
  	struct akcipher_alg *rsa_alg;
a49de377e   Tadeusz Struk   crypto: Add hash ...
572
  	const char *hash_name;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
573
  	int err;
7bcb2c99f   Eric Biggers   crypto: algapi - ...
574
575
576
  	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
  	if (err)
  		return err;
73bed26f7   Eric Biggers   crypto: akcipher ...
577

a49de377e   Tadeusz Struk   crypto: Add hash ...
578
  	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
579
580
  	if (!inst)
  		return -ENOMEM;
a49de377e   Tadeusz Struk   crypto: Add hash ...
581
  	ctx = akcipher_instance_ctx(inst);
a49de377e   Tadeusz Struk   crypto: Add hash ...
582

0708bb435   Eric Biggers   crypto: rsa-pkcs1...
583
584
  	err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
  				   crypto_attr_alg_name(tb[1]), 0, mask);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
585
  	if (err)
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
586
  		goto err_free_inst;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
587

0708bb435   Eric Biggers   crypto: rsa-pkcs1...
588
  	rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
589
590
  
  	err = -ENAMETOOLONG;
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
591
592
  	hash_name = crypto_attr_alg_name(tb[2]);
  	if (IS_ERR(hash_name)) {
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
593
594
595
  		if (snprintf(inst->alg.base.cra_name,
  			     CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
  			     rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
596
  			goto err_free_inst;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
597
598
599
600
601
  
  		if (snprintf(inst->alg.base.cra_driver_name,
  			     CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
  			     rsa_alg->base.cra_driver_name) >=
  			     CRYPTO_MAX_ALG_NAME)
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
602
  			goto err_free_inst;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
603
  	} else {
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
604
605
606
607
608
  		ctx->digest_info = rsa_lookup_asn1(hash_name);
  		if (!ctx->digest_info) {
  			err = -EINVAL;
  			goto err_free_inst;
  		}
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
609
610
611
  		if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
  			     "pkcs1pad(%s,%s)", rsa_alg->base.cra_name,
  			     hash_name) >= CRYPTO_MAX_ALG_NAME)
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
612
  			goto err_free_inst;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
613
614
615
616
617
  
  		if (snprintf(inst->alg.base.cra_driver_name,
  			     CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)",
  			     rsa_alg->base.cra_driver_name,
  			     hash_name) >= CRYPTO_MAX_ALG_NAME)
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
618
  			goto err_free_inst;
b3a8c8a5e   Denis Kenzior   crypto: rsa-pkcs1...
619
  	}
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
620

3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
  	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
  	inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
  
  	inst->alg.init = pkcs1pad_init_tfm;
  	inst->alg.exit = pkcs1pad_exit_tfm;
  
  	inst->alg.encrypt = pkcs1pad_encrypt;
  	inst->alg.decrypt = pkcs1pad_decrypt;
  	inst->alg.sign = pkcs1pad_sign;
  	inst->alg.verify = pkcs1pad_verify;
  	inst->alg.set_pub_key = pkcs1pad_set_pub_key;
  	inst->alg.set_priv_key = pkcs1pad_set_priv_key;
  	inst->alg.max_size = pkcs1pad_get_max_size;
  	inst->alg.reqsize = sizeof(struct pkcs1pad_request) + rsa_alg->reqsize;
  
  	inst->free = pkcs1pad_free;
  
  	err = akcipher_register_instance(tmpl, inst);
0708bb435   Eric Biggers   crypto: rsa-pkcs1...
639
640
641
642
  	if (err) {
  err_free_inst:
  		pkcs1pad_free(inst);
  	}
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
643
644
645
646
647
648
649
650
  	return err;
  }
  
  struct crypto_template rsa_pkcs1pad_tmpl = {
  	.name = "pkcs1pad",
  	.create = pkcs1pad_create,
  	.module = THIS_MODULE,
  };