crypto: mediatek - use AES library for GCM key derivation
authorArd Biesheuvel <ardb@kernel.org>
Tue, 7 Jul 2020 06:32:03 +0000 (09:32 +0300)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 16 Jul 2020 11:49:04 +0000 (21:49 +1000)
The Mediatek accelerator driver calls into a dynamically allocated
skcipher of the ctr(aes) variety to perform GCM key derivation, which
involves AES encryption of a single block consisting of NUL bytes.

There is no point in using the skcipher API for this, so use the AES
library interface instead.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/Kconfig
drivers/crypto/mediatek/mtk-aes.c

index 7bc58bf..585ad58 100644 (file)
@@ -758,10 +758,9 @@ config CRYPTO_DEV_ZYNQMP_AES
 config CRYPTO_DEV_MEDIATEK
        tristate "MediaTek's EIP97 Cryptographic Engine driver"
        depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST
-       select CRYPTO_AES
+       select CRYPTO_LIB_AES
        select CRYPTO_AEAD
        select CRYPTO_SKCIPHER
-       select CRYPTO_CTR
        select CRYPTO_SHA1
        select CRYPTO_SHA256
        select CRYPTO_SHA512
index 78d660d..4ad3571 100644 (file)
@@ -137,8 +137,6 @@ struct mtk_aes_gcm_ctx {
 
        u32 authsize;
        size_t textlen;
-
-       struct crypto_skcipher *ctr;
 };
 
 struct mtk_aes_drv {
@@ -996,17 +994,8 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
                              u32 keylen)
 {
        struct mtk_aes_base_ctx *ctx = crypto_aead_ctx(aead);
-       struct mtk_aes_gcm_ctx *gctx = mtk_aes_gcm_ctx_cast(ctx);
-       struct crypto_skcipher *ctr = gctx->ctr;
-       struct {
-               u32 hash[4];
-               u8 iv[8];
-
-               struct crypto_wait wait;
-
-               struct scatterlist sg[1];
-               struct skcipher_request req;
-       } *data;
+       u8 hash[AES_BLOCK_SIZE] __aligned(4) = {};
+       struct crypto_aes_ctx aes_ctx;
        int err;
 
        switch (keylen) {
@@ -1026,39 +1015,18 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
 
        ctx->keylen = SIZE_IN_WORDS(keylen);
 
-       /* Same as crypto_gcm_setkey() from crypto/gcm.c */
-       crypto_skcipher_clear_flags(ctr, CRYPTO_TFM_REQ_MASK);
-       crypto_skcipher_set_flags(ctr, crypto_aead_get_flags(aead) &
-                                 CRYPTO_TFM_REQ_MASK);
-       err = crypto_skcipher_setkey(ctr, key, keylen);
+       err = aes_expandkey(&aes_ctx, key, keylen);
        if (err)
                return err;
 
-       data = kzalloc(sizeof(*data) + crypto_skcipher_reqsize(ctr),
-                      GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       crypto_init_wait(&data->wait);
-       sg_init_one(data->sg, &data->hash, AES_BLOCK_SIZE);
-       skcipher_request_set_tfm(&data->req, ctr);
-       skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
-                                     CRYPTO_TFM_REQ_MAY_BACKLOG,
-                                     crypto_req_done, &data->wait);
-       skcipher_request_set_crypt(&data->req, data->sg, data->sg,
-                                  AES_BLOCK_SIZE, data->iv);
-
-       err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
-                             &data->wait);
-       if (err)
-               goto out;
+       aes_encrypt(&aes_ctx, hash, hash);
+       memzero_explicit(&aes_ctx, sizeof(aes_ctx));
 
        mtk_aes_write_state_le(ctx->key, (const u32 *)key, keylen);
-       mtk_aes_write_state_be(ctx->key + ctx->keylen, data->hash,
+       mtk_aes_write_state_be(ctx->key + ctx->keylen, (const u32 *)hash,
                               AES_BLOCK_SIZE);
-out:
-       kzfree(data);
-       return err;
+
+       return 0;
 }
 
 static int mtk_aes_gcm_setauthsize(struct crypto_aead *aead,
@@ -1095,32 +1063,17 @@ static int mtk_aes_gcm_init(struct crypto_aead *aead)
 {
        struct mtk_aes_gcm_ctx *ctx = crypto_aead_ctx(aead);
 
-       ctx->ctr = crypto_alloc_skcipher("ctr(aes)", 0,
-                                        CRYPTO_ALG_ASYNC);
-       if (IS_ERR(ctx->ctr)) {
-               pr_err("Error allocating ctr(aes)\n");
-               return PTR_ERR(ctx->ctr);
-       }
-
        crypto_aead_set_reqsize(aead, sizeof(struct mtk_aes_reqctx));
        ctx->base.start = mtk_aes_gcm_start;
        return 0;
 }
 
-static void mtk_aes_gcm_exit(struct crypto_aead *aead)
-{
-       struct mtk_aes_gcm_ctx *ctx = crypto_aead_ctx(aead);
-
-       crypto_free_skcipher(ctx->ctr);
-}
-
 static struct aead_alg aes_gcm_alg = {
        .setkey         = mtk_aes_gcm_setkey,
        .setauthsize    = mtk_aes_gcm_setauthsize,
        .encrypt        = mtk_aes_gcm_encrypt,
        .decrypt        = mtk_aes_gcm_decrypt,
        .init           = mtk_aes_gcm_init,
-       .exit           = mtk_aes_gcm_exit,
        .ivsize         = GCM_AES_IV_SIZE,
        .maxauthsize    = AES_BLOCK_SIZE,