1fbf31dd5STom Zanussi // SPDX-License-Identifier: GPL-2.0-only
2fbf31dd5STom Zanussi /*
3fbf31dd5STom Zanussi * Intel Keem Bay OCS AES Crypto Driver.
4fbf31dd5STom Zanussi *
5fbf31dd5STom Zanussi * Copyright (C) 2018-2020 Intel Corporation
6fbf31dd5STom Zanussi */
7fbf31dd5STom Zanussi
8fbf31dd5STom Zanussi #include <crypto/aes.h>
9fbf31dd5STom Zanussi #include <crypto/engine.h>
10fbf31dd5STom Zanussi #include <crypto/gcm.h>
11fbf31dd5STom Zanussi #include <crypto/internal/aead.h>
12fbf31dd5STom Zanussi #include <crypto/internal/skcipher.h>
13530d7b00SHerbert Xu #include <crypto/scatterwalk.h>
14530d7b00SHerbert Xu #include <linux/clk.h>
15530d7b00SHerbert Xu #include <linux/completion.h>
16530d7b00SHerbert Xu #include <linux/dma-mapping.h>
17530d7b00SHerbert Xu #include <linux/err.h>
18530d7b00SHerbert Xu #include <linux/interrupt.h>
19530d7b00SHerbert Xu #include <linux/io.h>
20530d7b00SHerbert Xu #include <linux/kernel.h>
21530d7b00SHerbert Xu #include <linux/module.h>
22530d7b00SHerbert Xu #include <linux/of.h>
23530d7b00SHerbert Xu #include <linux/platform_device.h>
24530d7b00SHerbert Xu #include <linux/string.h>
25fbf31dd5STom Zanussi
26fbf31dd5STom Zanussi #include "ocs-aes.h"
27fbf31dd5STom Zanussi
28fbf31dd5STom Zanussi #define KMB_OCS_PRIORITY 350
29fbf31dd5STom Zanussi #define DRV_NAME "keembay-ocs-aes"
30fbf31dd5STom Zanussi
31fbf31dd5STom Zanussi #define OCS_AES_MIN_KEY_SIZE 16
32fbf31dd5STom Zanussi #define OCS_AES_MAX_KEY_SIZE 32
33fbf31dd5STom Zanussi #define OCS_AES_KEYSIZE_128 16
34fbf31dd5STom Zanussi #define OCS_AES_KEYSIZE_192 24
35fbf31dd5STom Zanussi #define OCS_AES_KEYSIZE_256 32
36fbf31dd5STom Zanussi #define OCS_SM4_KEY_SIZE 16
37fbf31dd5STom Zanussi
38fbf31dd5STom Zanussi /**
39fbf31dd5STom Zanussi * struct ocs_aes_tctx - OCS AES Transform context
40fbf31dd5STom Zanussi * @aes_dev: The OCS AES device.
41fbf31dd5STom Zanussi * @key: AES/SM4 key.
42fbf31dd5STom Zanussi * @key_len: The length (in bytes) of @key.
43fbf31dd5STom Zanussi * @cipher: OCS cipher to use (either AES or SM4).
44fbf31dd5STom Zanussi * @sw_cipher: The cipher to use as fallback.
45fbf31dd5STom Zanussi * @use_fallback: Whether or not fallback cipher should be used.
46fbf31dd5STom Zanussi */
47fbf31dd5STom Zanussi struct ocs_aes_tctx {
48fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev;
49fbf31dd5STom Zanussi u8 key[OCS_AES_KEYSIZE_256];
50fbf31dd5STom Zanussi unsigned int key_len;
51fbf31dd5STom Zanussi enum ocs_cipher cipher;
52fbf31dd5STom Zanussi union {
53fbf31dd5STom Zanussi struct crypto_sync_skcipher *sk;
54fbf31dd5STom Zanussi struct crypto_aead *aead;
55fbf31dd5STom Zanussi } sw_cipher;
56fbf31dd5STom Zanussi bool use_fallback;
57fbf31dd5STom Zanussi };
58fbf31dd5STom Zanussi
59fbf31dd5STom Zanussi /**
60fbf31dd5STom Zanussi * struct ocs_aes_rctx - OCS AES Request context.
61fbf31dd5STom Zanussi * @instruction: Instruction to be executed (encrypt / decrypt).
62fbf31dd5STom Zanussi * @mode: Mode to use (ECB, CBC, CTR, CCm, GCM, CTS)
63fbf31dd5STom Zanussi * @src_nents: Number of source SG entries.
64fbf31dd5STom Zanussi * @dst_nents: Number of destination SG entries.
65fbf31dd5STom Zanussi * @src_dma_count: The number of DMA-mapped entries of the source SG.
66fbf31dd5STom Zanussi * @dst_dma_count: The number of DMA-mapped entries of the destination SG.
67fbf31dd5STom Zanussi * @in_place: Whether or not this is an in place request, i.e.,
68fbf31dd5STom Zanussi * src_sg == dst_sg.
69fbf31dd5STom Zanussi * @src_dll: OCS DMA linked list for input data.
70fbf31dd5STom Zanussi * @dst_dll: OCS DMA linked list for output data.
71fbf31dd5STom Zanussi * @last_ct_blk: Buffer to hold last cipher text block (only used in CBC
72fbf31dd5STom Zanussi * mode).
73fbf31dd5STom Zanussi * @cts_swap: Whether or not CTS swap must be performed.
74fbf31dd5STom Zanussi * @aad_src_dll: OCS DMA linked list for input AAD data.
75fbf31dd5STom Zanussi * @aad_dst_dll: OCS DMA linked list for output AAD data.
76fbf31dd5STom Zanussi * @in_tag: Buffer to hold input encrypted tag (only used for
77fbf31dd5STom Zanussi * CCM/GCM decrypt).
78fbf31dd5STom Zanussi * @out_tag: Buffer to hold output encrypted / decrypted tag (only
79fbf31dd5STom Zanussi * used for GCM encrypt / decrypt).
80fbf31dd5STom Zanussi */
81fbf31dd5STom Zanussi struct ocs_aes_rctx {
82fbf31dd5STom Zanussi /* Fields common across all modes. */
83fbf31dd5STom Zanussi enum ocs_instruction instruction;
84fbf31dd5STom Zanussi enum ocs_mode mode;
85fbf31dd5STom Zanussi int src_nents;
86fbf31dd5STom Zanussi int dst_nents;
87fbf31dd5STom Zanussi int src_dma_count;
88fbf31dd5STom Zanussi int dst_dma_count;
89fbf31dd5STom Zanussi bool in_place;
90fbf31dd5STom Zanussi struct ocs_dll_desc src_dll;
91fbf31dd5STom Zanussi struct ocs_dll_desc dst_dll;
92fbf31dd5STom Zanussi
93fbf31dd5STom Zanussi /* CBC specific */
94fbf31dd5STom Zanussi u8 last_ct_blk[AES_BLOCK_SIZE];
95fbf31dd5STom Zanussi
96fbf31dd5STom Zanussi /* CTS specific */
97fbf31dd5STom Zanussi int cts_swap;
98fbf31dd5STom Zanussi
99fbf31dd5STom Zanussi /* CCM/GCM specific */
100fbf31dd5STom Zanussi struct ocs_dll_desc aad_src_dll;
101fbf31dd5STom Zanussi struct ocs_dll_desc aad_dst_dll;
102fbf31dd5STom Zanussi u8 in_tag[AES_BLOCK_SIZE];
103fbf31dd5STom Zanussi
104fbf31dd5STom Zanussi /* GCM specific */
105fbf31dd5STom Zanussi u8 out_tag[AES_BLOCK_SIZE];
106fbf31dd5STom Zanussi };
107fbf31dd5STom Zanussi
108fbf31dd5STom Zanussi /* Driver data. */
109fbf31dd5STom Zanussi struct ocs_aes_drv {
110fbf31dd5STom Zanussi struct list_head dev_list;
111fbf31dd5STom Zanussi spinlock_t lock; /* Protects dev_list. */
112fbf31dd5STom Zanussi };
113fbf31dd5STom Zanussi
114fbf31dd5STom Zanussi static struct ocs_aes_drv ocs_aes = {
115fbf31dd5STom Zanussi .dev_list = LIST_HEAD_INIT(ocs_aes.dev_list),
116fbf31dd5STom Zanussi .lock = __SPIN_LOCK_UNLOCKED(ocs_aes.lock),
117fbf31dd5STom Zanussi };
118fbf31dd5STom Zanussi
kmb_ocs_aes_find_dev(struct ocs_aes_tctx * tctx)119fbf31dd5STom Zanussi static struct ocs_aes_dev *kmb_ocs_aes_find_dev(struct ocs_aes_tctx *tctx)
120fbf31dd5STom Zanussi {
121fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev;
122fbf31dd5STom Zanussi
123fbf31dd5STom Zanussi spin_lock(&ocs_aes.lock);
124fbf31dd5STom Zanussi
125fbf31dd5STom Zanussi if (tctx->aes_dev) {
126fbf31dd5STom Zanussi aes_dev = tctx->aes_dev;
127fbf31dd5STom Zanussi goto exit;
128fbf31dd5STom Zanussi }
129fbf31dd5STom Zanussi
130fbf31dd5STom Zanussi /* Only a single OCS device available */
131fbf31dd5STom Zanussi aes_dev = list_first_entry(&ocs_aes.dev_list, struct ocs_aes_dev, list);
132fbf31dd5STom Zanussi tctx->aes_dev = aes_dev;
133fbf31dd5STom Zanussi
134fbf31dd5STom Zanussi exit:
135fbf31dd5STom Zanussi spin_unlock(&ocs_aes.lock);
136fbf31dd5STom Zanussi
137fbf31dd5STom Zanussi return aes_dev;
138fbf31dd5STom Zanussi }
139fbf31dd5STom Zanussi
140fbf31dd5STom Zanussi /*
141fbf31dd5STom Zanussi * Ensure key is 128-bit or 256-bit for AES or 128-bit for SM4 and an actual
142fbf31dd5STom Zanussi * key is being passed in.
143fbf31dd5STom Zanussi *
144fbf31dd5STom Zanussi * Return: 0 if key is valid, -EINVAL otherwise.
145fbf31dd5STom Zanussi */
check_key(const u8 * in_key,size_t key_len,enum ocs_cipher cipher)146fbf31dd5STom Zanussi static int check_key(const u8 *in_key, size_t key_len, enum ocs_cipher cipher)
147fbf31dd5STom Zanussi {
148fbf31dd5STom Zanussi if (!in_key)
149fbf31dd5STom Zanussi return -EINVAL;
150fbf31dd5STom Zanussi
151fbf31dd5STom Zanussi /* For AES, only 128-byte or 256-byte keys are supported. */
152fbf31dd5STom Zanussi if (cipher == OCS_AES && (key_len == OCS_AES_KEYSIZE_128 ||
153fbf31dd5STom Zanussi key_len == OCS_AES_KEYSIZE_256))
154fbf31dd5STom Zanussi return 0;
155fbf31dd5STom Zanussi
156fbf31dd5STom Zanussi /* For SM4, only 128-byte keys are supported. */
157fbf31dd5STom Zanussi if (cipher == OCS_SM4 && key_len == OCS_AES_KEYSIZE_128)
158fbf31dd5STom Zanussi return 0;
159fbf31dd5STom Zanussi
160fbf31dd5STom Zanussi /* Everything else is unsupported. */
161fbf31dd5STom Zanussi return -EINVAL;
162fbf31dd5STom Zanussi }
163fbf31dd5STom Zanussi
164fbf31dd5STom Zanussi /* Save key into transformation context. */
save_key(struct ocs_aes_tctx * tctx,const u8 * in_key,size_t key_len,enum ocs_cipher cipher)165fbf31dd5STom Zanussi static int save_key(struct ocs_aes_tctx *tctx, const u8 *in_key, size_t key_len,
166fbf31dd5STom Zanussi enum ocs_cipher cipher)
167fbf31dd5STom Zanussi {
168fbf31dd5STom Zanussi int ret;
169fbf31dd5STom Zanussi
170fbf31dd5STom Zanussi ret = check_key(in_key, key_len, cipher);
171fbf31dd5STom Zanussi if (ret)
172fbf31dd5STom Zanussi return ret;
173fbf31dd5STom Zanussi
174fbf31dd5STom Zanussi memcpy(tctx->key, in_key, key_len);
175fbf31dd5STom Zanussi tctx->key_len = key_len;
176fbf31dd5STom Zanussi tctx->cipher = cipher;
177fbf31dd5STom Zanussi
178fbf31dd5STom Zanussi return 0;
179fbf31dd5STom Zanussi }
180fbf31dd5STom Zanussi
181fbf31dd5STom Zanussi /* Set key for symmetric cypher. */
kmb_ocs_sk_set_key(struct crypto_skcipher * tfm,const u8 * in_key,size_t key_len,enum ocs_cipher cipher)182fbf31dd5STom Zanussi static int kmb_ocs_sk_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
183fbf31dd5STom Zanussi size_t key_len, enum ocs_cipher cipher)
184fbf31dd5STom Zanussi {
185fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
186fbf31dd5STom Zanussi
187fbf31dd5STom Zanussi /* Fallback is used for AES with 192-bit key. */
188fbf31dd5STom Zanussi tctx->use_fallback = (cipher == OCS_AES &&
189fbf31dd5STom Zanussi key_len == OCS_AES_KEYSIZE_192);
190fbf31dd5STom Zanussi
191fbf31dd5STom Zanussi if (!tctx->use_fallback)
192fbf31dd5STom Zanussi return save_key(tctx, in_key, key_len, cipher);
193fbf31dd5STom Zanussi
194fbf31dd5STom Zanussi crypto_sync_skcipher_clear_flags(tctx->sw_cipher.sk,
195fbf31dd5STom Zanussi CRYPTO_TFM_REQ_MASK);
196fbf31dd5STom Zanussi crypto_sync_skcipher_set_flags(tctx->sw_cipher.sk,
197fbf31dd5STom Zanussi tfm->base.crt_flags &
198fbf31dd5STom Zanussi CRYPTO_TFM_REQ_MASK);
199fbf31dd5STom Zanussi
200fbf31dd5STom Zanussi return crypto_sync_skcipher_setkey(tctx->sw_cipher.sk, in_key, key_len);
201fbf31dd5STom Zanussi }
202fbf31dd5STom Zanussi
203fbf31dd5STom Zanussi /* Set key for AEAD cipher. */
kmb_ocs_aead_set_key(struct crypto_aead * tfm,const u8 * in_key,size_t key_len,enum ocs_cipher cipher)204fbf31dd5STom Zanussi static int kmb_ocs_aead_set_key(struct crypto_aead *tfm, const u8 *in_key,
205fbf31dd5STom Zanussi size_t key_len, enum ocs_cipher cipher)
206fbf31dd5STom Zanussi {
207fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(tfm);
208fbf31dd5STom Zanussi
209fbf31dd5STom Zanussi /* Fallback is used for AES with 192-bit key. */
210fbf31dd5STom Zanussi tctx->use_fallback = (cipher == OCS_AES &&
211fbf31dd5STom Zanussi key_len == OCS_AES_KEYSIZE_192);
212fbf31dd5STom Zanussi
213fbf31dd5STom Zanussi if (!tctx->use_fallback)
214fbf31dd5STom Zanussi return save_key(tctx, in_key, key_len, cipher);
215fbf31dd5STom Zanussi
216fbf31dd5STom Zanussi crypto_aead_clear_flags(tctx->sw_cipher.aead, CRYPTO_TFM_REQ_MASK);
217fbf31dd5STom Zanussi crypto_aead_set_flags(tctx->sw_cipher.aead,
218fbf31dd5STom Zanussi crypto_aead_get_flags(tfm) & CRYPTO_TFM_REQ_MASK);
219fbf31dd5STom Zanussi
220fbf31dd5STom Zanussi return crypto_aead_setkey(tctx->sw_cipher.aead, in_key, key_len);
221fbf31dd5STom Zanussi }
222fbf31dd5STom Zanussi
223fbf31dd5STom Zanussi /* Swap two AES blocks in SG lists. */
sg_swap_blocks(struct scatterlist * sgl,unsigned int nents,off_t blk1_offset,off_t blk2_offset)224fbf31dd5STom Zanussi static void sg_swap_blocks(struct scatterlist *sgl, unsigned int nents,
225fbf31dd5STom Zanussi off_t blk1_offset, off_t blk2_offset)
226fbf31dd5STom Zanussi {
227fbf31dd5STom Zanussi u8 tmp_buf1[AES_BLOCK_SIZE], tmp_buf2[AES_BLOCK_SIZE];
228fbf31dd5STom Zanussi
229fbf31dd5STom Zanussi /*
230fbf31dd5STom Zanussi * No easy way to copy within sg list, so copy both blocks to temporary
231fbf31dd5STom Zanussi * buffers first.
232fbf31dd5STom Zanussi */
233fbf31dd5STom Zanussi sg_pcopy_to_buffer(sgl, nents, tmp_buf1, AES_BLOCK_SIZE, blk1_offset);
234fbf31dd5STom Zanussi sg_pcopy_to_buffer(sgl, nents, tmp_buf2, AES_BLOCK_SIZE, blk2_offset);
235fbf31dd5STom Zanussi sg_pcopy_from_buffer(sgl, nents, tmp_buf1, AES_BLOCK_SIZE, blk2_offset);
236fbf31dd5STom Zanussi sg_pcopy_from_buffer(sgl, nents, tmp_buf2, AES_BLOCK_SIZE, blk1_offset);
237fbf31dd5STom Zanussi }
238fbf31dd5STom Zanussi
239fbf31dd5STom Zanussi /* Initialize request context to default values. */
ocs_aes_init_rctx(struct ocs_aes_rctx * rctx)240fbf31dd5STom Zanussi static void ocs_aes_init_rctx(struct ocs_aes_rctx *rctx)
241fbf31dd5STom Zanussi {
242fbf31dd5STom Zanussi /* Zero everything. */
243fbf31dd5STom Zanussi memset(rctx, 0, sizeof(*rctx));
244fbf31dd5STom Zanussi
245fbf31dd5STom Zanussi /* Set initial value for DMA addresses. */
246fbf31dd5STom Zanussi rctx->src_dll.dma_addr = DMA_MAPPING_ERROR;
247fbf31dd5STom Zanussi rctx->dst_dll.dma_addr = DMA_MAPPING_ERROR;
248fbf31dd5STom Zanussi rctx->aad_src_dll.dma_addr = DMA_MAPPING_ERROR;
249fbf31dd5STom Zanussi rctx->aad_dst_dll.dma_addr = DMA_MAPPING_ERROR;
250fbf31dd5STom Zanussi }
251fbf31dd5STom Zanussi
kmb_ocs_sk_validate_input(struct skcipher_request * req,enum ocs_mode mode)252fbf31dd5STom Zanussi static int kmb_ocs_sk_validate_input(struct skcipher_request *req,
253fbf31dd5STom Zanussi enum ocs_mode mode)
254fbf31dd5STom Zanussi {
255fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
256fbf31dd5STom Zanussi int iv_size = crypto_skcipher_ivsize(tfm);
257fbf31dd5STom Zanussi
258fbf31dd5STom Zanussi switch (mode) {
259fbf31dd5STom Zanussi case OCS_MODE_ECB:
260fbf31dd5STom Zanussi /* Ensure input length is multiple of block size */
261fbf31dd5STom Zanussi if (req->cryptlen % AES_BLOCK_SIZE != 0)
262fbf31dd5STom Zanussi return -EINVAL;
263fbf31dd5STom Zanussi
264fbf31dd5STom Zanussi return 0;
265fbf31dd5STom Zanussi
266fbf31dd5STom Zanussi case OCS_MODE_CBC:
267fbf31dd5STom Zanussi /* Ensure input length is multiple of block size */
268fbf31dd5STom Zanussi if (req->cryptlen % AES_BLOCK_SIZE != 0)
269fbf31dd5STom Zanussi return -EINVAL;
270fbf31dd5STom Zanussi
271fbf31dd5STom Zanussi /* Ensure IV is present and block size in length */
272fbf31dd5STom Zanussi if (!req->iv || iv_size != AES_BLOCK_SIZE)
273fbf31dd5STom Zanussi return -EINVAL;
274fbf31dd5STom Zanussi /*
275fbf31dd5STom Zanussi * NOTE: Since req->cryptlen == 0 case was already handled in
276fbf31dd5STom Zanussi * kmb_ocs_sk_common(), the above two conditions also guarantee
277fbf31dd5STom Zanussi * that: cryptlen >= iv_size
278fbf31dd5STom Zanussi */
279fbf31dd5STom Zanussi return 0;
280fbf31dd5STom Zanussi
281fbf31dd5STom Zanussi case OCS_MODE_CTR:
282fbf31dd5STom Zanussi /* Ensure IV is present and block size in length */
283fbf31dd5STom Zanussi if (!req->iv || iv_size != AES_BLOCK_SIZE)
284fbf31dd5STom Zanussi return -EINVAL;
285fbf31dd5STom Zanussi return 0;
286fbf31dd5STom Zanussi
287fbf31dd5STom Zanussi case OCS_MODE_CTS:
288fbf31dd5STom Zanussi /* Ensure input length >= block size */
289fbf31dd5STom Zanussi if (req->cryptlen < AES_BLOCK_SIZE)
290fbf31dd5STom Zanussi return -EINVAL;
291fbf31dd5STom Zanussi
292fbf31dd5STom Zanussi /* Ensure IV is present and block size in length */
293fbf31dd5STom Zanussi if (!req->iv || iv_size != AES_BLOCK_SIZE)
294fbf31dd5STom Zanussi return -EINVAL;
295fbf31dd5STom Zanussi
296fbf31dd5STom Zanussi return 0;
297fbf31dd5STom Zanussi default:
298fbf31dd5STom Zanussi return -EINVAL;
299fbf31dd5STom Zanussi }
300fbf31dd5STom Zanussi }
301fbf31dd5STom Zanussi
302fbf31dd5STom Zanussi /*
303fbf31dd5STom Zanussi * Called by encrypt() / decrypt() skcipher functions.
304fbf31dd5STom Zanussi *
305fbf31dd5STom Zanussi * Use fallback if needed, otherwise initialize context and enqueue request
306fbf31dd5STom Zanussi * into engine.
307fbf31dd5STom Zanussi */
kmb_ocs_sk_common(struct skcipher_request * req,enum ocs_cipher cipher,enum ocs_instruction instruction,enum ocs_mode mode)308fbf31dd5STom Zanussi static int kmb_ocs_sk_common(struct skcipher_request *req,
309fbf31dd5STom Zanussi enum ocs_cipher cipher,
310fbf31dd5STom Zanussi enum ocs_instruction instruction,
311fbf31dd5STom Zanussi enum ocs_mode mode)
312fbf31dd5STom Zanussi {
313fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
314fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = skcipher_request_ctx(req);
315fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
316fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev;
317fbf31dd5STom Zanussi int rc;
318fbf31dd5STom Zanussi
319fbf31dd5STom Zanussi if (tctx->use_fallback) {
320fbf31dd5STom Zanussi SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, tctx->sw_cipher.sk);
321fbf31dd5STom Zanussi
322fbf31dd5STom Zanussi skcipher_request_set_sync_tfm(subreq, tctx->sw_cipher.sk);
323fbf31dd5STom Zanussi skcipher_request_set_callback(subreq, req->base.flags, NULL,
324fbf31dd5STom Zanussi NULL);
325fbf31dd5STom Zanussi skcipher_request_set_crypt(subreq, req->src, req->dst,
326fbf31dd5STom Zanussi req->cryptlen, req->iv);
327fbf31dd5STom Zanussi
328fbf31dd5STom Zanussi if (instruction == OCS_ENCRYPT)
329fbf31dd5STom Zanussi rc = crypto_skcipher_encrypt(subreq);
330fbf31dd5STom Zanussi else
331fbf31dd5STom Zanussi rc = crypto_skcipher_decrypt(subreq);
332fbf31dd5STom Zanussi
333fbf31dd5STom Zanussi skcipher_request_zero(subreq);
334fbf31dd5STom Zanussi
335fbf31dd5STom Zanussi return rc;
336fbf31dd5STom Zanussi }
337fbf31dd5STom Zanussi
338fbf31dd5STom Zanussi /*
339fbf31dd5STom Zanussi * If cryptlen == 0, no processing needed for ECB, CBC and CTR.
340fbf31dd5STom Zanussi *
341fbf31dd5STom Zanussi * For CTS continue: kmb_ocs_sk_validate_input() will return -EINVAL.
342fbf31dd5STom Zanussi */
343fbf31dd5STom Zanussi if (!req->cryptlen && mode != OCS_MODE_CTS)
344fbf31dd5STom Zanussi return 0;
345fbf31dd5STom Zanussi
346fbf31dd5STom Zanussi rc = kmb_ocs_sk_validate_input(req, mode);
347fbf31dd5STom Zanussi if (rc)
348fbf31dd5STom Zanussi return rc;
349fbf31dd5STom Zanussi
350fbf31dd5STom Zanussi aes_dev = kmb_ocs_aes_find_dev(tctx);
351fbf31dd5STom Zanussi if (!aes_dev)
352fbf31dd5STom Zanussi return -ENODEV;
353fbf31dd5STom Zanussi
354fbf31dd5STom Zanussi if (cipher != tctx->cipher)
355fbf31dd5STom Zanussi return -EINVAL;
356fbf31dd5STom Zanussi
357fbf31dd5STom Zanussi ocs_aes_init_rctx(rctx);
358fbf31dd5STom Zanussi rctx->instruction = instruction;
359fbf31dd5STom Zanussi rctx->mode = mode;
360fbf31dd5STom Zanussi
361fbf31dd5STom Zanussi return crypto_transfer_skcipher_request_to_engine(aes_dev->engine, req);
362fbf31dd5STom Zanussi }
363fbf31dd5STom Zanussi
cleanup_ocs_dma_linked_list(struct device * dev,struct ocs_dll_desc * dll)364fbf31dd5STom Zanussi static void cleanup_ocs_dma_linked_list(struct device *dev,
365fbf31dd5STom Zanussi struct ocs_dll_desc *dll)
366fbf31dd5STom Zanussi {
367fbf31dd5STom Zanussi if (dll->vaddr)
368fbf31dd5STom Zanussi dma_free_coherent(dev, dll->size, dll->vaddr, dll->dma_addr);
369fbf31dd5STom Zanussi dll->vaddr = NULL;
370fbf31dd5STom Zanussi dll->size = 0;
371fbf31dd5STom Zanussi dll->dma_addr = DMA_MAPPING_ERROR;
372fbf31dd5STom Zanussi }
373fbf31dd5STom Zanussi
kmb_ocs_sk_dma_cleanup(struct skcipher_request * req)374fbf31dd5STom Zanussi static void kmb_ocs_sk_dma_cleanup(struct skcipher_request *req)
375fbf31dd5STom Zanussi {
376fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
377fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = skcipher_request_ctx(req);
378fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
379fbf31dd5STom Zanussi struct device *dev = tctx->aes_dev->dev;
380fbf31dd5STom Zanussi
381fbf31dd5STom Zanussi if (rctx->src_dma_count) {
382fbf31dd5STom Zanussi dma_unmap_sg(dev, req->src, rctx->src_nents, DMA_TO_DEVICE);
383fbf31dd5STom Zanussi rctx->src_dma_count = 0;
384fbf31dd5STom Zanussi }
385fbf31dd5STom Zanussi
386fbf31dd5STom Zanussi if (rctx->dst_dma_count) {
387fbf31dd5STom Zanussi dma_unmap_sg(dev, req->dst, rctx->dst_nents, rctx->in_place ?
388fbf31dd5STom Zanussi DMA_BIDIRECTIONAL :
389fbf31dd5STom Zanussi DMA_FROM_DEVICE);
390fbf31dd5STom Zanussi rctx->dst_dma_count = 0;
391fbf31dd5STom Zanussi }
392fbf31dd5STom Zanussi
393fbf31dd5STom Zanussi /* Clean up OCS DMA linked lists */
394fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->src_dll);
395fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->dst_dll);
396fbf31dd5STom Zanussi }
397fbf31dd5STom Zanussi
kmb_ocs_sk_prepare_inplace(struct skcipher_request * req)398fbf31dd5STom Zanussi static int kmb_ocs_sk_prepare_inplace(struct skcipher_request *req)
399fbf31dd5STom Zanussi {
400fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
401fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = skcipher_request_ctx(req);
402fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
403fbf31dd5STom Zanussi int iv_size = crypto_skcipher_ivsize(tfm);
404fbf31dd5STom Zanussi int rc;
405fbf31dd5STom Zanussi
406fbf31dd5STom Zanussi /*
407fbf31dd5STom Zanussi * For CBC decrypt, save last block (iv) to last_ct_blk buffer.
408fbf31dd5STom Zanussi *
409fbf31dd5STom Zanussi * Note: if we are here, we already checked that cryptlen >= iv_size
410fbf31dd5STom Zanussi * and iv_size == AES_BLOCK_SIZE (i.e., the size of last_ct_blk); see
411fbf31dd5STom Zanussi * kmb_ocs_sk_validate_input().
412fbf31dd5STom Zanussi */
413fbf31dd5STom Zanussi if (rctx->mode == OCS_MODE_CBC && rctx->instruction == OCS_DECRYPT)
414fbf31dd5STom Zanussi scatterwalk_map_and_copy(rctx->last_ct_blk, req->src,
415fbf31dd5STom Zanussi req->cryptlen - iv_size, iv_size, 0);
416fbf31dd5STom Zanussi
417fbf31dd5STom Zanussi /* For CTS decrypt, swap last two blocks, if needed. */
418fbf31dd5STom Zanussi if (rctx->cts_swap && rctx->instruction == OCS_DECRYPT)
419fbf31dd5STom Zanussi sg_swap_blocks(req->dst, rctx->dst_nents,
420fbf31dd5STom Zanussi req->cryptlen - AES_BLOCK_SIZE,
421fbf31dd5STom Zanussi req->cryptlen - (2 * AES_BLOCK_SIZE));
422fbf31dd5STom Zanussi
423fbf31dd5STom Zanussi /* src and dst buffers are the same, use bidirectional DMA mapping. */
424fbf31dd5STom Zanussi rctx->dst_dma_count = dma_map_sg(tctx->aes_dev->dev, req->dst,
425fbf31dd5STom Zanussi rctx->dst_nents, DMA_BIDIRECTIONAL);
426fbf31dd5STom Zanussi if (rctx->dst_dma_count == 0) {
427fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev, "Failed to map destination sg\n");
428fbf31dd5STom Zanussi return -ENOMEM;
429fbf31dd5STom Zanussi }
430fbf31dd5STom Zanussi
431fbf31dd5STom Zanussi /* Create DST linked list */
432fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
433fbf31dd5STom Zanussi rctx->dst_dma_count, &rctx->dst_dll,
434fbf31dd5STom Zanussi req->cryptlen, 0);
435fbf31dd5STom Zanussi if (rc)
436fbf31dd5STom Zanussi return rc;
437fbf31dd5STom Zanussi /*
438fbf31dd5STom Zanussi * If descriptor creation was successful, set the src_dll.dma_addr to
439fbf31dd5STom Zanussi * the value of dst_dll.dma_addr, as we do in-place AES operation on
440fbf31dd5STom Zanussi * the src.
441fbf31dd5STom Zanussi */
442fbf31dd5STom Zanussi rctx->src_dll.dma_addr = rctx->dst_dll.dma_addr;
443fbf31dd5STom Zanussi
444fbf31dd5STom Zanussi return 0;
445fbf31dd5STom Zanussi }
446fbf31dd5STom Zanussi
kmb_ocs_sk_prepare_notinplace(struct skcipher_request * req)447fbf31dd5STom Zanussi static int kmb_ocs_sk_prepare_notinplace(struct skcipher_request *req)
448fbf31dd5STom Zanussi {
449fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
450fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = skcipher_request_ctx(req);
451fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
452fbf31dd5STom Zanussi int rc;
453fbf31dd5STom Zanussi
454fbf31dd5STom Zanussi rctx->src_nents = sg_nents_for_len(req->src, req->cryptlen);
455fbf31dd5STom Zanussi if (rctx->src_nents < 0)
456fbf31dd5STom Zanussi return -EBADMSG;
457fbf31dd5STom Zanussi
458fbf31dd5STom Zanussi /* Map SRC SG. */
459fbf31dd5STom Zanussi rctx->src_dma_count = dma_map_sg(tctx->aes_dev->dev, req->src,
460fbf31dd5STom Zanussi rctx->src_nents, DMA_TO_DEVICE);
461fbf31dd5STom Zanussi if (rctx->src_dma_count == 0) {
462fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev, "Failed to map source sg\n");
463fbf31dd5STom Zanussi return -ENOMEM;
464fbf31dd5STom Zanussi }
465fbf31dd5STom Zanussi
466fbf31dd5STom Zanussi /* Create SRC linked list */
467fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->src,
468fbf31dd5STom Zanussi rctx->src_dma_count, &rctx->src_dll,
469fbf31dd5STom Zanussi req->cryptlen, 0);
470fbf31dd5STom Zanussi if (rc)
471fbf31dd5STom Zanussi return rc;
472fbf31dd5STom Zanussi
473fbf31dd5STom Zanussi /* Map DST SG. */
474fbf31dd5STom Zanussi rctx->dst_dma_count = dma_map_sg(tctx->aes_dev->dev, req->dst,
475fbf31dd5STom Zanussi rctx->dst_nents, DMA_FROM_DEVICE);
476fbf31dd5STom Zanussi if (rctx->dst_dma_count == 0) {
477fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev, "Failed to map destination sg\n");
478fbf31dd5STom Zanussi return -ENOMEM;
479fbf31dd5STom Zanussi }
480fbf31dd5STom Zanussi
481fbf31dd5STom Zanussi /* Create DST linked list */
482fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
483fbf31dd5STom Zanussi rctx->dst_dma_count, &rctx->dst_dll,
484fbf31dd5STom Zanussi req->cryptlen, 0);
485fbf31dd5STom Zanussi if (rc)
486fbf31dd5STom Zanussi return rc;
487fbf31dd5STom Zanussi
488fbf31dd5STom Zanussi /* If this is not a CTS decrypt operation with swapping, we are done. */
489fbf31dd5STom Zanussi if (!(rctx->cts_swap && rctx->instruction == OCS_DECRYPT))
490fbf31dd5STom Zanussi return 0;
491fbf31dd5STom Zanussi
492fbf31dd5STom Zanussi /*
493fbf31dd5STom Zanussi * Otherwise, we have to copy src to dst (as we cannot modify src).
494fbf31dd5STom Zanussi * Use OCS AES bypass mode to copy src to dst via DMA.
495fbf31dd5STom Zanussi *
496fbf31dd5STom Zanussi * NOTE: for anything other than small data sizes this is rather
497fbf31dd5STom Zanussi * inefficient.
498fbf31dd5STom Zanussi */
499fbf31dd5STom Zanussi rc = ocs_aes_bypass_op(tctx->aes_dev, rctx->dst_dll.dma_addr,
500fbf31dd5STom Zanussi rctx->src_dll.dma_addr, req->cryptlen);
501fbf31dd5STom Zanussi if (rc)
502fbf31dd5STom Zanussi return rc;
503fbf31dd5STom Zanussi
504fbf31dd5STom Zanussi /*
505fbf31dd5STom Zanussi * Now dst == src, so clean up what we did so far and use in_place
506fbf31dd5STom Zanussi * logic.
507fbf31dd5STom Zanussi */
508fbf31dd5STom Zanussi kmb_ocs_sk_dma_cleanup(req);
509fbf31dd5STom Zanussi rctx->in_place = true;
510fbf31dd5STom Zanussi
511fbf31dd5STom Zanussi return kmb_ocs_sk_prepare_inplace(req);
512fbf31dd5STom Zanussi }
513fbf31dd5STom Zanussi
kmb_ocs_sk_run(struct skcipher_request * req)514fbf31dd5STom Zanussi static int kmb_ocs_sk_run(struct skcipher_request *req)
515fbf31dd5STom Zanussi {
516fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
517fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = skcipher_request_ctx(req);
518fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
519fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev = tctx->aes_dev;
520fbf31dd5STom Zanussi int iv_size = crypto_skcipher_ivsize(tfm);
521fbf31dd5STom Zanussi int rc;
522fbf31dd5STom Zanussi
523fbf31dd5STom Zanussi rctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
524fbf31dd5STom Zanussi if (rctx->dst_nents < 0)
525fbf31dd5STom Zanussi return -EBADMSG;
526fbf31dd5STom Zanussi
527fbf31dd5STom Zanussi /*
528fbf31dd5STom Zanussi * If 2 blocks or greater, and multiple of block size swap last two
529fbf31dd5STom Zanussi * blocks to be compatible with other crypto API CTS implementations:
530fbf31dd5STom Zanussi * OCS mode uses CBC-CS2, whereas other crypto API implementations use
531fbf31dd5STom Zanussi * CBC-CS3.
532fbf31dd5STom Zanussi * CBC-CS2 and CBC-CS3 defined by:
533fbf31dd5STom Zanussi * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a-add.pdf
534fbf31dd5STom Zanussi */
535fbf31dd5STom Zanussi rctx->cts_swap = (rctx->mode == OCS_MODE_CTS &&
536fbf31dd5STom Zanussi req->cryptlen > AES_BLOCK_SIZE &&
537fbf31dd5STom Zanussi req->cryptlen % AES_BLOCK_SIZE == 0);
538fbf31dd5STom Zanussi
539fbf31dd5STom Zanussi rctx->in_place = (req->src == req->dst);
540fbf31dd5STom Zanussi
541fbf31dd5STom Zanussi if (rctx->in_place)
542fbf31dd5STom Zanussi rc = kmb_ocs_sk_prepare_inplace(req);
543fbf31dd5STom Zanussi else
544fbf31dd5STom Zanussi rc = kmb_ocs_sk_prepare_notinplace(req);
545fbf31dd5STom Zanussi
546fbf31dd5STom Zanussi if (rc)
547fbf31dd5STom Zanussi goto error;
548fbf31dd5STom Zanussi
549fbf31dd5STom Zanussi rc = ocs_aes_op(aes_dev, rctx->mode, tctx->cipher, rctx->instruction,
550fbf31dd5STom Zanussi rctx->dst_dll.dma_addr, rctx->src_dll.dma_addr,
551fbf31dd5STom Zanussi req->cryptlen, req->iv, iv_size);
552fbf31dd5STom Zanussi if (rc)
553fbf31dd5STom Zanussi goto error;
554fbf31dd5STom Zanussi
555fbf31dd5STom Zanussi /* Clean-up DMA before further processing output. */
556fbf31dd5STom Zanussi kmb_ocs_sk_dma_cleanup(req);
557fbf31dd5STom Zanussi
558fbf31dd5STom Zanussi /* For CTS Encrypt, swap last 2 blocks, if needed. */
559fbf31dd5STom Zanussi if (rctx->cts_swap && rctx->instruction == OCS_ENCRYPT) {
560fbf31dd5STom Zanussi sg_swap_blocks(req->dst, rctx->dst_nents,
561fbf31dd5STom Zanussi req->cryptlen - AES_BLOCK_SIZE,
562fbf31dd5STom Zanussi req->cryptlen - (2 * AES_BLOCK_SIZE));
563fbf31dd5STom Zanussi return 0;
564fbf31dd5STom Zanussi }
565fbf31dd5STom Zanussi
566fbf31dd5STom Zanussi /* For CBC copy IV to req->IV. */
567fbf31dd5STom Zanussi if (rctx->mode == OCS_MODE_CBC) {
568fbf31dd5STom Zanussi /* CBC encrypt case. */
569fbf31dd5STom Zanussi if (rctx->instruction == OCS_ENCRYPT) {
570fbf31dd5STom Zanussi scatterwalk_map_and_copy(req->iv, req->dst,
571fbf31dd5STom Zanussi req->cryptlen - iv_size,
572fbf31dd5STom Zanussi iv_size, 0);
573fbf31dd5STom Zanussi return 0;
574fbf31dd5STom Zanussi }
575fbf31dd5STom Zanussi /* CBC decrypt case. */
576fbf31dd5STom Zanussi if (rctx->in_place)
577fbf31dd5STom Zanussi memcpy(req->iv, rctx->last_ct_blk, iv_size);
578fbf31dd5STom Zanussi else
579fbf31dd5STom Zanussi scatterwalk_map_and_copy(req->iv, req->src,
580fbf31dd5STom Zanussi req->cryptlen - iv_size,
581fbf31dd5STom Zanussi iv_size, 0);
582fbf31dd5STom Zanussi return 0;
583fbf31dd5STom Zanussi }
584fbf31dd5STom Zanussi /* For all other modes there's nothing to do. */
585fbf31dd5STom Zanussi
586fbf31dd5STom Zanussi return 0;
587fbf31dd5STom Zanussi
588fbf31dd5STom Zanussi error:
589fbf31dd5STom Zanussi kmb_ocs_sk_dma_cleanup(req);
590fbf31dd5STom Zanussi
591fbf31dd5STom Zanussi return rc;
592fbf31dd5STom Zanussi }
593fbf31dd5STom Zanussi
kmb_ocs_aead_validate_input(struct aead_request * req,enum ocs_instruction instruction,enum ocs_mode mode)594fbf31dd5STom Zanussi static int kmb_ocs_aead_validate_input(struct aead_request *req,
595fbf31dd5STom Zanussi enum ocs_instruction instruction,
596fbf31dd5STom Zanussi enum ocs_mode mode)
597fbf31dd5STom Zanussi {
598fbf31dd5STom Zanussi struct crypto_aead *tfm = crypto_aead_reqtfm(req);
599fbf31dd5STom Zanussi int tag_size = crypto_aead_authsize(tfm);
600fbf31dd5STom Zanussi int iv_size = crypto_aead_ivsize(tfm);
601fbf31dd5STom Zanussi
602fbf31dd5STom Zanussi /* For decrypt crytplen == len(PT) + len(tag). */
603fbf31dd5STom Zanussi if (instruction == OCS_DECRYPT && req->cryptlen < tag_size)
604fbf31dd5STom Zanussi return -EINVAL;
605fbf31dd5STom Zanussi
606fbf31dd5STom Zanussi /* IV is mandatory. */
607fbf31dd5STom Zanussi if (!req->iv)
608fbf31dd5STom Zanussi return -EINVAL;
609fbf31dd5STom Zanussi
610fbf31dd5STom Zanussi switch (mode) {
611fbf31dd5STom Zanussi case OCS_MODE_GCM:
612fbf31dd5STom Zanussi if (iv_size != GCM_AES_IV_SIZE)
613fbf31dd5STom Zanussi return -EINVAL;
614fbf31dd5STom Zanussi
615fbf31dd5STom Zanussi return 0;
616fbf31dd5STom Zanussi
617fbf31dd5STom Zanussi case OCS_MODE_CCM:
618fbf31dd5STom Zanussi /* Ensure IV is present and block size in length */
619fbf31dd5STom Zanussi if (iv_size != AES_BLOCK_SIZE)
620fbf31dd5STom Zanussi return -EINVAL;
621fbf31dd5STom Zanussi
622fbf31dd5STom Zanussi return 0;
623fbf31dd5STom Zanussi
624fbf31dd5STom Zanussi default:
625fbf31dd5STom Zanussi return -EINVAL;
626fbf31dd5STom Zanussi }
627fbf31dd5STom Zanussi }
628fbf31dd5STom Zanussi
629fbf31dd5STom Zanussi /*
630fbf31dd5STom Zanussi * Called by encrypt() / decrypt() aead functions.
631fbf31dd5STom Zanussi *
632fbf31dd5STom Zanussi * Use fallback if needed, otherwise initialize context and enqueue request
633fbf31dd5STom Zanussi * into engine.
634fbf31dd5STom Zanussi */
kmb_ocs_aead_common(struct aead_request * req,enum ocs_cipher cipher,enum ocs_instruction instruction,enum ocs_mode mode)635fbf31dd5STom Zanussi static int kmb_ocs_aead_common(struct aead_request *req,
636fbf31dd5STom Zanussi enum ocs_cipher cipher,
637fbf31dd5STom Zanussi enum ocs_instruction instruction,
638fbf31dd5STom Zanussi enum ocs_mode mode)
639fbf31dd5STom Zanussi {
640fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
641fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = aead_request_ctx(req);
642fbf31dd5STom Zanussi struct ocs_aes_dev *dd;
643fbf31dd5STom Zanussi int rc;
644fbf31dd5STom Zanussi
645fbf31dd5STom Zanussi if (tctx->use_fallback) {
646fbf31dd5STom Zanussi struct aead_request *subreq = aead_request_ctx(req);
647fbf31dd5STom Zanussi
648fbf31dd5STom Zanussi aead_request_set_tfm(subreq, tctx->sw_cipher.aead);
649fbf31dd5STom Zanussi aead_request_set_callback(subreq, req->base.flags,
650fbf31dd5STom Zanussi req->base.complete, req->base.data);
651fbf31dd5STom Zanussi aead_request_set_crypt(subreq, req->src, req->dst,
652fbf31dd5STom Zanussi req->cryptlen, req->iv);
653fbf31dd5STom Zanussi aead_request_set_ad(subreq, req->assoclen);
654fbf31dd5STom Zanussi rc = crypto_aead_setauthsize(tctx->sw_cipher.aead,
655fbf31dd5STom Zanussi crypto_aead_authsize(crypto_aead_reqtfm(req)));
656fbf31dd5STom Zanussi if (rc)
657fbf31dd5STom Zanussi return rc;
658fbf31dd5STom Zanussi
659fbf31dd5STom Zanussi return (instruction == OCS_ENCRYPT) ?
660fbf31dd5STom Zanussi crypto_aead_encrypt(subreq) :
661fbf31dd5STom Zanussi crypto_aead_decrypt(subreq);
662fbf31dd5STom Zanussi }
663fbf31dd5STom Zanussi
664fbf31dd5STom Zanussi rc = kmb_ocs_aead_validate_input(req, instruction, mode);
665fbf31dd5STom Zanussi if (rc)
666fbf31dd5STom Zanussi return rc;
667fbf31dd5STom Zanussi
668fbf31dd5STom Zanussi dd = kmb_ocs_aes_find_dev(tctx);
669fbf31dd5STom Zanussi if (!dd)
670fbf31dd5STom Zanussi return -ENODEV;
671fbf31dd5STom Zanussi
672fbf31dd5STom Zanussi if (cipher != tctx->cipher)
673fbf31dd5STom Zanussi return -EINVAL;
674fbf31dd5STom Zanussi
675fbf31dd5STom Zanussi ocs_aes_init_rctx(rctx);
676fbf31dd5STom Zanussi rctx->instruction = instruction;
677fbf31dd5STom Zanussi rctx->mode = mode;
678fbf31dd5STom Zanussi
679fbf31dd5STom Zanussi return crypto_transfer_aead_request_to_engine(dd->engine, req);
680fbf31dd5STom Zanussi }
681fbf31dd5STom Zanussi
kmb_ocs_aead_dma_cleanup(struct aead_request * req)682fbf31dd5STom Zanussi static void kmb_ocs_aead_dma_cleanup(struct aead_request *req)
683fbf31dd5STom Zanussi {
684fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
685fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = aead_request_ctx(req);
686fbf31dd5STom Zanussi struct device *dev = tctx->aes_dev->dev;
687fbf31dd5STom Zanussi
688fbf31dd5STom Zanussi if (rctx->src_dma_count) {
689fbf31dd5STom Zanussi dma_unmap_sg(dev, req->src, rctx->src_nents, DMA_TO_DEVICE);
690fbf31dd5STom Zanussi rctx->src_dma_count = 0;
691fbf31dd5STom Zanussi }
692fbf31dd5STom Zanussi
693fbf31dd5STom Zanussi if (rctx->dst_dma_count) {
694fbf31dd5STom Zanussi dma_unmap_sg(dev, req->dst, rctx->dst_nents, rctx->in_place ?
695fbf31dd5STom Zanussi DMA_BIDIRECTIONAL :
696fbf31dd5STom Zanussi DMA_FROM_DEVICE);
697fbf31dd5STom Zanussi rctx->dst_dma_count = 0;
698fbf31dd5STom Zanussi }
699fbf31dd5STom Zanussi /* Clean up OCS DMA linked lists */
700fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->src_dll);
701fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->dst_dll);
702fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->aad_src_dll);
703fbf31dd5STom Zanussi cleanup_ocs_dma_linked_list(dev, &rctx->aad_dst_dll);
704fbf31dd5STom Zanussi }
705fbf31dd5STom Zanussi
706fbf31dd5STom Zanussi /**
707fbf31dd5STom Zanussi * kmb_ocs_aead_dma_prepare() - Do DMA mapping for AEAD processing.
708fbf31dd5STom Zanussi * @req: The AEAD request being processed.
709fbf31dd5STom Zanussi * @src_dll_size: Where to store the length of the data mapped into the
710fbf31dd5STom Zanussi * src_dll OCS DMA list.
711fbf31dd5STom Zanussi *
712fbf31dd5STom Zanussi * Do the following:
713fbf31dd5STom Zanussi * - DMA map req->src and req->dst
714fbf31dd5STom Zanussi * - Initialize the following OCS DMA linked lists: rctx->src_dll,
715fbf31dd5STom Zanussi * rctx->dst_dll, rctx->aad_src_dll and rxtc->aad_dst_dll.
716fbf31dd5STom Zanussi *
717fbf31dd5STom Zanussi * Return: 0 on success, negative error code otherwise.
718fbf31dd5STom Zanussi */
kmb_ocs_aead_dma_prepare(struct aead_request * req,u32 * src_dll_size)719fbf31dd5STom Zanussi static int kmb_ocs_aead_dma_prepare(struct aead_request *req, u32 *src_dll_size)
720fbf31dd5STom Zanussi {
721fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
722fbf31dd5STom Zanussi const int tag_size = crypto_aead_authsize(crypto_aead_reqtfm(req));
723fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = aead_request_ctx(req);
724fbf31dd5STom Zanussi u32 in_size; /* The length of the data to be mapped by src_dll. */
725fbf31dd5STom Zanussi u32 out_size; /* The length of the data to be mapped by dst_dll. */
726fbf31dd5STom Zanussi u32 dst_size; /* The length of the data in dst_sg. */
727fbf31dd5STom Zanussi int rc;
728fbf31dd5STom Zanussi
729fbf31dd5STom Zanussi /* Get number of entries in input data SG list. */
730fbf31dd5STom Zanussi rctx->src_nents = sg_nents_for_len(req->src,
731fbf31dd5STom Zanussi req->assoclen + req->cryptlen);
732fbf31dd5STom Zanussi if (rctx->src_nents < 0)
733fbf31dd5STom Zanussi return -EBADMSG;
734fbf31dd5STom Zanussi
735fbf31dd5STom Zanussi if (rctx->instruction == OCS_DECRYPT) {
736fbf31dd5STom Zanussi /*
737fbf31dd5STom Zanussi * For decrypt:
738fbf31dd5STom Zanussi * - src sg list is: AAD|CT|tag
739fbf31dd5STom Zanussi * - dst sg list expects: AAD|PT
740fbf31dd5STom Zanussi *
741fbf31dd5STom Zanussi * in_size == len(CT); out_size == len(PT)
742fbf31dd5STom Zanussi */
743fbf31dd5STom Zanussi
744fbf31dd5STom Zanussi /* req->cryptlen includes both CT and tag. */
745fbf31dd5STom Zanussi in_size = req->cryptlen - tag_size;
746fbf31dd5STom Zanussi
747fbf31dd5STom Zanussi /* out_size = PT size == CT size */
748fbf31dd5STom Zanussi out_size = in_size;
749fbf31dd5STom Zanussi
750fbf31dd5STom Zanussi /* len(dst_sg) == len(AAD) + len(PT) */
751fbf31dd5STom Zanussi dst_size = req->assoclen + out_size;
752fbf31dd5STom Zanussi
753fbf31dd5STom Zanussi /*
754fbf31dd5STom Zanussi * Copy tag from source SG list to 'in_tag' buffer.
755fbf31dd5STom Zanussi *
756fbf31dd5STom Zanussi * Note: this needs to be done here, before DMA mapping src_sg.
757fbf31dd5STom Zanussi */
758fbf31dd5STom Zanussi sg_pcopy_to_buffer(req->src, rctx->src_nents, rctx->in_tag,
759fbf31dd5STom Zanussi tag_size, req->assoclen + in_size);
760fbf31dd5STom Zanussi
761fbf31dd5STom Zanussi } else { /* OCS_ENCRYPT */
762fbf31dd5STom Zanussi /*
763fbf31dd5STom Zanussi * For encrypt:
764fbf31dd5STom Zanussi * src sg list is: AAD|PT
765fbf31dd5STom Zanussi * dst sg list expects: AAD|CT|tag
766fbf31dd5STom Zanussi */
767fbf31dd5STom Zanussi /* in_size == len(PT) */
768fbf31dd5STom Zanussi in_size = req->cryptlen;
769fbf31dd5STom Zanussi
770fbf31dd5STom Zanussi /*
771fbf31dd5STom Zanussi * In CCM mode the OCS engine appends the tag to the ciphertext,
772fbf31dd5STom Zanussi * but in GCM mode the tag must be read from the tag registers
773fbf31dd5STom Zanussi * and appended manually below
774fbf31dd5STom Zanussi */
775fbf31dd5STom Zanussi out_size = (rctx->mode == OCS_MODE_CCM) ? in_size + tag_size :
776fbf31dd5STom Zanussi in_size;
777fbf31dd5STom Zanussi /* len(dst_sg) == len(AAD) + len(CT) + len(tag) */
778fbf31dd5STom Zanussi dst_size = req->assoclen + in_size + tag_size;
779fbf31dd5STom Zanussi }
780fbf31dd5STom Zanussi *src_dll_size = in_size;
781fbf31dd5STom Zanussi
782fbf31dd5STom Zanussi /* Get number of entries in output data SG list. */
783fbf31dd5STom Zanussi rctx->dst_nents = sg_nents_for_len(req->dst, dst_size);
784fbf31dd5STom Zanussi if (rctx->dst_nents < 0)
785fbf31dd5STom Zanussi return -EBADMSG;
786fbf31dd5STom Zanussi
787fbf31dd5STom Zanussi rctx->in_place = (req->src == req->dst) ? 1 : 0;
788fbf31dd5STom Zanussi
789fbf31dd5STom Zanussi /* Map destination; use bidirectional mapping for in-place case. */
790fbf31dd5STom Zanussi rctx->dst_dma_count = dma_map_sg(tctx->aes_dev->dev, req->dst,
791fbf31dd5STom Zanussi rctx->dst_nents,
792fbf31dd5STom Zanussi rctx->in_place ? DMA_BIDIRECTIONAL :
793fbf31dd5STom Zanussi DMA_FROM_DEVICE);
794fbf31dd5STom Zanussi if (rctx->dst_dma_count == 0 && rctx->dst_nents != 0) {
795fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev, "Failed to map destination sg\n");
796fbf31dd5STom Zanussi return -ENOMEM;
797fbf31dd5STom Zanussi }
798fbf31dd5STom Zanussi
799fbf31dd5STom Zanussi /* Create AAD DST list: maps dst[0:AAD_SIZE-1]. */
800fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
801fbf31dd5STom Zanussi rctx->dst_dma_count,
802fbf31dd5STom Zanussi &rctx->aad_dst_dll, req->assoclen,
803fbf31dd5STom Zanussi 0);
804fbf31dd5STom Zanussi if (rc)
805fbf31dd5STom Zanussi return rc;
806fbf31dd5STom Zanussi
807fbf31dd5STom Zanussi /* Create DST list: maps dst[AAD_SIZE:out_size] */
808fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
809fbf31dd5STom Zanussi rctx->dst_dma_count, &rctx->dst_dll,
810fbf31dd5STom Zanussi out_size, req->assoclen);
811fbf31dd5STom Zanussi if (rc)
812fbf31dd5STom Zanussi return rc;
813fbf31dd5STom Zanussi
814fbf31dd5STom Zanussi if (rctx->in_place) {
815fbf31dd5STom Zanussi /* If this is not CCM encrypt, we are done. */
816fbf31dd5STom Zanussi if (!(rctx->mode == OCS_MODE_CCM &&
817fbf31dd5STom Zanussi rctx->instruction == OCS_ENCRYPT)) {
818fbf31dd5STom Zanussi /*
819fbf31dd5STom Zanussi * SRC and DST are the same, so re-use the same DMA
820fbf31dd5STom Zanussi * addresses (to avoid allocating new DMA lists
821fbf31dd5STom Zanussi * identical to the dst ones).
822fbf31dd5STom Zanussi */
823fbf31dd5STom Zanussi rctx->src_dll.dma_addr = rctx->dst_dll.dma_addr;
824fbf31dd5STom Zanussi rctx->aad_src_dll.dma_addr = rctx->aad_dst_dll.dma_addr;
825fbf31dd5STom Zanussi
826fbf31dd5STom Zanussi return 0;
827fbf31dd5STom Zanussi }
828fbf31dd5STom Zanussi /*
829fbf31dd5STom Zanussi * For CCM encrypt the input and output linked lists contain
830fbf31dd5STom Zanussi * different amounts of data, so, we need to create different
831fbf31dd5STom Zanussi * SRC and AAD SRC lists, even for the in-place case.
832fbf31dd5STom Zanussi */
833fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
834fbf31dd5STom Zanussi rctx->dst_dma_count,
835fbf31dd5STom Zanussi &rctx->aad_src_dll,
836fbf31dd5STom Zanussi req->assoclen, 0);
837fbf31dd5STom Zanussi if (rc)
838fbf31dd5STom Zanussi return rc;
839fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->dst,
840fbf31dd5STom Zanussi rctx->dst_dma_count,
841fbf31dd5STom Zanussi &rctx->src_dll, in_size,
842fbf31dd5STom Zanussi req->assoclen);
843fbf31dd5STom Zanussi if (rc)
844fbf31dd5STom Zanussi return rc;
845fbf31dd5STom Zanussi
846fbf31dd5STom Zanussi return 0;
847fbf31dd5STom Zanussi }
848fbf31dd5STom Zanussi /* Not in-place case. */
849fbf31dd5STom Zanussi
850fbf31dd5STom Zanussi /* Map source SG. */
851fbf31dd5STom Zanussi rctx->src_dma_count = dma_map_sg(tctx->aes_dev->dev, req->src,
852fbf31dd5STom Zanussi rctx->src_nents, DMA_TO_DEVICE);
853fbf31dd5STom Zanussi if (rctx->src_dma_count == 0 && rctx->src_nents != 0) {
854fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev, "Failed to map source sg\n");
855fbf31dd5STom Zanussi return -ENOMEM;
856fbf31dd5STom Zanussi }
857fbf31dd5STom Zanussi
858fbf31dd5STom Zanussi /* Create AAD SRC list. */
859fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->src,
860fbf31dd5STom Zanussi rctx->src_dma_count,
861fbf31dd5STom Zanussi &rctx->aad_src_dll,
862fbf31dd5STom Zanussi req->assoclen, 0);
863fbf31dd5STom Zanussi if (rc)
864fbf31dd5STom Zanussi return rc;
865fbf31dd5STom Zanussi
866fbf31dd5STom Zanussi /* Create SRC list. */
867fbf31dd5STom Zanussi rc = ocs_create_linked_list_from_sg(tctx->aes_dev, req->src,
868fbf31dd5STom Zanussi rctx->src_dma_count,
869fbf31dd5STom Zanussi &rctx->src_dll, in_size,
870fbf31dd5STom Zanussi req->assoclen);
871fbf31dd5STom Zanussi if (rc)
872fbf31dd5STom Zanussi return rc;
873fbf31dd5STom Zanussi
874fbf31dd5STom Zanussi if (req->assoclen == 0)
875fbf31dd5STom Zanussi return 0;
876fbf31dd5STom Zanussi
877fbf31dd5STom Zanussi /* Copy AAD from src sg to dst sg using OCS DMA. */
878fbf31dd5STom Zanussi rc = ocs_aes_bypass_op(tctx->aes_dev, rctx->aad_dst_dll.dma_addr,
879fbf31dd5STom Zanussi rctx->aad_src_dll.dma_addr, req->cryptlen);
880fbf31dd5STom Zanussi if (rc)
881fbf31dd5STom Zanussi dev_err(tctx->aes_dev->dev,
882fbf31dd5STom Zanussi "Failed to copy source AAD to destination AAD\n");
883fbf31dd5STom Zanussi
884fbf31dd5STom Zanussi return rc;
885fbf31dd5STom Zanussi }
886fbf31dd5STom Zanussi
kmb_ocs_aead_run(struct aead_request * req)887fbf31dd5STom Zanussi static int kmb_ocs_aead_run(struct aead_request *req)
888fbf31dd5STom Zanussi {
889fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
890fbf31dd5STom Zanussi const int tag_size = crypto_aead_authsize(crypto_aead_reqtfm(req));
891fbf31dd5STom Zanussi struct ocs_aes_rctx *rctx = aead_request_ctx(req);
892fbf31dd5STom Zanussi u32 in_size; /* The length of the data mapped by src_dll. */
893fbf31dd5STom Zanussi int rc;
894fbf31dd5STom Zanussi
895fbf31dd5STom Zanussi rc = kmb_ocs_aead_dma_prepare(req, &in_size);
896fbf31dd5STom Zanussi if (rc)
897fbf31dd5STom Zanussi goto exit;
898fbf31dd5STom Zanussi
899fbf31dd5STom Zanussi /* For CCM, we just call the OCS processing and we are done. */
900fbf31dd5STom Zanussi if (rctx->mode == OCS_MODE_CCM) {
901fbf31dd5STom Zanussi rc = ocs_aes_ccm_op(tctx->aes_dev, tctx->cipher,
902fbf31dd5STom Zanussi rctx->instruction, rctx->dst_dll.dma_addr,
903fbf31dd5STom Zanussi rctx->src_dll.dma_addr, in_size,
904fbf31dd5STom Zanussi req->iv,
905fbf31dd5STom Zanussi rctx->aad_src_dll.dma_addr, req->assoclen,
906fbf31dd5STom Zanussi rctx->in_tag, tag_size);
907fbf31dd5STom Zanussi goto exit;
908fbf31dd5STom Zanussi }
909fbf31dd5STom Zanussi /* GCM case; invoke OCS processing. */
910fbf31dd5STom Zanussi rc = ocs_aes_gcm_op(tctx->aes_dev, tctx->cipher,
911fbf31dd5STom Zanussi rctx->instruction,
912fbf31dd5STom Zanussi rctx->dst_dll.dma_addr,
913fbf31dd5STom Zanussi rctx->src_dll.dma_addr, in_size,
914fbf31dd5STom Zanussi req->iv,
915fbf31dd5STom Zanussi rctx->aad_src_dll.dma_addr, req->assoclen,
916fbf31dd5STom Zanussi rctx->out_tag, tag_size);
917fbf31dd5STom Zanussi if (rc)
918fbf31dd5STom Zanussi goto exit;
919fbf31dd5STom Zanussi
920fbf31dd5STom Zanussi /* For GCM decrypt, we have to compare in_tag with out_tag. */
921fbf31dd5STom Zanussi if (rctx->instruction == OCS_DECRYPT) {
922fbf31dd5STom Zanussi rc = memcmp(rctx->in_tag, rctx->out_tag, tag_size) ?
923fbf31dd5STom Zanussi -EBADMSG : 0;
924fbf31dd5STom Zanussi goto exit;
925fbf31dd5STom Zanussi }
926fbf31dd5STom Zanussi
927fbf31dd5STom Zanussi /* For GCM encrypt, we must manually copy out_tag to DST sg. */
928fbf31dd5STom Zanussi
929fbf31dd5STom Zanussi /* Clean-up must be called before the sg_pcopy_from_buffer() below. */
930fbf31dd5STom Zanussi kmb_ocs_aead_dma_cleanup(req);
931fbf31dd5STom Zanussi
932fbf31dd5STom Zanussi /* Copy tag to destination sg after AAD and CT. */
933fbf31dd5STom Zanussi sg_pcopy_from_buffer(req->dst, rctx->dst_nents, rctx->out_tag,
934fbf31dd5STom Zanussi tag_size, req->assoclen + req->cryptlen);
935fbf31dd5STom Zanussi
936fbf31dd5STom Zanussi /* Return directly as DMA cleanup already done. */
937fbf31dd5STom Zanussi return 0;
938fbf31dd5STom Zanussi
939fbf31dd5STom Zanussi exit:
940fbf31dd5STom Zanussi kmb_ocs_aead_dma_cleanup(req);
941fbf31dd5STom Zanussi
942fbf31dd5STom Zanussi return rc;
943fbf31dd5STom Zanussi }
944fbf31dd5STom Zanussi
kmb_ocs_aes_sk_do_one_request(struct crypto_engine * engine,void * areq)945fbf31dd5STom Zanussi static int kmb_ocs_aes_sk_do_one_request(struct crypto_engine *engine,
946fbf31dd5STom Zanussi void *areq)
947fbf31dd5STom Zanussi {
948fbf31dd5STom Zanussi struct skcipher_request *req =
949fbf31dd5STom Zanussi container_of(areq, struct skcipher_request, base);
950fbf31dd5STom Zanussi struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
951fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
952fbf31dd5STom Zanussi int err;
953fbf31dd5STom Zanussi
954fbf31dd5STom Zanussi if (!tctx->aes_dev) {
955fbf31dd5STom Zanussi err = -ENODEV;
956fbf31dd5STom Zanussi goto exit;
957fbf31dd5STom Zanussi }
958fbf31dd5STom Zanussi
959fbf31dd5STom Zanussi err = ocs_aes_set_key(tctx->aes_dev, tctx->key_len, tctx->key,
960fbf31dd5STom Zanussi tctx->cipher);
961fbf31dd5STom Zanussi if (err)
962fbf31dd5STom Zanussi goto exit;
963fbf31dd5STom Zanussi
964fbf31dd5STom Zanussi err = kmb_ocs_sk_run(req);
965fbf31dd5STom Zanussi
966fbf31dd5STom Zanussi exit:
967fbf31dd5STom Zanussi crypto_finalize_skcipher_request(engine, req, err);
968fbf31dd5STom Zanussi
969fbf31dd5STom Zanussi return 0;
970fbf31dd5STom Zanussi }
971fbf31dd5STom Zanussi
kmb_ocs_aes_aead_do_one_request(struct crypto_engine * engine,void * areq)972fbf31dd5STom Zanussi static int kmb_ocs_aes_aead_do_one_request(struct crypto_engine *engine,
973fbf31dd5STom Zanussi void *areq)
974fbf31dd5STom Zanussi {
975fbf31dd5STom Zanussi struct aead_request *req = container_of(areq,
976fbf31dd5STom Zanussi struct aead_request, base);
977fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
978fbf31dd5STom Zanussi int err;
979fbf31dd5STom Zanussi
980fbf31dd5STom Zanussi if (!tctx->aes_dev)
981fbf31dd5STom Zanussi return -ENODEV;
982fbf31dd5STom Zanussi
983fbf31dd5STom Zanussi err = ocs_aes_set_key(tctx->aes_dev, tctx->key_len, tctx->key,
984fbf31dd5STom Zanussi tctx->cipher);
985fbf31dd5STom Zanussi if (err)
986fbf31dd5STom Zanussi goto exit;
987fbf31dd5STom Zanussi
988fbf31dd5STom Zanussi err = kmb_ocs_aead_run(req);
989fbf31dd5STom Zanussi
990fbf31dd5STom Zanussi exit:
991fbf31dd5STom Zanussi crypto_finalize_aead_request(tctx->aes_dev->engine, req, err);
992fbf31dd5STom Zanussi
993fbf31dd5STom Zanussi return 0;
994fbf31dd5STom Zanussi }
995fbf31dd5STom Zanussi
kmb_ocs_aes_set_key(struct crypto_skcipher * tfm,const u8 * in_key,unsigned int key_len)996fbf31dd5STom Zanussi static int kmb_ocs_aes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
997fbf31dd5STom Zanussi unsigned int key_len)
998fbf31dd5STom Zanussi {
999fbf31dd5STom Zanussi return kmb_ocs_sk_set_key(tfm, in_key, key_len, OCS_AES);
1000fbf31dd5STom Zanussi }
1001fbf31dd5STom Zanussi
kmb_ocs_aes_aead_set_key(struct crypto_aead * tfm,const u8 * in_key,unsigned int key_len)1002fbf31dd5STom Zanussi static int kmb_ocs_aes_aead_set_key(struct crypto_aead *tfm, const u8 *in_key,
1003fbf31dd5STom Zanussi unsigned int key_len)
1004fbf31dd5STom Zanussi {
1005fbf31dd5STom Zanussi return kmb_ocs_aead_set_key(tfm, in_key, key_len, OCS_AES);
1006fbf31dd5STom Zanussi }
1007fbf31dd5STom Zanussi
1008fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB
kmb_ocs_aes_ecb_encrypt(struct skcipher_request * req)1009fbf31dd5STom Zanussi static int kmb_ocs_aes_ecb_encrypt(struct skcipher_request *req)
1010fbf31dd5STom Zanussi {
1011fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_ECB);
1012fbf31dd5STom Zanussi }
1013fbf31dd5STom Zanussi
kmb_ocs_aes_ecb_decrypt(struct skcipher_request * req)1014fbf31dd5STom Zanussi static int kmb_ocs_aes_ecb_decrypt(struct skcipher_request *req)
1015fbf31dd5STom Zanussi {
1016fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_ECB);
1017fbf31dd5STom Zanussi }
1018fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB */
1019fbf31dd5STom Zanussi
kmb_ocs_aes_cbc_encrypt(struct skcipher_request * req)1020fbf31dd5STom Zanussi static int kmb_ocs_aes_cbc_encrypt(struct skcipher_request *req)
1021fbf31dd5STom Zanussi {
1022fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_CBC);
1023fbf31dd5STom Zanussi }
1024fbf31dd5STom Zanussi
kmb_ocs_aes_cbc_decrypt(struct skcipher_request * req)1025fbf31dd5STom Zanussi static int kmb_ocs_aes_cbc_decrypt(struct skcipher_request *req)
1026fbf31dd5STom Zanussi {
1027fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_CBC);
1028fbf31dd5STom Zanussi }
1029fbf31dd5STom Zanussi
kmb_ocs_aes_ctr_encrypt(struct skcipher_request * req)1030fbf31dd5STom Zanussi static int kmb_ocs_aes_ctr_encrypt(struct skcipher_request *req)
1031fbf31dd5STom Zanussi {
1032fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_CTR);
1033fbf31dd5STom Zanussi }
1034fbf31dd5STom Zanussi
kmb_ocs_aes_ctr_decrypt(struct skcipher_request * req)1035fbf31dd5STom Zanussi static int kmb_ocs_aes_ctr_decrypt(struct skcipher_request *req)
1036fbf31dd5STom Zanussi {
1037fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_CTR);
1038fbf31dd5STom Zanussi }
1039fbf31dd5STom Zanussi
1040fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS
kmb_ocs_aes_cts_encrypt(struct skcipher_request * req)1041fbf31dd5STom Zanussi static int kmb_ocs_aes_cts_encrypt(struct skcipher_request *req)
1042fbf31dd5STom Zanussi {
1043fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_CTS);
1044fbf31dd5STom Zanussi }
1045fbf31dd5STom Zanussi
kmb_ocs_aes_cts_decrypt(struct skcipher_request * req)1046fbf31dd5STom Zanussi static int kmb_ocs_aes_cts_decrypt(struct skcipher_request *req)
1047fbf31dd5STom Zanussi {
1048fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_CTS);
1049fbf31dd5STom Zanussi }
1050fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS */
1051fbf31dd5STom Zanussi
kmb_ocs_aes_gcm_encrypt(struct aead_request * req)1052fbf31dd5STom Zanussi static int kmb_ocs_aes_gcm_encrypt(struct aead_request *req)
1053fbf31dd5STom Zanussi {
1054fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_GCM);
1055fbf31dd5STom Zanussi }
1056fbf31dd5STom Zanussi
kmb_ocs_aes_gcm_decrypt(struct aead_request * req)1057fbf31dd5STom Zanussi static int kmb_ocs_aes_gcm_decrypt(struct aead_request *req)
1058fbf31dd5STom Zanussi {
1059fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_GCM);
1060fbf31dd5STom Zanussi }
1061fbf31dd5STom Zanussi
kmb_ocs_aes_ccm_encrypt(struct aead_request * req)1062fbf31dd5STom Zanussi static int kmb_ocs_aes_ccm_encrypt(struct aead_request *req)
1063fbf31dd5STom Zanussi {
1064fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_AES, OCS_ENCRYPT, OCS_MODE_CCM);
1065fbf31dd5STom Zanussi }
1066fbf31dd5STom Zanussi
kmb_ocs_aes_ccm_decrypt(struct aead_request * req)1067fbf31dd5STom Zanussi static int kmb_ocs_aes_ccm_decrypt(struct aead_request *req)
1068fbf31dd5STom Zanussi {
1069fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_AES, OCS_DECRYPT, OCS_MODE_CCM);
1070fbf31dd5STom Zanussi }
1071fbf31dd5STom Zanussi
kmb_ocs_sm4_set_key(struct crypto_skcipher * tfm,const u8 * in_key,unsigned int key_len)1072fbf31dd5STom Zanussi static int kmb_ocs_sm4_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
1073fbf31dd5STom Zanussi unsigned int key_len)
1074fbf31dd5STom Zanussi {
1075fbf31dd5STom Zanussi return kmb_ocs_sk_set_key(tfm, in_key, key_len, OCS_SM4);
1076fbf31dd5STom Zanussi }
1077fbf31dd5STom Zanussi
kmb_ocs_sm4_aead_set_key(struct crypto_aead * tfm,const u8 * in_key,unsigned int key_len)1078fbf31dd5STom Zanussi static int kmb_ocs_sm4_aead_set_key(struct crypto_aead *tfm, const u8 *in_key,
1079fbf31dd5STom Zanussi unsigned int key_len)
1080fbf31dd5STom Zanussi {
1081fbf31dd5STom Zanussi return kmb_ocs_aead_set_key(tfm, in_key, key_len, OCS_SM4);
1082fbf31dd5STom Zanussi }
1083fbf31dd5STom Zanussi
1084fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB
kmb_ocs_sm4_ecb_encrypt(struct skcipher_request * req)1085fbf31dd5STom Zanussi static int kmb_ocs_sm4_ecb_encrypt(struct skcipher_request *req)
1086fbf31dd5STom Zanussi {
1087fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_ECB);
1088fbf31dd5STom Zanussi }
1089fbf31dd5STom Zanussi
kmb_ocs_sm4_ecb_decrypt(struct skcipher_request * req)1090fbf31dd5STom Zanussi static int kmb_ocs_sm4_ecb_decrypt(struct skcipher_request *req)
1091fbf31dd5STom Zanussi {
1092fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_ECB);
1093fbf31dd5STom Zanussi }
1094fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB */
1095fbf31dd5STom Zanussi
kmb_ocs_sm4_cbc_encrypt(struct skcipher_request * req)1096fbf31dd5STom Zanussi static int kmb_ocs_sm4_cbc_encrypt(struct skcipher_request *req)
1097fbf31dd5STom Zanussi {
1098fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_CBC);
1099fbf31dd5STom Zanussi }
1100fbf31dd5STom Zanussi
kmb_ocs_sm4_cbc_decrypt(struct skcipher_request * req)1101fbf31dd5STom Zanussi static int kmb_ocs_sm4_cbc_decrypt(struct skcipher_request *req)
1102fbf31dd5STom Zanussi {
1103fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_CBC);
1104fbf31dd5STom Zanussi }
1105fbf31dd5STom Zanussi
kmb_ocs_sm4_ctr_encrypt(struct skcipher_request * req)1106fbf31dd5STom Zanussi static int kmb_ocs_sm4_ctr_encrypt(struct skcipher_request *req)
1107fbf31dd5STom Zanussi {
1108fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_CTR);
1109fbf31dd5STom Zanussi }
1110fbf31dd5STom Zanussi
kmb_ocs_sm4_ctr_decrypt(struct skcipher_request * req)1111fbf31dd5STom Zanussi static int kmb_ocs_sm4_ctr_decrypt(struct skcipher_request *req)
1112fbf31dd5STom Zanussi {
1113fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_CTR);
1114fbf31dd5STom Zanussi }
1115fbf31dd5STom Zanussi
1116fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS
kmb_ocs_sm4_cts_encrypt(struct skcipher_request * req)1117fbf31dd5STom Zanussi static int kmb_ocs_sm4_cts_encrypt(struct skcipher_request *req)
1118fbf31dd5STom Zanussi {
1119fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_CTS);
1120fbf31dd5STom Zanussi }
1121fbf31dd5STom Zanussi
kmb_ocs_sm4_cts_decrypt(struct skcipher_request * req)1122fbf31dd5STom Zanussi static int kmb_ocs_sm4_cts_decrypt(struct skcipher_request *req)
1123fbf31dd5STom Zanussi {
1124fbf31dd5STom Zanussi return kmb_ocs_sk_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_CTS);
1125fbf31dd5STom Zanussi }
1126fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS */
1127fbf31dd5STom Zanussi
kmb_ocs_sm4_gcm_encrypt(struct aead_request * req)1128fbf31dd5STom Zanussi static int kmb_ocs_sm4_gcm_encrypt(struct aead_request *req)
1129fbf31dd5STom Zanussi {
1130fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_GCM);
1131fbf31dd5STom Zanussi }
1132fbf31dd5STom Zanussi
kmb_ocs_sm4_gcm_decrypt(struct aead_request * req)1133fbf31dd5STom Zanussi static int kmb_ocs_sm4_gcm_decrypt(struct aead_request *req)
1134fbf31dd5STom Zanussi {
1135fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_GCM);
1136fbf31dd5STom Zanussi }
1137fbf31dd5STom Zanussi
kmb_ocs_sm4_ccm_encrypt(struct aead_request * req)1138fbf31dd5STom Zanussi static int kmb_ocs_sm4_ccm_encrypt(struct aead_request *req)
1139fbf31dd5STom Zanussi {
1140fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_SM4, OCS_ENCRYPT, OCS_MODE_CCM);
1141fbf31dd5STom Zanussi }
1142fbf31dd5STom Zanussi
kmb_ocs_sm4_ccm_decrypt(struct aead_request * req)1143fbf31dd5STom Zanussi static int kmb_ocs_sm4_ccm_decrypt(struct aead_request *req)
1144fbf31dd5STom Zanussi {
1145fbf31dd5STom Zanussi return kmb_ocs_aead_common(req, OCS_SM4, OCS_DECRYPT, OCS_MODE_CCM);
1146fbf31dd5STom Zanussi }
1147fbf31dd5STom Zanussi
ocs_aes_init_tfm(struct crypto_skcipher * tfm)1148fbf31dd5STom Zanussi static int ocs_aes_init_tfm(struct crypto_skcipher *tfm)
1149fbf31dd5STom Zanussi {
1150fbf31dd5STom Zanussi const char *alg_name = crypto_tfm_alg_name(&tfm->base);
1151fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
1152fbf31dd5STom Zanussi struct crypto_sync_skcipher *blk;
1153fbf31dd5STom Zanussi
1154fbf31dd5STom Zanussi /* set fallback cipher in case it will be needed */
1155fbf31dd5STom Zanussi blk = crypto_alloc_sync_skcipher(alg_name, 0, CRYPTO_ALG_NEED_FALLBACK);
1156fbf31dd5STom Zanussi if (IS_ERR(blk))
1157fbf31dd5STom Zanussi return PTR_ERR(blk);
1158fbf31dd5STom Zanussi
1159fbf31dd5STom Zanussi tctx->sw_cipher.sk = blk;
1160fbf31dd5STom Zanussi
1161fbf31dd5STom Zanussi crypto_skcipher_set_reqsize(tfm, sizeof(struct ocs_aes_rctx));
1162fbf31dd5STom Zanussi
1163530d7b00SHerbert Xu return 0;
1164fbf31dd5STom Zanussi }
1165fbf31dd5STom Zanussi
ocs_sm4_init_tfm(struct crypto_skcipher * tfm)1166fbf31dd5STom Zanussi static int ocs_sm4_init_tfm(struct crypto_skcipher *tfm)
1167fbf31dd5STom Zanussi {
1168fbf31dd5STom Zanussi crypto_skcipher_set_reqsize(tfm, sizeof(struct ocs_aes_rctx));
1169fbf31dd5STom Zanussi
1170530d7b00SHerbert Xu return 0;
1171fbf31dd5STom Zanussi }
1172fbf31dd5STom Zanussi
clear_key(struct ocs_aes_tctx * tctx)1173fbf31dd5STom Zanussi static inline void clear_key(struct ocs_aes_tctx *tctx)
1174fbf31dd5STom Zanussi {
1175fbf31dd5STom Zanussi memzero_explicit(tctx->key, OCS_AES_KEYSIZE_256);
1176fbf31dd5STom Zanussi
1177fbf31dd5STom Zanussi /* Zero key registers if set */
1178fbf31dd5STom Zanussi if (tctx->aes_dev)
1179fbf31dd5STom Zanussi ocs_aes_set_key(tctx->aes_dev, OCS_AES_KEYSIZE_256,
1180fbf31dd5STom Zanussi tctx->key, OCS_AES);
1181fbf31dd5STom Zanussi }
1182fbf31dd5STom Zanussi
ocs_exit_tfm(struct crypto_skcipher * tfm)1183fbf31dd5STom Zanussi static void ocs_exit_tfm(struct crypto_skcipher *tfm)
1184fbf31dd5STom Zanussi {
1185fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_skcipher_ctx(tfm);
1186fbf31dd5STom Zanussi
1187fbf31dd5STom Zanussi clear_key(tctx);
1188fbf31dd5STom Zanussi
1189fbf31dd5STom Zanussi if (tctx->sw_cipher.sk) {
1190fbf31dd5STom Zanussi crypto_free_sync_skcipher(tctx->sw_cipher.sk);
1191fbf31dd5STom Zanussi tctx->sw_cipher.sk = NULL;
1192fbf31dd5STom Zanussi }
1193fbf31dd5STom Zanussi }
1194fbf31dd5STom Zanussi
ocs_aes_aead_cra_init(struct crypto_aead * tfm)1195fbf31dd5STom Zanussi static int ocs_aes_aead_cra_init(struct crypto_aead *tfm)
1196fbf31dd5STom Zanussi {
1197fbf31dd5STom Zanussi const char *alg_name = crypto_tfm_alg_name(&tfm->base);
1198fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(tfm);
1199fbf31dd5STom Zanussi struct crypto_aead *blk;
1200fbf31dd5STom Zanussi
1201fbf31dd5STom Zanussi /* Set fallback cipher in case it will be needed */
1202fbf31dd5STom Zanussi blk = crypto_alloc_aead(alg_name, 0, CRYPTO_ALG_NEED_FALLBACK);
1203fbf31dd5STom Zanussi if (IS_ERR(blk))
1204fbf31dd5STom Zanussi return PTR_ERR(blk);
1205fbf31dd5STom Zanussi
1206fbf31dd5STom Zanussi tctx->sw_cipher.aead = blk;
1207fbf31dd5STom Zanussi
1208fbf31dd5STom Zanussi crypto_aead_set_reqsize(tfm,
1209fbf31dd5STom Zanussi max(sizeof(struct ocs_aes_rctx),
1210fbf31dd5STom Zanussi (sizeof(struct aead_request) +
1211fbf31dd5STom Zanussi crypto_aead_reqsize(tctx->sw_cipher.aead))));
1212fbf31dd5STom Zanussi
1213530d7b00SHerbert Xu return 0;
1214fbf31dd5STom Zanussi }
1215fbf31dd5STom Zanussi
kmb_ocs_aead_ccm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)1216fbf31dd5STom Zanussi static int kmb_ocs_aead_ccm_setauthsize(struct crypto_aead *tfm,
1217fbf31dd5STom Zanussi unsigned int authsize)
1218fbf31dd5STom Zanussi {
1219fbf31dd5STom Zanussi switch (authsize) {
1220fbf31dd5STom Zanussi case 4:
1221fbf31dd5STom Zanussi case 6:
1222fbf31dd5STom Zanussi case 8:
1223fbf31dd5STom Zanussi case 10:
1224fbf31dd5STom Zanussi case 12:
1225fbf31dd5STom Zanussi case 14:
1226fbf31dd5STom Zanussi case 16:
1227fbf31dd5STom Zanussi return 0;
1228fbf31dd5STom Zanussi default:
1229fbf31dd5STom Zanussi return -EINVAL;
1230fbf31dd5STom Zanussi }
1231fbf31dd5STom Zanussi }
1232fbf31dd5STom Zanussi
kmb_ocs_aead_gcm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)1233fbf31dd5STom Zanussi static int kmb_ocs_aead_gcm_setauthsize(struct crypto_aead *tfm,
1234fbf31dd5STom Zanussi unsigned int authsize)
1235fbf31dd5STom Zanussi {
1236fbf31dd5STom Zanussi return crypto_gcm_check_authsize(authsize);
1237fbf31dd5STom Zanussi }
1238fbf31dd5STom Zanussi
ocs_sm4_aead_cra_init(struct crypto_aead * tfm)1239fbf31dd5STom Zanussi static int ocs_sm4_aead_cra_init(struct crypto_aead *tfm)
1240fbf31dd5STom Zanussi {
1241fbf31dd5STom Zanussi crypto_aead_set_reqsize(tfm, sizeof(struct ocs_aes_rctx));
1242fbf31dd5STom Zanussi
1243530d7b00SHerbert Xu return 0;
1244fbf31dd5STom Zanussi }
1245fbf31dd5STom Zanussi
ocs_aead_cra_exit(struct crypto_aead * tfm)1246fbf31dd5STom Zanussi static void ocs_aead_cra_exit(struct crypto_aead *tfm)
1247fbf31dd5STom Zanussi {
1248fbf31dd5STom Zanussi struct ocs_aes_tctx *tctx = crypto_aead_ctx(tfm);
1249fbf31dd5STom Zanussi
1250fbf31dd5STom Zanussi clear_key(tctx);
1251fbf31dd5STom Zanussi
1252fbf31dd5STom Zanussi if (tctx->sw_cipher.aead) {
1253fbf31dd5STom Zanussi crypto_free_aead(tctx->sw_cipher.aead);
1254fbf31dd5STom Zanussi tctx->sw_cipher.aead = NULL;
1255fbf31dd5STom Zanussi }
1256fbf31dd5STom Zanussi }
1257fbf31dd5STom Zanussi
1258530d7b00SHerbert Xu static struct skcipher_engine_alg algs[] = {
1259fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB
1260fbf31dd5STom Zanussi {
1261530d7b00SHerbert Xu .base.base.cra_name = "ecb(aes)",
1262530d7b00SHerbert Xu .base.base.cra_driver_name = "ecb-aes-keembay-ocs",
1263530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1264530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1265fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1266fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1267530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1268530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1269530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1270530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1271fbf31dd5STom Zanussi
1272530d7b00SHerbert Xu .base.min_keysize = OCS_AES_MIN_KEY_SIZE,
1273530d7b00SHerbert Xu .base.max_keysize = OCS_AES_MAX_KEY_SIZE,
1274530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_set_key,
1275530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_ecb_encrypt,
1276530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_ecb_decrypt,
1277530d7b00SHerbert Xu .base.init = ocs_aes_init_tfm,
1278530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1279530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1280fbf31dd5STom Zanussi },
1281fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB */
1282fbf31dd5STom Zanussi {
1283530d7b00SHerbert Xu .base.base.cra_name = "cbc(aes)",
1284530d7b00SHerbert Xu .base.base.cra_driver_name = "cbc-aes-keembay-ocs",
1285530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1286530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1287fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1288fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1289530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1290530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1291530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1292530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1293fbf31dd5STom Zanussi
1294530d7b00SHerbert Xu .base.min_keysize = OCS_AES_MIN_KEY_SIZE,
1295530d7b00SHerbert Xu .base.max_keysize = OCS_AES_MAX_KEY_SIZE,
1296530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1297530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_set_key,
1298530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_cbc_encrypt,
1299530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_cbc_decrypt,
1300530d7b00SHerbert Xu .base.init = ocs_aes_init_tfm,
1301530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1302530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1303fbf31dd5STom Zanussi },
1304fbf31dd5STom Zanussi {
1305530d7b00SHerbert Xu .base.base.cra_name = "ctr(aes)",
1306530d7b00SHerbert Xu .base.base.cra_driver_name = "ctr-aes-keembay-ocs",
1307530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1308530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1309fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1310fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1311530d7b00SHerbert Xu .base.base.cra_blocksize = 1,
1312530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1313530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1314530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1315fbf31dd5STom Zanussi
1316530d7b00SHerbert Xu .base.min_keysize = OCS_AES_MIN_KEY_SIZE,
1317530d7b00SHerbert Xu .base.max_keysize = OCS_AES_MAX_KEY_SIZE,
1318530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1319530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_set_key,
1320530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_ctr_encrypt,
1321530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_ctr_decrypt,
1322530d7b00SHerbert Xu .base.init = ocs_aes_init_tfm,
1323530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1324530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1325fbf31dd5STom Zanussi },
1326fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS
1327fbf31dd5STom Zanussi {
1328530d7b00SHerbert Xu .base.base.cra_name = "cts(cbc(aes))",
1329530d7b00SHerbert Xu .base.base.cra_driver_name = "cts-aes-keembay-ocs",
1330530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1331530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1332fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1333fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1334530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1335530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1336530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1337530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1338fbf31dd5STom Zanussi
1339530d7b00SHerbert Xu .base.min_keysize = OCS_AES_MIN_KEY_SIZE,
1340530d7b00SHerbert Xu .base.max_keysize = OCS_AES_MAX_KEY_SIZE,
1341530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1342530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_set_key,
1343530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_cts_encrypt,
1344530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_cts_decrypt,
1345530d7b00SHerbert Xu .base.init = ocs_aes_init_tfm,
1346530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1347530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1348fbf31dd5STom Zanussi },
1349fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS */
1350fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB
1351fbf31dd5STom Zanussi {
1352530d7b00SHerbert Xu .base.base.cra_name = "ecb(sm4)",
1353530d7b00SHerbert Xu .base.base.cra_driver_name = "ecb-sm4-keembay-ocs",
1354530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1355530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1356fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1357530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1358530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1359530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1360530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1361fbf31dd5STom Zanussi
1362530d7b00SHerbert Xu .base.min_keysize = OCS_SM4_KEY_SIZE,
1363530d7b00SHerbert Xu .base.max_keysize = OCS_SM4_KEY_SIZE,
1364530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_set_key,
1365530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_ecb_encrypt,
1366530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_ecb_decrypt,
1367530d7b00SHerbert Xu .base.init = ocs_sm4_init_tfm,
1368530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1369530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1370fbf31dd5STom Zanussi },
1371fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB */
1372fbf31dd5STom Zanussi {
1373530d7b00SHerbert Xu .base.base.cra_name = "cbc(sm4)",
1374530d7b00SHerbert Xu .base.base.cra_driver_name = "cbc-sm4-keembay-ocs",
1375530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1376530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1377fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1378530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1379530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1380530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1381530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1382fbf31dd5STom Zanussi
1383530d7b00SHerbert Xu .base.min_keysize = OCS_SM4_KEY_SIZE,
1384530d7b00SHerbert Xu .base.max_keysize = OCS_SM4_KEY_SIZE,
1385530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1386530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_set_key,
1387530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_cbc_encrypt,
1388530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_cbc_decrypt,
1389530d7b00SHerbert Xu .base.init = ocs_sm4_init_tfm,
1390530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1391530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1392fbf31dd5STom Zanussi },
1393fbf31dd5STom Zanussi {
1394530d7b00SHerbert Xu .base.base.cra_name = "ctr(sm4)",
1395530d7b00SHerbert Xu .base.base.cra_driver_name = "ctr-sm4-keembay-ocs",
1396530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1397530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1398fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1399530d7b00SHerbert Xu .base.base.cra_blocksize = 1,
1400530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1401530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1402530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1403fbf31dd5STom Zanussi
1404530d7b00SHerbert Xu .base.min_keysize = OCS_SM4_KEY_SIZE,
1405530d7b00SHerbert Xu .base.max_keysize = OCS_SM4_KEY_SIZE,
1406530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1407530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_set_key,
1408530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_ctr_encrypt,
1409530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_ctr_decrypt,
1410530d7b00SHerbert Xu .base.init = ocs_sm4_init_tfm,
1411530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1412530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1413fbf31dd5STom Zanussi },
1414fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS
1415fbf31dd5STom Zanussi {
1416530d7b00SHerbert Xu .base.base.cra_name = "cts(cbc(sm4))",
1417530d7b00SHerbert Xu .base.base.cra_driver_name = "cts-sm4-keembay-ocs",
1418530d7b00SHerbert Xu .base.base.cra_priority = KMB_OCS_PRIORITY,
1419530d7b00SHerbert Xu .base.base.cra_flags = CRYPTO_ALG_ASYNC |
1420fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1421530d7b00SHerbert Xu .base.base.cra_blocksize = AES_BLOCK_SIZE,
1422530d7b00SHerbert Xu .base.base.cra_ctxsize = sizeof(struct ocs_aes_tctx),
1423530d7b00SHerbert Xu .base.base.cra_module = THIS_MODULE,
1424530d7b00SHerbert Xu .base.base.cra_alignmask = 0,
1425fbf31dd5STom Zanussi
1426530d7b00SHerbert Xu .base.min_keysize = OCS_SM4_KEY_SIZE,
1427530d7b00SHerbert Xu .base.max_keysize = OCS_SM4_KEY_SIZE,
1428530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1429530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_set_key,
1430530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_cts_encrypt,
1431530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_cts_decrypt,
1432530d7b00SHerbert Xu .base.init = ocs_sm4_init_tfm,
1433530d7b00SHerbert Xu .base.exit = ocs_exit_tfm,
1434530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_sk_do_one_request,
1435fbf31dd5STom Zanussi }
1436fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS */
1437fbf31dd5STom Zanussi };
1438fbf31dd5STom Zanussi
1439530d7b00SHerbert Xu static struct aead_engine_alg algs_aead[] = {
1440fbf31dd5STom Zanussi {
1441530d7b00SHerbert Xu .base.base = {
1442fbf31dd5STom Zanussi .cra_name = "gcm(aes)",
1443fbf31dd5STom Zanussi .cra_driver_name = "gcm-aes-keembay-ocs",
1444fbf31dd5STom Zanussi .cra_priority = KMB_OCS_PRIORITY,
1445fbf31dd5STom Zanussi .cra_flags = CRYPTO_ALG_ASYNC |
1446fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1447fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1448fbf31dd5STom Zanussi .cra_blocksize = 1,
1449fbf31dd5STom Zanussi .cra_ctxsize = sizeof(struct ocs_aes_tctx),
1450fbf31dd5STom Zanussi .cra_alignmask = 0,
1451fbf31dd5STom Zanussi .cra_module = THIS_MODULE,
1452fbf31dd5STom Zanussi },
1453530d7b00SHerbert Xu .base.init = ocs_aes_aead_cra_init,
1454530d7b00SHerbert Xu .base.exit = ocs_aead_cra_exit,
1455530d7b00SHerbert Xu .base.ivsize = GCM_AES_IV_SIZE,
1456530d7b00SHerbert Xu .base.maxauthsize = AES_BLOCK_SIZE,
1457530d7b00SHerbert Xu .base.setauthsize = kmb_ocs_aead_gcm_setauthsize,
1458530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_aead_set_key,
1459530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_gcm_encrypt,
1460530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_gcm_decrypt,
1461530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_aead_do_one_request,
1462fbf31dd5STom Zanussi },
1463fbf31dd5STom Zanussi {
1464530d7b00SHerbert Xu .base.base = {
1465fbf31dd5STom Zanussi .cra_name = "ccm(aes)",
1466fbf31dd5STom Zanussi .cra_driver_name = "ccm-aes-keembay-ocs",
1467fbf31dd5STom Zanussi .cra_priority = KMB_OCS_PRIORITY,
1468fbf31dd5STom Zanussi .cra_flags = CRYPTO_ALG_ASYNC |
1469fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY |
1470fbf31dd5STom Zanussi CRYPTO_ALG_NEED_FALLBACK,
1471fbf31dd5STom Zanussi .cra_blocksize = 1,
1472fbf31dd5STom Zanussi .cra_ctxsize = sizeof(struct ocs_aes_tctx),
1473fbf31dd5STom Zanussi .cra_alignmask = 0,
1474fbf31dd5STom Zanussi .cra_module = THIS_MODULE,
1475fbf31dd5STom Zanussi },
1476530d7b00SHerbert Xu .base.init = ocs_aes_aead_cra_init,
1477530d7b00SHerbert Xu .base.exit = ocs_aead_cra_exit,
1478530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1479530d7b00SHerbert Xu .base.maxauthsize = AES_BLOCK_SIZE,
1480530d7b00SHerbert Xu .base.setauthsize = kmb_ocs_aead_ccm_setauthsize,
1481530d7b00SHerbert Xu .base.setkey = kmb_ocs_aes_aead_set_key,
1482530d7b00SHerbert Xu .base.encrypt = kmb_ocs_aes_ccm_encrypt,
1483530d7b00SHerbert Xu .base.decrypt = kmb_ocs_aes_ccm_decrypt,
1484530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_aead_do_one_request,
1485fbf31dd5STom Zanussi },
1486fbf31dd5STom Zanussi {
1487530d7b00SHerbert Xu .base.base = {
1488fbf31dd5STom Zanussi .cra_name = "gcm(sm4)",
1489fbf31dd5STom Zanussi .cra_driver_name = "gcm-sm4-keembay-ocs",
1490fbf31dd5STom Zanussi .cra_priority = KMB_OCS_PRIORITY,
1491fbf31dd5STom Zanussi .cra_flags = CRYPTO_ALG_ASYNC |
1492fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1493fbf31dd5STom Zanussi .cra_blocksize = 1,
1494fbf31dd5STom Zanussi .cra_ctxsize = sizeof(struct ocs_aes_tctx),
1495fbf31dd5STom Zanussi .cra_alignmask = 0,
1496fbf31dd5STom Zanussi .cra_module = THIS_MODULE,
1497fbf31dd5STom Zanussi },
1498530d7b00SHerbert Xu .base.init = ocs_sm4_aead_cra_init,
1499530d7b00SHerbert Xu .base.exit = ocs_aead_cra_exit,
1500530d7b00SHerbert Xu .base.ivsize = GCM_AES_IV_SIZE,
1501530d7b00SHerbert Xu .base.maxauthsize = AES_BLOCK_SIZE,
1502530d7b00SHerbert Xu .base.setauthsize = kmb_ocs_aead_gcm_setauthsize,
1503530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_aead_set_key,
1504530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_gcm_encrypt,
1505530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_gcm_decrypt,
1506530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_aead_do_one_request,
1507fbf31dd5STom Zanussi },
1508fbf31dd5STom Zanussi {
1509530d7b00SHerbert Xu .base.base = {
1510fbf31dd5STom Zanussi .cra_name = "ccm(sm4)",
1511fbf31dd5STom Zanussi .cra_driver_name = "ccm-sm4-keembay-ocs",
1512fbf31dd5STom Zanussi .cra_priority = KMB_OCS_PRIORITY,
1513fbf31dd5STom Zanussi .cra_flags = CRYPTO_ALG_ASYNC |
1514fbf31dd5STom Zanussi CRYPTO_ALG_KERN_DRIVER_ONLY,
1515fbf31dd5STom Zanussi .cra_blocksize = 1,
1516fbf31dd5STom Zanussi .cra_ctxsize = sizeof(struct ocs_aes_tctx),
1517fbf31dd5STom Zanussi .cra_alignmask = 0,
1518fbf31dd5STom Zanussi .cra_module = THIS_MODULE,
1519fbf31dd5STom Zanussi },
1520530d7b00SHerbert Xu .base.init = ocs_sm4_aead_cra_init,
1521530d7b00SHerbert Xu .base.exit = ocs_aead_cra_exit,
1522530d7b00SHerbert Xu .base.ivsize = AES_BLOCK_SIZE,
1523530d7b00SHerbert Xu .base.maxauthsize = AES_BLOCK_SIZE,
1524530d7b00SHerbert Xu .base.setauthsize = kmb_ocs_aead_ccm_setauthsize,
1525530d7b00SHerbert Xu .base.setkey = kmb_ocs_sm4_aead_set_key,
1526530d7b00SHerbert Xu .base.encrypt = kmb_ocs_sm4_ccm_encrypt,
1527530d7b00SHerbert Xu .base.decrypt = kmb_ocs_sm4_ccm_decrypt,
1528530d7b00SHerbert Xu .op.do_one_request = kmb_ocs_aes_aead_do_one_request,
1529fbf31dd5STom Zanussi }
1530fbf31dd5STom Zanussi };
1531fbf31dd5STom Zanussi
unregister_aes_algs(struct ocs_aes_dev * aes_dev)1532fbf31dd5STom Zanussi static void unregister_aes_algs(struct ocs_aes_dev *aes_dev)
1533fbf31dd5STom Zanussi {
1534530d7b00SHerbert Xu crypto_engine_unregister_aeads(algs_aead, ARRAY_SIZE(algs_aead));
1535530d7b00SHerbert Xu crypto_engine_unregister_skciphers(algs, ARRAY_SIZE(algs));
1536fbf31dd5STom Zanussi }
1537fbf31dd5STom Zanussi
register_aes_algs(struct ocs_aes_dev * aes_dev)1538fbf31dd5STom Zanussi static int register_aes_algs(struct ocs_aes_dev *aes_dev)
1539fbf31dd5STom Zanussi {
1540fbf31dd5STom Zanussi int ret;
1541fbf31dd5STom Zanussi
1542fbf31dd5STom Zanussi /*
1543fbf31dd5STom Zanussi * If any algorithm fails to register, all preceding algorithms that
1544fbf31dd5STom Zanussi * were successfully registered will be automatically unregistered.
1545fbf31dd5STom Zanussi */
1546530d7b00SHerbert Xu ret = crypto_engine_register_aeads(algs_aead, ARRAY_SIZE(algs_aead));
1547fbf31dd5STom Zanussi if (ret)
1548fbf31dd5STom Zanussi return ret;
1549fbf31dd5STom Zanussi
1550530d7b00SHerbert Xu ret = crypto_engine_register_skciphers(algs, ARRAY_SIZE(algs));
1551fbf31dd5STom Zanussi if (ret)
1552530d7b00SHerbert Xu crypto_engine_unregister_aeads(algs_aead, ARRAY_SIZE(algs));
1553fbf31dd5STom Zanussi
1554fbf31dd5STom Zanussi return ret;
1555fbf31dd5STom Zanussi }
1556fbf31dd5STom Zanussi
1557fbf31dd5STom Zanussi /* Device tree driver match. */
1558fbf31dd5STom Zanussi static const struct of_device_id kmb_ocs_aes_of_match[] = {
1559fbf31dd5STom Zanussi {
1560fbf31dd5STom Zanussi .compatible = "intel,keembay-ocs-aes",
1561fbf31dd5STom Zanussi },
1562fbf31dd5STom Zanussi {}
1563fbf31dd5STom Zanussi };
1564fbf31dd5STom Zanussi
kmb_ocs_aes_remove(struct platform_device * pdev)1565*98272bf6SUwe Kleine-König static void kmb_ocs_aes_remove(struct platform_device *pdev)
1566fbf31dd5STom Zanussi {
1567fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev;
1568fbf31dd5STom Zanussi
1569fbf31dd5STom Zanussi aes_dev = platform_get_drvdata(pdev);
1570fbf31dd5STom Zanussi
1571fbf31dd5STom Zanussi unregister_aes_algs(aes_dev);
1572fbf31dd5STom Zanussi
1573fbf31dd5STom Zanussi spin_lock(&ocs_aes.lock);
1574fbf31dd5STom Zanussi list_del(&aes_dev->list);
1575fbf31dd5STom Zanussi spin_unlock(&ocs_aes.lock);
1576fbf31dd5STom Zanussi
1577fbf31dd5STom Zanussi crypto_engine_exit(aes_dev->engine);
1578fbf31dd5STom Zanussi }
1579fbf31dd5STom Zanussi
kmb_ocs_aes_probe(struct platform_device * pdev)1580fbf31dd5STom Zanussi static int kmb_ocs_aes_probe(struct platform_device *pdev)
1581fbf31dd5STom Zanussi {
1582fbf31dd5STom Zanussi struct device *dev = &pdev->dev;
1583fbf31dd5STom Zanussi struct ocs_aes_dev *aes_dev;
1584fbf31dd5STom Zanussi int rc;
1585fbf31dd5STom Zanussi
1586fbf31dd5STom Zanussi aes_dev = devm_kzalloc(dev, sizeof(*aes_dev), GFP_KERNEL);
1587fbf31dd5STom Zanussi if (!aes_dev)
1588fbf31dd5STom Zanussi return -ENOMEM;
1589fbf31dd5STom Zanussi
1590fbf31dd5STom Zanussi aes_dev->dev = dev;
1591fbf31dd5STom Zanussi
1592fbf31dd5STom Zanussi platform_set_drvdata(pdev, aes_dev);
1593fbf31dd5STom Zanussi
1594fbf31dd5STom Zanussi rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1595fbf31dd5STom Zanussi if (rc) {
1596fbf31dd5STom Zanussi dev_err(dev, "Failed to set 32 bit dma mask %d\n", rc);
1597fbf31dd5STom Zanussi return rc;
1598fbf31dd5STom Zanussi }
1599fbf31dd5STom Zanussi
1600fbf31dd5STom Zanussi /* Get base register address. */
1601fbf31dd5STom Zanussi aes_dev->base_reg = devm_platform_ioremap_resource(pdev, 0);
1602fbf31dd5STom Zanussi if (IS_ERR(aes_dev->base_reg))
1603fbf31dd5STom Zanussi return PTR_ERR(aes_dev->base_reg);
1604fbf31dd5STom Zanussi
1605fbf31dd5STom Zanussi /* Get and request IRQ */
1606fbf31dd5STom Zanussi aes_dev->irq = platform_get_irq(pdev, 0);
1607fbf31dd5STom Zanussi if (aes_dev->irq < 0)
1608fbf31dd5STom Zanussi return aes_dev->irq;
1609fbf31dd5STom Zanussi
1610fbf31dd5STom Zanussi rc = devm_request_threaded_irq(dev, aes_dev->irq, ocs_aes_irq_handler,
1611fbf31dd5STom Zanussi NULL, 0, "keembay-ocs-aes", aes_dev);
1612fbf31dd5STom Zanussi if (rc < 0) {
1613fbf31dd5STom Zanussi dev_err(dev, "Could not request IRQ\n");
1614fbf31dd5STom Zanussi return rc;
1615fbf31dd5STom Zanussi }
1616fbf31dd5STom Zanussi
1617fbf31dd5STom Zanussi INIT_LIST_HEAD(&aes_dev->list);
1618fbf31dd5STom Zanussi spin_lock(&ocs_aes.lock);
1619fbf31dd5STom Zanussi list_add_tail(&aes_dev->list, &ocs_aes.dev_list);
1620fbf31dd5STom Zanussi spin_unlock(&ocs_aes.lock);
1621fbf31dd5STom Zanussi
1622fbf31dd5STom Zanussi init_completion(&aes_dev->irq_completion);
1623fbf31dd5STom Zanussi
1624fbf31dd5STom Zanussi /* Initialize crypto engine */
1625fbf31dd5STom Zanussi aes_dev->engine = crypto_engine_alloc_init(dev, true);
1626fbf31dd5STom Zanussi if (!aes_dev->engine) {
1627fbf31dd5STom Zanussi rc = -ENOMEM;
1628fbf31dd5STom Zanussi goto list_del;
1629fbf31dd5STom Zanussi }
1630fbf31dd5STom Zanussi
1631fbf31dd5STom Zanussi rc = crypto_engine_start(aes_dev->engine);
1632fbf31dd5STom Zanussi if (rc) {
1633fbf31dd5STom Zanussi dev_err(dev, "Could not start crypto engine\n");
1634fbf31dd5STom Zanussi goto cleanup;
1635fbf31dd5STom Zanussi }
1636fbf31dd5STom Zanussi
1637fbf31dd5STom Zanussi rc = register_aes_algs(aes_dev);
1638fbf31dd5STom Zanussi if (rc) {
1639fbf31dd5STom Zanussi dev_err(dev,
1640fbf31dd5STom Zanussi "Could not register OCS algorithms with Crypto API\n");
1641fbf31dd5STom Zanussi goto cleanup;
1642fbf31dd5STom Zanussi }
1643fbf31dd5STom Zanussi
1644fbf31dd5STom Zanussi return 0;
1645fbf31dd5STom Zanussi
1646fbf31dd5STom Zanussi cleanup:
1647fbf31dd5STom Zanussi crypto_engine_exit(aes_dev->engine);
1648fbf31dd5STom Zanussi list_del:
1649fbf31dd5STom Zanussi spin_lock(&ocs_aes.lock);
1650fbf31dd5STom Zanussi list_del(&aes_dev->list);
1651fbf31dd5STom Zanussi spin_unlock(&ocs_aes.lock);
1652fbf31dd5STom Zanussi
1653fbf31dd5STom Zanussi return rc;
1654fbf31dd5STom Zanussi }
1655fbf31dd5STom Zanussi
1656fbf31dd5STom Zanussi /* The OCS driver is a platform device. */
1657fbf31dd5STom Zanussi static struct platform_driver kmb_ocs_aes_driver = {
1658fbf31dd5STom Zanussi .probe = kmb_ocs_aes_probe,
1659*98272bf6SUwe Kleine-König .remove_new = kmb_ocs_aes_remove,
1660fbf31dd5STom Zanussi .driver = {
1661fbf31dd5STom Zanussi .name = DRV_NAME,
1662fbf31dd5STom Zanussi .of_match_table = kmb_ocs_aes_of_match,
1663fbf31dd5STom Zanussi },
1664fbf31dd5STom Zanussi };
1665fbf31dd5STom Zanussi
1666fbf31dd5STom Zanussi module_platform_driver(kmb_ocs_aes_driver);
1667fbf31dd5STom Zanussi
1668fbf31dd5STom Zanussi MODULE_DESCRIPTION("Intel Keem Bay Offload and Crypto Subsystem (OCS) AES/SM4 Driver");
1669fbf31dd5STom Zanussi MODULE_LICENSE("GPL");
1670fbf31dd5STom Zanussi
1671fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("cbc-aes-keembay-ocs");
1672fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ctr-aes-keembay-ocs");
1673fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("gcm-aes-keembay-ocs");
1674fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ccm-aes-keembay-ocs");
1675fbf31dd5STom Zanussi
1676fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("cbc-sm4-keembay-ocs");
1677fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ctr-sm4-keembay-ocs");
1678fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("gcm-sm4-keembay-ocs");
1679fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ccm-sm4-keembay-ocs");
1680fbf31dd5STom Zanussi
1681fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB
1682fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ecb-aes-keembay-ocs");
1683fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("ecb-sm4-keembay-ocs");
1684fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB */
1685fbf31dd5STom Zanussi
1686fbf31dd5STom Zanussi #ifdef CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS
1687fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("cts-aes-keembay-ocs");
1688fbf31dd5STom Zanussi MODULE_ALIAS_CRYPTO("cts-sm4-keembay-ocs");
1689fbf31dd5STom Zanussi #endif /* CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS */
1690