root/crypto/rsa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _rsa_enc
  2. _rsa_dec
  3. rsa_get_key
  4. rsa_enc
  5. rsa_dec
  6. rsa_free_mpi_key
  7. rsa_check_key_length
  8. rsa_set_pub_key
  9. rsa_set_priv_key
  10. rsa_max_size
  11. rsa_exit_tfm
  12. rsa_init
  13. rsa_exit

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

/* [<][>][^][v][top][bottom][index][help] */