Move helpers for setting public/private keys, RSA akcipher instance setup, keysize querying etc. to rsa-common.c. Signed-off-by: Varad Gautam <varad.gautam@xxxxxxxx> --- crypto/rsa-common.c | 183 +++++++++++++++++++++++++++ crypto/rsa-pkcs1pad.c | 183 --------------------------- include/crypto/internal/rsa-common.h | 13 ++ 3 files changed, 196 insertions(+), 183 deletions(-) diff --git a/crypto/rsa-common.c b/crypto/rsa-common.c index 60073c56e3748..d70d7d405165f 100644 --- a/crypto/rsa-common.c +++ b/crypto/rsa-common.c @@ -74,3 +74,186 @@ const struct rsa_asn1_template *rsa_lookup_asn1(const char *name) return p; return NULL; } + +int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + int err; + + ctx->key_size = 0; + + err = crypto_akcipher_set_pub_key(ctx->child, key, keylen); + if (err) + return err; + + /* Find out new modulus size from rsa implementation */ + err = crypto_akcipher_maxsize(ctx->child); + if (err > PAGE_SIZE) + return -EOPNOTSUPP; + + ctx->key_size = err; + return 0; +} + +int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + int err; + + ctx->key_size = 0; + + err = crypto_akcipher_set_priv_key(ctx->child, key, keylen); + if (err) + return err; + + /* Find out new modulus size from rsa implementation */ + err = crypto_akcipher_maxsize(ctx->child); + if (err > PAGE_SIZE) + return -EOPNOTSUPP; + + ctx->key_size = err; + return 0; +} + +unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm) +{ + struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + + /* + * The maximum destination buffer size for the encrypt/sign operations + * will be the same as for RSA, even though it's smaller for + * decrypt/verify. + */ + + return ctx->key_size; +} + +void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf, + size_t len, struct scatterlist *next) +{ + int nsegs = next ? 2 : 1; + + sg_init_table(sg, nsegs); + sg_set_buf(sg, buf, len); + + if (next) + sg_chain(sg, nsegs, next); +} + +int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm) +{ + struct akcipher_instance *inst = akcipher_alg_instance(tfm); + struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst); + struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + struct crypto_akcipher *child_tfm; + + child_tfm = crypto_spawn_akcipher(&ictx->spawn); + if (IS_ERR(child_tfm)) + return PTR_ERR(child_tfm); + + ctx->child = child_tfm; + return 0; +} + +void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm) +{ + struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + + crypto_free_akcipher(ctx->child); +} + +void rsapad_akcipher_free(struct akcipher_instance *inst) +{ + struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst); + struct crypto_akcipher_spawn *spawn = &ctx->spawn; + + crypto_drop_akcipher(spawn); + kfree(inst); +} + +int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb, + struct akcipher_alg *alg) +{ + u32 mask; + struct akcipher_instance *inst; + struct rsapad_inst_ctx *ctx; + struct akcipher_alg *rsa_alg; + const char *hash_name; + int err; + + err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask); + if (err) + return err; + + inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); + if (!inst) + return -ENOMEM; + + ctx = akcipher_instance_ctx(inst); + + err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst), + crypto_attr_alg_name(tb[1]), 0, mask); + if (err) + goto err_free_inst; + + rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn); + + err = -ENAMETOOLONG; + hash_name = crypto_attr_alg_name(tb[2]); + if (IS_ERR(hash_name)) { + if (snprintf(inst->alg.base.cra_name, + CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name, + rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + + if (snprintf(inst->alg.base.cra_driver_name, + CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name, + rsa_alg->base.cra_driver_name) >= + CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + } else { + ctx->digest_info = rsa_lookup_asn1(hash_name); + if (!ctx->digest_info) { + err = -EINVAL; + goto err_free_inst; + } + + if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, + "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name, + hash_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + + if (snprintf(inst->alg.base.cra_driver_name, + CRYPTO_MAX_ALG_NAME, "%s(%s,%s)", + tmpl->name, + rsa_alg->base.cra_driver_name, + hash_name) >= CRYPTO_MAX_ALG_NAME) + goto err_free_inst; + } + + inst->alg.base.cra_priority = rsa_alg->base.cra_priority; + inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx); + + inst->alg.init = alg->init; + inst->alg.exit = alg->exit; + + inst->alg.encrypt = alg->encrypt; + inst->alg.decrypt = alg->decrypt; + inst->alg.sign = alg->sign; + inst->alg.verify = alg->verify; + inst->alg.set_pub_key = alg->set_pub_key; + inst->alg.set_priv_key = alg->set_priv_key; + inst->alg.max_size = alg->max_size; + inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize; + + inst->free = rsapad_akcipher_free; + + err = akcipher_register_instance(tmpl, inst); + if (err) { +err_free_inst: + rsapad_akcipher_free(inst); + } + return err; +} diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index ffb7220b3d10a..30b0193b7352a 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -9,73 +9,6 @@ #include <linux/module.h> #include <linux/random.h> -static int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key, - unsigned int keylen) -{ - struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); - int err; - - ctx->key_size = 0; - - err = crypto_akcipher_set_pub_key(ctx->child, key, keylen); - if (err) - return err; - - /* Find out new modulus size from rsa implementation */ - err = crypto_akcipher_maxsize(ctx->child); - if (err > PAGE_SIZE) - return -ENOTSUPP; - - ctx->key_size = err; - return 0; -} - -static int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key, - unsigned int keylen) -{ - struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); - int err; - - ctx->key_size = 0; - - err = crypto_akcipher_set_priv_key(ctx->child, key, keylen); - if (err) - return err; - - /* Find out new modulus size from rsa implementation */ - err = crypto_akcipher_maxsize(ctx->child); - if (err > PAGE_SIZE) - return -ENOTSUPP; - - ctx->key_size = err; - return 0; -} - -static unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm) -{ - struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); - - /* - * The maximum destination buffer size for the encrypt/sign operations - * will be the same as for RSA, even though it's smaller for - * decrypt/verify. - */ - - return ctx->key_size; -} - -static void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf, - size_t len, struct scatterlist *next) -{ - int nsegs = next ? 2 : 1; - - sg_init_table(sg, nsegs); - sg_set_buf(sg, buf, len); - - if (next) - sg_chain(sg, nsegs, next); -} - typedef int (*rsa_akcipher_complete_cb)(struct akcipher_request *, int); static void rsapad_akcipher_req_complete(struct crypto_async_request *child_async_req, int err, rsa_akcipher_complete_cb cb) @@ -461,37 +394,6 @@ static int pkcs1pad_verify(struct akcipher_request *req) return err; } -static int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm) -{ - struct akcipher_instance *inst = akcipher_alg_instance(tfm); - struct rsapad_inst_ctx *ictx = akcipher_instance_ctx(inst); - struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); - struct crypto_akcipher *child_tfm; - - child_tfm = crypto_spawn_akcipher(&ictx->spawn); - if (IS_ERR(child_tfm)) - return PTR_ERR(child_tfm); - - ctx->child = child_tfm; - return 0; -} - -static void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm) -{ - struct rsapad_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); - - crypto_free_akcipher(ctx->child); -} - -static void rsapad_akcipher_free(struct akcipher_instance *inst) -{ - struct rsapad_inst_ctx *ctx = akcipher_instance_ctx(inst); - struct crypto_akcipher_spawn *spawn = &ctx->spawn; - - crypto_drop_akcipher(spawn); - kfree(inst); -} - static struct akcipher_alg pkcs1pad_alg = { .init = rsapad_akcipher_init_tfm, .exit = rsapad_akcipher_exit_tfm, @@ -505,91 +407,6 @@ static struct akcipher_alg pkcs1pad_alg = { .max_size = rsapad_get_max_size }; -static int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb, - struct akcipher_alg *alg) -{ - u32 mask; - struct akcipher_instance *inst; - struct rsapad_inst_ctx *ctx; - struct akcipher_alg *rsa_alg; - const char *hash_name; - int err; - - err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask); - if (err) - return err; - - inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); - if (!inst) - return -ENOMEM; - - ctx = akcipher_instance_ctx(inst); - - err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst), - crypto_attr_alg_name(tb[1]), 0, mask); - if (err) - goto err_free_inst; - - rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn); - - err = -ENAMETOOLONG; - hash_name = crypto_attr_alg_name(tb[2]); - if (IS_ERR(hash_name)) { - if (snprintf(inst->alg.base.cra_name, - CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name, - rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) - goto err_free_inst; - - if (snprintf(inst->alg.base.cra_driver_name, - CRYPTO_MAX_ALG_NAME, "%s(%s)", tmpl->name, - rsa_alg->base.cra_driver_name) >= - CRYPTO_MAX_ALG_NAME) - goto err_free_inst; - } else { - ctx->digest_info = rsa_lookup_asn1(hash_name); - if (!ctx->digest_info) { - err = -EINVAL; - goto err_free_inst; - } - - if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, - "%s(%s,%s)", tmpl->name, rsa_alg->base.cra_name, - hash_name) >= CRYPTO_MAX_ALG_NAME) - goto err_free_inst; - - if (snprintf(inst->alg.base.cra_driver_name, - CRYPTO_MAX_ALG_NAME, "%s(%s,%s)", - tmpl->name, - rsa_alg->base.cra_driver_name, - hash_name) >= CRYPTO_MAX_ALG_NAME) - goto err_free_inst; - } - - inst->alg.base.cra_priority = rsa_alg->base.cra_priority; - inst->alg.base.cra_ctxsize = sizeof(struct rsapad_tfm_ctx); - - inst->alg.init = alg->init; - inst->alg.exit = alg->exit; - - inst->alg.encrypt = alg->encrypt; - inst->alg.decrypt = alg->decrypt; - inst->alg.sign = alg->sign; - inst->alg.verify = alg->verify; - inst->alg.set_pub_key = alg->set_pub_key; - inst->alg.set_priv_key = alg->set_priv_key; - inst->alg.max_size = alg->max_size; - inst->alg.reqsize = sizeof(struct rsapad_akciper_req_ctx) + rsa_alg->reqsize; - - inst->free = rsapad_akcipher_free; - - err = akcipher_register_instance(tmpl, inst); - if (err) { -err_free_inst: - rsapad_akcipher_free(inst); - } - return err; -} - static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) { return rsapad_akcipher_create(tmpl, tb, &pkcs1pad_alg); diff --git a/include/crypto/internal/rsa-common.h b/include/crypto/internal/rsa-common.h index ecdce0cdafaa3..a6f20cce610ab 100644 --- a/include/crypto/internal/rsa-common.h +++ b/include/crypto/internal/rsa-common.h @@ -34,4 +34,17 @@ struct rsapad_akciper_req_ctx { struct akcipher_request child_req; }; +int rsapad_set_pub_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen); +int rsapad_set_priv_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen); +unsigned int rsapad_get_max_size(struct crypto_akcipher *tfm); +void rsapad_akcipher_sg_set_buf(struct scatterlist *sg, void *buf, + size_t len, struct scatterlist *next); +int rsapad_akcipher_init_tfm(struct crypto_akcipher *tfm); +void rsapad_akcipher_exit_tfm(struct crypto_akcipher *tfm); +void rsapad_akcipher_free(struct akcipher_instance *inst); +int rsapad_akcipher_create(struct crypto_template *tmpl, struct rtattr **tb, + struct akcipher_alg *alg); + #endif -- 2.30.2