Lines Matching +full:crypto +full:- +full:engine
1 // SPDX-License-Identifier: GPL-2.0-only
3 * K3 DTHE V2 crypto accelerator driver
5 * Copyright (C) Texas Instruments 2025 - https://www.ti.com
6 * Author: T Pratham <t-pratham@ti.com>
9 #include <crypto/aead.h>
10 #include <crypto/aes.h>
11 #include <crypto/algapi.h>
12 #include <crypto/engine.h>
13 #include <crypto/internal/aead.h>
14 #include <crypto/internal/skcipher.h>
16 #include "dthev2-common.h"
20 #include <linux/dma-mapping.h>
26 // AES Engine
97 ctx->dev_data = dev_data; in dthe_cipher_init_tfm()
98 ctx->keylen = 0; in dthe_cipher_init_tfm()
108 ctx->dev_data = dev_data; in dthe_cipher_xts_init_tfm()
109 ctx->keylen = 0; in dthe_cipher_xts_init_tfm()
111 ctx->skcipher_fb = crypto_alloc_sync_skcipher("xts(aes)", 0, in dthe_cipher_xts_init_tfm()
113 if (IS_ERR(ctx->skcipher_fb)) { in dthe_cipher_xts_init_tfm()
114 dev_err(dev_data->dev, "fallback driver xts(aes) couldn't be loaded\n"); in dthe_cipher_xts_init_tfm()
115 return PTR_ERR(ctx->skcipher_fb); in dthe_cipher_xts_init_tfm()
125 crypto_free_sync_skcipher(ctx->skcipher_fb); in dthe_cipher_xts_exit_tfm()
133 return -EINVAL; in dthe_aes_setkey()
135 ctx->keylen = keylen; in dthe_aes_setkey()
136 memcpy(ctx->key, key, keylen); in dthe_aes_setkey()
145 ctx->aes_mode = DTHE_AES_ECB; in dthe_aes_ecb_setkey()
154 ctx->aes_mode = DTHE_AES_CBC; in dthe_aes_cbc_setkey()
166 return -EINVAL; in dthe_aes_xts_setkey()
168 ctx->aes_mode = DTHE_AES_XTS; in dthe_aes_xts_setkey()
169 ctx->keylen = keylen / 2; in dthe_aes_xts_setkey()
170 memcpy(ctx->key, key, keylen); in dthe_aes_xts_setkey()
172 crypto_sync_skcipher_clear_flags(ctx->skcipher_fb, CRYPTO_TFM_REQ_MASK); in dthe_aes_xts_setkey()
173 crypto_sync_skcipher_set_flags(ctx->skcipher_fb, in dthe_aes_xts_setkey()
177 return crypto_sync_skcipher_setkey(ctx->skcipher_fb, key, keylen); in dthe_aes_xts_setkey()
185 void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE; in dthe_aes_set_ctrl_key()
188 writel_relaxed(ctx->key[0], aes_base_reg + DTHE_P_AES_KEY1_0); in dthe_aes_set_ctrl_key()
189 writel_relaxed(ctx->key[1], aes_base_reg + DTHE_P_AES_KEY1_1); in dthe_aes_set_ctrl_key()
190 writel_relaxed(ctx->key[2], aes_base_reg + DTHE_P_AES_KEY1_2); in dthe_aes_set_ctrl_key()
191 writel_relaxed(ctx->key[3], aes_base_reg + DTHE_P_AES_KEY1_3); in dthe_aes_set_ctrl_key()
193 if (ctx->keylen > AES_KEYSIZE_128) { in dthe_aes_set_ctrl_key()
194 writel_relaxed(ctx->key[4], aes_base_reg + DTHE_P_AES_KEY1_4); in dthe_aes_set_ctrl_key()
195 writel_relaxed(ctx->key[5], aes_base_reg + DTHE_P_AES_KEY1_5); in dthe_aes_set_ctrl_key()
197 if (ctx->keylen == AES_KEYSIZE_256) { in dthe_aes_set_ctrl_key()
198 writel_relaxed(ctx->key[6], aes_base_reg + DTHE_P_AES_KEY1_6); in dthe_aes_set_ctrl_key()
199 writel_relaxed(ctx->key[7], aes_base_reg + DTHE_P_AES_KEY1_7); in dthe_aes_set_ctrl_key()
202 if (ctx->aes_mode == DTHE_AES_XTS) { in dthe_aes_set_ctrl_key()
203 size_t key2_offset = ctx->keylen / sizeof(u32); in dthe_aes_set_ctrl_key()
205 writel_relaxed(ctx->key[key2_offset + 0], aes_base_reg + DTHE_P_AES_KEY2_0); in dthe_aes_set_ctrl_key()
206 writel_relaxed(ctx->key[key2_offset + 1], aes_base_reg + DTHE_P_AES_KEY2_1); in dthe_aes_set_ctrl_key()
207 writel_relaxed(ctx->key[key2_offset + 2], aes_base_reg + DTHE_P_AES_KEY2_2); in dthe_aes_set_ctrl_key()
208 writel_relaxed(ctx->key[key2_offset + 3], aes_base_reg + DTHE_P_AES_KEY2_3); in dthe_aes_set_ctrl_key()
210 if (ctx->keylen > AES_KEYSIZE_128) { in dthe_aes_set_ctrl_key()
211 writel_relaxed(ctx->key[key2_offset + 4], aes_base_reg + DTHE_P_AES_KEY2_4); in dthe_aes_set_ctrl_key()
212 writel_relaxed(ctx->key[key2_offset + 5], aes_base_reg + DTHE_P_AES_KEY2_5); in dthe_aes_set_ctrl_key()
214 if (ctx->keylen == AES_KEYSIZE_256) { in dthe_aes_set_ctrl_key()
215 writel_relaxed(ctx->key[key2_offset + 6], aes_base_reg + DTHE_P_AES_KEY2_6); in dthe_aes_set_ctrl_key()
216 writel_relaxed(ctx->key[key2_offset + 7], aes_base_reg + DTHE_P_AES_KEY2_7); in dthe_aes_set_ctrl_key()
220 if (rctx->enc) in dthe_aes_set_ctrl_key()
223 if (ctx->keylen == AES_KEYSIZE_128) in dthe_aes_set_ctrl_key()
225 else if (ctx->keylen == AES_KEYSIZE_192) in dthe_aes_set_ctrl_key()
232 switch (ctx->aes_mode) { in dthe_aes_set_ctrl_key()
259 complete(&rctx->aes_compl); in dthe_aes_dma_in_callback()
262 static int dthe_aes_run(struct crypto_engine *engine, void *areq) in dthe_aes_run() argument
269 unsigned int len = req->cryptlen; in dthe_aes_run()
270 struct scatterlist *src = req->src; in dthe_aes_run()
271 struct scatterlist *dst = req->dst; in dthe_aes_run()
287 void __iomem *aes_base_reg = dev_data->regs + DTHE_P_AES_BASE; in dthe_aes_run()
308 tx_dev = dmaengine_get_dma_device(dev_data->dma_aes_tx); in dthe_aes_run()
309 rx_dev = dmaengine_get_dma_device(dev_data->dma_aes_rx); in dthe_aes_run()
313 ret = -EINVAL; in dthe_aes_run()
325 ret = -EINVAL; in dthe_aes_run()
330 desc_in = dmaengine_prep_slave_sg(dev_data->dma_aes_rx, dst, dst_mapped_nents, in dthe_aes_run()
333 dev_err(dev_data->dev, "IN prep_slave_sg() failed\n"); in dthe_aes_run()
334 ret = -EINVAL; in dthe_aes_run()
338 desc_out = dmaengine_prep_slave_sg(dev_data->dma_aes_tx, src, src_mapped_nents, in dthe_aes_run()
341 dev_err(dev_data->dev, "OUT prep_slave_sg() failed\n"); in dthe_aes_run()
342 ret = -EINVAL; in dthe_aes_run()
346 desc_in->callback = dthe_aes_dma_in_callback; in dthe_aes_run()
347 desc_in->callback_param = req; in dthe_aes_run()
349 init_completion(&rctx->aes_compl); in dthe_aes_run()
351 if (ctx->aes_mode == DTHE_AES_ECB) in dthe_aes_run()
354 dthe_aes_set_ctrl_key(ctx, rctx, (u32 *)req->iv); in dthe_aes_run()
356 writel_relaxed(lower_32_bits(req->cryptlen), aes_base_reg + DTHE_P_AES_C_LENGTH_0); in dthe_aes_run()
357 writel_relaxed(upper_32_bits(req->cryptlen), aes_base_reg + DTHE_P_AES_C_LENGTH_1); in dthe_aes_run()
362 dma_async_issue_pending(dev_data->dma_aes_rx); in dthe_aes_run()
363 dma_async_issue_pending(dev_data->dma_aes_tx); in dthe_aes_run()
366 ret = wait_for_completion_timeout(&rctx->aes_compl, msecs_to_jiffies(DTHE_DMA_TIMEOUT_MS)); in dthe_aes_run()
368 ret = -ETIMEDOUT; in dthe_aes_run()
369 dmaengine_terminate_sync(dev_data->dma_aes_rx); in dthe_aes_run()
370 dmaengine_terminate_sync(dev_data->dma_aes_tx); in dthe_aes_run()
379 if (ctx->aes_mode != DTHE_AES_ECB) { in dthe_aes_run()
380 u32 *iv_out = (u32 *)req->iv; in dthe_aes_run()
395 crypto_finalize_skcipher_request(dev_data->engine, req, ret); in dthe_aes_run()
405 struct crypto_engine *engine; in dthe_aes_crypt() local
409 * - need to return -EINVAL for ECB, CBC as they are block ciphers in dthe_aes_crypt()
410 * - need to fallback to software as H/W doesn't support Ciphertext Stealing for XTS in dthe_aes_crypt()
412 if (req->cryptlen % AES_BLOCK_SIZE) { in dthe_aes_crypt()
413 if (ctx->aes_mode == DTHE_AES_XTS) { in dthe_aes_crypt()
414 SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->skcipher_fb); in dthe_aes_crypt()
417 req->base.complete, req->base.data); in dthe_aes_crypt()
418 skcipher_request_set_crypt(subreq, req->src, req->dst, in dthe_aes_crypt()
419 req->cryptlen, req->iv); in dthe_aes_crypt()
421 return rctx->enc ? crypto_skcipher_encrypt(subreq) : in dthe_aes_crypt()
424 return -EINVAL; in dthe_aes_crypt()
429 * Except for XTS mode, where data length should be non-zero. in dthe_aes_crypt()
431 if (req->cryptlen == 0) { in dthe_aes_crypt()
432 if (ctx->aes_mode == DTHE_AES_XTS) in dthe_aes_crypt()
433 return -EINVAL; in dthe_aes_crypt()
437 engine = dev_data->engine; in dthe_aes_crypt()
438 return crypto_transfer_skcipher_request_to_engine(engine, req); in dthe_aes_crypt()
445 rctx->enc = 1; in dthe_aes_encrypt()
453 rctx->enc = 0; in dthe_aes_decrypt()
467 .cra_driver_name = "ecb-aes-dthev2",
472 .cra_alignmask = AES_BLOCK_SIZE - 1,
490 .cra_driver_name = "cbc-aes-dthev2",
495 .cra_alignmask = AES_BLOCK_SIZE - 1,
514 .cra_driver_name = "xts-aes-dthev2",
520 .cra_alignmask = AES_BLOCK_SIZE - 1,