RE: [PATCH v2 1/4] crypto: rsa - generalize ASN.1 sequences

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----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



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux