162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* RSA asymmetric public-key algorithm [RFC3447] 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2015, Intel Corporation 562306a36Sopenharmony_ci * Authors: Tadeusz Struk <tadeusz.struk@intel.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/fips.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/mpi.h> 1162306a36Sopenharmony_ci#include <crypto/internal/rsa.h> 1262306a36Sopenharmony_ci#include <crypto/internal/akcipher.h> 1362306a36Sopenharmony_ci#include <crypto/akcipher.h> 1462306a36Sopenharmony_ci#include <crypto/algapi.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct rsa_mpi_key { 1762306a36Sopenharmony_ci MPI n; 1862306a36Sopenharmony_ci MPI e; 1962306a36Sopenharmony_ci MPI d; 2062306a36Sopenharmony_ci MPI p; 2162306a36Sopenharmony_ci MPI q; 2262306a36Sopenharmony_ci MPI dp; 2362306a36Sopenharmony_ci MPI dq; 2462306a36Sopenharmony_ci MPI qinv; 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * RSAEP function [RFC3447 sec 5.1.1] 2962306a36Sopenharmony_ci * c = m^e mod n; 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_cistatic int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci /* (1) Validate 0 <= m < n */ 3462306a36Sopenharmony_ci if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) 3562306a36Sopenharmony_ci return -EINVAL; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* (2) c = m^e mod n */ 3862306a36Sopenharmony_ci return mpi_powm(c, m, key->e, key->n); 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* 4262306a36Sopenharmony_ci * RSADP function [RFC3447 sec 5.1.2] 4362306a36Sopenharmony_ci * m_1 = c^dP mod p; 4462306a36Sopenharmony_ci * m_2 = c^dQ mod q; 4562306a36Sopenharmony_ci * h = (m_1 - m_2) * qInv mod p; 4662306a36Sopenharmony_ci * m = m_2 + q * h; 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_cistatic int _rsa_dec_crt(const struct rsa_mpi_key *key, MPI m_or_m1_or_h, MPI c) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci MPI m2, m12_or_qh; 5162306a36Sopenharmony_ci int ret = -ENOMEM; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* (1) Validate 0 <= c < n */ 5462306a36Sopenharmony_ci if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) 5562306a36Sopenharmony_ci return -EINVAL; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci m2 = mpi_alloc(0); 5862306a36Sopenharmony_ci m12_or_qh = mpi_alloc(0); 5962306a36Sopenharmony_ci if (!m2 || !m12_or_qh) 6062306a36Sopenharmony_ci goto err_free_mpi; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* (2i) m_1 = c^dP mod p */ 6362306a36Sopenharmony_ci ret = mpi_powm(m_or_m1_or_h, c, key->dp, key->p); 6462306a36Sopenharmony_ci if (ret) 6562306a36Sopenharmony_ci goto err_free_mpi; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* (2i) m_2 = c^dQ mod q */ 6862306a36Sopenharmony_ci ret = mpi_powm(m2, c, key->dq, key->q); 6962306a36Sopenharmony_ci if (ret) 7062306a36Sopenharmony_ci goto err_free_mpi; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* (2iii) h = (m_1 - m_2) * qInv mod p */ 7362306a36Sopenharmony_ci mpi_sub(m12_or_qh, m_or_m1_or_h, m2); 7462306a36Sopenharmony_ci mpi_mulm(m_or_m1_or_h, m12_or_qh, key->qinv, key->p); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci /* (2iv) m = m_2 + q * h */ 7762306a36Sopenharmony_ci mpi_mul(m12_or_qh, key->q, m_or_m1_or_h); 7862306a36Sopenharmony_ci mpi_addm(m_or_m1_or_h, m2, m12_or_qh, key->n); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci ret = 0; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cierr_free_mpi: 8362306a36Sopenharmony_ci mpi_free(m12_or_qh); 8462306a36Sopenharmony_ci mpi_free(m2); 8562306a36Sopenharmony_ci return ret; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci return akcipher_tfm_ctx(tfm); 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic int rsa_enc(struct akcipher_request *req) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 9662306a36Sopenharmony_ci const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 9762306a36Sopenharmony_ci MPI m, c = mpi_alloc(0); 9862306a36Sopenharmony_ci int ret = 0; 9962306a36Sopenharmony_ci int sign; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci if (!c) 10262306a36Sopenharmony_ci return -ENOMEM; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci if (unlikely(!pkey->n || !pkey->e)) { 10562306a36Sopenharmony_ci ret = -EINVAL; 10662306a36Sopenharmony_ci goto err_free_c; 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci ret = -ENOMEM; 11062306a36Sopenharmony_ci m = mpi_read_raw_from_sgl(req->src, req->src_len); 11162306a36Sopenharmony_ci if (!m) 11262306a36Sopenharmony_ci goto err_free_c; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci ret = _rsa_enc(pkey, c, m); 11562306a36Sopenharmony_ci if (ret) 11662306a36Sopenharmony_ci goto err_free_m; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign); 11962306a36Sopenharmony_ci if (ret) 12062306a36Sopenharmony_ci goto err_free_m; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (sign < 0) 12362306a36Sopenharmony_ci ret = -EBADMSG; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cierr_free_m: 12662306a36Sopenharmony_ci mpi_free(m); 12762306a36Sopenharmony_cierr_free_c: 12862306a36Sopenharmony_ci mpi_free(c); 12962306a36Sopenharmony_ci return ret; 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic int rsa_dec(struct akcipher_request *req) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 13562306a36Sopenharmony_ci const struct rsa_mpi_key *pkey = rsa_get_key(tfm); 13662306a36Sopenharmony_ci MPI c, m = mpi_alloc(0); 13762306a36Sopenharmony_ci int ret = 0; 13862306a36Sopenharmony_ci int sign; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (!m) 14162306a36Sopenharmony_ci return -ENOMEM; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci if (unlikely(!pkey->n || !pkey->d)) { 14462306a36Sopenharmony_ci ret = -EINVAL; 14562306a36Sopenharmony_ci goto err_free_m; 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci ret = -ENOMEM; 14962306a36Sopenharmony_ci c = mpi_read_raw_from_sgl(req->src, req->src_len); 15062306a36Sopenharmony_ci if (!c) 15162306a36Sopenharmony_ci goto err_free_m; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci ret = _rsa_dec_crt(pkey, m, c); 15462306a36Sopenharmony_ci if (ret) 15562306a36Sopenharmony_ci goto err_free_c; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign); 15862306a36Sopenharmony_ci if (ret) 15962306a36Sopenharmony_ci goto err_free_c; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci if (sign < 0) 16262306a36Sopenharmony_ci ret = -EBADMSG; 16362306a36Sopenharmony_cierr_free_c: 16462306a36Sopenharmony_ci mpi_free(c); 16562306a36Sopenharmony_cierr_free_m: 16662306a36Sopenharmony_ci mpi_free(m); 16762306a36Sopenharmony_ci return ret; 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic void rsa_free_mpi_key(struct rsa_mpi_key *key) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci mpi_free(key->d); 17362306a36Sopenharmony_ci mpi_free(key->e); 17462306a36Sopenharmony_ci mpi_free(key->n); 17562306a36Sopenharmony_ci mpi_free(key->p); 17662306a36Sopenharmony_ci mpi_free(key->q); 17762306a36Sopenharmony_ci mpi_free(key->dp); 17862306a36Sopenharmony_ci mpi_free(key->dq); 17962306a36Sopenharmony_ci mpi_free(key->qinv); 18062306a36Sopenharmony_ci key->d = NULL; 18162306a36Sopenharmony_ci key->e = NULL; 18262306a36Sopenharmony_ci key->n = NULL; 18362306a36Sopenharmony_ci key->p = NULL; 18462306a36Sopenharmony_ci key->q = NULL; 18562306a36Sopenharmony_ci key->dp = NULL; 18662306a36Sopenharmony_ci key->dq = NULL; 18762306a36Sopenharmony_ci key->qinv = NULL; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic int rsa_check_key_length(unsigned int len) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci switch (len) { 19362306a36Sopenharmony_ci case 512: 19462306a36Sopenharmony_ci case 1024: 19562306a36Sopenharmony_ci case 1536: 19662306a36Sopenharmony_ci if (fips_enabled) 19762306a36Sopenharmony_ci return -EINVAL; 19862306a36Sopenharmony_ci fallthrough; 19962306a36Sopenharmony_ci case 2048: 20062306a36Sopenharmony_ci case 3072: 20162306a36Sopenharmony_ci case 4096: 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci return -EINVAL; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic int rsa_check_exponent_fips(MPI e) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci MPI e_max = NULL; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci /* check if odd */ 21362306a36Sopenharmony_ci if (!mpi_test_bit(e, 0)) { 21462306a36Sopenharmony_ci return -EINVAL; 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* check if 2^16 < e < 2^256. */ 21862306a36Sopenharmony_ci if (mpi_cmp_ui(e, 65536) <= 0) { 21962306a36Sopenharmony_ci return -EINVAL; 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci e_max = mpi_alloc(0); 22362306a36Sopenharmony_ci if (!e_max) 22462306a36Sopenharmony_ci return -ENOMEM; 22562306a36Sopenharmony_ci mpi_set_bit(e_max, 256); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (mpi_cmp(e, e_max) >= 0) { 22862306a36Sopenharmony_ci mpi_free(e_max); 22962306a36Sopenharmony_ci return -EINVAL; 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci mpi_free(e_max); 23362306a36Sopenharmony_ci return 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, 23762306a36Sopenharmony_ci unsigned int keylen) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 24062306a36Sopenharmony_ci struct rsa_key raw_key = {0}; 24162306a36Sopenharmony_ci int ret; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci /* Free the old MPI key if any */ 24462306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci ret = rsa_parse_pub_key(&raw_key, key, keylen); 24762306a36Sopenharmony_ci if (ret) 24862306a36Sopenharmony_ci return ret; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 25162306a36Sopenharmony_ci if (!mpi_key->e) 25262306a36Sopenharmony_ci goto err; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 25562306a36Sopenharmony_ci if (!mpi_key->n) 25662306a36Sopenharmony_ci goto err; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 25962306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 26062306a36Sopenharmony_ci return -EINVAL; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (fips_enabled && rsa_check_exponent_fips(mpi_key->e)) { 26462306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 26562306a36Sopenharmony_ci return -EINVAL; 26662306a36Sopenharmony_ci } 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci return 0; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cierr: 27162306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 27262306a36Sopenharmony_ci return -ENOMEM; 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cistatic int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, 27662306a36Sopenharmony_ci unsigned int keylen) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci struct rsa_mpi_key *mpi_key = akcipher_tfm_ctx(tfm); 27962306a36Sopenharmony_ci struct rsa_key raw_key = {0}; 28062306a36Sopenharmony_ci int ret; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci /* Free the old MPI key if any */ 28362306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci ret = rsa_parse_priv_key(&raw_key, key, keylen); 28662306a36Sopenharmony_ci if (ret) 28762306a36Sopenharmony_ci return ret; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci mpi_key->d = mpi_read_raw_data(raw_key.d, raw_key.d_sz); 29062306a36Sopenharmony_ci if (!mpi_key->d) 29162306a36Sopenharmony_ci goto err; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci mpi_key->e = mpi_read_raw_data(raw_key.e, raw_key.e_sz); 29462306a36Sopenharmony_ci if (!mpi_key->e) 29562306a36Sopenharmony_ci goto err; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci mpi_key->n = mpi_read_raw_data(raw_key.n, raw_key.n_sz); 29862306a36Sopenharmony_ci if (!mpi_key->n) 29962306a36Sopenharmony_ci goto err; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci mpi_key->p = mpi_read_raw_data(raw_key.p, raw_key.p_sz); 30262306a36Sopenharmony_ci if (!mpi_key->p) 30362306a36Sopenharmony_ci goto err; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci mpi_key->q = mpi_read_raw_data(raw_key.q, raw_key.q_sz); 30662306a36Sopenharmony_ci if (!mpi_key->q) 30762306a36Sopenharmony_ci goto err; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci mpi_key->dp = mpi_read_raw_data(raw_key.dp, raw_key.dp_sz); 31062306a36Sopenharmony_ci if (!mpi_key->dp) 31162306a36Sopenharmony_ci goto err; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci mpi_key->dq = mpi_read_raw_data(raw_key.dq, raw_key.dq_sz); 31462306a36Sopenharmony_ci if (!mpi_key->dq) 31562306a36Sopenharmony_ci goto err; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci mpi_key->qinv = mpi_read_raw_data(raw_key.qinv, raw_key.qinv_sz); 31862306a36Sopenharmony_ci if (!mpi_key->qinv) 31962306a36Sopenharmony_ci goto err; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) { 32262306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 32362306a36Sopenharmony_ci return -EINVAL; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci if (fips_enabled && rsa_check_exponent_fips(mpi_key->e)) { 32762306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 32862306a36Sopenharmony_ci return -EINVAL; 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci return 0; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cierr: 33462306a36Sopenharmony_ci rsa_free_mpi_key(mpi_key); 33562306a36Sopenharmony_ci return -ENOMEM; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic unsigned int rsa_max_size(struct crypto_akcipher *tfm) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci return mpi_get_size(pkey->n); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic void rsa_exit_tfm(struct crypto_akcipher *tfm) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci struct rsa_mpi_key *pkey = akcipher_tfm_ctx(tfm); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci rsa_free_mpi_key(pkey); 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic struct akcipher_alg rsa = { 35362306a36Sopenharmony_ci .encrypt = rsa_enc, 35462306a36Sopenharmony_ci .decrypt = rsa_dec, 35562306a36Sopenharmony_ci .set_priv_key = rsa_set_priv_key, 35662306a36Sopenharmony_ci .set_pub_key = rsa_set_pub_key, 35762306a36Sopenharmony_ci .max_size = rsa_max_size, 35862306a36Sopenharmony_ci .exit = rsa_exit_tfm, 35962306a36Sopenharmony_ci .base = { 36062306a36Sopenharmony_ci .cra_name = "rsa", 36162306a36Sopenharmony_ci .cra_driver_name = "rsa-generic", 36262306a36Sopenharmony_ci .cra_priority = 100, 36362306a36Sopenharmony_ci .cra_module = THIS_MODULE, 36462306a36Sopenharmony_ci .cra_ctxsize = sizeof(struct rsa_mpi_key), 36562306a36Sopenharmony_ci }, 36662306a36Sopenharmony_ci}; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistatic int __init rsa_init(void) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci int err; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci err = crypto_register_akcipher(&rsa); 37362306a36Sopenharmony_ci if (err) 37462306a36Sopenharmony_ci return err; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci err = crypto_register_template(&rsa_pkcs1pad_tmpl); 37762306a36Sopenharmony_ci if (err) { 37862306a36Sopenharmony_ci crypto_unregister_akcipher(&rsa); 37962306a36Sopenharmony_ci return err; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci return 0; 38362306a36Sopenharmony_ci} 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic void __exit rsa_exit(void) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci crypto_unregister_template(&rsa_pkcs1pad_tmpl); 38862306a36Sopenharmony_ci crypto_unregister_akcipher(&rsa); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cisubsys_initcall(rsa_init); 39262306a36Sopenharmony_cimodule_exit(rsa_exit); 39362306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("rsa"); 39462306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 39562306a36Sopenharmony_ciMODULE_DESCRIPTION("RSA generic algorithm"); 396