On 04/10/22 22:47, Ard Biesheuvel wrote: > On Tue, 4 Oct 2022 at 11:51, Nikunj A. Dadhania <nikunj@xxxxxxx> wrote: >> >>> AES in GCM mode seems like a >>> thing that we might be able to add to the crypto library API without >>> much hassle (which already has a minimal implementation of AES) >> >> That will be great ! >> > > Try this branch and see if it works for you > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=libgcm Thanks Ard, I had to make few changes to the api to get it working for my usecase. The ghash is store/retrieved from the AUTHTAG field of message header as per "Table 97. Message Header Format" in the SNP ABI document: https://www.amd.com/system/files/TechDocs/56860.pdf Below are the changes I had made in my tree. --- diff --git a/include/crypto/gcm.h b/include/crypto/gcm.h index bab85df6df7a..838d1b4e25c3 100644 --- a/include/crypto/gcm.h +++ b/include/crypto/gcm.h @@ -74,9 +74,11 @@ int gcm_setkey(struct gcm_ctx *ctx, const u8 *key, unsigned int keysize, unsigned int authsize); void gcm_encrypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, - int src_len, const u8 *assoc, int assoc_len, const u8 *iv); + int src_len, const u8 *assoc, int assoc_len, const u8 *iv, + u8 *authtag); int gcm_decrypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, - int src_len, const u8 *assoc, int assoc_len, const u8 *iv); + int src_len, const u8 *assoc, int assoc_len, const u8 *iv, + u8 *authtag); #endif diff --git a/lib/crypto/gcm.c b/lib/crypto/gcm.c index d80e430505ee..34c86b2ea2aa 100644 --- a/lib/crypto/gcm.c +++ b/lib/crypto/gcm.c @@ -30,7 +30,7 @@ int gcm_setkey(struct gcm_ctx *ctx, const u8 *key, static int gcm_crypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, int crypt_len, const u8 *assoc, int assoc_len, - const u8 *iv, bool encrypt) + const u8 *iv, bool encrypt, u8 *authtag) { be128 tail = { cpu_to_be64(assoc_len * 8), cpu_to_be64(crypt_len * 8) }; u8 ctr[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; @@ -76,8 +76,8 @@ static int gcm_crypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, put_unaligned_be32(1, ctr + GCM_AES_IV_SIZE); aes_encrypt(&ctx->aes_ctx, buf, ctr); - crypto_xor_cpy(encrypt ? dst : buf, buf, (u8 *)&ghash, ctx->authsize); - if (!encrypt && crypto_memneq(src, buf, ctx->authsize)) + crypto_xor_cpy(encrypt ? authtag : buf, buf, (u8 *)&ghash, ctx->authsize); + if (!encrypt && crypto_memneq(authtag, buf, ctx->authsize)) ret = -EBADMSG; memzero_explicit(&ghash, sizeof(ghash)); @@ -87,16 +87,18 @@ static int gcm_crypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, } void gcm_encrypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, - int src_len, const u8 *assoc, int assoc_len, const u8 *iv) + int src_len, const u8 *assoc, int assoc_len, const u8 *iv, + u8 *authtag) { - gcm_crypt(ctx, dst, src, src_len, assoc, assoc_len, iv, true); + gcm_crypt(ctx, dst, src, src_len, assoc, assoc_len, iv, true, authtag); } int gcm_decrypt(const struct gcm_ctx *ctx, u8 *dst, const u8 *src, - int src_len, const u8 *assoc, int assoc_len, const u8 *iv) + int src_len, const u8 *assoc, int assoc_len, const u8 *iv, + u8 *authtag) { return gcm_crypt(ctx, dst, src, src_len - ctx->authsize, assoc, - assoc_len, iv, false); + assoc_len, iv, false, authtag); }