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