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