Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.20-rc2 398 lines 7.6 kB view raw
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 19struct 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 */ 29static 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 */ 43static 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/* 54 * RSASP1 function [RFC3447 sec 5.2.1] 55 * s = m^d mod n 56 */ 57static 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 */ 71static 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} 80 81static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) 82{ 83 return akcipher_tfm_ctx(tfm); 84} 85 86static int rsa_enc(struct akcipher_request *req) 87{ 88 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 89 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 90 MPI m, c = mpi_alloc(0); 91 int ret = 0; 92 int sign; 93 94 if (!c) 95 return -ENOMEM; 96 97 if (unlikely(!pkey->n || !pkey->e)) { 98 ret = -EINVAL; 99 goto err_free_c; 100 } 101 102 ret = -ENOMEM; 103 m = mpi_read_raw_from_sgl(req->src, req->src_len); 104 if (!m) 105 goto err_free_c; 106 107 ret = _rsa_enc(pkey, c, m); 108 if (ret) 109 goto err_free_m; 110 111 ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign); 112 if (ret) 113 goto err_free_m; 114 115 if (sign < 0) 116 ret = -EBADMSG; 117 118err_free_m: 119 mpi_free(m); 120err_free_c: 121 mpi_free(c); 122 return ret; 123} 124 125static int rsa_dec(struct akcipher_request *req) 126{ 127 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 128 const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 129 MPI c, m = mpi_alloc(0); 130 int ret = 0; 131 int sign; 132 133 if (!m) 134 return -ENOMEM; 135 136 if (unlikely(!pkey->n || !pkey->d)) { 137 ret = -EINVAL; 138 goto err_free_m; 139 } 140 141 ret = -ENOMEM; 142 c = mpi_read_raw_from_sgl(req->src, req->src_len); 143 if (!c) 144 goto err_free_m; 145 146 ret = _rsa_dec(pkey, m, c); 147 if (ret) 148 goto err_free_c; 149 150 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 151 if (ret) 152 goto err_free_c; 153 154 if (sign < 0) 155 ret = -EBADMSG; 156err_free_c: 157 mpi_free(c); 158err_free_m: 159 mpi_free(m); 160 return ret; 161} 162 163static 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 195err_free_m: 196 mpi_free(m); 197err_free_s: 198 mpi_free(s); 199 return ret; 200} 201 202static 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 235err_free_s: 236 mpi_free(s); 237err_free_m: 238 mpi_free(m); 239 return ret; 240} 241 242static void rsa_free_mpi_key(struct rsa_mpi_key *key) 243{ 244 mpi_free(key->d); 245 mpi_free(key->e); 246 mpi_free(key->n); 247 key->d = NULL; 248 key->e = NULL; 249 key->n = NULL; 250} 251 252static int rsa_check_key_length(unsigned int len) 253{ 254 switch (len) { 255 case 512: 256 case 1024: 257 case 1536: 258 case 2048: 259 case 3072: 260 case 4096: 261 return 0; 262 } 263 264 return -EINVAL; 265} 266 267static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, 268 unsigned int keylen) 269{ 270 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 271 struct rsa_key raw_key = {0}; 272 int ret; 273 274 /* Free the old MPI key if any */ 275 rsa_free_mpi_key(mpi_key); 276 277 ret = rsa_parse_pub_key(&raw_key, key, keylen); 278 if (ret) 279 return ret; 280 281 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 282 if (!mpi_key->e) 283 goto err; 284 285 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 286 if (!mpi_key->n) 287 goto err; 288 289 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 290 rsa_free_mpi_key(mpi_key); 291 return -EINVAL; 292 } 293 294 return 0; 295 296err: 297 rsa_free_mpi_key(mpi_key); 298 return -ENOMEM; 299} 300 301static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, 302 unsigned int keylen) 303{ 304 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 305 struct rsa_key raw_key = {0}; 306 int ret; 307 308 /* Free the old MPI key if any */ 309 rsa_free_mpi_key(mpi_key); 310 311 ret = rsa_parse_priv_key(&raw_key, key, keylen); 312 if (ret) 313 return ret; 314 315 mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz); 316 if (!mpi_key->d) 317 goto err; 318 319 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 320 if (!mpi_key->e) 321 goto err; 322 323 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 324 if (!mpi_key->n) 325 goto err; 326 327 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 328 rsa_free_mpi_key(mpi_key); 329 return -EINVAL; 330 } 331 332 return 0; 333 334err: 335 rsa_free_mpi_key(mpi_key); 336 return -ENOMEM; 337} 338 339static unsigned int rsa_max_size(struct crypto_akcipher *tfm) 340{ 341 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 342 343 return mpi_get_size(pkey->n); 344} 345 346static void rsa_exit_tfm(struct crypto_akcipher *tfm) 347{ 348 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 349 350 rsa_free_mpi_key(pkey); 351} 352 353static struct akcipher_alg rsa = { 354 .encrypt = rsa_enc, 355 .decrypt = rsa_dec, 356 .sign = rsa_sign, 357 .verify = rsa_verify, 358 .set_priv_key = rsa_set_priv_key, 359 .set_pub_key = rsa_set_pub_key, 360 .max_size = rsa_max_size, 361 .exit = rsa_exit_tfm, 362 .base = { 363 .cra_name = "rsa", 364 .cra_driver_name = "rsa-generic", 365 .cra_priority = 100, 366 .cra_module = THIS_MODULE, 367 .cra_ctxsize = sizeof(struct rsa_mpi_key), 368 }, 369}; 370 371static int rsa_init(void) 372{ 373 int err; 374 375 err = crypto_register_akcipher(&rsa); 376 if (err) 377 return err; 378 379 err = crypto_register_template(&rsa_pkcs1pad_tmpl); 380 if (err) { 381 crypto_unregister_akcipher(&rsa); 382 return err; 383 } 384 385 return 0; 386} 387 388static void rsa_exit(void) 389{ 390 crypto_unregister_template(&rsa_pkcs1pad_tmpl); 391 crypto_unregister_akcipher(&rsa); 392} 393 394module_init(rsa_init); 395module_exit(rsa_exit); 396MODULE_ALIAS_CRYPTO("rsa"); 397MODULE_LICENSE("GPL"); 398MODULE_DESCRIPTION("RSA generic algorithm");