linux/crypto/rsa.c
<<
>>
Prefs
   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#include <crypto/algapi.h>
  17
  18/*
  19 * RSAEP function [RFC3447 sec 5.1.1]
  20 * c = m^e mod n;
  21 */
  22static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m)
  23{
  24        /* (1) Validate 0 <= m < n */
  25        if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
  26                return -EINVAL;
  27
  28        /* (2) c = m^e mod n */
  29        return mpi_powm(c, m, key->e, key->n);
  30}
  31
  32/*
  33 * RSADP function [RFC3447 sec 5.1.2]
  34 * m = c^d mod n;
  35 */
  36static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c)
  37{
  38        /* (1) Validate 0 <= c < n */
  39        if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
  40                return -EINVAL;
  41
  42        /* (2) m = c^d mod n */
  43        return mpi_powm(m, c, key->d, key->n);
  44}
  45
  46/*
  47 * RSASP1 function [RFC3447 sec 5.2.1]
  48 * s = m^d mod n
  49 */
  50static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m)
  51{
  52        /* (1) Validate 0 <= m < n */
  53        if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
  54                return -EINVAL;
  55
  56        /* (2) s = m^d mod n */
  57        return mpi_powm(s, m, key->d, key->n);
  58}
  59
  60/*
  61 * RSAVP1 function [RFC3447 sec 5.2.2]
  62 * m = s^e mod n;
  63 */
  64static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s)
  65{
  66        /* (1) Validate 0 <= s < n */
  67        if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0)
  68                return -EINVAL;
  69
  70        /* (2) m = s^e mod n */
  71        return mpi_powm(m, s, key->e, key->n);
  72}
  73
  74static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm)
  75{
  76        return akcipher_tfm_ctx(tfm);
  77}
  78
  79static int rsa_enc(struct akcipher_request *req)
  80{
  81        struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  82        const struct rsa_key *pkey = rsa_get_key(tfm);
  83        MPI m, c = mpi_alloc(0);
  84        int ret = 0;
  85        int sign;
  86
  87        if (!c)
  88                return -ENOMEM;
  89
  90        if (unlikely(!pkey->n || !pkey->e)) {
  91                ret = -EINVAL;
  92                goto err_free_c;
  93        }
  94
  95        ret = -ENOMEM;
  96        m = mpi_read_raw_from_sgl(req->src, req->src_len);
  97        if (!m)
  98                goto err_free_c;
  99
 100        ret = _rsa_enc(pkey, c, m);
 101        if (ret)
 102                goto err_free_m;
 103
 104        ret = mpi_write_to_sgl(c, req->dst, &req->dst_len, &sign);
 105        if (ret)
 106                goto err_free_m;
 107
 108        if (sign < 0)
 109                ret = -EBADMSG;
 110
 111err_free_m:
 112        mpi_free(m);
 113err_free_c:
 114        mpi_free(c);
 115        return ret;
 116}
 117
 118static int rsa_dec(struct akcipher_request *req)
 119{
 120        struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 121        const struct rsa_key *pkey = rsa_get_key(tfm);
 122        MPI c, m = mpi_alloc(0);
 123        int ret = 0;
 124        int sign;
 125
 126        if (!m)
 127                return -ENOMEM;
 128
 129        if (unlikely(!pkey->n || !pkey->d)) {
 130                ret = -EINVAL;
 131                goto err_free_m;
 132        }
 133
 134        ret = -ENOMEM;
 135        c = mpi_read_raw_from_sgl(req->src, req->src_len);
 136        if (!c)
 137                goto err_free_m;
 138
 139        ret = _rsa_dec(pkey, m, c);
 140        if (ret)
 141                goto err_free_c;
 142
 143        ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
 144        if (ret)
 145                goto err_free_c;
 146
 147        if (sign < 0)
 148                ret = -EBADMSG;
 149err_free_c:
 150        mpi_free(c);
 151err_free_m:
 152        mpi_free(m);
 153        return ret;
 154}
 155
 156static int rsa_sign(struct akcipher_request *req)
 157{
 158        struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 159        const struct rsa_key *pkey = rsa_get_key(tfm);
 160        MPI m, s = mpi_alloc(0);
 161        int ret = 0;
 162        int sign;
 163
 164        if (!s)
 165                return -ENOMEM;
 166
 167        if (unlikely(!pkey->n || !pkey->d)) {
 168                ret = -EINVAL;
 169                goto err_free_s;
 170        }
 171
 172        ret = -ENOMEM;
 173        m = mpi_read_raw_from_sgl(req->src, req->src_len);
 174        if (!m)
 175                goto err_free_s;
 176
 177        ret = _rsa_sign(pkey, s, m);
 178        if (ret)
 179                goto err_free_m;
 180
 181        ret = mpi_write_to_sgl(s, req->dst, &req->dst_len, &sign);
 182        if (ret)
 183                goto err_free_m;
 184
 185        if (sign < 0)
 186                ret = -EBADMSG;
 187
 188err_free_m:
 189        mpi_free(m);
 190err_free_s:
 191        mpi_free(s);
 192        return ret;
 193}
 194
 195static int rsa_verify(struct akcipher_request *req)
 196{
 197        struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 198        const struct rsa_key *pkey = rsa_get_key(tfm);
 199        MPI s, m = mpi_alloc(0);
 200        int ret = 0;
 201        int sign;
 202
 203        if (!m)
 204                return -ENOMEM;
 205
 206        if (unlikely(!pkey->n || !pkey->e)) {
 207                ret = -EINVAL;
 208                goto err_free_m;
 209        }
 210
 211        ret = -ENOMEM;
 212        s = mpi_read_raw_from_sgl(req->src, req->src_len);
 213        if (!s) {
 214                ret = -ENOMEM;
 215                goto err_free_m;
 216        }
 217
 218        ret = _rsa_verify(pkey, m, s);
 219        if (ret)
 220                goto err_free_s;
 221
 222        ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
 223        if (ret)
 224                goto err_free_s;
 225
 226        if (sign < 0)
 227                ret = -EBADMSG;
 228
 229err_free_s:
 230        mpi_free(s);
 231err_free_m:
 232        mpi_free(m);
 233        return ret;
 234}
 235
 236static int rsa_check_key_length(unsigned int len)
 237{
 238        switch (len) {
 239        case 512:
 240        case 1024:
 241        case 1536:
 242        case 2048:
 243        case 3072:
 244        case 4096:
 245                return 0;
 246        }
 247
 248        return -EINVAL;
 249}
 250
 251static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
 252                           unsigned int keylen)
 253{
 254        struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
 255        int ret;
 256
 257        ret = rsa_parse_pub_key(pkey, key, keylen);
 258        if (ret)
 259                return ret;
 260
 261        if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
 262                rsa_free_key(pkey);
 263                ret = -EINVAL;
 264        }
 265        return ret;
 266}
 267
 268static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
 269                            unsigned int keylen)
 270{
 271        struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
 272        int ret;
 273
 274        ret = rsa_parse_priv_key(pkey, key, keylen);
 275        if (ret)
 276                return ret;
 277
 278        if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
 279                rsa_free_key(pkey);
 280                ret = -EINVAL;
 281        }
 282        return ret;
 283}
 284
 285static int rsa_max_size(struct crypto_akcipher *tfm)
 286{
 287        struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
 288
 289        return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
 290}
 291
 292static void rsa_exit_tfm(struct crypto_akcipher *tfm)
 293{
 294        struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
 295
 296        rsa_free_key(pkey);
 297}
 298
 299static struct akcipher_alg rsa = {
 300        .encrypt = rsa_enc,
 301        .decrypt = rsa_dec,
 302        .sign = rsa_sign,
 303        .verify = rsa_verify,
 304        .set_priv_key = rsa_set_priv_key,
 305        .set_pub_key = rsa_set_pub_key,
 306        .max_size = rsa_max_size,
 307        .exit = rsa_exit_tfm,
 308        .base = {
 309                .cra_name = "rsa",
 310                .cra_driver_name = "rsa-generic",
 311                .cra_priority = 100,
 312                .cra_module = THIS_MODULE,
 313                .cra_ctxsize = sizeof(struct rsa_key),
 314        },
 315};
 316
 317static int rsa_init(void)
 318{
 319        int err;
 320
 321        err = crypto_register_akcipher(&rsa);
 322        if (err)
 323                return err;
 324
 325        err = crypto_register_template(&rsa_pkcs1pad_tmpl);
 326        if (err) {
 327                crypto_unregister_akcipher(&rsa);
 328                return err;
 329        }
 330
 331        return 0;
 332}
 333
 334static void rsa_exit(void)
 335{
 336        crypto_unregister_template(&rsa_pkcs1pad_tmpl);
 337        crypto_unregister_akcipher(&rsa);
 338}
 339
 340module_init(rsa_init);
 341module_exit(rsa_exit);
 342MODULE_ALIAS_CRYPTO("rsa");
 343MODULE_LICENSE("GPL");
 344MODULE_DESCRIPTION("RSA generic algorithm");
 345