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