Blame view

crypto/rsa-pkcs1pad.c 17.5 KB
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * RSA padding templates.
   *
   * Copyright (c) 2015  Intel Corporation
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 2 of the License, or (at your option)
   * any later version.
   */
  
  #include <crypto/algapi.h>
  #include <crypto/akcipher.h>
  #include <crypto/internal/akcipher.h>
  #include <linux/err.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/random.h>
a49de377e   Tadeusz Struk   crypto: Add hash ...
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
90
  /*
   * 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...
91
92
  struct pkcs1pad_ctx {
  	struct crypto_akcipher *child;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
93
94
  	unsigned int key_size;
  };
a49de377e   Tadeusz Struk   crypto: Add hash ...
95
96
  struct pkcs1pad_inst_ctx {
  	struct crypto_akcipher_spawn spawn;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
97
  	const struct rsa_asn1_template *digest_info;
a49de377e   Tadeusz Struk   crypto: Add hash ...
98
  };
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
99
  struct pkcs1pad_request {
0f2c83190   Herbert Xu   crypto: rsa-pkcs1...
100
  	struct scatterlist in_sg[2], out_sg[1];
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
101
  	uint8_t *in_buf, *out_buf;
a6d7bfd0f   Tadeusz Struk   crypto: rsa-pkcs1...
102
  	struct akcipher_request child_req;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
103
104
105
106
107
108
  };
  
  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...
109
110
111
  	int err;
  
  	ctx->key_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
112
113
  
  	err = crypto_akcipher_set_pub_key(ctx->child, key, keylen);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
114
115
  	if (err)
  		return err;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
116

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

73f791896   Herbert Xu   crypto: rsa-pkcs1...
122
123
  	ctx->key_size = err;
  	return 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
124
125
126
127
128
129
  }
  
  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...
130
131
132
  	int err;
  
  	ctx->key_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
133
134
  
  	err = crypto_akcipher_set_priv_key(ctx->child, key, keylen);
73f791896   Herbert Xu   crypto: rsa-pkcs1...
135
136
  	if (err)
  		return err;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
137

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

73f791896   Herbert Xu   crypto: rsa-pkcs1...
143
144
  	ctx->key_size = err;
  	return 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
145
  }
543de102e   Tudor-Dan Ambarus   crypto: pkcs1pad ...
146
  static unsigned int pkcs1pad_get_max_size(struct crypto_akcipher *tfm)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
147
148
149
150
151
152
153
154
  {
  	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 ...
155
  	return ctx->key_size;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
156
157
158
159
160
  }
  
  static void pkcs1pad_sg_set_buf(struct scatterlist *sg, void *buf, size_t len,
  		struct scatterlist *next)
  {
0f2c83190   Herbert Xu   crypto: rsa-pkcs1...
161
162
163
164
  	int nsegs = next ? 2 : 1;
  
  	sg_init_table(sg, nsegs);
  	sg_set_buf(sg, buf, len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
165
166
167
168
169
170
171
172
173
174
  
  	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...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  	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;
  
  	out_buf = kzalloc(ctx->key_size, GFP_ATOMIC);
  	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);
  	kzfree(out_buf);
  
  out:
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
202
203
204
  	req->dst_len = ctx->key_size;
  
  	kfree(req_ctx->in_buf);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
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
241
242
  
  	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...
243
  	req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len,
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
244
  				  GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
245
246
247
248
249
250
251
252
253
254
255
  	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);
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
256
  	req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
257
258
259
260
261
262
263
264
265
266
267
  	if (!req_ctx->out_buf) {
  		kfree(req_ctx->in_buf);
  		return -ENOMEM;
  	}
  
  	pkcs1pad_sg_set_buf(req_ctx->out_sg, req_ctx->out_buf,
  			ctx->key_size, NULL);
  
  	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...
268
269
270
  	/* 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...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  	err = crypto_akcipher_encrypt(&req_ctx->child_req);
  	if (err != -EINPROGRESS &&
  			(err != -EBUSY ||
  			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
  		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...
285
  	unsigned int dst_len;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
286
  	unsigned int pos;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
287
  	u8 *out_buf;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
288
289
290
  
  	if (err)
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
291
292
293
  	err = -EINVAL;
  	dst_len = req_ctx->child_req.dst_len;
  	if (dst_len < ctx->key_size - 1)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
294
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
295
296
297
298
299
300
301
302
303
  
  	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...
304
  	}
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
305
  	if (out_buf[0] != 0x02)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
306
  		goto done;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
307
308
309
  
  	for (pos = 1; pos < dst_len; pos++)
  		if (out_buf[pos] == 0x00)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
310
  			break;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
311
  	if (pos < 9 || pos == dst_len)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
312
  		goto done;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
313
  	pos++;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
314
315
316
  	err = 0;
  
  	if (req->dst_len < dst_len - pos)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
317
  		err = -EOVERFLOW;
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
318
  	req->dst_len = dst_len - pos;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
319
320
321
322
  
  	if (!err)
  		sg_copy_from_buffer(req->dst,
  				sg_nents_for_len(req->dst, req->dst_len),
0cf43f509   Herbert Xu   crypto: rsa-pkcs1...
323
  				out_buf + pos, req->dst_len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  
  done:
  	kzfree(req_ctx->out_buf);
  
  	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...
355
  	req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
356
357
358
359
  	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...
360
  			    ctx->key_size, NULL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
361
362
363
364
  
  	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...
365
366
367
368
  	/* 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...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
  	err = crypto_akcipher_decrypt(&req_ctx->child_req);
  	if (err != -EINPROGRESS &&
  			(err != -EBUSY ||
  			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
  		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...
383
384
385
  	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...
386
  	int err;
a49de377e   Tadeusz Struk   crypto: Add hash ...
387
  	unsigned int ps_end, digest_size = 0;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
388
389
390
  
  	if (!ctx->key_size)
  		return -EINVAL;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
391
  	digest_size = digest_info->size;
a49de377e   Tadeusz Struk   crypto: Add hash ...
392
393
  
  	if (req->src_len + digest_size > ctx->key_size - 11)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
394
395
396
397
398
399
  		return -EOVERFLOW;
  
  	if (req->dst_len < ctx->key_size) {
  		req->dst_len = ctx->key_size;
  		return -EOVERFLOW;
  	}
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
400
  	req_ctx->in_buf = kmalloc(ctx->key_size - 1 - req->src_len,
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
401
  				  GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
402
403
  	if (!req_ctx->in_buf)
  		return -ENOMEM;
a49de377e   Tadeusz Struk   crypto: Add hash ...
404
  	ps_end = ctx->key_size - digest_size - req->src_len - 2;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
405
406
407
  	req_ctx->in_buf[0] = 0x01;
  	memset(req_ctx->in_buf + 1, 0xff, ps_end - 1);
  	req_ctx->in_buf[ps_end] = 0x00;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
408
409
  	memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data,
  	       digest_info->size);
a49de377e   Tadeusz Struk   crypto: Add hash ...
410

3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
411
412
  	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...
413
414
415
  	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...
416
417
418
  	/* 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...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
  	err = crypto_akcipher_sign(&req_ctx->child_req);
  	if (err != -EINPROGRESS &&
  			(err != -EBUSY ||
  			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
  		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...
433
434
435
  	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...
436
  	unsigned int dst_len;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
437
  	unsigned int pos;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
438
  	u8 *out_buf;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
439
440
441
  
  	if (err)
  		goto done;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
442
443
444
  	err = -EINVAL;
  	dst_len = req_ctx->child_req.dst_len;
  	if (dst_len < ctx->key_size - 1)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
445
  		goto done;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
446
447
448
449
450
451
452
453
454
  
  	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...
455
  	}
a49de377e   Tadeusz Struk   crypto: Add hash ...
456
  	err = -EBADMSG;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
457
  	if (out_buf[0] != 0x01)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
458
  		goto done;
a49de377e   Tadeusz Struk   crypto: Add hash ...
459

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

27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
464
  	if (pos < 9 || pos == dst_len || out_buf[pos] != 0x00)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
465
  		goto done;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
466
  	pos++;
fec17cb22   Jason A. Donenfeld   crypto: rsa-pkcs1...
467
  	if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size))
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
468
  		goto done;
a49de377e   Tadeusz Struk   crypto: Add hash ...
469

c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
470
  	pos += digest_info->size;
a49de377e   Tadeusz Struk   crypto: Add hash ...
471
472
  
  	err = 0;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
473
  	if (req->dst_len < dst_len - pos)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
474
  		err = -EOVERFLOW;
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
475
  	req->dst_len = dst_len - pos;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
476
477
478
479
  
  	if (!err)
  		sg_copy_from_buffer(req->dst,
  				sg_nents_for_len(req->dst, req->dst_len),
27710b8ea   Herbert Xu   crypto: rsa-pkcs1...
480
  				out_buf + pos, req->dst_len);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
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
511
512
513
514
515
  done:
  	kzfree(req_ctx->out_buf);
  
  	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;
a49de377e   Tadeusz Struk   crypto: Add hash ...
516
  	if (!ctx->key_size || req->src_len < ctx->key_size)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
517
  		return -EINVAL;
3a32ce507   Herbert Xu   crypto: rsa-pkcs1...
518
  	req_ctx->out_buf = kmalloc(ctx->key_size, GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
519
520
521
522
  	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...
523
  			    ctx->key_size, NULL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
524
525
526
527
  
  	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...
528
529
530
531
  	/* 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...
532
533
534
535
536
537
538
539
540
541
542
543
  	err = crypto_akcipher_verify(&req_ctx->child_req);
  	if (err != -EINPROGRESS &&
  			(err != -EBUSY ||
  			 !(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
  		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 ...
544
  	struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
545
546
  	struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
  	struct crypto_akcipher *child_tfm;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
547
  	child_tfm = crypto_spawn_akcipher(&ictx->spawn);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
548
549
550
551
  	if (IS_ERR(child_tfm))
  		return PTR_ERR(child_tfm);
  
  	ctx->child = child_tfm;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
552
553
554
555
556
557
558
559
560
561
562
563
  	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 ...
564
565
  	struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst);
  	struct crypto_akcipher_spawn *spawn = &ctx->spawn;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
566
567
  
  	crypto_drop_akcipher(spawn);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
568
569
570
571
572
  	kfree(inst);
  }
  
  static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
  {
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
573
  	const struct rsa_asn1_template *digest_info;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
574
575
  	struct crypto_attr_type *algt;
  	struct akcipher_instance *inst;
a49de377e   Tadeusz Struk   crypto: Add hash ...
576
  	struct pkcs1pad_inst_ctx *ctx;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
577
578
579
  	struct crypto_akcipher_spawn *spawn;
  	struct akcipher_alg *rsa_alg;
  	const char *rsa_alg_name;
a49de377e   Tadeusz Struk   crypto: Add hash ...
580
  	const char *hash_name;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
581
582
583
584
585
586
587
588
589
590
591
592
  	int err;
  
  	algt = crypto_get_attr_type(tb);
  	if (IS_ERR(algt))
  		return PTR_ERR(algt);
  
  	if ((algt->type ^ CRYPTO_ALG_TYPE_AKCIPHER) & algt->mask)
  		return -EINVAL;
  
  	rsa_alg_name = crypto_attr_alg_name(tb[1]);
  	if (IS_ERR(rsa_alg_name))
  		return PTR_ERR(rsa_alg_name);
a49de377e   Tadeusz Struk   crypto: Add hash ...
593
594
  	hash_name = crypto_attr_alg_name(tb[2]);
  	if (IS_ERR(hash_name))
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
595
596
597
598
599
  		return PTR_ERR(hash_name);
  
  	digest_info = rsa_lookup_asn1(hash_name);
  	if (!digest_info)
  		return -EINVAL;
a49de377e   Tadeusz Struk   crypto: Add hash ...
600
601
  
  	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
602
603
  	if (!inst)
  		return -ENOMEM;
a49de377e   Tadeusz Struk   crypto: Add hash ...
604
605
  	ctx = akcipher_instance_ctx(inst);
  	spawn = &ctx->spawn;
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
606
  	ctx->digest_info = digest_info;
a49de377e   Tadeusz Struk   crypto: Add hash ...
607

3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
608
609
610
611
612
613
614
615
616
  	crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst));
  	err = crypto_grab_akcipher(spawn, rsa_alg_name, 0,
  			crypto_requires_sync(algt->type, algt->mask));
  	if (err)
  		goto out_free_inst;
  
  	rsa_alg = crypto_spawn_akcipher_alg(spawn);
  
  	err = -ENAMETOOLONG;
a49de377e   Tadeusz Struk   crypto: Add hash ...
617

c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
618
619
620
621
622
623
624
  	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 ||
  	    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)
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  		goto out_drop_alg;
  
  	inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC;
  	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);
  	if (err)
c0d20d22e   Herbert Xu   crypto: rsa-pkcs1...
647
  		goto out_drop_alg;
3d5b1ecde   Andrzej Zaborowski   crypto: rsa - RSA...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
  
  	return 0;
  
  out_drop_alg:
  	crypto_drop_akcipher(spawn);
  out_free_inst:
  	kfree(inst);
  	return err;
  }
  
  struct crypto_template rsa_pkcs1pad_tmpl = {
  	.name = "pkcs1pad",
  	.create = pkcs1pad_create,
  	.module = THIS_MODULE,
  };