aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorCatalin Vasile <catalin.vasile@freescale.com>2014-10-31 06:45:38 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-11-06 10:15:05 -0500
commit7222d1a3410388c8e21a5028ba2beb498938b57f (patch)
tree189c73374692a432c49b528ba51d87064d0db100 /drivers/crypto
parentdaebc465858867f48ee86a88f56020c3fe0d96f6 (diff)
crypto: caam - add support for givencrypt cbc(aes) and rfc3686(ctr(aes))
Add support for one-shot givencrypt algorithms. Givencrypt algorithms will generate their IV and encrypt data within the same shared job descriptors. Current algorithms merged from ablkcipher to givencrypt are: - AES Cipher Block Chaining (CBC) - AES Counter Mode (CTR) compliant with RFC3686 Signed-off-by: Catalin Vasile <catalin.vasile@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c285
1 files changed, 281 insertions, 4 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 34f84d87a4e4..44b306b60fb8 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1835,6 +1835,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1835 u32 *key_jump_cmd; 1835 u32 *key_jump_cmd;
1836 u32 *desc; 1836 u32 *desc;
1837 u32 *nonce; 1837 u32 *nonce;
1838 u32 geniv;
1838 u32 ctx1_iv_off = 0; 1839 u32 ctx1_iv_off = 0;
1839 const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == 1840 const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
1840 OP_ALG_AAI_CTR_MOD128); 1841 OP_ALG_AAI_CTR_MOD128);
@@ -1993,6 +1994,83 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1993 DUMP_PREFIX_ADDRESS, 16, 4, desc, 1994 DUMP_PREFIX_ADDRESS, 16, 4, desc,
1994 desc_bytes(desc), 1); 1995 desc_bytes(desc), 1);
1995#endif 1996#endif
1997 /* ablkcipher_givencrypt shared descriptor */
1998 desc = ctx->sh_desc_givenc;
1999
2000 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
2001 /* Skip if already shared */
2002 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2003 JUMP_COND_SHRD);
2004
2005 /* Load class1 key only */
2006 append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
2007 ctx->enckeylen, CLASS_1 |
2008 KEY_DEST_CLASS_REG);
2009
2010 /* Load Nonce into CONTEXT1 reg */
2011 if (is_rfc3686) {
2012 nonce = (u32 *)(key + keylen);
2013 append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
2014 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
2015 append_move(desc, MOVE_WAITCOMP |
2016 MOVE_SRC_OUTFIFO |
2017 MOVE_DEST_CLASS1CTX |
2018 (16 << MOVE_OFFSET_SHIFT) |
2019 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
2020 }
2021 set_jump_tgt_here(desc, key_jump_cmd);
2022
2023 /* Generate IV */
2024 geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
2025 NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
2026 NFIFOENTRY_PTYPE_RND | (crt->ivsize << NFIFOENTRY_DLEN_SHIFT);
2027 append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
2028 LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
2029 append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
2030 append_move(desc, MOVE_WAITCOMP |
2031 MOVE_SRC_INFIFO |
2032 MOVE_DEST_CLASS1CTX |
2033 (crt->ivsize << MOVE_LEN_SHIFT) |
2034 (ctx1_iv_off << MOVE_OFFSET_SHIFT));
2035 append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
2036
2037 /* Copy generated IV to memory */
2038 append_seq_store(desc, crt->ivsize,
2039 LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
2040 (ctx1_iv_off << LDST_OFFSET_SHIFT));
2041
2042 /* Load Counter into CONTEXT1 reg */
2043 if (is_rfc3686)
2044 append_load_imm_u32(desc, (u32)1, LDST_IMM |
2045 LDST_CLASS_1_CCB |
2046 LDST_SRCDST_BYTE_CONTEXT |
2047 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
2048 LDST_OFFSET_SHIFT));
2049
2050 if (ctx1_iv_off)
2051 append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
2052 (1 << JUMP_OFFSET_SHIFT));
2053
2054 /* Load operation */
2055 append_operation(desc, ctx->class1_alg_type |
2056 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
2057
2058 /* Perform operation */
2059 ablkcipher_append_src_dst(desc);
2060
2061 ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc,
2062 desc_bytes(desc),
2063 DMA_TO_DEVICE);
2064 if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
2065 dev_err(jrdev, "unable to map shared descriptor\n");
2066 return -ENOMEM;
2067 }
2068#ifdef DEBUG
2069 print_hex_dump(KERN_ERR,
2070 "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
2071 DUMP_PREFIX_ADDRESS, 16, 4, desc,
2072 desc_bytes(desc), 1);
2073#endif
1996 2074
1997 return ret; 2075 return ret;
1998} 2076}
@@ -2480,6 +2558,54 @@ static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
2480} 2558}
2481 2559
2482/* 2560/*
2561 * Fill in ablkcipher givencrypt job descriptor
2562 */
2563static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
2564 struct ablkcipher_edesc *edesc,
2565 struct ablkcipher_request *req,
2566 bool iv_contig)
2567{
2568 struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2569 int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2570 u32 *desc = edesc->hw_desc;
2571 u32 out_options, in_options;
2572 dma_addr_t dst_dma, src_dma;
2573 int len, sec4_sg_index = 0;
2574
2575#ifdef DEBUG
2576 print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
2577 DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2578 ivsize, 1);
2579 print_hex_dump(KERN_ERR, "src @" __stringify(__LINE__) ": ",
2580 DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2581 edesc->src_nents ? 100 : req->nbytes, 1);
2582#endif
2583
2584 len = desc_len(sh_desc);
2585 init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2586
2587 if (!edesc->src_nents) {
2588 src_dma = sg_dma_address(req->src);
2589 in_options = 0;
2590 } else {
2591 src_dma = edesc->sec4_sg_dma;
2592 sec4_sg_index += edesc->src_nents;
2593 in_options = LDST_SGF;
2594 }
2595 append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
2596
2597 if (iv_contig) {
2598 dst_dma = edesc->iv_dma;
2599 out_options = 0;
2600 } else {
2601 dst_dma = edesc->sec4_sg_dma +
2602 sec4_sg_index * sizeof(struct sec4_sg_entry);
2603 out_options = LDST_SGF;
2604 }
2605 append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, out_options);
2606}
2607
2608/*
2483 * allocate and map the aead extended descriptor 2609 * allocate and map the aead extended descriptor
2484 */ 2610 */
2485static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, 2611static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
@@ -3099,6 +3225,151 @@ static int ablkcipher_decrypt(struct ablkcipher_request *req)
3099 return ret; 3225 return ret;
3100} 3226}
3101 3227
3228/*
3229 * allocate and map the ablkcipher extended descriptor
3230 * for ablkcipher givencrypt
3231 */
3232static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
3233 struct skcipher_givcrypt_request *greq,
3234 int desc_bytes,
3235 bool *iv_contig_out)
3236{
3237 struct ablkcipher_request *req = &greq->creq;
3238 struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
3239 struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
3240 struct device *jrdev = ctx->jrdev;
3241 gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
3242 CRYPTO_TFM_REQ_MAY_SLEEP)) ?
3243 GFP_KERNEL : GFP_ATOMIC;
3244 int src_nents, dst_nents = 0, sec4_sg_bytes;
3245 struct ablkcipher_edesc *edesc;
3246 dma_addr_t iv_dma = 0;
3247 bool iv_contig = false;
3248 int sgc;
3249 int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
3250 bool src_chained = false, dst_chained = false;
3251 int sec4_sg_index;
3252
3253 src_nents = sg_count(req->src, req->nbytes, &src_chained);
3254
3255 if (unlikely(req->dst != req->src))
3256 dst_nents = sg_count(req->dst, req->nbytes, &dst_chained);
3257
3258 if (likely(req->src == req->dst)) {
3259 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
3260 DMA_BIDIRECTIONAL, src_chained);
3261 } else {
3262 sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
3263 DMA_TO_DEVICE, src_chained);
3264 sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
3265 DMA_FROM_DEVICE, dst_chained);
3266 }
3267
3268 /*
3269 * Check if iv can be contiguous with source and destination.
3270 * If so, include it. If not, create scatterlist.
3271 */
3272 iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
3273 if (dma_mapping_error(jrdev, iv_dma)) {
3274 dev_err(jrdev, "unable to map IV\n");
3275 return ERR_PTR(-ENOMEM);
3276 }
3277
3278 if (!dst_nents && iv_dma + ivsize == sg_dma_address(req->dst))
3279 iv_contig = true;
3280 else
3281 dst_nents = dst_nents ? : 1;
3282 sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
3283 sizeof(struct sec4_sg_entry);
3284
3285 /* allocate space for base edesc and hw desc commands, link tables */
3286 edesc = kmalloc(sizeof(*edesc) + desc_bytes +
3287 sec4_sg_bytes, GFP_DMA | flags);
3288 if (!edesc) {
3289 dev_err(jrdev, "could not allocate extended descriptor\n");
3290 return ERR_PTR(-ENOMEM);
3291 }
3292
3293 edesc->src_nents = src_nents;
3294 edesc->src_chained = src_chained;
3295 edesc->dst_nents = dst_nents;
3296 edesc->dst_chained = dst_chained;
3297 edesc->sec4_sg_bytes = sec4_sg_bytes;
3298 edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
3299 desc_bytes;
3300
3301 sec4_sg_index = 0;
3302 if (src_nents) {
3303 sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
3304 sec4_sg_index += src_nents;
3305 }
3306
3307 if (!iv_contig) {
3308 dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
3309 iv_dma, ivsize, 0);
3310 sec4_sg_index += 1;
3311 sg_to_sec4_sg_last(req->dst, dst_nents,
3312 edesc->sec4_sg + sec4_sg_index, 0);
3313 }
3314
3315 edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
3316 sec4_sg_bytes, DMA_TO_DEVICE);
3317 if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
3318 dev_err(jrdev, "unable to map S/G table\n");
3319 return ERR_PTR(-ENOMEM);
3320 }
3321 edesc->iv_dma = iv_dma;
3322
3323#ifdef DEBUG
3324 print_hex_dump(KERN_ERR,
3325 "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
3326 DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
3327 sec4_sg_bytes, 1);
3328#endif
3329
3330 *iv_contig_out = iv_contig;
3331 return edesc;
3332}
3333
3334static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
3335{
3336 struct ablkcipher_request *req = &creq->creq;
3337 struct ablkcipher_edesc *edesc;
3338 struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
3339 struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
3340 struct device *jrdev = ctx->jrdev;
3341 bool iv_contig;
3342 u32 *desc;
3343 int ret = 0;
3344
3345 /* allocate extended descriptor */
3346 edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN *
3347 CAAM_CMD_SZ, &iv_contig);
3348 if (IS_ERR(edesc))
3349 return PTR_ERR(edesc);
3350
3351 /* Create and submit job descriptor*/
3352 init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
3353 edesc, req, iv_contig);
3354#ifdef DEBUG
3355 print_hex_dump(KERN_ERR,
3356 "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
3357 DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
3358 desc_bytes(edesc->hw_desc), 1);
3359#endif
3360 desc = edesc->hw_desc;
3361 ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
3362
3363 if (!ret) {
3364 ret = -EINPROGRESS;
3365 } else {
3366 ablkcipher_unmap(jrdev, edesc, req);
3367 kfree(edesc);
3368 }
3369
3370 return ret;
3371}
3372
3102#define template_aead template_u.aead 3373#define template_aead template_u.aead
3103#define template_ablkcipher template_u.ablkcipher 3374#define template_ablkcipher template_u.ablkcipher
3104struct caam_alg_template { 3375struct caam_alg_template {
@@ -3769,12 +4040,13 @@ static struct caam_alg_template driver_algs[] = {
3769 .name = "cbc(aes)", 4040 .name = "cbc(aes)",
3770 .driver_name = "cbc-aes-caam", 4041 .driver_name = "cbc-aes-caam",
3771 .blocksize = AES_BLOCK_SIZE, 4042 .blocksize = AES_BLOCK_SIZE,
3772 .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 4043 .type = CRYPTO_ALG_TYPE_GIVCIPHER,
3773 .template_ablkcipher = { 4044 .template_ablkcipher = {
3774 .setkey = ablkcipher_setkey, 4045 .setkey = ablkcipher_setkey,
3775 .encrypt = ablkcipher_encrypt, 4046 .encrypt = ablkcipher_encrypt,
3776 .decrypt = ablkcipher_decrypt, 4047 .decrypt = ablkcipher_decrypt,
3777 .geniv = "eseqiv", 4048 .givencrypt = ablkcipher_givencrypt,
4049 .geniv = "<built-in>",
3778 .min_keysize = AES_MIN_KEY_SIZE, 4050 .min_keysize = AES_MIN_KEY_SIZE,
3779 .max_keysize = AES_MAX_KEY_SIZE, 4051 .max_keysize = AES_MAX_KEY_SIZE,
3780 .ivsize = AES_BLOCK_SIZE, 4052 .ivsize = AES_BLOCK_SIZE,
@@ -3833,12 +4105,13 @@ static struct caam_alg_template driver_algs[] = {
3833 .name = "rfc3686(ctr(aes))", 4105 .name = "rfc3686(ctr(aes))",
3834 .driver_name = "rfc3686-ctr-aes-caam", 4106 .driver_name = "rfc3686-ctr-aes-caam",
3835 .blocksize = 1, 4107 .blocksize = 1,
3836 .type = CRYPTO_ALG_TYPE_ABLKCIPHER, 4108 .type = CRYPTO_ALG_TYPE_GIVCIPHER,
3837 .template_ablkcipher = { 4109 .template_ablkcipher = {
3838 .setkey = ablkcipher_setkey, 4110 .setkey = ablkcipher_setkey,
3839 .encrypt = ablkcipher_encrypt, 4111 .encrypt = ablkcipher_encrypt,
3840 .decrypt = ablkcipher_decrypt, 4112 .decrypt = ablkcipher_decrypt,
3841 .geniv = "seqiv", 4113 .givencrypt = ablkcipher_givencrypt,
4114 .geniv = "<built-in>",
3842 .min_keysize = AES_MIN_KEY_SIZE + 4115 .min_keysize = AES_MIN_KEY_SIZE +
3843 CTR_RFC3686_NONCE_SIZE, 4116 CTR_RFC3686_NONCE_SIZE,
3844 .max_keysize = AES_MAX_KEY_SIZE + 4117 .max_keysize = AES_MAX_KEY_SIZE +
@@ -3946,6 +4219,10 @@ static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
3946 alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | 4219 alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
3947 template->type; 4220 template->type;
3948 switch (template->type) { 4221 switch (template->type) {
4222 case CRYPTO_ALG_TYPE_GIVCIPHER:
4223 alg->cra_type = &crypto_givcipher_type;
4224 alg->cra_ablkcipher = template->template_ablkcipher;
4225 break;
3949 case CRYPTO_ALG_TYPE_ABLKCIPHER: 4226 case CRYPTO_ALG_TYPE_ABLKCIPHER:
3950 alg->cra_type = &crypto_ablkcipher_type; 4227 alg->cra_type = &crypto_ablkcipher_type;
3951 alg->cra_ablkcipher = template->template_ablkcipher; 4228 alg->cra_ablkcipher = template->template_ablkcipher;