Forgot to Cc Michael Weiser.

On 11/17/2016 10:20 AM, Horia Geantă wrote:
> ablkcipher API is not completely removed from kernels <= v4.9.
> Thus it's still valid to use ablkcipher algorithms.
> 
> Fix the case when implementers register ablkcipher algorithms
> and cryptodev casts them to skcipher without checking their type.
> 
> Note: alg returned by crypto_ablkcipher_alg() is no longer checked
> to be non-NULL. This is guaranteed by the fact that ablkcipher_tfm
> (out->async.s) is valid.
> 
> Fixes: cb186f682679 ("Support skcipher in addition to ablkcipher API")
> Tested-by: Cristian Stoica <cristian.sto...@nxp.com>
> Signed-off-by: Horia Geantă <horia.gea...@nxp.com>
> ---
>  cipherapi.h |  4 ----
>  cryptlib.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++------------
>  2 files changed, 44 insertions(+), 16 deletions(-)
> 
> diff --git a/cipherapi.h b/cipherapi.h
> index 07d992333ad7..b6ed6c279350 100644
> --- a/cipherapi.h
> +++ b/cipherapi.h
> @@ -6,12 +6,10 @@
>  #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
>  # include <linux/crypto.h>
>  
> -typedef struct ablkcipher_alg cryptodev_blkcipher_alg_t;
>  typedef struct crypto_ablkcipher cryptodev_crypto_blkcipher_t;
>  typedef struct ablkcipher_request cryptodev_blkcipher_request_t;
>  
>  # define cryptodev_crypto_alloc_blkcipher crypto_alloc_ablkcipher
> -# define cryptodev_crypto_blkcipher_alg crypto_ablkcipher_alg
>  # define cryptodev_crypto_blkcipher_blocksize crypto_ablkcipher_blocksize
>  # define cryptodev_crypto_blkcipher_ivsize crypto_ablkcipher_ivsize
>  # define cryptodev_crypto_blkcipher_alignmask crypto_ablkcipher_alignmask
> @@ -37,12 +35,10 @@ static inline void 
> cryptodev_blkcipher_request_free(cryptodev_blkcipher_request_
>  #else
>  #include <crypto/skcipher.h>
>  
> -typedef struct skcipher_alg cryptodev_blkcipher_alg_t;
>  typedef struct crypto_skcipher cryptodev_crypto_blkcipher_t;
>  typedef struct skcipher_request cryptodev_blkcipher_request_t;
>  
>  # define cryptodev_crypto_alloc_blkcipher crypto_alloc_skcipher
> -# define cryptodev_crypto_blkcipher_alg crypto_skcipher_alg
>  # define cryptodev_crypto_blkcipher_blocksize crypto_skcipher_blocksize
>  # define cryptodev_crypto_blkcipher_ivsize crypto_skcipher_ivsize
>  # define cryptodev_crypto_blkcipher_alignmask crypto_skcipher_alignmask
> diff --git a/cryptlib.c b/cryptlib.c
> index 5a6e0ba5fe88..2c6028ee2b23 100644
> --- a/cryptlib.c
> +++ b/cryptlib.c
> @@ -38,6 +38,7 @@
>  #include "cryptodev_int.h"
>  #include "cipherapi.h"
>  
> +extern const struct crypto_type crypto_givcipher_type;
>  
>  static void cryptodev_complete(struct crypto_async_request *req, int err)
>  {
> @@ -121,6 +122,19 @@ error:
>       return ret;
>  }
>  
> +/* Was correct key length supplied? */
> +static int check_key_size(size_t keylen, const char *alg_name,
> +                       unsigned int min_keysize, unsigned int max_keysize)
> +{
> +     if (max_keysize > 0 && unlikely((keylen < min_keysize) ||
> +                                     (keylen > max_keysize))) {
> +             ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to 
> %u.",
> +                    keylen, alg_name, min_keysize, max_keysize);
> +             return -EINVAL;
> +     }
> +
> +     return 0;
> +}
>  
>  int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
>                               uint8_t *keyp, size_t keylen, int stream, int 
> aead)
> @@ -128,7 +142,12 @@ int cryptodev_cipher_init(struct cipher_data *out, const 
> char *alg_name,
>       int ret;
>  
>       if (aead == 0) {
> -             cryptodev_blkcipher_alg_t *alg;
> +             unsigned int min_keysize, max_keysize;
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
> +             struct crypto_tfm *tfm;
> +#else
> +             struct ablkcipher_alg *alg;
> +#endif
>  
>               out->async.s = cryptodev_crypto_alloc_blkcipher(alg_name, 0, 0);
>               if (unlikely(IS_ERR(out->async.s))) {
> @@ -136,18 +155,31 @@ int cryptodev_cipher_init(struct cipher_data *out, 
> const char *alg_name,
>                               return -EINVAL;
>               }
>  
> -             alg = cryptodev_crypto_blkcipher_alg(out->async.s);
> -             if (alg != NULL) {
> -                     /* Was correct key length supplied? */
> -                     if (alg->max_keysize > 0 &&
> -                                     unlikely((keylen < alg->min_keysize) ||
> -                                     (keylen > alg->max_keysize))) {
> -                             ddebug(1, "Wrong keylen '%zu' for algorithm 
> '%s'. Use %u to %u.",
> -                                             keylen, alg_name, 
> alg->min_keysize, alg->max_keysize);
> -                             ret = -EINVAL;
> -                             goto error;
> -                     }
> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
> +             tfm = crypto_skcipher_tfm(out->async.s);
> +             if ((tfm->__crt_alg->cra_type == &crypto_ablkcipher_type) ||
> +                 (tfm->__crt_alg->cra_type == &crypto_givcipher_type)) {
> +                     struct ablkcipher_alg *alg;
> +
> +                     alg = &tfm->__crt_alg->cra_ablkcipher;
> +                     min_keysize = alg->min_keysize;
> +                     max_keysize = alg->max_keysize;
> +             } else {
> +                     struct skcipher_alg *alg;
> +
> +                     alg = crypto_skcipher_alg(out->async.s);
> +                     min_keysize = alg->min_keysize;
> +                     max_keysize = alg->max_keysize;
>               }
> +#else
> +             alg = crypto_ablkcipher_alg(out->async.s);
> +             min_keysize = alg->min_keysize;
> +             max_keysize = alg->max_keysize;
> +#endif
> +             ret = check_key_size(keylen, alg_name, min_keysize,
> +                                  max_keysize);
> +             if (ret)
> +                     goto error;
>  
>               out->blocksize = 
> cryptodev_crypto_blkcipher_blocksize(out->async.s);
>               out->ivsize = cryptodev_crypto_blkcipher_ivsize(out->async.s);
> 

_______________________________________________
Cryptodev-linux-devel mailing list
Cryptodev-linux-devel@gna.org
https://mail.gna.org/listinfo/cryptodev-linux-devel

Reply via email to