> -----Original Message----- > From: linux-crypto-owner@xxxxxxxxxxxxxxx [mailto:linux-crypto- > owner@xxxxxxxxxxxxxxx] On Behalf Of Tudor Ambarus > Sent: Wednesday, March 23, 2016 5:04 PM > To: herbert@xxxxxxxxxxxxxxxxxxx; tadeusz.struk@xxxxxxxxx > Cc: linux-crypto@xxxxxxxxxxxxxxx; smueller@xxxxxxxxxx; Horia Ioan Geanta > Neag <horia.geanta@xxxxxxx>; Tudor-Dan Ambarus <tudor- > dan.ambarus@xxxxxxx> > Subject: [PATCH v2 1/4] crypto: rsa - generalize ASN.1 sequences > > Use common ASN.1 sequences for all RSA implementations. > > Give hardware RSA implementations the chance to use the RSA's software > implementation parser even if they are likely to want to use raw integers. > > The parser expects a context that contains at the first address a pointer to a > struct rsa_asn1_action instance that has function pointers to specific parser > actions (return MPI or raw integer keys), followed by a key representation > structure (for MPI or raw integers). > > This approach has the advantage that users can select specific parser actions > by using a general parser with function pointers to specific actions. > > Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@xxxxxxx> Acked-by: Cristian Stoica <cristian.stoica@xxxxxxx> > --- > crypto/rsa.c | 60 ++++++++++----- > crypto/rsa_helper.c | 166 ++++++++++++++++++++++++++++++++---- > ------ > include/crypto/internal/rsa.h | 31 ++++++-- > 3 files changed, 194 insertions(+), 63 deletions(-) > > diff --git a/crypto/rsa.c b/crypto/rsa.c index 77d737f..7cb0153 100644 > --- a/crypto/rsa.c > +++ b/crypto/rsa.c > @@ -19,7 +19,7 @@ > * RSAEP function [RFC3447 sec 5.1.1] > * c = m^e mod n; > */ > -static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m) > +static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m) > { > /* (1) Validate 0 <= m < n */ > if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) @@ -33,7 > +33,7 @@ static int _rsa_enc(const struct rsa_key *key, MPI c, MPI m) > * RSADP function [RFC3447 sec 5.1.2] > * m = c^d mod n; > */ > -static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c) > +static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c) > { > /* (1) Validate 0 <= c < n */ > if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0) @@ -47,7 +47,7 > @@ static int _rsa_dec(const struct rsa_key *key, MPI m, MPI c) > * RSASP1 function [RFC3447 sec 5.2.1] > * s = m^d mod n > */ > -static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m) > +static int _rsa_sign(const struct rsa_mpi_key *key, MPI s, MPI m) > { > /* (1) Validate 0 <= m < n */ > if (mpi_cmp_ui(m, 0) < 0 || mpi_cmp(m, key->n) >= 0) @@ -61,7 > +61,7 @@ static int _rsa_sign(const struct rsa_key *key, MPI s, MPI m) > * RSAVP1 function [RFC3447 sec 5.2.2] > * m = s^e mod n; > */ > -static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s) > +static int _rsa_verify(const struct rsa_mpi_key *key, MPI m, MPI s) > { > /* (1) Validate 0 <= s < n */ > if (mpi_cmp_ui(s, 0) < 0 || mpi_cmp(s, key->n) >= 0) @@ -71,15 > +71,17 @@ static int _rsa_verify(const struct rsa_key *key, MPI m, MPI s) > return mpi_powm(m, s, key->e, key->n); } > > -static inline struct rsa_key *rsa_get_key(struct crypto_akcipher *tfm) > +static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher > +*tfm) > { > - return akcipher_tfm_ctx(tfm); > + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); > + > + return &ctx->key; > } > > static int rsa_enc(struct akcipher_request *req) { > struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); > - const struct rsa_key *pkey = rsa_get_key(tfm); > + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); > MPI m, c = mpi_alloc(0); > int ret = 0; > int sign; > @@ -118,7 +120,7 @@ err_free_c: > static int rsa_dec(struct akcipher_request *req) { > struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); > - const struct rsa_key *pkey = rsa_get_key(tfm); > + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); > MPI c, m = mpi_alloc(0); > int ret = 0; > int sign; > @@ -156,7 +158,7 @@ err_free_m: > static int rsa_sign(struct akcipher_request *req) { > struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); > - const struct rsa_key *pkey = rsa_get_key(tfm); > + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); > MPI m, s = mpi_alloc(0); > int ret = 0; > int sign; > @@ -195,7 +197,7 @@ err_free_s: > static int rsa_verify(struct akcipher_request *req) { > struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); > - const struct rsa_key *pkey = rsa_get_key(tfm); > + const struct rsa_mpi_key *pkey = rsa_get_key(tfm); > MPI s, m = mpi_alloc(0); > int ret = 0; > int sign; > @@ -251,15 +253,16 @@ static int rsa_check_key_length(unsigned int len) > static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, > unsigned int keylen) > { > - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); > + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); > + struct rsa_mpi_key *pkey = &ctx->key; > int ret; > > - ret = rsa_parse_pub_key(pkey, key, keylen); > + ret = rsa_parse_mpi_pub_key(ctx, key, keylen); > if (ret) > return ret; > > if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) { > - rsa_free_key(pkey); > + rsa_free_mpi_key(pkey); > ret = -EINVAL; > } > return ret; > @@ -268,15 +271,16 @@ static int rsa_set_pub_key(struct crypto_akcipher > *tfm, const void *key, static int rsa_set_priv_key(struct crypto_akcipher > *tfm, const void *key, > unsigned int keylen) > { > - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); > + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); > + struct rsa_mpi_key *pkey = &ctx->key; > int ret; > > - ret = rsa_parse_priv_key(pkey, key, keylen); > + ret = rsa_parse_mpi_priv_key(ctx, key, keylen); > if (ret) > return ret; > > if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) { > - rsa_free_key(pkey); > + rsa_free_mpi_key(pkey); > ret = -EINVAL; > } > return ret; > @@ -284,16 +288,31 @@ static int rsa_set_priv_key(struct crypto_akcipher > *tfm, const void *key, > > static int rsa_max_size(struct crypto_akcipher *tfm) { > - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); > + struct rsa_mpi_key *pkey = rsa_get_key(tfm); > > return pkey->n ? mpi_get_size(pkey->n) : -EINVAL; } > > +static const struct rsa_asn1_action rsa_action = { > + .get_n = rsa_get_mpi_n, > + .get_e = rsa_get_mpi_e, > + .get_d = rsa_get_mpi_d, > +}; > + > +static int rsa_init_tfm(struct crypto_akcipher *tfm) { > + struct rsa_ctx *ctx = akcipher_tfm_ctx(tfm); > + > + ctx->action = &rsa_action; > + > + return 0; > +} > + > static void rsa_exit_tfm(struct crypto_akcipher *tfm) { > - struct rsa_key *pkey = akcipher_tfm_ctx(tfm); > + struct rsa_mpi_key *pkey = rsa_get_key(tfm); > > - rsa_free_key(pkey); > + rsa_free_mpi_key(pkey); > } > > static struct akcipher_alg rsa = { > @@ -304,13 +323,14 @@ static struct akcipher_alg rsa = { > .set_priv_key = rsa_set_priv_key, > .set_pub_key = rsa_set_pub_key, > .max_size = rsa_max_size, > + .init = rsa_init_tfm, > .exit = rsa_exit_tfm, > .base = { > .cra_name = "rsa", > .cra_driver_name = "rsa-generic", > .cra_priority = 100, > .cra_module = THIS_MODULE, > - .cra_ctxsize = sizeof(struct rsa_key), > + .cra_ctxsize = sizeof(struct rsa_ctx), > }, > }; > > diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c index > d226f48..0149ed3 100644 > --- a/crypto/rsa_helper.c > +++ b/crypto/rsa_helper.c > @@ -21,7 +21,95 @@ > int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, > const void *value, size_t vlen) > { > - struct rsa_key *key = context; > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_n) > + return (*action)->get_n(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) > +{ > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_e) > + return (*action)->get_e(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) > +{ > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_d) > + return (*action)->get_d(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_p(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) > +{ > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_p) > + return (*action)->get_p(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_q(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) > +{ > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_q) > + return (*action)->get_q(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_dp(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) { > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_dp) > + return (*action)->get_dp(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_dq(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) { > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_dq) > + return (*action)->get_dq(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_qinv(void *context, size_t hdrlen, unsigned char tag, > + const void *value, size_t vlen) > +{ > + const struct rsa_asn1_action **action = context; > + > + if ((*action)->get_qinv) > + return (*action)->get_qinv(context, value, vlen); > + > + return 0; > +} > + > +int rsa_get_mpi_n(void *context, const void *value, size_t vlen) { > + struct rsa_ctx *ctx = context; > + struct rsa_mpi_key *key = &ctx->key; > > key->n = mpi_read_raw_data(value, vlen); > > @@ -38,11 +126,12 @@ int rsa_get_n(void *context, size_t hdrlen, unsigned > char tag, > } > return 0; > } > +EXPORT_SYMBOL_GPL(rsa_get_mpi_n); > > -int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, > - const void *value, size_t vlen) > +int rsa_get_mpi_e(void *context, const void *value, size_t vlen) > { > - struct rsa_key *key = context; > + struct rsa_ctx *ctx = context; > + struct rsa_mpi_key *key = &ctx->key; > > key->e = mpi_read_raw_data(value, vlen); > > @@ -51,11 +140,12 @@ int rsa_get_e(void *context, size_t hdrlen, unsigned > char tag, > > return 0; > } > +EXPORT_SYMBOL_GPL(rsa_get_mpi_e); > > -int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, > - const void *value, size_t vlen) > +int rsa_get_mpi_d(void *context, const void *value, size_t vlen) > { > - struct rsa_key *key = context; > + struct rsa_ctx *ctx = context; > + struct rsa_mpi_key *key = &ctx->key; > > key->d = mpi_read_raw_data(value, vlen); > > @@ -72,8 +162,14 @@ int rsa_get_d(void *context, size_t hdrlen, unsigned > char tag, > } > return 0; > } > +EXPORT_SYMBOL_GPL(rsa_get_mpi_d); > > -static void free_mpis(struct rsa_key *key) > +/** > + * rsa_free_mpi_key() - frees rsa key allocated by rsa_parse_key() > + * > + * @rsa_mpi_key: struct rsa_mpi_key key representation > + */ > +void rsa_free_mpi_key(struct rsa_mpi_key *key) > { > mpi_free(key->n); > mpi_free(key->e); > @@ -82,68 +178,64 @@ static void free_mpis(struct rsa_key *key) > key->e = NULL; > key->d = NULL; > } > +EXPORT_SYMBOL_GPL(rsa_free_mpi_key); > > /** > - * rsa_free_key() - frees rsa key allocated by rsa_parse_key() > + * rsa_parse_mpi_pub_key() - extracts an RSA public key from BER encoded > buffer > + * and stores it in the provided context. > * > - * @rsa_key: struct rsa_key key representation > - */ > -void rsa_free_key(struct rsa_key *key) > -{ > - free_mpis(key); > -} > -EXPORT_SYMBOL_GPL(rsa_free_key); > - > -/** > - * rsa_parse_pub_key() - extracts an rsa public key from BER encoded > buffer > - * and stores it in the provided struct rsa_key > - * > - * @rsa_key: struct rsa_key key representation > + * @rsa_ctx: RSA internal context > * @key: key in BER format > * @key_len: length of key > * > * Return: 0 on success or error code in case of error > */ > -int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, > - unsigned int key_len) > +int rsa_parse_mpi_pub_key(struct rsa_ctx *ctx, const void *key, > + unsigned int key_len) > { > + struct rsa_mpi_key *rsa_key = &ctx->key; > int ret; > > - free_mpis(rsa_key); > - ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, > key_len); > + /* Free the old key if any */ > + rsa_free_mpi_key(rsa_key); > + > + ret = asn1_ber_decoder(&rsapubkey_decoder, ctx, key, key_len); > if (ret < 0) > goto error; > > return 0; > error: > - free_mpis(rsa_key); > + rsa_free_mpi_key(rsa_key); > return ret; > } > -EXPORT_SYMBOL_GPL(rsa_parse_pub_key); > +EXPORT_SYMBOL_GPL(rsa_parse_mpi_pub_key); > > /** > - * rsa_parse_pub_key() - extracts an rsa private key from BER encoded > buffer > - * and stores it in the provided struct rsa_key > + * rsa_parse_mpi_priv_key() - extracts an RSA private key from BER > encoded > + * buffer and stores it in the provided context. > * > - * @rsa_key: struct rsa_key key representation > + * @rsa_ctx: RSA internal context > * @key: key in BER format > * @key_len: length of key > * > * Return: 0 on success or error code in case of error > */ > -int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, > - unsigned int key_len) > +int rsa_parse_mpi_priv_key(struct rsa_ctx *ctx, const void *key, > + unsigned int key_len) > { > + struct rsa_mpi_key *rsa_key = &ctx->key; > int ret; > > - free_mpis(rsa_key); > - ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, > key_len); > + /* Free the old key if any */ > + rsa_free_mpi_key(rsa_key); > + > + ret = asn1_ber_decoder(&rsaprivkey_decoder, ctx, key, key_len); > if (ret < 0) > goto error; > > return 0; > error: > - free_mpis(rsa_key); > + rsa_free_mpi_key(rsa_key); > return ret; > } > -EXPORT_SYMBOL_GPL(rsa_parse_priv_key); > +EXPORT_SYMBOL_GPL(rsa_parse_mpi_priv_key); > diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h > index c7585bd..f8ef7b1 100644 > --- a/include/crypto/internal/rsa.h > +++ b/include/crypto/internal/rsa.h > @@ -14,19 +14,38 @@ > #define _RSA_HELPER_ > #include <linux/mpi.h> > > -struct rsa_key { > +struct rsa_asn1_action { > + int (*get_n)(void *context, const void *value, size_t vlen); > + int (*get_e)(void *context, const void *value, size_t vlen); > + int (*get_d)(void *context, const void *value, size_t vlen); > + int (*get_p)(void *context, const void *value, size_t vlen); > + int (*get_q)(void *context, const void *value, size_t vlen); > + int (*get_dp)(void *context, const void *value, size_t vlen); > + int (*get_dq)(void *context, const void *value, size_t vlen); > + int (*get_qinv)(void *context, const void *value, size_t vlen); }; > + > +struct rsa_mpi_key { > MPI n; > MPI e; > MPI d; > }; > > -int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, > - unsigned int key_len); > +struct rsa_ctx { > + const struct rsa_asn1_action *action; > + struct rsa_mpi_key key; > +}; > + > +int rsa_get_mpi_n(void *context, const void *value, size_t vlen); int > +rsa_get_mpi_e(void *context, const void *value, size_t vlen); int > +rsa_get_mpi_d(void *context, const void *value, size_t vlen); > > -int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, > - unsigned int key_len); > +void rsa_free_mpi_key(struct rsa_mpi_key *key); > > -void rsa_free_key(struct rsa_key *rsa_key); > +int rsa_parse_mpi_pub_key(struct rsa_ctx *ctx, const void *key, > + unsigned int key_len); > +int rsa_parse_mpi_priv_key(struct rsa_ctx *ctx, const void *key, > + unsigned int key_len); > > extern struct crypto_template rsa_pkcs1pad_tmpl; #endif > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the > body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at > http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html