mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
crypto: mediatek - use AES library for GCM key derivation
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>
This commit is contained in:
parent
56ca499f1b
commit
f441ba2ad3
@ -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
|
||||
|
@ -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,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user