From 1259b90c5e2874322e0b34b17d6a5eed84d928b6 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 6 Feb 2020 14:13:02 -0500 Subject: [PATCH] fixes for 4.19 Signed-off-by: Sasha Levin --- ...-convert-to-skcipher-api-and-make-th.patch | 707 ++++++++++++++++++ queue-4.19/series | 1 + 2 files changed, 708 insertions(+) create mode 100644 queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-th.patch diff --git a/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-th.patch b/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-th.patch new file mode 100644 index 00000000000..0bc3218f701 --- /dev/null +++ b/queue-4.19/crypto-geode-aes-convert-to-skcipher-api-and-make-th.patch @@ -0,0 +1,707 @@ +From 094d5f7bb4f021941b2750fdb45856d8e61bb70f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2020 18:15:34 +0100 +Subject: crypto: geode-aes - convert to skcipher API and make thread-safe + +From: Florian Bezdeka + +commit 4549f7e5aa27ffc2cba63b5db8842a3b486f5688 upstream. + +The geode AES driver is heavily broken because it stores per-request +state in the transform context. So it will crash or produce the wrong +result if used by any of the many places in the kernel that issue +concurrent requests for the same transform object. + +This driver is also implemented using the deprecated blkcipher API, +which makes it difficult to fix, and puts it among the drivers +preventing that API from being removed. + +Convert this driver to use the skcipher API, and change it to not store +per-request state in the transform context. + +Fixes: 9fe757b ("[PATCH] crypto: Add support for the Geode LX AES hardware") +Signed-off-by: Eric Biggers +Signed-off-by: Herbert Xu +Signed-off-by: Florian Bezdeka +Signed-off-by: Sasha Levin +--- + drivers/crypto/geode-aes.c | 442 ++++++++++++------------------------- + drivers/crypto/geode-aes.h | 15 +- + 2 files changed, 149 insertions(+), 308 deletions(-) + +diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c +index d670f7000cbb8..0bd99c0decf58 100644 +--- a/drivers/crypto/geode-aes.c ++++ b/drivers/crypto/geode-aes.c +@@ -14,7 +14,7 @@ + #include + #include + #include +-#include ++#include + + #include + #include +@@ -28,12 +28,12 @@ static spinlock_t lock; + + /* Write a 128 bit field (either a writable key or IV) */ + static inline void +-_writefield(u32 offset, void *value) ++_writefield(u32 offset, const void *value) + { + int i; + + for (i = 0; i < 4; i++) +- iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4)); ++ iowrite32(((const u32 *) value)[i], _iobase + offset + (i * 4)); + } + + /* Read a 128 bit field (either a writable key or IV) */ +@@ -47,12 +47,12 @@ _readfield(u32 offset, void *value) + } + + static int +-do_crypt(void *src, void *dst, int len, u32 flags) ++do_crypt(const void *src, void *dst, u32 len, u32 flags) + { + u32 status; + u32 counter = AES_OP_TIMEOUT; + +- iowrite32(virt_to_phys(src), _iobase + AES_SOURCEA_REG); ++ iowrite32(virt_to_phys((void *)src), _iobase + AES_SOURCEA_REG); + iowrite32(virt_to_phys(dst), _iobase + AES_DSTA_REG); + iowrite32(len, _iobase + AES_LENA_REG); + +@@ -69,16 +69,14 @@ do_crypt(void *src, void *dst, int len, u32 flags) + return counter ? 0 : 1; + } + +-static unsigned int +-geode_aes_crypt(struct geode_aes_op *op) ++static void ++geode_aes_crypt(const struct geode_aes_tfm_ctx *tctx, const void *src, ++ void *dst, u32 len, u8 *iv, int mode, int dir) + { + u32 flags = 0; + unsigned long iflags; + int ret; + +- if (op->len == 0) +- return 0; +- + /* If the source and destination is the same, then + * we need to turn on the coherent flags, otherwise + * we don't need to worry +@@ -86,32 +84,28 @@ geode_aes_crypt(struct geode_aes_op *op) + + flags |= (AES_CTRL_DCA | AES_CTRL_SCA); + +- if (op->dir == AES_DIR_ENCRYPT) ++ if (dir == AES_DIR_ENCRYPT) + flags |= AES_CTRL_ENCRYPT; + + /* Start the critical section */ + + spin_lock_irqsave(&lock, iflags); + +- if (op->mode == AES_MODE_CBC) { ++ if (mode == AES_MODE_CBC) { + flags |= AES_CTRL_CBC; +- _writefield(AES_WRITEIV0_REG, op->iv); ++ _writefield(AES_WRITEIV0_REG, iv); + } + +- if (!(op->flags & AES_FLAGS_HIDDENKEY)) { +- flags |= AES_CTRL_WRKEY; +- _writefield(AES_WRITEKEY0_REG, op->key); +- } ++ flags |= AES_CTRL_WRKEY; ++ _writefield(AES_WRITEKEY0_REG, tctx->key); + +- ret = do_crypt(op->src, op->dst, op->len, flags); ++ ret = do_crypt(src, dst, len, flags); + BUG_ON(ret); + +- if (op->mode == AES_MODE_CBC) +- _readfield(AES_WRITEIV0_REG, op->iv); ++ if (mode == AES_MODE_CBC) ++ _readfield(AES_WRITEIV0_REG, iv); + + spin_unlock_irqrestore(&lock, iflags); +- +- return op->len; + } + + /* CRYPTO-API Functions */ +@@ -119,13 +113,13 @@ geode_aes_crypt(struct geode_aes_op *op) + static int geode_setkey_cip(struct crypto_tfm *tfm, const u8 *key, + unsigned int len) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + unsigned int ret; + +- op->keylen = len; ++ tctx->keylen = len; + + if (len == AES_KEYSIZE_128) { +- memcpy(op->key, key, len); ++ memcpy(tctx->key, key, len); + return 0; + } + +@@ -138,132 +132,93 @@ static int geode_setkey_cip(struct crypto_tfm *tfm, const u8 *key, + /* + * The requested key size is not supported by HW, do a fallback + */ +- op->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; +- op->fallback.cip->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); ++ tctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ++ tctx->fallback.cip->base.crt_flags |= ++ (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); + +- ret = crypto_cipher_setkey(op->fallback.cip, key, len); ++ ret = crypto_cipher_setkey(tctx->fallback.cip, key, len); + if (ret) { + tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; +- tfm->crt_flags |= (op->fallback.cip->base.crt_flags & CRYPTO_TFM_RES_MASK); ++ tfm->crt_flags |= (tctx->fallback.cip->base.crt_flags & ++ CRYPTO_TFM_RES_MASK); + } + return ret; + } + +-static int geode_setkey_blk(struct crypto_tfm *tfm, const u8 *key, +- unsigned int len) ++static int geode_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, ++ unsigned int len) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + unsigned int ret; + +- op->keylen = len; ++ tctx->keylen = len; + + if (len == AES_KEYSIZE_128) { +- memcpy(op->key, key, len); ++ memcpy(tctx->key, key, len); + return 0; + } + + if (len != AES_KEYSIZE_192 && len != AES_KEYSIZE_256) { + /* not supported at all */ +- tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; ++ crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + /* + * The requested key size is not supported by HW, do a fallback + */ +- crypto_skcipher_clear_flags(op->fallback.blk, CRYPTO_TFM_REQ_MASK); +- crypto_skcipher_set_flags(op->fallback.blk, +- tfm->crt_flags & CRYPTO_TFM_REQ_MASK); +- +- ret = crypto_skcipher_setkey(op->fallback.blk, key, len); +- if (ret) { +- tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; +- tfm->crt_flags |= crypto_skcipher_get_flags(op->fallback.blk) & +- CRYPTO_TFM_RES_MASK; +- } ++ crypto_skcipher_clear_flags(tctx->fallback.skcipher, ++ CRYPTO_TFM_REQ_MASK); ++ crypto_skcipher_set_flags(tctx->fallback.skcipher, ++ crypto_skcipher_get_flags(tfm) & ++ CRYPTO_TFM_REQ_MASK); ++ ret = crypto_skcipher_setkey(tctx->fallback.skcipher, key, len); ++ crypto_skcipher_set_flags(tfm, ++ crypto_skcipher_get_flags(tctx->fallback.skcipher) & ++ CRYPTO_TFM_RES_MASK); + return ret; + } + +-static int fallback_blk_dec(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- SKCIPHER_REQUEST_ON_STACK(req, op->fallback.blk); +- +- skcipher_request_set_tfm(req, op->fallback.blk); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, src, dst, nbytes, desc->info); +- +- return crypto_skcipher_decrypt(req); +-} +- +-static int fallback_blk_enc(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) +-{ +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- SKCIPHER_REQUEST_ON_STACK(req, op->fallback.blk); +- +- skcipher_request_set_tfm(req, op->fallback.blk); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, src, dst, nbytes, desc->info); +- +- return crypto_skcipher_encrypt(req); +-} +- + static void + geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- if (unlikely(op->keylen != AES_KEYSIZE_128)) { +- crypto_cipher_encrypt_one(op->fallback.cip, out, in); ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ crypto_cipher_encrypt_one(tctx->fallback.cip, out, in); + return; + } + +- op->src = (void *) in; +- op->dst = (void *) out; +- op->mode = AES_MODE_ECB; +- op->flags = 0; +- op->len = AES_BLOCK_SIZE; +- op->dir = AES_DIR_ENCRYPT; +- +- geode_aes_crypt(op); ++ geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, ++ AES_MODE_ECB, AES_DIR_ENCRYPT); + } + + + static void + geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- if (unlikely(op->keylen != AES_KEYSIZE_128)) { +- crypto_cipher_decrypt_one(op->fallback.cip, out, in); ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ crypto_cipher_decrypt_one(tctx->fallback.cip, out, in); + return; + } + +- op->src = (void *) in; +- op->dst = (void *) out; +- op->mode = AES_MODE_ECB; +- op->flags = 0; +- op->len = AES_BLOCK_SIZE; +- op->dir = AES_DIR_DECRYPT; +- +- geode_aes_crypt(op); ++ geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, ++ AES_MODE_ECB, AES_DIR_DECRYPT); + } + + static int fallback_init_cip(struct crypto_tfm *tfm) + { + const char *name = crypto_tfm_alg_name(tfm); +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- op->fallback.cip = crypto_alloc_cipher(name, 0, +- CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); ++ tctx->fallback.cip = crypto_alloc_cipher(name, 0, ++ CRYPTO_ALG_NEED_FALLBACK); + +- if (IS_ERR(op->fallback.cip)) { ++ if (IS_ERR(tctx->fallback.cip)) { + printk(KERN_ERR "Error allocating fallback algo %s\n", name); +- return PTR_ERR(op->fallback.cip); ++ return PTR_ERR(tctx->fallback.cip); + } + + return 0; +@@ -271,10 +226,9 @@ static int fallback_init_cip(struct crypto_tfm *tfm) + + static void fallback_exit_cip(struct crypto_tfm *tfm) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); ++ struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + +- crypto_free_cipher(op->fallback.cip); +- op->fallback.cip = NULL; ++ crypto_free_cipher(tctx->fallback.cip); + } + + static struct crypto_alg geode_alg = { +@@ -287,7 +241,7 @@ static struct crypto_alg geode_alg = { + .cra_init = fallback_init_cip, + .cra_exit = fallback_exit_cip, + .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), ++ .cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), + .cra_module = THIS_MODULE, + .cra_u = { + .cipher = { +@@ -300,222 +254,126 @@ static struct crypto_alg geode_alg = { + } + }; + +-static int +-geode_cbc_decrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) ++static int geode_init_skcipher(struct crypto_skcipher *tfm) + { +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_dec(desc, dst, src, nbytes); ++ const char *name = crypto_tfm_alg_name(&tfm->base); ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- op->iv = walk.iv; +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_CBC; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_DECRYPT; +- +- ret = geode_aes_crypt(op); +- +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); ++ tctx->fallback.skcipher = ++ crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tctx->fallback.skcipher)) { ++ printk(KERN_ERR "Error allocating fallback algo %s\n", name); ++ return PTR_ERR(tctx->fallback.skcipher); + } + +- return err; ++ crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) + ++ crypto_skcipher_reqsize(tctx->fallback.skcipher)); ++ return 0; + } + +-static int +-geode_cbc_encrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) ++static void geode_exit_skcipher(struct crypto_skcipher *tfm) + { +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; ++ struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_enc(desc, dst, src, nbytes); ++ crypto_free_skcipher(tctx->fallback.skcipher); ++} + +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- op->iv = walk.iv; ++static int geode_skcipher_crypt(struct skcipher_request *req, int mode, int dir) ++{ ++ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); ++ const struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); ++ struct skcipher_walk walk; ++ unsigned int nbytes; ++ int err; ++ ++ if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { ++ struct skcipher_request *subreq = skcipher_request_ctx(req); ++ ++ *subreq = *req; ++ skcipher_request_set_tfm(subreq, tctx->fallback.skcipher); ++ if (dir == AES_DIR_DECRYPT) ++ return crypto_skcipher_decrypt(subreq); ++ else ++ return crypto_skcipher_encrypt(subreq); ++ } + +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_CBC; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_ENCRYPT; ++ err = skcipher_walk_virt(&walk, req, false); + +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); ++ while ((nbytes = walk.nbytes) != 0) { ++ geode_aes_crypt(tctx, walk.src.virt.addr, walk.dst.virt.addr, ++ round_down(nbytes, AES_BLOCK_SIZE), ++ walk.iv, mode, dir); ++ err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE); + } + + return err; + } + +-static int fallback_init_blk(struct crypto_tfm *tfm) ++static int geode_cbc_encrypt(struct skcipher_request *req) + { +- const char *name = crypto_tfm_alg_name(tfm); +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); +- +- op->fallback.blk = crypto_alloc_skcipher(name, 0, +- CRYPTO_ALG_ASYNC | +- CRYPTO_ALG_NEED_FALLBACK); +- +- if (IS_ERR(op->fallback.blk)) { +- printk(KERN_ERR "Error allocating fallback algo %s\n", name); +- return PTR_ERR(op->fallback.blk); +- } +- +- return 0; ++ return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_ENCRYPT); + } + +-static void fallback_exit_blk(struct crypto_tfm *tfm) ++static int geode_cbc_decrypt(struct skcipher_request *req) + { +- struct geode_aes_op *op = crypto_tfm_ctx(tfm); +- +- crypto_free_skcipher(op->fallback.blk); +- op->fallback.blk = NULL; ++ return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_DECRYPT); + } + +-static struct crypto_alg geode_cbc_alg = { +- .cra_name = "cbc(aes)", +- .cra_driver_name = "cbc-aes-geode", +- .cra_priority = 400, +- .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | +- CRYPTO_ALG_KERN_DRIVER_ONLY | +- CRYPTO_ALG_NEED_FALLBACK, +- .cra_init = fallback_init_blk, +- .cra_exit = fallback_exit_blk, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), +- .cra_alignmask = 15, +- .cra_type = &crypto_blkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_u = { +- .blkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = geode_setkey_blk, +- .encrypt = geode_cbc_encrypt, +- .decrypt = geode_cbc_decrypt, +- .ivsize = AES_BLOCK_SIZE, +- } +- } +-}; +- +-static int +-geode_ecb_decrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) ++static int geode_ecb_encrypt(struct skcipher_request *req) + { +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_dec(desc, dst, src, nbytes); +- +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_ECB; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_DECRYPT; +- +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- err = blkcipher_walk_done(desc, &walk, nbytes); +- } +- +- return err; ++ return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_ENCRYPT); + } + +-static int +-geode_ecb_encrypt(struct blkcipher_desc *desc, +- struct scatterlist *dst, struct scatterlist *src, +- unsigned int nbytes) ++static int geode_ecb_decrypt(struct skcipher_request *req) + { +- struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); +- struct blkcipher_walk walk; +- int err, ret; +- +- if (nbytes % AES_BLOCK_SIZE) +- return -EINVAL; +- +- if (unlikely(op->keylen != AES_KEYSIZE_128)) +- return fallback_blk_enc(desc, dst, src, nbytes); +- +- blkcipher_walk_init(&walk, dst, src, nbytes); +- err = blkcipher_walk_virt(desc, &walk); +- +- while ((nbytes = walk.nbytes)) { +- op->src = walk.src.virt.addr, +- op->dst = walk.dst.virt.addr; +- op->mode = AES_MODE_ECB; +- op->len = nbytes - (nbytes % AES_BLOCK_SIZE); +- op->dir = AES_DIR_ENCRYPT; +- +- ret = geode_aes_crypt(op); +- nbytes -= ret; +- ret = blkcipher_walk_done(desc, &walk, nbytes); +- } +- +- return err; ++ return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_DECRYPT); + } + +-static struct crypto_alg geode_ecb_alg = { +- .cra_name = "ecb(aes)", +- .cra_driver_name = "ecb-aes-geode", +- .cra_priority = 400, +- .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | +- CRYPTO_ALG_KERN_DRIVER_ONLY | +- CRYPTO_ALG_NEED_FALLBACK, +- .cra_init = fallback_init_blk, +- .cra_exit = fallback_exit_blk, +- .cra_blocksize = AES_BLOCK_SIZE, +- .cra_ctxsize = sizeof(struct geode_aes_op), +- .cra_alignmask = 15, +- .cra_type = &crypto_blkcipher_type, +- .cra_module = THIS_MODULE, +- .cra_u = { +- .blkcipher = { +- .min_keysize = AES_MIN_KEY_SIZE, +- .max_keysize = AES_MAX_KEY_SIZE, +- .setkey = geode_setkey_blk, +- .encrypt = geode_ecb_encrypt, +- .decrypt = geode_ecb_decrypt, +- } +- } ++static struct skcipher_alg geode_skcipher_algs[] = { ++ { ++ .base.cra_name = "cbc(aes)", ++ .base.cra_driver_name = "cbc-aes-geode", ++ .base.cra_priority = 400, ++ .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), ++ .base.cra_alignmask = 15, ++ .base.cra_module = THIS_MODULE, ++ .init = geode_init_skcipher, ++ .exit = geode_exit_skcipher, ++ .setkey = geode_setkey_skcipher, ++ .encrypt = geode_cbc_encrypt, ++ .decrypt = geode_cbc_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, ++ }, { ++ .base.cra_name = "ecb(aes)", ++ .base.cra_driver_name = "ecb-aes-geode", ++ .base.cra_priority = 400, ++ .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | ++ CRYPTO_ALG_NEED_FALLBACK, ++ .base.cra_blocksize = AES_BLOCK_SIZE, ++ .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), ++ .base.cra_alignmask = 15, ++ .base.cra_module = THIS_MODULE, ++ .init = geode_init_skcipher, ++ .exit = geode_exit_skcipher, ++ .setkey = geode_setkey_skcipher, ++ .encrypt = geode_ecb_encrypt, ++ .decrypt = geode_ecb_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ }, + }; + + static void geode_aes_remove(struct pci_dev *dev) + { + crypto_unregister_alg(&geode_alg); +- crypto_unregister_alg(&geode_ecb_alg); +- crypto_unregister_alg(&geode_cbc_alg); ++ crypto_unregister_skciphers(geode_skcipher_algs, ++ ARRAY_SIZE(geode_skcipher_algs)); + + pci_iounmap(dev, _iobase); + _iobase = NULL; +@@ -553,20 +411,14 @@ static int geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id) + if (ret) + goto eiomap; + +- ret = crypto_register_alg(&geode_ecb_alg); ++ ret = crypto_register_skciphers(geode_skcipher_algs, ++ ARRAY_SIZE(geode_skcipher_algs)); + if (ret) + goto ealg; + +- ret = crypto_register_alg(&geode_cbc_alg); +- if (ret) +- goto eecb; +- + dev_notice(&dev->dev, "GEODE AES engine enabled.\n"); + return 0; + +- eecb: +- crypto_unregister_alg(&geode_ecb_alg); +- + ealg: + crypto_unregister_alg(&geode_alg); + +diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h +index c5763a041bb8b..157443dc6d8aa 100644 +--- a/drivers/crypto/geode-aes.h ++++ b/drivers/crypto/geode-aes.h +@@ -50,21 +50,10 @@ + + #define AES_OP_TIMEOUT 0x50000 + +-struct geode_aes_op { +- +- void *src; +- void *dst; +- +- u32 mode; +- u32 dir; +- u32 flags; +- int len; +- ++struct geode_aes_tfm_ctx { + u8 key[AES_KEYSIZE_128]; +- u8 *iv; +- + union { +- struct crypto_skcipher *blk; ++ struct crypto_skcipher *skcipher; + struct crypto_cipher *cip; + } fallback; + u32 keylen; +-- +2.20.1 + diff --git a/queue-4.19/series b/queue-4.19/series index f6078346e3b..b0b281276d9 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -54,3 +54,4 @@ s390-mm-fix-dynamic-pagetable-upgrade-for-hugetlbfs.patch powerpc-xmon-don-t-access-asdr-in-vms.patch powerpc-pseries-advance-pfn-if-section-is-not-present-in-lmb_is_removable.patch smb3-fix-signing-verification-of-large-reads.patch +crypto-geode-aes-convert-to-skcipher-api-and-make-th.patch -- 2.47.3