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 }; 21 22 /* 23 * RSAEP function [RFC3447 sec 5.1.1] 24 * c = m^e mod n; 25 */ 26 static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) 27 { 28 /* (1) Validate 0 <= m < n */ 29 if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) 30 return -EINVAL; 31 32 /* (2) c = m^e mod n */ 33 return mpi_powm(c, m, key->e, key->n); 34 } 35 36 /* 37 * RSADP function [RFC3447 sec 5.1.2] 38 * m = c^d mod n; 39 */ 40 static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c) 41 { 42 /* (1) Validate 0 <= c < n */ 43 if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) 44 return -EINVAL; 45 46 /* (2) m = c^d mod n */ 47 return mpi_powm(m, c, key->d, key->n); 48 } 49 50 static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) 51 { 52 return akcipher_tfm_ctx(tfm); 53 } 54 55 static int rsa_enc(struct akcipher_request *req) 56 { 57 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 58 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 59 MPI m, c = mpi_alloc(0); 60 int ret = 0; 61 int sign; 62 63 if (!c) 64 return -ENOMEM; 65 66 if (unlikely(!pkey->n || !pkey->e)) { 67 ret = -EINVAL; 68 goto err_free_c; 69 } 70 71 ret = -ENOMEM; 72 m = mpi_read_raw_from_sgl(req->src, req->src_len); 73 if (!m) 74 goto err_free_c; 75 76 ret = _rsa_enc(pkey, c, m); 77 if (ret) 78 goto err_free_m; 79 80 ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign); 81 if (ret) 82 goto err_free_m; 83 84 if (sign < 0) 85 ret = -EBADMSG; 86 87 err_free_m: 88 mpi_free(m); 89 err_free_c: 90 mpi_free(c); 91 return ret; 92 } 93 94 static int rsa_dec(struct akcipher_request *req) 95 { 96 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 97 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 98 MPI c, m = mpi_alloc(0); 99 int ret = 0; 100 int sign; 101 102 if (!m) 103 return -ENOMEM; 104 105 if (unlikely(!pkey->n || !pkey->d)) { 106 ret = -EINVAL; 107 goto err_free_m; 108 } 109 110 ret = -ENOMEM; 111 c = mpi_read_raw_from_sgl(req->src, req->src_len); 112 if (!c) 113 goto err_free_m; 114 115 ret = _rsa_dec(pkey, m, c); 116 if (ret) 117 goto err_free_c; 118 119 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 120 if (ret) 121 goto err_free_c; 122 123 if (sign < 0) 124 ret = -EBADMSG; 125 err_free_c: 126 mpi_free(c); 127 err_free_m: 128 mpi_free(m); 129 return ret; 130 } 131 132 static void rsa_free_mpi_key(struct rsa_mpi_key *key) 133 { 134 mpi_free(key->d); 135 mpi_free(key->e); 136 mpi_free(key->n); 137 key->d = NULL; 138 key->e = NULL; 139 key->n = NULL; 140 } 141 142 static int rsa_check_key_length(unsigned int len) 143 { 144 switch (len) { 145 case 512: 146 case 1024: 147 case 1536: 148 if (fips_enabled) 149 return -EINVAL; 150 fallthrough; 151 case 2048: 152 case 3072: 153 case 4096: 154 return 0; 155 } 156 157 return -EINVAL; 158 } 159 160 static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, 161 unsigned int keylen) 162 { 163 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 164 struct rsa_key raw_key = {0}; 165 int ret; 166 167 /* Free the old MPI key if any */ 168 rsa_free_mpi_key(mpi_key); 169 170 ret = rsa_parse_pub_key(&raw_key, key, keylen); 171 if (ret) 172 return ret; 173 174 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 175 if (!mpi_key->e) 176 goto err; 177 178 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 179 if (!mpi_key->n) 180 goto err; 181 182 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 183 rsa_free_mpi_key(mpi_key); 184 return -EINVAL; 185 } 186 187 return 0; 188 189 err: 190 rsa_free_mpi_key(mpi_key); 191 return -ENOMEM; 192 } 193 194 static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, 195 unsigned int keylen) 196 { 197 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 198 struct rsa_key raw_key = {0}; 199 int ret; 200 201 /* Free the old MPI key if any */ 202 rsa_free_mpi_key(mpi_key); 203 204 ret = rsa_parse_priv_key(&raw_key, key, keylen); 205 if (ret) 206 return ret; 207 208 mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz); 209 if (!mpi_key->d) 210 goto err; 211 212 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 213 if (!mpi_key->e) 214 goto err; 215 216 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 217 if (!mpi_key->n) 218 goto err; 219 220 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 221 rsa_free_mpi_key(mpi_key); 222 return -EINVAL; 223 } 224 225 return 0; 226 227 err: 228 rsa_free_mpi_key(mpi_key); 229 return -ENOMEM; 230 } 231 232 static unsigned int rsa_max_size(struct crypto_akcipher *tfm) 233 { 234 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 235 236 return mpi_get_size(pkey->n); 237 } 238 239 static void rsa_exit_tfm(struct crypto_akcipher *tfm) 240 { 241 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 242 243 rsa_free_mpi_key(pkey); 244 } 245 246 static struct akcipher_alg rsa = { 247 .encrypt = rsa_enc, 248 .decrypt = rsa_dec, 249 .set_priv_key = rsa_set_priv_key, 250 .set_pub_key = rsa_set_pub_key, 251 .max_size = rsa_max_size, 252 .exit = rsa_exit_tfm, 253 .base = { 254 .cra_name = "rsa", 255 .cra_driver_name = "rsa-generic", 256 .cra_priority = 100, 257 .cra_module = THIS_MODULE, 258 .cra_ctxsize = sizeof(struct rsa_mpi_key), 259 }, 260 }; 261 262 static int rsa_init(void) 263 { 264 int err; 265 266 err = crypto_register_akcipher(&rsa); 267 if (err) 268 return err; 269 270 err = crypto_register_template(&rsa_pkcs1pad_tmpl); 271 if (err) { 272 crypto_unregister_akcipher(&rsa); 273 return err; 274 } 275 276 return 0; 277 } 278 279 static void rsa_exit(void) 280 { 281 crypto_unregister_template(&rsa_pkcs1pad_tmpl); 282 crypto_unregister_akcipher(&rsa); 283 } 284 285 subsys_initcall(rsa_init); 286 module_exit(rsa_exit); 287 MODULE_ALIAS_CRYPTO("rsa"); 288 MODULE_LICENSE("GPL"); 289 MODULE_DESCRIPTION("RSA generic algorithm"); 290