Hi,
Although AM335X AES HW supports many modes, but the AES driver only supports CBC, ECB and CTR mode. Some customers want to use GCM mode. By looking at the driver, I see I need to do following changes in omap4-aes.c but I would like you review it, especailly for #4).
Thanks a lot.
Bin
1). Add an ALG in struct crypto_alg alg[ ] for "gcm(aes)" ;
2). Add
#define FLAGS_GCM BIT(7)
3). Add two functions:
static int omap4_aes_gcm_encrypt(struct ablkcipher_request *req)
{
return omap4_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_GCM);
}
static int omap4_aes_gcm_decrypt(struct ablkcipher_request *req)
{
return omap4_aes_crypt(req, FLAGS_GCM);
}
4). Change omap4_aes_ctr_encrypt():
static int omap4_aes_write_ctrl(struct omap4_aes_dev *dd)
{
unsigned int key32;
int i, err;
u32 val, mask;
err = omap4_aes_hw_init(dd);
if (err)
return err;
pr_debug("Set key\n");
key32 = dd->ctx->keylen / sizeof(u32);
/* set a key */
for (i = 0; i < key32; i++) {
omap4_aes_write(dd, AES_REG_KEY1(i),
__le32_to_cpu(dd->ctx->key[i]));
}
if ((dd->flags & (FLAGS_CBC | FLAGS_CTR | FLAGS_GCM)) && dd->req->info)
omap4_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
if (dd->flags & FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
else if (dd->flags & FLAGS_CTR)
val |= AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
else if (dd->flags & FLAGS_GCM)
val |= AES_REG_CTRL_GCM | AES_REG_CTRL_CTR | AES_REG_CTRL_CTR_WIDTH_32;
<-- This is the part I'm not sure: are we always using Autonomous GHASH? CTRL_CTR also needs to be set for GCM, right? Is WIDTH_32 right value for GCM?
if (dd->flags & FLAGS_ENCRYPT)
val |= AES_REG_CTRL_DIRECTION;
mask = AES_REG_CTRL_CBC | AES_REG_CTRL_CTR | AES_REG_CTRL_GCM | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE_MASK | AES_REG_CTRL_CTR_WIDTH_MASK;
omap4_aes_write_mask(dd, AES_REG_CTRL, val, mask);
return 0;
}