[PATCH v3] crypto: rsa - return raw integers for the ASN.1 parser

2016-06-07 Thread Tudor Ambarus
Return the raw key with no other processing so that the caller
can copy it or MPI parse it, etc.

The scope is to have only one ANS.1 parser for all RSA
implementations.

Update the RSA software implementation so that it does
the MPI conversion on top.

Signed-off-by: Tudor Ambarus 
---
 crypto/rsa.c  | 119 ++-
 crypto/rsa_helper.c   | 128 +-
 include/crypto/internal/rsa.h |  22 ++--
 3 files changed, 161 insertions(+), 108 deletions(-)

diff --git a/crypto/rsa.c b/crypto/rsa.c
index 77d737f..ea78d61 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -14,12 +14,24 @@
 #include 
 #include 
 #include 
+#include 
+
+struct rsa_mpi_key {
+   MPI n;
+   MPI e;
+   MPI d;
+};
+
+struct rsa_ctx {
+   struct rsa_key key;
+   struct rsa_mpi_key mpi_key;
+};
 
 /*
  * 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 +45,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 +59,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 +73,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 +83,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->mpi_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 +132,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 +170,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 +209,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;
@@ -233,67 +247,94 @@ err_free_m:
return ret;
 }
 
-static int rsa_check_key_length(unsigned int len)
+static void rsa_free_mpi_key(struct rsa_mpi_key *key)
 {
-   switch (len) {
-   case 512:
-   case 1024:
-   case 1536:
-   case 2048:
-   case 3072:
-   case 4096:
-   return 0;
-   }
-
-   return -EINVAL;
+   mpi_free(key->d);
+   mpi_free(key->e);
+   mpi_free(key->n);
+   key->d = NULL;
+   key->e = NULL;
+   key->n = NULL;
 }
 
 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_key *pkey = &ctx->key;
+   struct rsa_mpi_key *mpi_key = &ctx->mpi_key;
int ret;
 
+   /* Free the old MPI key if any */
+   rsa_free_mpi_key(mpi_key);
+
ret

Re: [PATCH v3] crypto: rsa - return raw integers for the ASN.1 parser

2016-06-07 Thread Stephan Mueller
Am Dienstag, 7. Juni 2016, 17:21:09 schrieb Tudor Ambarus:

Hi Tudor,

> Return the raw key with no other processing so that the caller
> can copy it or MPI parse it, etc.
> 
> The scope is to have only one ANS.1 parser for all RSA
> implementations.
> 
> Update the RSA software implementation so that it does
> the MPI conversion on top.
> 
> Signed-off-by: Tudor Ambarus 
> ---
>  crypto/rsa.c  | 119 ++-
> crypto/rsa_helper.c   | 128
> +- include/crypto/internal/rsa.h | 
> 22 ++--
>  3 files changed, 161 insertions(+), 108 deletions(-)
> 
> diff --git a/crypto/rsa.c b/crypto/rsa.c
> index 77d737f..ea78d61 100644
> --- a/crypto/rsa.c
> +++ b/crypto/rsa.c
> @@ -14,12 +14,24 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +
> +struct rsa_mpi_key {
> + MPI n;
> + MPI e;
> + MPI d;
> +};
> +
> +struct rsa_ctx {
> + struct rsa_key key;
> + struct rsa_mpi_key mpi_key;
> +};
> 
>  /*
>   * 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 +45,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 +59,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 +73,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 +83,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->mpi_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 +132,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 +170,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 +209,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;
> @@ -233,67 +247,94 @@ err_free_m:
>   return ret;
>  }
> 
> -static int rsa_check_key_length(unsigned int len)
> +static void rsa_free_mpi_key(struct rsa_mpi_key *key)
>  {
> - switch (len) {
> - case 512:
> - case 1024:
> - case 1536:
> - case 2048:
> - case 3072:
> - case 4096:
> - return 0;
> - }
> -
> - return -EINVAL;
> + mpi_free(key->d);
> + mpi_free(key->e);
> + mpi_free(key->n);
> + key->d = NULL;
> + key->e = NULL;
> + key->n = NULL;
>  }
> 
>  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

RE: [PATCH v3] crypto: rsa - return raw integers for the ASN.1 parser

2016-06-08 Thread Tudor-Dan Ambarus
Hi Stephan,

> >  int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
> >   const void *value, size_t vlen)
> >  {
> > struct rsa_key *key = context;
> > +   const u8 *ptr = value;
> > +   int ret;
> >
> > -   key->n = mpi_read_raw_data(value, vlen);
> > +   while (!*ptr && vlen) {
> > +   ptr++;
> > +   vlen--;
> > +   }
> 
> As you do this operation 3 times, isn't an inline better here?

Actually this operation makes sense only for n to determine its length.
I will remove the while from rsa_get_e/d. 

> 
> >
> > -   if (!key->n)
> > -   return -ENOMEM;
> > +   /* invalid key provided */
> > +   if (!ptr)
> > +   return -EINVAL;
> 
> Hm, you check the pointer here, but you dereference it already above. So, I
> guess you want to move that check to the beginning of the function?

Sure. Thank you for reviewing!
ta
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html