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

crypto: rsa - add a new rsa generic implementation

Add a new rsa generic SW implementation.
This implements only cryptographic primitives.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>

Added select on ASN1.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tadeusz Struk and committed by
Herbert Xu
cfc2bb32 3c339ab8

+484
+8
crypto/Kconfig
··· 100 100 select CRYPTO_AKCIPHER2 101 101 select CRYPTO_ALGAPI 102 102 103 + config CRYPTO_RSA 104 + tristate "RSA algorithm" 105 + select AKCIPHER 106 + select MPILIB 107 + select ASN1 108 + help 109 + Generic implementation of the RSA public key algorithm. 110 + 103 111 config CRYPTO_MANAGER 104 112 tristate "Cryptographic algorithm manager" 105 113 select CRYPTO_MANAGER2
+8
crypto/Makefile
··· 30 30 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o 31 31 obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o 32 32 33 + $(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h 34 + clean-files += rsakey-asn1.c rsakey-asn1.h 35 + 36 + rsa_generic-y := rsakey-asn1.o 37 + rsa_generic-y += rsa.o 38 + rsa_generic-y += rsa_helper.o 39 + obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o 40 + 33 41 cryptomgr-y := algboss.o testmgr.o 34 42 35 43 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
+315
crypto/rsa.c
··· 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 <crypto/internal/rsa.h> 14 + #include <crypto/internal/akcipher.h> 15 + #include <crypto/akcipher.h> 16 + 17 + /* 18 + * RSAEP function [RFC3447 sec 5.1.1] 19 + * c = m^e mod n; 20 + */ 21 + static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m) 22 + { 23 + /* (1) Validate 0 <= m < n */ 24 + if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) 25 + return -EINVAL; 26 + 27 + /* (2) c = m^e mod n */ 28 + return mpi_powm(c, m, key->e, key->n); 29 + } 30 + 31 + /* 32 + * RSADP function [RFC3447 sec 5.1.2] 33 + * m = c^d mod n; 34 + */ 35 + static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c) 36 + { 37 + /* (1) Validate 0 <= c < n */ 38 + if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) 39 + return -EINVAL; 40 + 41 + /* (2) m = c^d mod n */ 42 + return mpi_powm(m, c, key->d, key->n); 43 + } 44 + 45 + /* 46 + * RSASP1 function [RFC3447 sec 5.2.1] 47 + * s = m^d mod n 48 + */ 49 + static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m) 50 + { 51 + /* (1) Validate 0 <= m < n */ 52 + if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) 53 + return -EINVAL; 54 + 55 + /* (2) s = m^d mod n */ 56 + return mpi_powm(s, m, key->d, key->n); 57 + } 58 + 59 + /* 60 + * RSAVP1 function [RFC3447 sec 5.2.2] 61 + * m = s^e mod n; 62 + */ 63 + static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s) 64 + { 65 + /* (1) Validate 0 <= s < n */ 66 + if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0) 67 + return -EINVAL; 68 + 69 + /* (2) m = s^e mod n */ 70 + return mpi_powm(m, s, key->e, key->n); 71 + } 72 + 73 + static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm) 74 + { 75 + return akcipher_tfm_ctx(tfm); 76 + } 77 + 78 + static int rsa_enc(struct akcipher_request *req) 79 + { 80 + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 81 + const struct rsa_key *pkey = rsa_get_key(tfm); 82 + MPI m, c = mpi_alloc(0); 83 + int ret = 0; 84 + int sign; 85 + 86 + if (!c) 87 + return -ENOMEM; 88 + 89 + if (unlikely(!pkey->n || !pkey->e)) { 90 + ret = -EINVAL; 91 + goto err_free_c; 92 + } 93 + 94 + if (req->dst_len < mpi_get_size(pkey->n)) { 95 + req->dst_len = mpi_get_size(pkey->n); 96 + ret = -EOVERFLOW; 97 + goto err_free_c; 98 + } 99 + 100 + m = mpi_read_raw_data(req->src, req->src_len); 101 + if (!m) { 102 + ret = -ENOMEM; 103 + goto err_free_c; 104 + } 105 + 106 + ret = _rsa_enc(pkey, c, m); 107 + if (ret) 108 + goto err_free_m; 109 + 110 + ret = mpi_read_buffer(c, req->dst, req->dst_len, &req->dst_len, &sign); 111 + if (ret) 112 + goto err_free_m; 113 + 114 + if (sign < 0) { 115 + ret = -EBADMSG; 116 + goto err_free_m; 117 + } 118 + 119 + err_free_m: 120 + mpi_free(m); 121 + err_free_c: 122 + mpi_free(c); 123 + return ret; 124 + } 125 + 126 + static int rsa_dec(struct akcipher_request *req) 127 + { 128 + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 129 + const struct rsa_key *pkey = rsa_get_key(tfm); 130 + MPI c, m = mpi_alloc(0); 131 + int ret = 0; 132 + int sign; 133 + 134 + if (!m) 135 + return -ENOMEM; 136 + 137 + if (unlikely(!pkey->n || !pkey->d)) { 138 + ret = -EINVAL; 139 + goto err_free_m; 140 + } 141 + 142 + if (req->dst_len < mpi_get_size(pkey->n)) { 143 + req->dst_len = mpi_get_size(pkey->n); 144 + ret = -EOVERFLOW; 145 + goto err_free_m; 146 + } 147 + 148 + c = mpi_read_raw_data(req->src, req->src_len); 149 + if (!c) { 150 + ret = -ENOMEM; 151 + goto err_free_m; 152 + } 153 + 154 + ret = _rsa_dec(pkey, m, c); 155 + if (ret) 156 + goto err_free_c; 157 + 158 + ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign); 159 + if (ret) 160 + goto err_free_c; 161 + 162 + if (sign < 0) { 163 + ret = -EBADMSG; 164 + goto err_free_c; 165 + } 166 + 167 + err_free_c: 168 + mpi_free(c); 169 + err_free_m: 170 + mpi_free(m); 171 + return ret; 172 + } 173 + 174 + static int rsa_sign(struct akcipher_request *req) 175 + { 176 + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 177 + const struct rsa_key *pkey = rsa_get_key(tfm); 178 + MPI m, s = mpi_alloc(0); 179 + int ret = 0; 180 + int sign; 181 + 182 + if (!s) 183 + return -ENOMEM; 184 + 185 + if (unlikely(!pkey->n || !pkey->d)) { 186 + ret = -EINVAL; 187 + goto err_free_s; 188 + } 189 + 190 + if (req->dst_len < mpi_get_size(pkey->n)) { 191 + req->dst_len = mpi_get_size(pkey->n); 192 + ret = -EOVERFLOW; 193 + goto err_free_s; 194 + } 195 + 196 + m = mpi_read_raw_data(req->src, req->src_len); 197 + if (!m) { 198 + ret = -ENOMEM; 199 + goto err_free_s; 200 + } 201 + 202 + ret = _rsa_sign(pkey, s, m); 203 + if (ret) 204 + goto err_free_m; 205 + 206 + ret = mpi_read_buffer(s, req->dst, req->dst_len, &req->dst_len, &sign); 207 + if (ret) 208 + goto err_free_m; 209 + 210 + if (sign < 0) { 211 + ret = -EBADMSG; 212 + goto err_free_m; 213 + } 214 + 215 + err_free_m: 216 + mpi_free(m); 217 + err_free_s: 218 + mpi_free(s); 219 + return ret; 220 + } 221 + 222 + static int rsa_verify(struct akcipher_request *req) 223 + { 224 + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 225 + const struct rsa_key *pkey = rsa_get_key(tfm); 226 + MPI s, m = mpi_alloc(0); 227 + int ret = 0; 228 + int sign; 229 + 230 + if (!m) 231 + return -ENOMEM; 232 + 233 + if (unlikely(!pkey->n || !pkey->e)) { 234 + ret = -EINVAL; 235 + goto err_free_m; 236 + } 237 + 238 + if (req->dst_len < mpi_get_size(pkey->n)) { 239 + req->dst_len = mpi_get_size(pkey->n); 240 + ret = -EOVERFLOW; 241 + goto err_free_m; 242 + } 243 + 244 + s = mpi_read_raw_data(req->src, req->src_len); 245 + if (!s) { 246 + ret = -ENOMEM; 247 + goto err_free_m; 248 + } 249 + 250 + ret = _rsa_verify(pkey, m, s); 251 + if (ret) 252 + goto err_free_s; 253 + 254 + ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign); 255 + if (ret) 256 + goto err_free_s; 257 + 258 + if (sign < 0) { 259 + ret = -EBADMSG; 260 + goto err_free_s; 261 + } 262 + 263 + err_free_s: 264 + mpi_free(s); 265 + err_free_m: 266 + mpi_free(m); 267 + return ret; 268 + } 269 + 270 + static int rsa_setkey(struct crypto_akcipher *tfm, const void *key, 271 + unsigned int keylen) 272 + { 273 + struct rsa_key *pkey = akcipher_tfm_ctx(tfm); 274 + 275 + return rsa_parse_key(pkey, key, keylen); 276 + } 277 + 278 + static void rsa_exit_tfm(struct crypto_akcipher *tfm) 279 + { 280 + struct rsa_key *pkey = akcipher_tfm_ctx(tfm); 281 + 282 + rsa_free_key(pkey); 283 + } 284 + 285 + static struct akcipher_alg rsa = { 286 + .encrypt = rsa_enc, 287 + .decrypt = rsa_dec, 288 + .sign = rsa_sign, 289 + .verify = rsa_verify, 290 + .setkey = rsa_setkey, 291 + .exit = rsa_exit_tfm, 292 + .base = { 293 + .cra_name = "rsa", 294 + .cra_driver_name = "rsa-generic", 295 + .cra_priority = 100, 296 + .cra_module = THIS_MODULE, 297 + .cra_ctxsize = sizeof(struct rsa_key), 298 + }, 299 + }; 300 + 301 + static int rsa_init(void) 302 + { 303 + return crypto_register_akcipher(&rsa); 304 + } 305 + 306 + static void rsa_exit(void) 307 + { 308 + crypto_unregister_akcipher(&rsa); 309 + } 310 + 311 + module_init(rsa_init); 312 + module_exit(rsa_exit); 313 + MODULE_ALIAS_CRYPTO("rsa"); 314 + MODULE_LICENSE("GPL"); 315 + MODULE_DESCRIPTION("RSA generic algorithm");
+121
crypto/rsa_helper.c
··· 1 + /* 2 + * RSA key extract helper 3 + * 4 + * Copyright (c) 2015, Intel Corporation 5 + * Authors: Tadeusz Struk <tadeusz.struk@intel.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the Free 9 + * Software Foundation; either version 2 of the License, or (at your option) 10 + * any later version. 11 + * 12 + */ 13 + #include <linux/kernel.h> 14 + #include <linux/export.h> 15 + #include <linux/err.h> 16 + #include <linux/fips.h> 17 + #include <crypto/internal/rsa.h> 18 + #include "rsakey-asn1.h" 19 + 20 + int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, 21 + const void *value, size_t vlen) 22 + { 23 + struct rsa_key *key = context; 24 + 25 + key->n = mpi_read_raw_data(value, vlen); 26 + 27 + if (!key->n) 28 + return -ENOMEM; 29 + 30 + /* In FIPS mode only allow key size 2K & 3K */ 31 + if (fips_enabled && (mpi_get_size(key->n) != 256 || 32 + mpi_get_size(key->n) != 384)) { 33 + pr_err("RSA: key size not allowed in FIPS mode\n"); 34 + mpi_free(key->n); 35 + key->n = NULL; 36 + return -EINVAL; 37 + } 38 + return 0; 39 + } 40 + 41 + int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, 42 + const void *value, size_t vlen) 43 + { 44 + struct rsa_key *key = context; 45 + 46 + key->e = mpi_read_raw_data(value, vlen); 47 + 48 + if (!key->e) 49 + return -ENOMEM; 50 + 51 + return 0; 52 + } 53 + 54 + int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, 55 + const void *value, size_t vlen) 56 + { 57 + struct rsa_key *key = context; 58 + 59 + key->d = mpi_read_raw_data(value, vlen); 60 + 61 + if (!key->d) 62 + return -ENOMEM; 63 + 64 + /* In FIPS mode only allow key size 2K & 3K */ 65 + if (fips_enabled && (mpi_get_size(key->d) != 256 || 66 + mpi_get_size(key->d) != 384)) { 67 + pr_err("RSA: key size not allowed in FIPS mode\n"); 68 + mpi_free(key->d); 69 + key->d = NULL; 70 + return -EINVAL; 71 + } 72 + return 0; 73 + } 74 + 75 + static void free_mpis(struct rsa_key *key) 76 + { 77 + mpi_free(key->n); 78 + mpi_free(key->e); 79 + mpi_free(key->d); 80 + key->n = NULL; 81 + key->e = NULL; 82 + key->d = NULL; 83 + } 84 + 85 + /** 86 + * rsa_free_key() - frees rsa key allocated by rsa_parse_key() 87 + * 88 + * @rsa_key: struct rsa_key key representation 89 + */ 90 + void rsa_free_key(struct rsa_key *key) 91 + { 92 + free_mpis(key); 93 + } 94 + EXPORT_SYMBOL_GPL(rsa_free_key); 95 + 96 + /** 97 + * rsa_parse_key() - extracts an rsa key from BER encoded buffer 98 + * and stores it in the provided struct rsa_key 99 + * 100 + * @rsa_key: struct rsa_key key representation 101 + * @key: key in BER format 102 + * @key_len: length of key 103 + * 104 + * Return: 0 on success or error code in case of error 105 + */ 106 + int rsa_parse_key(struct rsa_key *rsa_key, const void *key, 107 + unsigned int key_len) 108 + { 109 + int ret; 110 + 111 + free_mpis(rsa_key); 112 + ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len); 113 + if (ret < 0) 114 + goto error; 115 + 116 + return 0; 117 + error: 118 + free_mpis(rsa_key); 119 + return ret; 120 + } 121 + EXPORT_SYMBOL_GPL(rsa_parse_key);
+5
crypto/rsakey.asn1
··· 1 + RsaKey ::= SEQUENCE { 2 + n INTEGER ({ rsa_get_n }), 3 + e INTEGER ({ rsa_get_e }), 4 + d INTEGER ({ rsa_get_d }) 5 + }
+27
include/crypto/internal/rsa.h
··· 1 + /* 2 + * RSA internal helpers 3 + * 4 + * Copyright (c) 2015, Intel Corporation 5 + * Authors: Tadeusz Struk <tadeusz.struk@intel.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the Free 9 + * Software Foundation; either version 2 of the License, or (at your option) 10 + * any later version. 11 + * 12 + */ 13 + #ifndef _RSA_HELPER_ 14 + #define _RSA_HELPER_ 15 + #include <linux/mpi.h> 16 + 17 + struct rsa_key { 18 + MPI n; 19 + MPI e; 20 + MPI d; 21 + }; 22 + 23 + int rsa_parse_key(struct rsa_key *rsa_key, const void *key, 24 + unsigned int key_len); 25 + 26 + void rsa_free_key(struct rsa_key *rsa_key); 27 + #endif