• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /* RSA asymmetric public-key algorithm [RFC3447]
2   *
3   * Copyright (c) 2015, Intel Corporation
4   * Authors: Tadeusz Struk <tadeusz.struk@intel.com>
5   *
6   * This program is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public Licence
8   * as published by the Free Software Foundation; either version
9   * 2 of the Licence, or (at your option) any later version.
10   */
11  
12  #include <linux/module.h>
13  #include <linux/mpi.h>
14  #include <crypto/internal/rsa.h>
15  #include <crypto/internal/akcipher.h>
16  #include <crypto/akcipher.h>
17  #include <crypto/algapi.h>
18  
19  struct rsa_mpi_key {
20  	MPI n;
21  	MPI e;
22  	MPI d;
23  };
24  
25  /*
26   * RSAEP function [RFC3447 sec 5.1.1]
27   * c = m^e mod n;
28   */
_rsa_enc(const struct rsa_mpi_key * key,MPI c,MPI m)29  static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m)
30  {
31  	/* (1) Validate 0 <= m < n */
32  	if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
33  		return -EINVAL;
34  
35  	/* (2) c = m^e mod n */
36  	return mpi_powm(c, m, key->e, key->n);
37  }
38  
39  /*
40   * RSADP function [RFC3447 sec 5.1.2]
41   * m = c^d mod n;
42   */
_rsa_dec(const struct rsa_mpi_key * key,MPI m,MPI c)43  static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c)
44  {
45  	/* (1) Validate 0 <= c < n */
46  	if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
47  		return -EINVAL;
48  
49  	/* (2) m = c^d mod n */
50  	return mpi_powm(m, c, key->d, key->n);
51  }
52  
53  /*
54   * RSASP1 function [RFC3447 sec 5.2.1]
55   * s = m^d mod n
56   */
_rsa_sign(const struct rsa_mpi_key * key,MPI s,MPI m)57  static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m)
58  {
59  	/* (1) Validate 0 <= m < n */
60  	if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
61  		return -EINVAL;
62  
63  	/* (2) s = m^d mod n */
64  	return mpi_powm(s, m, key->d, key->n);
65  }
66  
67  /*
68   * RSAVP1 function [RFC3447 sec 5.2.2]
69   * m = s^e mod n;
70   */
_rsa_verify(const struct rsa_mpi_key * key,MPI m,MPI s)71  static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s)
72  {
73  	/* (1) Validate 0 <= s < n */
74  	if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
75  		return -EINVAL;
76  
77  	/* (2) m = s^e mod n */
78  	return mpi_powm(m, s, key->e, key->n);
79  }
80  
rsa_get_key(struct crypto_akcipher * tfm)81  static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
82  {
83  	return akcipher_tfm_ctx(tfm);
84  }
85  
rsa_enc(struct akcipher_request * req)86  static int rsa_enc(struct akcipher_request *req)
87  {
88  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
89  	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
90  	MPI m, c = mpi_alloc(0);
91  	int ret = 0;
92  	int sign;
93  
94  	if (!c)
95  		return -ENOMEM;
96  
97  	if (unlikely(!pkey->n || !pkey->e)) {
98  		ret = -EINVAL;
99  		goto err_free_c;
100  	}
101  
102  	ret = -ENOMEM;
103  	m = mpi_read_raw_from_sgl(req->src, req->src_len);
104  	if (!m)
105  		goto err_free_c;
106  
107  	ret = _rsa_enc(pkey, c, m);
108  	if (ret)
109  		goto err_free_m;
110  
111  	ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign);
112  	if (ret)
113  		goto err_free_m;
114  
115  	if (sign < 0)
116  		ret = -EBADMSG;
117  
118  err_free_m:
119  	mpi_free(m);
120  err_free_c:
121  	mpi_free(c);
122  	return ret;
123  }
124  
rsa_dec(struct akcipher_request * req)125  static int rsa_dec(struct akcipher_request *req)
126  {
127  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
128  	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
129  	MPI c, m = mpi_alloc(0);
130  	int ret = 0;
131  	int sign;
132  
133  	if (!m)
134  		return -ENOMEM;
135  
136  	if (unlikely(!pkey->n || !pkey->d)) {
137  		ret = -EINVAL;
138  		goto err_free_m;
139  	}
140  
141  	ret = -ENOMEM;
142  	c = mpi_read_raw_from_sgl(req->src, req->src_len);
143  	if (!c)
144  		goto err_free_m;
145  
146  	ret = _rsa_dec(pkey, m, c);
147  	if (ret)
148  		goto err_free_c;
149  
150  	ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign);
151  	if (ret)
152  		goto err_free_c;
153  
154  	if (sign < 0)
155  		ret = -EBADMSG;
156  err_free_c:
157  	mpi_free(c);
158  err_free_m:
159  	mpi_free(m);
160  	return ret;
161  }
162  
rsa_sign(struct akcipher_request * req)163  static int rsa_sign(struct akcipher_request *req)
164  {
165  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
166  	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
167  	MPI m, s = mpi_alloc(0);
168  	int ret = 0;
169  	int sign;
170  
171  	if (!s)
172  		return -ENOMEM;
173  
174  	if (unlikely(!pkey->n || !pkey->d)) {
175  		ret = -EINVAL;
176  		goto err_free_s;
177  	}
178  
179  	ret = -ENOMEM;
180  	m = mpi_read_raw_from_sgl(req->src, req->src_len);
181  	if (!m)
182  		goto err_free_s;
183  
184  	ret = _rsa_sign(pkey, s, m);
185  	if (ret)
186  		goto err_free_m;
187  
188  	ret = mpi_write_to_sgl(s, req->dst, req->dst_len, &sign);
189  	if (ret)
190  		goto err_free_m;
191  
192  	if (sign < 0)
193  		ret = -EBADMSG;
194  
195  err_free_m:
196  	mpi_free(m);
197  err_free_s:
198  	mpi_free(s);
199  	return ret;
200  }
201  
rsa_verify(struct akcipher_request * req)202  static int rsa_verify(struct akcipher_request *req)
203  {
204  	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
205  	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
206  	MPI s, m = mpi_alloc(0);
207  	int ret = 0;
208  	int sign;
209  
210  	if (!m)
211  		return -ENOMEM;
212  
213  	if (unlikely(!pkey->n || !pkey->e)) {
214  		ret = -EINVAL;
215  		goto err_free_m;
216  	}
217  
218  	ret = -ENOMEM;
219  	s = mpi_read_raw_from_sgl(req->src, req->src_len);
220  	if (!s) {
221  		ret = -ENOMEM;
222  		goto err_free_m;
223  	}
224  
225  	ret = _rsa_verify(pkey, m, s);
226  	if (ret)
227  		goto err_free_s;
228  
229  	ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign);
230  	if (ret)
231  		goto err_free_s;
232  
233  	if (sign < 0)
234  		ret = -EBADMSG;
235  
236  err_free_s:
237  	mpi_free(s);
238  err_free_m:
239  	mpi_free(m);
240  	return ret;
241  }
242  
rsa_free_mpi_key(struct rsa_mpi_key * key)243  static void rsa_free_mpi_key(struct rsa_mpi_key *key)
244  {
245  	mpi_free(key->d);
246  	mpi_free(key->e);
247  	mpi_free(key->n);
248  	key->d = NULL;
249  	key->e = NULL;
250  	key->n = NULL;
251  }
252  
rsa_check_key_length(unsigned int len)253  static int rsa_check_key_length(unsigned int len)
254  {
255  	switch (len) {
256  	case 512:
257  	case 1024:
258  	case 1536:
259  	case 2048:
260  	case 3072:
261  	case 4096:
262  		return 0;
263  	}
264  
265  	return -EINVAL;
266  }
267  
rsa_set_pub_key(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)268  static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
269  			   unsigned int keylen)
270  {
271  	struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
272  	struct rsa_key raw_key = {0};
273  	int ret;
274  
275  	/* Free the old MPI key if any */
276  	rsa_free_mpi_key(mpi_key);
277  
278  	ret = rsa_parse_pub_key(&raw_key, key, keylen);
279  	if (ret)
280  		return ret;
281  
282  	mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
283  	if (!mpi_key->e)
284  		goto err;
285  
286  	mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
287  	if (!mpi_key->n)
288  		goto err;
289  
290  	if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
291  		rsa_free_mpi_key(mpi_key);
292  		return -EINVAL;
293  	}
294  
295  	return 0;
296  
297  err:
298  	rsa_free_mpi_key(mpi_key);
299  	return -ENOMEM;
300  }
301  
rsa_set_priv_key(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)302  static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
303  			    unsigned int keylen)
304  {
305  	struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
306  	struct rsa_key raw_key = {0};
307  	int ret;
308  
309  	/* Free the old MPI key if any */
310  	rsa_free_mpi_key(mpi_key);
311  
312  	ret = rsa_parse_priv_key(&raw_key, key, keylen);
313  	if (ret)
314  		return ret;
315  
316  	mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
317  	if (!mpi_key->d)
318  		goto err;
319  
320  	mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
321  	if (!mpi_key->e)
322  		goto err;
323  
324  	mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
325  	if (!mpi_key->n)
326  		goto err;
327  
328  	if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
329  		rsa_free_mpi_key(mpi_key);
330  		return -EINVAL;
331  	}
332  
333  	return 0;
334  
335  err:
336  	rsa_free_mpi_key(mpi_key);
337  	return -ENOMEM;
338  }
339  
rsa_max_size(struct crypto_akcipher * tfm)340  static int rsa_max_size(struct crypto_akcipher *tfm)
341  {
342  	struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
343  
344  	return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
345  }
346  
rsa_exit_tfm(struct crypto_akcipher * tfm)347  static void rsa_exit_tfm(struct crypto_akcipher *tfm)
348  {
349  	struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
350  
351  	rsa_free_mpi_key(pkey);
352  }
353  
354  static struct akcipher_alg rsa = {
355  	.encrypt = rsa_enc,
356  	.decrypt = rsa_dec,
357  	.sign = rsa_sign,
358  	.verify = rsa_verify,
359  	.set_priv_key = rsa_set_priv_key,
360  	.set_pub_key = rsa_set_pub_key,
361  	.max_size = rsa_max_size,
362  	.exit = rsa_exit_tfm,
363  	.base = {
364  		.cra_name = "rsa",
365  		.cra_driver_name = "rsa-generic",
366  		.cra_priority = 100,
367  		.cra_module = THIS_MODULE,
368  		.cra_ctxsize = sizeof(struct rsa_mpi_key),
369  	},
370  };
371  
rsa_init(void)372  static int rsa_init(void)
373  {
374  	int err;
375  
376  	err = crypto_register_akcipher(&rsa);
377  	if (err)
378  		return err;
379  
380  	err = crypto_register_template(&rsa_pkcs1pad_tmpl);
381  	if (err) {
382  		crypto_unregister_akcipher(&rsa);
383  		return err;
384  	}
385  
386  	return 0;
387  }
388  
rsa_exit(void)389  static void rsa_exit(void)
390  {
391  	crypto_unregister_template(&rsa_pkcs1pad_tmpl);
392  	crypto_unregister_akcipher(&rsa);
393  }
394  
395  module_init(rsa_init);
396  module_exit(rsa_exit);
397  MODULE_ALIAS_CRYPTO("rsa");
398  MODULE_LICENSE("GPL");
399  MODULE_DESCRIPTION("RSA generic algorithm");
400