Branch data Line data Source code
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 : 3 : static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) 26 : : { 27 : : /* (1) Validate 0 <= m < n */ 28 : 3 : 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 : 3 : 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 : 0 : static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c) 40 : : { 41 : : /* (1) Validate 0 <= c < n */ 42 : 0 : 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 : 0 : 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 : 3 : 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 : 3 : MPI m, c = mpi_alloc(0); 59 : : int ret = 0; 60 : : int sign; 61 : : 62 : 3 : if (!c) 63 : : return -ENOMEM; 64 : : 65 : 3 : if (unlikely(!pkey->n || !pkey->e)) { 66 : : ret = -EINVAL; 67 : : goto err_free_c; 68 : : } 69 : : 70 : : ret = -ENOMEM; 71 : 3 : m = mpi_read_raw_from_sgl(req->src, req->src_len); 72 : 3 : if (!m) 73 : : goto err_free_c; 74 : : 75 : 3 : ret = _rsa_enc(pkey, c, m); 76 : 3 : if (ret) 77 : : goto err_free_m; 78 : : 79 : 3 : ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign); 80 : 3 : if (ret) 81 : : goto err_free_m; 82 : : 83 : 3 : if (sign < 0) 84 : : ret = -EBADMSG; 85 : : 86 : : err_free_m: 87 : 3 : mpi_free(m); 88 : : err_free_c: 89 : 3 : mpi_free(c); 90 : 3 : return ret; 91 : : } 92 : : 93 : 0 : 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 : 0 : MPI c, m = mpi_alloc(0); 98 : : int ret = 0; 99 : : int sign; 100 : : 101 : 0 : if (!m) 102 : : return -ENOMEM; 103 : : 104 : 0 : if (unlikely(!pkey->n || !pkey->d)) { 105 : : ret = -EINVAL; 106 : : goto err_free_m; 107 : : } 108 : : 109 : : ret = -ENOMEM; 110 : 0 : c = mpi_read_raw_from_sgl(req->src, req->src_len); 111 : 0 : if (!c) 112 : : goto err_free_m; 113 : : 114 : 0 : ret = _rsa_dec(pkey, m, c); 115 : 0 : if (ret) 116 : : goto err_free_c; 117 : : 118 : 0 : ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 119 : 0 : if (ret) 120 : : goto err_free_c; 121 : : 122 : 0 : if (sign < 0) 123 : : ret = -EBADMSG; 124 : : err_free_c: 125 : 0 : mpi_free(c); 126 : : err_free_m: 127 : 0 : mpi_free(m); 128 : 0 : return ret; 129 : : } 130 : : 131 : 3 : static void rsa_free_mpi_key(struct rsa_mpi_key *key) 132 : : { 133 : 3 : mpi_free(key->d); 134 : 3 : mpi_free(key->e); 135 : 3 : mpi_free(key->n); 136 : 3 : key->d = NULL; 137 : 3 : key->e = NULL; 138 : 3 : key->n = NULL; 139 : 3 : } 140 : : 141 : : static int rsa_check_key_length(unsigned int len) 142 : : { 143 : 3 : 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 : 3 : 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 : 3 : struct rsa_key raw_key = {0}; 161 : : int ret; 162 : : 163 : : /* Free the old MPI key if any */ 164 : 3 : rsa_free_mpi_key(mpi_key); 165 : : 166 : 3 : ret = rsa_parse_pub_key(&raw_key, key, keylen); 167 : 3 : if (ret) 168 : : return ret; 169 : : 170 : 3 : mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 171 : 3 : if (!mpi_key->e) 172 : : goto err; 173 : : 174 : 3 : mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 175 : 3 : if (!mpi_key->n) 176 : : goto err; 177 : : 178 : 3 : if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 179 : 0 : rsa_free_mpi_key(mpi_key); 180 : 0 : return -EINVAL; 181 : : } 182 : : 183 : : return 0; 184 : : 185 : : err: 186 : 0 : rsa_free_mpi_key(mpi_key); 187 : 0 : return -ENOMEM; 188 : : } 189 : : 190 : 0 : 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 : 0 : struct rsa_key raw_key = {0}; 195 : : int ret; 196 : : 197 : : /* Free the old MPI key if any */ 198 : 0 : rsa_free_mpi_key(mpi_key); 199 : : 200 : 0 : ret = rsa_parse_priv_key(&raw_key, key, keylen); 201 : 0 : if (ret) 202 : : return ret; 203 : : 204 : 0 : mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz); 205 : 0 : if (!mpi_key->d) 206 : : goto err; 207 : : 208 : 0 : mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 209 : 0 : if (!mpi_key->e) 210 : : goto err; 211 : : 212 : 0 : mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 213 : 0 : if (!mpi_key->n) 214 : : goto err; 215 : : 216 : 0 : if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 217 : 0 : rsa_free_mpi_key(mpi_key); 218 : 0 : return -EINVAL; 219 : : } 220 : : 221 : : return 0; 222 : : 223 : : err: 224 : 0 : rsa_free_mpi_key(mpi_key); 225 : 0 : return -ENOMEM; 226 : : } 227 : : 228 : 3 : static unsigned int rsa_max_size(struct crypto_akcipher *tfm) 229 : : { 230 : : struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 231 : : 232 : 3 : return mpi_get_size(pkey->n); 233 : : } 234 : : 235 : 3 : static void rsa_exit_tfm(struct crypto_akcipher *tfm) 236 : : { 237 : : struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 238 : : 239 : 3 : rsa_free_mpi_key(pkey); 240 : 3 : } 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 : 3 : static int rsa_init(void) 259 : : { 260 : : int err; 261 : : 262 : 3 : err = crypto_register_akcipher(&rsa); 263 : 3 : if (err) 264 : : return err; 265 : : 266 : 3 : err = crypto_register_template(&rsa_pkcs1pad_tmpl); 267 : 3 : if (err) { 268 : 0 : crypto_unregister_akcipher(&rsa); 269 : 0 : return err; 270 : : } 271 : : 272 : : return 0; 273 : : } 274 : : 275 : 0 : static void rsa_exit(void) 276 : : { 277 : 0 : crypto_unregister_template(&rsa_pkcs1pad_tmpl); 278 : 0 : crypto_unregister_akcipher(&rsa); 279 : 0 : } 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");