xref: /openbmc/linux/crypto/rsa.c (revision 2831f4d3)
1b4d0d230SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2cfc2bb32STadeusz Struk /* RSA asymmetric public-key algorithm [RFC3447]
3cfc2bb32STadeusz Struk  *
4cfc2bb32STadeusz Struk  * Copyright (c) 2015, Intel Corporation
5cfc2bb32STadeusz Struk  * Authors: Tadeusz Struk <tadeusz.struk@intel.com>
6cfc2bb32STadeusz Struk  */
7cfc2bb32STadeusz Struk 
81ce1baccSStephan Müller #include <linux/fips.h>
9cfc2bb32STadeusz Struk #include <linux/module.h>
105a7de973STudor Ambarus #include <linux/mpi.h>
11cfc2bb32STadeusz Struk #include <crypto/internal/rsa.h>
12cfc2bb32STadeusz Struk #include <crypto/internal/akcipher.h>
13cfc2bb32STadeusz Struk #include <crypto/akcipher.h>
143d5b1ecdSAndrzej Zaborowski #include <crypto/algapi.h>
15cfc2bb32STadeusz Struk 
165a7de973STudor Ambarus struct rsa_mpi_key {
175a7de973STudor Ambarus 	MPI n;
185a7de973STudor Ambarus 	MPI e;
195a7de973STudor Ambarus 	MPI d;
20f145d411SIgnat Korchagin 	MPI p;
21f145d411SIgnat Korchagin 	MPI q;
22f145d411SIgnat Korchagin 	MPI dp;
23f145d411SIgnat Korchagin 	MPI dq;
24f145d411SIgnat Korchagin 	MPI qinv;
255a7de973STudor Ambarus };
265a7de973STudor Ambarus 
27cfc2bb32STadeusz Struk /*
28cfc2bb32STadeusz Struk  * RSAEP function [RFC3447 sec 5.1.1]
29cfc2bb32STadeusz Struk  * c = m^e mod n;
30cfc2bb32STadeusz Struk  */
_rsa_enc(const struct rsa_mpi_key * key,MPI c,MPI m)315a7de973STudor Ambarus static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m)
32cfc2bb32STadeusz Struk {
33cfc2bb32STadeusz Struk 	/* (1) Validate 0 <= m < n */
34cfc2bb32STadeusz Struk 	if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0)
35cfc2bb32STadeusz Struk 		return -EINVAL;
36cfc2bb32STadeusz Struk 
37cfc2bb32STadeusz Struk 	/* (2) c = m^e mod n */
38cfc2bb32STadeusz Struk 	return mpi_powm(c, m, key->e, key->n);
39cfc2bb32STadeusz Struk }
40cfc2bb32STadeusz Struk 
41cfc2bb32STadeusz Struk /*
42cfc2bb32STadeusz Struk  * RSADP function [RFC3447 sec 5.1.2]
43f145d411SIgnat Korchagin  * m_1 = c^dP mod p;
44f145d411SIgnat Korchagin  * m_2 = c^dQ mod q;
45f145d411SIgnat Korchagin  * h = (m_1 - m_2) * qInv mod p;
46f145d411SIgnat Korchagin  * m = m_2 + q * h;
47cfc2bb32STadeusz Struk  */
_rsa_dec_crt(const struct rsa_mpi_key * key,MPI m_or_m1_or_h,MPI c)48f145d411SIgnat Korchagin static int _rsa_dec_crt(const struct rsa_mpi_key *key, MPI m_or_m1_or_h, MPI c)
49cfc2bb32STadeusz Struk {
50f145d411SIgnat Korchagin 	MPI m2, m12_or_qh;
51f145d411SIgnat Korchagin 	int ret = -ENOMEM;
52f145d411SIgnat Korchagin 
53cfc2bb32STadeusz Struk 	/* (1) Validate 0 <= c < n */
54cfc2bb32STadeusz Struk 	if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
55cfc2bb32STadeusz Struk 		return -EINVAL;
56cfc2bb32STadeusz Struk 
57f145d411SIgnat Korchagin 	m2 = mpi_alloc(0);
58f145d411SIgnat Korchagin 	m12_or_qh = mpi_alloc(0);
59f145d411SIgnat Korchagin 	if (!m2 || !m12_or_qh)
60f145d411SIgnat Korchagin 		goto err_free_mpi;
61f145d411SIgnat Korchagin 
62f145d411SIgnat Korchagin 	/* (2i) m_1 = c^dP mod p */
63f145d411SIgnat Korchagin 	ret = mpi_powm(m_or_m1_or_h, c, key->dp, key->p);
64f145d411SIgnat Korchagin 	if (ret)
65f145d411SIgnat Korchagin 		goto err_free_mpi;
66f145d411SIgnat Korchagin 
67f145d411SIgnat Korchagin 	/* (2i) m_2 = c^dQ mod q */
68f145d411SIgnat Korchagin 	ret = mpi_powm(m2, c, key->dq, key->q);
69f145d411SIgnat Korchagin 	if (ret)
70f145d411SIgnat Korchagin 		goto err_free_mpi;
71f145d411SIgnat Korchagin 
72f145d411SIgnat Korchagin 	/* (2iii) h = (m_1 - m_2) * qInv mod p */
73f145d411SIgnat Korchagin 	mpi_sub(m12_or_qh, m_or_m1_or_h, m2);
74f145d411SIgnat Korchagin 	mpi_mulm(m_or_m1_or_h, m12_or_qh, key->qinv, key->p);
75f145d411SIgnat Korchagin 
76f145d411SIgnat Korchagin 	/* (2iv) m = m_2 + q * h */
77f145d411SIgnat Korchagin 	mpi_mul(m12_or_qh, key->q, m_or_m1_or_h);
78f145d411SIgnat Korchagin 	mpi_addm(m_or_m1_or_h, m2, m12_or_qh, key->n);
79f145d411SIgnat Korchagin 
80f145d411SIgnat Korchagin 	ret = 0;
81f145d411SIgnat Korchagin 
82f145d411SIgnat Korchagin err_free_mpi:
83f145d411SIgnat Korchagin 	mpi_free(m12_or_qh);
84f145d411SIgnat Korchagin 	mpi_free(m2);
85f145d411SIgnat Korchagin 	return ret;
86cfc2bb32STadeusz Struk }
87cfc2bb32STadeusz Struk 
rsa_get_key(struct crypto_akcipher * tfm)885a7de973STudor Ambarus static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
89cfc2bb32STadeusz Struk {
90cfc2bb32STadeusz Struk 	return akcipher_tfm_ctx(tfm);
91cfc2bb32STadeusz Struk }
92cfc2bb32STadeusz Struk 
rsa_enc(struct akcipher_request * req)93cfc2bb32STadeusz Struk static int rsa_enc(struct akcipher_request *req)
94cfc2bb32STadeusz Struk {
95cfc2bb32STadeusz Struk 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
965a7de973STudor Ambarus 	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
97cfc2bb32STadeusz Struk 	MPI m, c = mpi_alloc(0);
98cfc2bb32STadeusz Struk 	int ret = 0;
99cfc2bb32STadeusz Struk 	int sign;
100cfc2bb32STadeusz Struk 
101cfc2bb32STadeusz Struk 	if (!c)
102cfc2bb32STadeusz Struk 		return -ENOMEM;
103cfc2bb32STadeusz Struk 
104cfc2bb32STadeusz Struk 	if (unlikely(!pkey->n || !pkey->e)) {
105cfc2bb32STadeusz Struk 		ret = -EINVAL;
106cfc2bb32STadeusz Struk 		goto err_free_c;
107cfc2bb32STadeusz Struk 	}
108cfc2bb32STadeusz Struk 
109cfc2bb32STadeusz Struk 	ret = -ENOMEM;
11022287b0bSTadeusz Struk 	m = mpi_read_raw_from_sgl(req->src, req->src_len);
11122287b0bSTadeusz Struk 	if (!m)
112cfc2bb32STadeusz Struk 		goto err_free_c;
113cfc2bb32STadeusz Struk 
114cfc2bb32STadeusz Struk 	ret = _rsa_enc(pkey, c, m);
115cfc2bb32STadeusz Struk 	if (ret)
116cfc2bb32STadeusz Struk 		goto err_free_m;
117cfc2bb32STadeusz Struk 
1189b45b7bbSHerbert Xu 	ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign);
119cfc2bb32STadeusz Struk 	if (ret)
120cfc2bb32STadeusz Struk 		goto err_free_m;
121cfc2bb32STadeusz Struk 
12222287b0bSTadeusz Struk 	if (sign < 0)
123cfc2bb32STadeusz Struk 		ret = -EBADMSG;
124cfc2bb32STadeusz Struk 
125cfc2bb32STadeusz Struk err_free_m:
126cfc2bb32STadeusz Struk 	mpi_free(m);
127cfc2bb32STadeusz Struk err_free_c:
128cfc2bb32STadeusz Struk 	mpi_free(c);
129cfc2bb32STadeusz Struk 	return ret;
130cfc2bb32STadeusz Struk }
131cfc2bb32STadeusz Struk 
rsa_dec(struct akcipher_request * req)132cfc2bb32STadeusz Struk static int rsa_dec(struct akcipher_request *req)
133cfc2bb32STadeusz Struk {
134cfc2bb32STadeusz Struk 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
1355a7de973STudor Ambarus 	const struct rsa_mpi_key *pkey = rsa_get_key(tfm);
136cfc2bb32STadeusz Struk 	MPI c, m = mpi_alloc(0);
137cfc2bb32STadeusz Struk 	int ret = 0;
138cfc2bb32STadeusz Struk 	int sign;
139cfc2bb32STadeusz Struk 
140cfc2bb32STadeusz Struk 	if (!m)
141cfc2bb32STadeusz Struk 		return -ENOMEM;
142cfc2bb32STadeusz Struk 
143cfc2bb32STadeusz Struk 	if (unlikely(!pkey->n || !pkey->d)) {
144cfc2bb32STadeusz Struk 		ret = -EINVAL;
145cfc2bb32STadeusz Struk 		goto err_free_m;
146cfc2bb32STadeusz Struk 	}
147cfc2bb32STadeusz Struk 
148cfc2bb32STadeusz Struk 	ret = -ENOMEM;
14922287b0bSTadeusz Struk 	c = mpi_read_raw_from_sgl(req->src, req->src_len);
15022287b0bSTadeusz Struk 	if (!c)
151cfc2bb32STadeusz Struk 		goto err_free_m;
152cfc2bb32STadeusz Struk 
153f145d411SIgnat Korchagin 	ret = _rsa_dec_crt(pkey, m, c);
154cfc2bb32STadeusz Struk 	if (ret)
155cfc2bb32STadeusz Struk 		goto err_free_c;
156cfc2bb32STadeusz Struk 
1579b45b7bbSHerbert Xu 	ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign);
158cfc2bb32STadeusz Struk 	if (ret)
159cfc2bb32STadeusz Struk 		goto err_free_c;
160cfc2bb32STadeusz Struk 
16122287b0bSTadeusz Struk 	if (sign < 0)
162cfc2bb32STadeusz Struk 		ret = -EBADMSG;
163cfc2bb32STadeusz Struk err_free_c:
164cfc2bb32STadeusz Struk 	mpi_free(c);
165cfc2bb32STadeusz Struk err_free_m:
166cfc2bb32STadeusz Struk 	mpi_free(m);
167cfc2bb32STadeusz Struk 	return ret;
168cfc2bb32STadeusz Struk }
169cfc2bb32STadeusz Struk 
rsa_free_mpi_key(struct rsa_mpi_key * key)1705a7de973STudor Ambarus static void rsa_free_mpi_key(struct rsa_mpi_key *key)
1715a7de973STudor Ambarus {
1725a7de973STudor Ambarus 	mpi_free(key->d);
1735a7de973STudor Ambarus 	mpi_free(key->e);
1745a7de973STudor Ambarus 	mpi_free(key->n);
175f145d411SIgnat Korchagin 	mpi_free(key->p);
176f145d411SIgnat Korchagin 	mpi_free(key->q);
177f145d411SIgnat Korchagin 	mpi_free(key->dp);
178f145d411SIgnat Korchagin 	mpi_free(key->dq);
179f145d411SIgnat Korchagin 	mpi_free(key->qinv);
1805a7de973STudor Ambarus 	key->d = NULL;
1815a7de973STudor Ambarus 	key->e = NULL;
1825a7de973STudor Ambarus 	key->n = NULL;
183f145d411SIgnat Korchagin 	key->p = NULL;
184f145d411SIgnat Korchagin 	key->q = NULL;
185f145d411SIgnat Korchagin 	key->dp = NULL;
186f145d411SIgnat Korchagin 	key->dq = NULL;
187f145d411SIgnat Korchagin 	key->qinv = NULL;
1885a7de973STudor Ambarus }
1895a7de973STudor Ambarus 
rsa_check_key_length(unsigned int len)1906e8ec66cSTadeusz Struk static int rsa_check_key_length(unsigned int len)
1916e8ec66cSTadeusz Struk {
1926e8ec66cSTadeusz Struk 	switch (len) {
1936e8ec66cSTadeusz Struk 	case 512:
1946e8ec66cSTadeusz Struk 	case 1024:
1956e8ec66cSTadeusz Struk 	case 1536:
1961ce1baccSStephan Müller 		if (fips_enabled)
1971ce1baccSStephan Müller 			return -EINVAL;
1981ce1baccSStephan Müller 		fallthrough;
1996e8ec66cSTadeusz Struk 	case 2048:
2006e8ec66cSTadeusz Struk 	case 3072:
2016e8ec66cSTadeusz Struk 	case 4096:
2026e8ec66cSTadeusz Struk 		return 0;
2036e8ec66cSTadeusz Struk 	}
2046e8ec66cSTadeusz Struk 
2056e8ec66cSTadeusz Struk 	return -EINVAL;
2066e8ec66cSTadeusz Struk }
2076e8ec66cSTadeusz Struk 
rsa_check_exponent_fips(MPI e)2086637e11eSMahmoud Adam static int rsa_check_exponent_fips(MPI e)
2096637e11eSMahmoud Adam {
2106637e11eSMahmoud Adam 	MPI e_max = NULL;
2116637e11eSMahmoud Adam 
2126637e11eSMahmoud Adam 	/* check if odd */
2136637e11eSMahmoud Adam 	if (!mpi_test_bit(e, 0)) {
2146637e11eSMahmoud Adam 		return -EINVAL;
2156637e11eSMahmoud Adam 	}
2166637e11eSMahmoud Adam 
2176637e11eSMahmoud Adam 	/* check if 2^16 < e < 2^256. */
2186637e11eSMahmoud Adam 	if (mpi_cmp_ui(e, 65536) <= 0) {
2196637e11eSMahmoud Adam 		return -EINVAL;
2206637e11eSMahmoud Adam 	}
2216637e11eSMahmoud Adam 
2226637e11eSMahmoud Adam 	e_max = mpi_alloc(0);
223*2831f4d3SDan Carpenter 	if (!e_max)
224*2831f4d3SDan Carpenter 		return -ENOMEM;
2256637e11eSMahmoud Adam 	mpi_set_bit(e_max, 256);
2266637e11eSMahmoud Adam 
2276637e11eSMahmoud Adam 	if (mpi_cmp(e, e_max) >= 0) {
2286637e11eSMahmoud Adam 		mpi_free(e_max);
2296637e11eSMahmoud Adam 		return -EINVAL;
2306637e11eSMahmoud Adam 	}
2316637e11eSMahmoud Adam 
2326637e11eSMahmoud Adam 	mpi_free(e_max);
2336637e11eSMahmoud Adam 	return 0;
2346637e11eSMahmoud Adam }
2356637e11eSMahmoud Adam 
rsa_set_pub_key(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)23622287b0bSTadeusz Struk static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
237cfc2bb32STadeusz Struk 			   unsigned int keylen)
238cfc2bb32STadeusz Struk {
2395a7de973STudor Ambarus 	struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
2405a7de973STudor Ambarus 	struct rsa_key raw_key = {0};
2416e8ec66cSTadeusz Struk 	int ret;
242cfc2bb32STadeusz Struk 
2435a7de973STudor Ambarus 	/* Free the old MPI key if any */
2445a7de973STudor Ambarus 	rsa_free_mpi_key(mpi_key);
2455a7de973STudor Ambarus 
2465a7de973STudor Ambarus 	ret = rsa_parse_pub_key(&raw_key, key, keylen);
2476e8ec66cSTadeusz Struk 	if (ret)
2486e8ec66cSTadeusz Struk 		return ret;
2496e8ec66cSTadeusz Struk 
2505a7de973STudor Ambarus 	mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
2515a7de973STudor Ambarus 	if (!mpi_key->e)
2525a7de973STudor Ambarus 		goto err;
2535a7de973STudor Ambarus 
2545a7de973STudor Ambarus 	mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
2555a7de973STudor Ambarus 	if (!mpi_key->n)
2565a7de973STudor Ambarus 		goto err;
2575a7de973STudor Ambarus 
2585a7de973STudor Ambarus 	if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
2595a7de973STudor Ambarus 		rsa_free_mpi_key(mpi_key);
2605a7de973STudor Ambarus 		return -EINVAL;
2616e8ec66cSTadeusz Struk 	}
2625a7de973STudor Ambarus 
2636637e11eSMahmoud Adam 	if (fips_enabled && rsa_check_exponent_fips(mpi_key->e)) {
2646637e11eSMahmoud Adam 		rsa_free_mpi_key(mpi_key);
2656637e11eSMahmoud Adam 		return -EINVAL;
2666637e11eSMahmoud Adam 	}
2676637e11eSMahmoud Adam 
2685a7de973STudor Ambarus 	return 0;
2695a7de973STudor Ambarus 
2705a7de973STudor Ambarus err:
2715a7de973STudor Ambarus 	rsa_free_mpi_key(mpi_key);
2725a7de973STudor Ambarus 	return -ENOMEM;
273cfc2bb32STadeusz Struk }
274cfc2bb32STadeusz Struk 
rsa_set_priv_key(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)27522287b0bSTadeusz Struk static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
27622287b0bSTadeusz Struk 			    unsigned int keylen)
27722287b0bSTadeusz Struk {
2785a7de973STudor Ambarus 	struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm);
2795a7de973STudor Ambarus 	struct rsa_key raw_key = {0};
28022287b0bSTadeusz Struk 	int ret;
28122287b0bSTadeusz Struk 
2825a7de973STudor Ambarus 	/* Free the old MPI key if any */
2835a7de973STudor Ambarus 	rsa_free_mpi_key(mpi_key);
2845a7de973STudor Ambarus 
2855a7de973STudor Ambarus 	ret = rsa_parse_priv_key(&raw_key, key, keylen);
28622287b0bSTadeusz Struk 	if (ret)
28722287b0bSTadeusz Struk 		return ret;
28822287b0bSTadeusz Struk 
2895a7de973STudor Ambarus 	mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz);
2905a7de973STudor Ambarus 	if (!mpi_key->d)
2915a7de973STudor Ambarus 		goto err;
2925a7de973STudor Ambarus 
2935a7de973STudor Ambarus 	mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz);
2945a7de973STudor Ambarus 	if (!mpi_key->e)
2955a7de973STudor Ambarus 		goto err;
2965a7de973STudor Ambarus 
2975a7de973STudor Ambarus 	mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz);
2985a7de973STudor Ambarus 	if (!mpi_key->n)
2995a7de973STudor Ambarus 		goto err;
3005a7de973STudor Ambarus 
301f145d411SIgnat Korchagin 	mpi_key->p = mpi_read_raw_data(raw_key.p, raw_key.p_sz);
302f145d411SIgnat Korchagin 	if (!mpi_key->p)
303f145d411SIgnat Korchagin 		goto err;
304f145d411SIgnat Korchagin 
305f145d411SIgnat Korchagin 	mpi_key->q = mpi_read_raw_data(raw_key.q, raw_key.q_sz);
306f145d411SIgnat Korchagin 	if (!mpi_key->q)
307f145d411SIgnat Korchagin 		goto err;
308f145d411SIgnat Korchagin 
309f145d411SIgnat Korchagin 	mpi_key->dp = mpi_read_raw_data(raw_key.dp, raw_key.dp_sz);
310f145d411SIgnat Korchagin 	if (!mpi_key->dp)
311f145d411SIgnat Korchagin 		goto err;
312f145d411SIgnat Korchagin 
313f145d411SIgnat Korchagin 	mpi_key->dq = mpi_read_raw_data(raw_key.dq, raw_key.dq_sz);
314f145d411SIgnat Korchagin 	if (!mpi_key->dq)
315f145d411SIgnat Korchagin 		goto err;
316f145d411SIgnat Korchagin 
317f145d411SIgnat Korchagin 	mpi_key->qinv = mpi_read_raw_data(raw_key.qinv, raw_key.qinv_sz);
318f145d411SIgnat Korchagin 	if (!mpi_key->qinv)
319f145d411SIgnat Korchagin 		goto err;
320f145d411SIgnat Korchagin 
3215a7de973STudor Ambarus 	if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
3225a7de973STudor Ambarus 		rsa_free_mpi_key(mpi_key);
3235a7de973STudor Ambarus 		return -EINVAL;
32422287b0bSTadeusz Struk 	}
3255a7de973STudor Ambarus 
3266637e11eSMahmoud Adam 	if (fips_enabled && rsa_check_exponent_fips(mpi_key->e)) {
3276637e11eSMahmoud Adam 		rsa_free_mpi_key(mpi_key);
3286637e11eSMahmoud Adam 		return -EINVAL;
3296637e11eSMahmoud Adam 	}
3306637e11eSMahmoud Adam 
3315a7de973STudor Ambarus 	return 0;
3325a7de973STudor Ambarus 
3335a7de973STudor Ambarus err:
3345a7de973STudor Ambarus 	rsa_free_mpi_key(mpi_key);
3355a7de973STudor Ambarus 	return -ENOMEM;
33622287b0bSTadeusz Struk }
33722287b0bSTadeusz Struk 
rsa_max_size(struct crypto_akcipher * tfm)3381c23b466STudor-Dan Ambarus static unsigned int rsa_max_size(struct crypto_akcipher *tfm)
33922287b0bSTadeusz Struk {
3405a7de973STudor Ambarus 	struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
34122287b0bSTadeusz Struk 
3421c23b466STudor-Dan Ambarus 	return mpi_get_size(pkey->n);
34322287b0bSTadeusz Struk }
34422287b0bSTadeusz Struk 
rsa_exit_tfm(struct crypto_akcipher * tfm)345cfc2bb32STadeusz Struk static void rsa_exit_tfm(struct crypto_akcipher *tfm)
346cfc2bb32STadeusz Struk {
3475a7de973STudor Ambarus 	struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm);
348cfc2bb32STadeusz Struk 
3495a7de973STudor Ambarus 	rsa_free_mpi_key(pkey);
350cfc2bb32STadeusz Struk }
351cfc2bb32STadeusz Struk 
352cfc2bb32STadeusz Struk static struct akcipher_alg rsa = {
353cfc2bb32STadeusz Struk 	.encrypt = rsa_enc,
354cfc2bb32STadeusz Struk 	.decrypt = rsa_dec,
35522287b0bSTadeusz Struk 	.set_priv_key = rsa_set_priv_key,
35622287b0bSTadeusz Struk 	.set_pub_key = rsa_set_pub_key,
35722287b0bSTadeusz Struk 	.max_size = rsa_max_size,
358cfc2bb32STadeusz Struk 	.exit = rsa_exit_tfm,
359cfc2bb32STadeusz Struk 	.base = {
360cfc2bb32STadeusz Struk 		.cra_name = "rsa",
361cfc2bb32STadeusz Struk 		.cra_driver_name = "rsa-generic",
362cfc2bb32STadeusz Struk 		.cra_priority = 100,
363cfc2bb32STadeusz Struk 		.cra_module = THIS_MODULE,
3645a7de973STudor Ambarus 		.cra_ctxsize = sizeof(struct rsa_mpi_key),
365cfc2bb32STadeusz Struk 	},
366cfc2bb32STadeusz Struk };
367cfc2bb32STadeusz Struk 
rsa_init(void)36833837be3SXiu Jianfeng static int __init rsa_init(void)
369cfc2bb32STadeusz Struk {
3703d5b1ecdSAndrzej Zaborowski 	int err;
3713d5b1ecdSAndrzej Zaborowski 
3723d5b1ecdSAndrzej Zaborowski 	err = crypto_register_akcipher(&rsa);
3733d5b1ecdSAndrzej Zaborowski 	if (err)
3743d5b1ecdSAndrzej Zaborowski 		return err;
3753d5b1ecdSAndrzej Zaborowski 
3763d5b1ecdSAndrzej Zaborowski 	err = crypto_register_template(&rsa_pkcs1pad_tmpl);
3773d5b1ecdSAndrzej Zaborowski 	if (err) {
3783d5b1ecdSAndrzej Zaborowski 		crypto_unregister_akcipher(&rsa);
3793d5b1ecdSAndrzej Zaborowski 		return err;
3803d5b1ecdSAndrzej Zaborowski 	}
3813d5b1ecdSAndrzej Zaborowski 
3823d5b1ecdSAndrzej Zaborowski 	return 0;
383cfc2bb32STadeusz Struk }
384cfc2bb32STadeusz Struk 
rsa_exit(void)38533837be3SXiu Jianfeng static void __exit rsa_exit(void)
386cfc2bb32STadeusz Struk {
3873d5b1ecdSAndrzej Zaborowski 	crypto_unregister_template(&rsa_pkcs1pad_tmpl);
388cfc2bb32STadeusz Struk 	crypto_unregister_akcipher(&rsa);
389cfc2bb32STadeusz Struk }
390cfc2bb32STadeusz Struk 
391c4741b23SEric Biggers subsys_initcall(rsa_init);
392cfc2bb32STadeusz Struk module_exit(rsa_exit);
393cfc2bb32STadeusz Struk MODULE_ALIAS_CRYPTO("rsa");
394cfc2bb32STadeusz Struk MODULE_LICENSE("GPL");
395cfc2bb32STadeusz Struk MODULE_DESCRIPTION("RSA generic algorithm");
396