/* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
#define CAAM_MAX_IV_LENGTH 16
+/* length of descriptors text */
+#define DESC_AEAD_SHARED_TEXT_LEN 4
+#define DESC_AEAD_ENCRYPT_TEXT_LEN 21
+#define DESC_AEAD_DECRYPT_TEXT_LEN 24
+#define DESC_AEAD_GIVENCRYPT_TEXT_LEN 27
+
#ifdef DEBUG
/* for print_hex_dumps with line references */
#define xstr(s) str(s)
struct device *jrdev = ctx->jrdev;
u32 *sh_desc;
u32 *jump_cmd;
+ bool keys_fit_inline = 0;
+
+ /*
+ * largest Job Descriptor and its Shared Descriptor
+ * must both fit into the 64-word Descriptor h/w Buffer
+ */
+ if ((DESC_AEAD_GIVENCRYPT_TEXT_LEN +
+ DESC_AEAD_SHARED_TEXT_LEN) * CAAM_CMD_SZ +
+ ctx->split_key_pad_len + ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
+ keys_fit_inline = 1;
/* build shared descriptor for this session */
- sh_desc = kmalloc(CAAM_CMD_SZ * 4 + ctx->split_key_pad_len +
- ctx->enckeylen, GFP_DMA | GFP_KERNEL);
+ sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN +
+ keys_fit_inline ?
+ ctx->split_key_pad_len + ctx->enckeylen :
+ CAAM_PTR_SZ * 2, GFP_DMA | GFP_KERNEL);
if (!sh_desc) {
dev_err(jrdev, "could not allocate shared descriptor\n");
return -ENOMEM;
jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL |
JUMP_COND_SHRD | JUMP_COND_SELF);
- /* process keys, starting with class 2/authentication */
- append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len,
- ctx->split_key_len,
- CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
-
- append_key_as_imm(sh_desc, (void *)ctx->key + ctx->split_key_pad_len,
- ctx->enckeylen, ctx->enckeylen,
- CLASS_1 | KEY_DEST_CLASS_REG);
+ /*
+ * process keys, starting with class 2/authentication.
+ */
+ if (keys_fit_inline) {
+ append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len,
+ ctx->split_key_len,
+ CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
+
+ append_key_as_imm(sh_desc, (void *)ctx->key +
+ ctx->split_key_pad_len, ctx->enckeylen,
+ ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ } else {
+ append_key(sh_desc, ctx->key_phys, ctx->split_key_len, CLASS_2 |
+ KEY_DEST_MDHA_SPLIT | KEY_ENC);
+ append_key(sh_desc, ctx->key_phys + ctx->split_key_pad_len,
+ ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
+ }
/* update jump cmd now that we are at the jump target */
set_jump_tgt_here(sh_desc, jump_cmd);
dma_addr_t iv_dma;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(areq, 21 * sizeof(u32));
+ edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_ENCRYPT_TEXT_LEN *
+ CAAM_CMD_SZ);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
req->cryptlen -= ctx->authsize;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 24 * sizeof(u32));
+ edesc = ipsec_esp_edesc_alloc(req, DESC_AEAD_DECRYPT_TEXT_LEN *
+ CAAM_CMD_SZ);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
debug("%s: giv %p\n", __func__, req->giv);
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(areq, 27 * sizeof(u32));
+ edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_GIVENCRYPT_TEXT_LEN *
+ CAAM_CMD_SZ);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
},
{
+ .name = "authenc(hmac(sha512),cbc(aes))",
+ .driver_name = "authenc-hmac-sha512-cbc-aes-caam",
+ .blocksize = AES_BLOCK_SIZE,
+ .aead = {
+ .setkey = aead_authenc_setkey,
+ .setauthsize = aead_authenc_setauthsize,
+ .encrypt = aead_authenc_encrypt,
+ .decrypt = aead_authenc_decrypt,
+ .givencrypt = aead_authenc_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA512_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+ OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+ },
+ {
.name = "authenc(hmac(sha1),cbc(des3_ede))",
.driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam",
.blocksize = DES3_EDE_BLOCK_SIZE,
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
},
{
+ .name = "authenc(hmac(sha512),cbc(des3_ede))",
+ .driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam",
+ .blocksize = DES3_EDE_BLOCK_SIZE,
+ .aead = {
+ .setkey = aead_authenc_setkey,
+ .setauthsize = aead_authenc_setauthsize,
+ .encrypt = aead_authenc_encrypt,
+ .decrypt = aead_authenc_decrypt,
+ .givencrypt = aead_authenc_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .maxauthsize = SHA512_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+ OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+ },
+ {
.name = "authenc(hmac(sha1),cbc(des))",
.driver_name = "authenc-hmac-sha1-cbc-des-caam",
.blocksize = DES_BLOCK_SIZE,
OP_ALG_AAI_HMAC_PRECOMP,
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
},
+ {
+ .name = "authenc(hmac(sha512),cbc(des))",
+ .driver_name = "authenc-hmac-sha512-cbc-des-caam",
+ .blocksize = DES_BLOCK_SIZE,
+ .aead = {
+ .setkey = aead_authenc_setkey,
+ .setauthsize = aead_authenc_setauthsize,
+ .encrypt = aead_authenc_encrypt,
+ .decrypt = aead_authenc_decrypt,
+ .givencrypt = aead_authenc_givencrypt,
+ .geniv = "<built-in>",
+ .ivsize = DES_BLOCK_SIZE,
+ .maxauthsize = SHA512_DIGEST_SIZE,
+ },
+ .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+ .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+ OP_ALG_AAI_HMAC_PRECOMP,
+ .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+ },
};
struct caam_crypto_alg {
dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys,
desc_bytes(ctx->sh_desc), DMA_TO_DEVICE);
kfree(ctx->sh_desc);
+
+ if (!dma_mapping_error(ctx->jrdev, ctx->key_phys))
+ dma_unmap_single(ctx->jrdev, ctx->key_phys,
+ ctx->split_key_pad_len + ctx->enckeylen,
+ DMA_TO_DEVICE);
+ kfree(ctx->key);
}
static void __exit caam_algapi_exit(void)