1 /* RSA asymmetric public-key algorithm [RFC3447] 2 * 3 * Copyright (c) 2015, Intel Corporation 4 * 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 */ 11 12 #include <linux/module.h> 13 #include <linux/mpi.h> 14 #include <crypto/internal/rsa.h> 15 #include <crypto/internal/akcipher.h> 16 #include <crypto/akcipher.h> 17 #include <crypto/algapi.h> 18 19 struct rsa_mpi_key { 20 MPI n; 21 MPI e; 22 MPI d; 23 }; 24 25 /* 26 * RSAEP function [RFC3447 sec 5.1.1] 27 * c = m^e mod n; 28 */ 29 static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) 30 { 31 /* (1) Validate 0 <= m < n */ 32 if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) 33 return -EINVAL; 34 35 /* (2) c = m^e mod n */ 36 return mpi_powm(c, m, key->e, key->n); 37 } 38 39 /* 40 * RSADP function [RFC3447 sec 5.1.2] 41 * m = c^d mod n; 42 */ 43 static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c) 44 { 45 /* (1) Validate 0 <= c < n */ 46 if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) 47 return -EINVAL; 48 49 /* (2) m = c^d mod n */ 50 return mpi_powm(m, c, key->d, key->n); 51 } 52 53 static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) 54 { 55 return akcipher_tfm_ctx(tfm); 56 } 57 58 static int rsa_enc(struct akcipher_request *req) 59 { 60 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 61 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 62 MPI m, c = mpi_alloc(0); 63 int ret = 0; 64 int sign; 65 66 if (!c) 67 return -ENOMEM; 68 69 if (unlikely(!pkey->n || !pkey->e)) { 70 ret = -EINVAL; 71 goto err_free_c; 72 } 73 74 ret = -ENOMEM; 75 m = mpi_read_raw_from_sgl(req->src, req->src_len); 76 if (!m) 77 goto err_free_c; 78 79 ret = _rsa_enc(pkey, c, m); 80 if (ret) 81 goto err_free_m; 82 83 ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign); 84 if (ret) 85 goto err_free_m; 86 87 if (sign < 0) 88 ret = -EBADMSG; 89 90 err_free_m: 91 mpi_free(m); 92 err_free_c: 93 mpi_free(c); 94 return ret; 95 } 96 97 static int rsa_dec(struct akcipher_request *req) 98 { 99 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 100 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 101 MPI c, m = mpi_alloc(0); 102 int ret = 0; 103 int sign; 104 105 if (!m) 106 return -ENOMEM; 107 108 if (unlikely(!pkey->n || !pkey->d)) { 109 ret = -EINVAL; 110 goto err_free_m; 111 } 112 113 ret = -ENOMEM; 114 c = mpi_read_raw_from_sgl(req->src, req->src_len); 115 if (!c) 116 goto err_free_m; 117 118 ret = _rsa_dec(pkey, m, c); 119 if (ret) 120 goto err_free_c; 121 122 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 123 if (ret) 124 goto err_free_c; 125 126 if (sign < 0) 127 ret = -EBADMSG; 128 err_free_c: 129 mpi_free(c); 130 err_free_m: 131 mpi_free(m); 132 return ret; 133 } 134 135 static void rsa_free_mpi_key(struct rsa_mpi_key *key) 136 { 137 mpi_free(key->d); 138 mpi_free(key->e); 139 mpi_free(key->n); 140 key->d = NULL; 141 key->e = NULL; 142 key->n = NULL; 143 } 144 145 static int rsa_check_key_length(unsigned int len) 146 { 147 switch (len) { 148 case 512: 149 case 1024: 150 case 1536: 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