Commit 4427b1b4 authored by Kim Phillips's avatar Kim Phillips Committed by Herbert Xu

crypto: caam - add support for sha512 variants of existing AEAD algorithms

In doing so, sha512 sized keys would not fit with the current
descriptor inlining mechanism, so we now calculate whether keys
should be referenced instead by pointers in the shared descriptor.

also, use symbols for descriptor text lengths, and, ahem, unmap and
free key i/o memory in cra_exit.
Signed-off-by: default avatarKim Phillips <kim.phillips@freescale.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 66664487
...@@ -61,6 +61,12 @@ ...@@ -61,6 +61,12 @@
/* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ /* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
#define CAAM_MAX_IV_LENGTH 16 #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 #ifdef DEBUG
/* for print_hex_dumps with line references */ /* for print_hex_dumps with line references */
#define xstr(s) str(s) #define xstr(s) str(s)
...@@ -219,10 +225,22 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx) ...@@ -219,10 +225,22 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx)
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
u32 *sh_desc; u32 *sh_desc;
u32 *jump_cmd; 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 */ /* build shared descriptor for this session */
sh_desc = kmalloc(CAAM_CMD_SZ * 4 + ctx->split_key_pad_len + sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN +
ctx->enckeylen, GFP_DMA | GFP_KERNEL); keys_fit_inline ?
ctx->split_key_pad_len + ctx->enckeylen :
CAAM_PTR_SZ * 2, GFP_DMA | GFP_KERNEL);
if (!sh_desc) { if (!sh_desc) {
dev_err(jrdev, "could not allocate shared descriptor\n"); dev_err(jrdev, "could not allocate shared descriptor\n");
return -ENOMEM; return -ENOMEM;
...@@ -233,14 +251,23 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx) ...@@ -233,14 +251,23 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx)
jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL | jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL |
JUMP_COND_SHRD | JUMP_COND_SELF); JUMP_COND_SHRD | JUMP_COND_SELF);
/* process keys, starting with class 2/authentication */ /*
* process keys, starting with class 2/authentication.
*/
if (keys_fit_inline) {
append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len, append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len,
ctx->split_key_len, ctx->split_key_len,
CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC); CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
append_key_as_imm(sh_desc, (void *)ctx->key + ctx->split_key_pad_len, append_key_as_imm(sh_desc, (void *)ctx->key +
ctx->enckeylen, ctx->enckeylen, ctx->split_key_pad_len, ctx->enckeylen,
CLASS_1 | KEY_DEST_CLASS_REG); 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 */ /* update jump cmd now that we are at the jump target */
set_jump_tgt_here(sh_desc, jump_cmd); set_jump_tgt_here(sh_desc, jump_cmd);
...@@ -746,7 +773,8 @@ static int aead_authenc_encrypt(struct aead_request *areq) ...@@ -746,7 +773,8 @@ static int aead_authenc_encrypt(struct aead_request *areq)
dma_addr_t iv_dma; dma_addr_t iv_dma;
/* allocate extended descriptor */ /* 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)) if (IS_ERR(edesc))
return PTR_ERR(edesc); return PTR_ERR(edesc);
...@@ -778,7 +806,8 @@ static int aead_authenc_decrypt(struct aead_request *req) ...@@ -778,7 +806,8 @@ static int aead_authenc_decrypt(struct aead_request *req)
req->cryptlen -= ctx->authsize; req->cryptlen -= ctx->authsize;
/* allocate extended descriptor */ /* 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)) if (IS_ERR(edesc))
return PTR_ERR(edesc); return PTR_ERR(edesc);
...@@ -813,7 +842,8 @@ static int aead_authenc_givencrypt(struct aead_givcrypt_request *req) ...@@ -813,7 +842,8 @@ static int aead_authenc_givencrypt(struct aead_givcrypt_request *req)
debug("%s: giv %p\n", __func__, req->giv); debug("%s: giv %p\n", __func__, req->giv);
/* allocate extended descriptor */ /* 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)) if (IS_ERR(edesc))
return PTR_ERR(edesc); return PTR_ERR(edesc);
...@@ -903,6 +933,25 @@ static struct caam_alg_template driver_algs[] = { ...@@ -903,6 +933,25 @@ static struct caam_alg_template driver_algs[] = {
OP_ALG_AAI_HMAC_PRECOMP, OP_ALG_AAI_HMAC_PRECOMP,
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, .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))", .name = "authenc(hmac(sha1),cbc(des3_ede))",
.driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam", .driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam",
...@@ -940,6 +989,25 @@ static struct caam_alg_template driver_algs[] = { ...@@ -940,6 +989,25 @@ static struct caam_alg_template driver_algs[] = {
OP_ALG_AAI_HMAC_PRECOMP, OP_ALG_AAI_HMAC_PRECOMP,
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, .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))", .name = "authenc(hmac(sha1),cbc(des))",
.driver_name = "authenc-hmac-sha1-cbc-des-caam", .driver_name = "authenc-hmac-sha1-cbc-des-caam",
...@@ -977,6 +1045,25 @@ static struct caam_alg_template driver_algs[] = { ...@@ -977,6 +1045,25 @@ static struct caam_alg_template driver_algs[] = {
OP_ALG_AAI_HMAC_PRECOMP, OP_ALG_AAI_HMAC_PRECOMP,
.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, .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 { struct caam_crypto_alg {
...@@ -1019,6 +1106,12 @@ static void caam_cra_exit(struct crypto_tfm *tfm) ...@@ -1019,6 +1106,12 @@ static void caam_cra_exit(struct crypto_tfm *tfm)
dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys, dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys,
desc_bytes(ctx->sh_desc), DMA_TO_DEVICE); desc_bytes(ctx->sh_desc), DMA_TO_DEVICE);
kfree(ctx->sh_desc); 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) static void __exit caam_algapi_exit(void)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define IMMEDIATE (1 << 23) #define IMMEDIATE (1 << 23)
#define CAAM_CMD_SZ sizeof(u32) #define CAAM_CMD_SZ sizeof(u32)
#define CAAM_PTR_SZ sizeof(dma_addr_t) #define CAAM_PTR_SZ sizeof(dma_addr_t)
#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * 64)
#ifdef DEBUG #ifdef DEBUG
#define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\ #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment