.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* RSA asymmetric public-key algorithm [RFC3447] |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (c) 2015, Intel Corporation |
---|
4 | 5 | * 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 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
48 | 44 | |
---|
49 | 45 | /* (2) m = c^d mod n */ |
---|
50 | 46 | 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 | | - */ |
---|
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 | | - */ |
---|
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 | 47 | } |
---|
80 | 48 | |
---|
81 | 49 | static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) |
---|
.. | .. |
---|
155 | 123 | ret = -EBADMSG; |
---|
156 | 124 | err_free_c: |
---|
157 | 125 | mpi_free(c); |
---|
158 | | -err_free_m: |
---|
159 | | - mpi_free(m); |
---|
160 | | - return ret; |
---|
161 | | -} |
---|
162 | | - |
---|
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 | | - |
---|
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 | | - s = mpi_read_raw_from_sgl(req->src, req->src_len); |
---|
219 | | - if (!s) { |
---|
220 | | - ret = -ENOMEM; |
---|
221 | | - goto err_free_m; |
---|
222 | | - } |
---|
223 | | - |
---|
224 | | - ret = _rsa_verify(pkey, m, s); |
---|
225 | | - if (ret) |
---|
226 | | - goto err_free_s; |
---|
227 | | - |
---|
228 | | - ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); |
---|
229 | | - if (ret) |
---|
230 | | - goto err_free_s; |
---|
231 | | - |
---|
232 | | - if (sign < 0) |
---|
233 | | - ret = -EBADMSG; |
---|
234 | | - |
---|
235 | | -err_free_s: |
---|
236 | | - mpi_free(s); |
---|
237 | 126 | err_free_m: |
---|
238 | 127 | mpi_free(m); |
---|
239 | 128 | return ret; |
---|
.. | .. |
---|
353 | 242 | static struct akcipher_alg rsa = { |
---|
354 | 243 | .encrypt = rsa_enc, |
---|
355 | 244 | .decrypt = rsa_dec, |
---|
356 | | - .sign = rsa_sign, |
---|
357 | | - .verify = rsa_verify, |
---|
358 | 245 | .set_priv_key = rsa_set_priv_key, |
---|
359 | 246 | .set_pub_key = rsa_set_pub_key, |
---|
360 | 247 | .max_size = rsa_max_size, |
---|
.. | .. |
---|
391 | 278 | crypto_unregister_akcipher(&rsa); |
---|
392 | 279 | } |
---|
393 | 280 | |
---|
394 | | -module_init(rsa_init); |
---|
| 281 | +subsys_initcall(rsa_init); |
---|
395 | 282 | module_exit(rsa_exit); |
---|
396 | 283 | MODULE_ALIAS_CRYPTO("rsa"); |
---|
397 | 284 | MODULE_LICENSE("GPL"); |
---|