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.10-rc1 399 lines 7.7 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 ret = -ENOMEM; 219 s = mpi_read_raw_from_sgl(req->src, req->src_len); 220 if (!s) { 221 ret = -ENOMEM; 222 goto err_free_m; 223 } 224 225 ret = _rsa_verify(pkey, m, s); 226 if (ret) 227 goto err_free_s; 228 229 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 230 if (ret) 231 goto err_free_s; 232 233 if (sign < 0) 234 ret = -EBADMSG; 235 236err_free_s: 237 mpi_free(s); 238err_free_m: 239 mpi_free(m); 240 return ret; 241} 242 243static void rsa_free_mpi_key(struct rsa_mpi_key *key) 244{ 245 mpi_free(key->d); 246 mpi_free(key->e); 247 mpi_free(key->n); 248 key->d = NULL; 249 key->e = NULL; 250 key->n = NULL; 251} 252 253static int rsa_check_key_length(unsigned int len) 254{ 255 switch (len) { 256 case 512: 257 case 1024: 258 case 1536: 259 case 2048: 260 case 3072: 261 case 4096: 262 return 0; 263 } 264 265 return -EINVAL; 266} 267 268static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, 269 unsigned int keylen) 270{ 271 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 272 struct rsa_key raw_key = {0}; 273 int ret; 274 275 /* Free the old MPI key if any */ 276 rsa_free_mpi_key(mpi_key); 277 278 ret = rsa_parse_pub_key(&raw_key, key, keylen); 279 if (ret) 280 return ret; 281 282 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 283 if (!mpi_key->e) 284 goto err; 285 286 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 287 if (!mpi_key->n) 288 goto err; 289 290 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 291 rsa_free_mpi_key(mpi_key); 292 return -EINVAL; 293 } 294 295 return 0; 296 297err: 298 rsa_free_mpi_key(mpi_key); 299 return -ENOMEM; 300} 301 302static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, 303 unsigned int keylen) 304{ 305 struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 306 struct rsa_key raw_key = {0}; 307 int ret; 308 309 /* Free the old MPI key if any */ 310 rsa_free_mpi_key(mpi_key); 311 312 ret = rsa_parse_priv_key(&raw_key, key, keylen); 313 if (ret) 314 return ret; 315 316 mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz); 317 if (!mpi_key->d) 318 goto err; 319 320 mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 321 if (!mpi_key->e) 322 goto err; 323 324 mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 325 if (!mpi_key->n) 326 goto err; 327 328 if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 329 rsa_free_mpi_key(mpi_key); 330 return -EINVAL; 331 } 332 333 return 0; 334 335err: 336 rsa_free_mpi_key(mpi_key); 337 return -ENOMEM; 338} 339 340static int rsa_max_size(struct crypto_akcipher *tfm) 341{ 342 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 343 344 return pkey->n ? mpi_get_size(pkey->n) : -EINVAL; 345} 346 347static void rsa_exit_tfm(struct crypto_akcipher *tfm) 348{ 349 struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 350 351 rsa_free_mpi_key(pkey); 352} 353 354static struct akcipher_alg rsa = { 355 .encrypt = rsa_enc, 356 .decrypt = rsa_dec, 357 .sign = rsa_sign, 358 .verify = rsa_verify, 359 .set_priv_key = rsa_set_priv_key, 360 .set_pub_key = rsa_set_pub_key, 361 .max_size = rsa_max_size, 362 .exit = rsa_exit_tfm, 363 .base = { 364 .cra_name = "rsa", 365 .cra_driver_name = "rsa-generic", 366 .cra_priority = 100, 367 .cra_module = THIS_MODULE, 368 .cra_ctxsize = sizeof(struct rsa_mpi_key), 369 }, 370}; 371 372static int rsa_init(void) 373{ 374 int err; 375 376 err = crypto_register_akcipher(&rsa); 377 if (err) 378 return err; 379 380 err = crypto_register_template(&rsa_pkcs1pad_tmpl); 381 if (err) { 382 crypto_unregister_akcipher(&rsa); 383 return err; 384 } 385 386 return 0; 387} 388 389static void rsa_exit(void) 390{ 391 crypto_unregister_template(&rsa_pkcs1pad_tmpl); 392 crypto_unregister_akcipher(&rsa); 393} 394 395module_init(rsa_init); 396module_exit(rsa_exit); 397MODULE_ALIAS_CRYPTO("rsa"); 398MODULE_LICENSE("GPL"); 399MODULE_DESCRIPTION("RSA generic algorithm");