cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rsa.c (5514B)


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