xref: /OK3568_Linux_fs/u-boot/drivers/crypto/fsl/jobdesc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * SEC Descriptor Construction Library
3*4882a593Smuzhiyun  * Basic job descriptor construction
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2014 Freescale Semiconductor, Inc.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <fsl_sec.h>
13*4882a593Smuzhiyun #include "desc_constr.h"
14*4882a593Smuzhiyun #include "jobdesc.h"
15*4882a593Smuzhiyun #include "rsa_caam.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #if defined(CONFIG_MX6) || defined(CONFIG_MX7)
18*4882a593Smuzhiyun /*!
19*4882a593Smuzhiyun  * Secure memory run command
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * @param   sec_mem_cmd  Secure memory command register
22*4882a593Smuzhiyun  * @return  cmd_status  Secure memory command status register
23*4882a593Smuzhiyun  */
secmem_set_cmd(uint32_t sec_mem_cmd)24*4882a593Smuzhiyun uint32_t secmem_set_cmd(uint32_t sec_mem_cmd)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	uint32_t temp_reg;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
29*4882a593Smuzhiyun 	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
30*4882a593Smuzhiyun 	uint32_t jr_id = 0;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	sec_out32(CAAM_SMCJR(sm_vid, jr_id), sec_mem_cmd);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	do {
35*4882a593Smuzhiyun 		temp_reg = sec_in32(CAAM_SMCSJR(sm_vid, jr_id));
36*4882a593Smuzhiyun 	} while (temp_reg & CMD_COMPLETE);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	return temp_reg;
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*!
42*4882a593Smuzhiyun  * CAAM page allocation:
43*4882a593Smuzhiyun  * Allocates a partition from secure memory, with the id
44*4882a593Smuzhiyun  * equal to partition_num. This will de-allocate the page
45*4882a593Smuzhiyun  * if it is already allocated. The partition will have
46*4882a593Smuzhiyun  * full access permissions. The permissions are set before,
47*4882a593Smuzhiyun  * running a job descriptor. A memory page of secure RAM
48*4882a593Smuzhiyun  * is allocated for the partition.
49*4882a593Smuzhiyun  *
50*4882a593Smuzhiyun  * @param   page  Number of the page to allocate.
51*4882a593Smuzhiyun  * @param   partition  Number of the partition to allocate.
52*4882a593Smuzhiyun  * @return  0 on success, ERROR_IN_PAGE_ALLOC otherwise
53*4882a593Smuzhiyun  */
caam_page_alloc(uint8_t page_num,uint8_t partition_num)54*4882a593Smuzhiyun int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	uint32_t temp_reg;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
59*4882a593Smuzhiyun 	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
60*4882a593Smuzhiyun 	uint32_t jr_id = 0;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	/*
63*4882a593Smuzhiyun 	 * De-Allocate partition_num if already allocated to ARM core
64*4882a593Smuzhiyun 	 */
65*4882a593Smuzhiyun 	if (sec_in32(CAAM_SMPO_0) & PARTITION_OWNER(partition_num)) {
66*4882a593Smuzhiyun 		temp_reg = secmem_set_cmd(PARTITION(partition_num) |
67*4882a593Smuzhiyun 						CMD_PART_DEALLOC);
68*4882a593Smuzhiyun 		if (temp_reg & SMCSJR_AERR) {
69*4882a593Smuzhiyun 			printf("Error: De-allocation status 0x%X\n", temp_reg);
70*4882a593Smuzhiyun 			return ERROR_IN_PAGE_ALLOC;
71*4882a593Smuzhiyun 		}
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	/* set the access rights to allow full access */
75*4882a593Smuzhiyun 	sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, partition_num), 0xF);
76*4882a593Smuzhiyun 	sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, partition_num), 0xF);
77*4882a593Smuzhiyun 	sec_out32(CAAM_SMAPJR(sm_vid, jr_id, partition_num), 0xFF);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/* Now need to allocate partition_num of secure RAM. */
80*4882a593Smuzhiyun 	/* De-Allocate page_num by starting with a page inquiry command */
81*4882a593Smuzhiyun 	temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* if the page is owned, de-allocate it */
84*4882a593Smuzhiyun 	if ((temp_reg & SMCSJR_PO) == PAGE_OWNED) {
85*4882a593Smuzhiyun 		temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_PAGE_DEALLOC);
86*4882a593Smuzhiyun 		if (temp_reg & SMCSJR_AERR) {
87*4882a593Smuzhiyun 			printf("Error: Allocation status 0x%X\n", temp_reg);
88*4882a593Smuzhiyun 			return ERROR_IN_PAGE_ALLOC;
89*4882a593Smuzhiyun 		}
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	/* Allocate page_num to partition_num */
93*4882a593Smuzhiyun 	temp_reg = secmem_set_cmd(PAGE(page_num) | PARTITION(partition_num)
94*4882a593Smuzhiyun 						| CMD_PAGE_ALLOC);
95*4882a593Smuzhiyun 	if (temp_reg & SMCSJR_AERR) {
96*4882a593Smuzhiyun 		printf("Error: Allocation status 0x%X\n", temp_reg);
97*4882a593Smuzhiyun 		return ERROR_IN_PAGE_ALLOC;
98*4882a593Smuzhiyun 	}
99*4882a593Smuzhiyun 	/* page inquiry command to ensure that the page was allocated */
100*4882a593Smuzhiyun 	temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/* if the page is not owned => problem */
103*4882a593Smuzhiyun 	if ((temp_reg & SMCSJR_PO) != PAGE_OWNED) {
104*4882a593Smuzhiyun 		printf("Allocation of page %d in partition %d failed 0x%X\n",
105*4882a593Smuzhiyun 		       temp_reg, page_num, partition_num);
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 		return ERROR_IN_PAGE_ALLOC;
108*4882a593Smuzhiyun 	}
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	return 0;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
inline_cnstr_jobdesc_blob_dek(uint32_t * desc,const uint8_t * plain_txt,uint8_t * dek_blob,uint32_t in_sz)113*4882a593Smuzhiyun int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
114*4882a593Smuzhiyun 				       uint8_t *dek_blob, uint32_t in_sz)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
117*4882a593Smuzhiyun 	uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
118*4882a593Smuzhiyun 	uint32_t jr_id = 0;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	uint32_t ret = 0;
121*4882a593Smuzhiyun 	u32 aad_w1, aad_w2;
122*4882a593Smuzhiyun 	/* output blob will have 32 bytes key blob in beginning and
123*4882a593Smuzhiyun 	 * 16 byte HMAC identifier at end of data blob */
124*4882a593Smuzhiyun 	uint32_t out_sz = in_sz + KEY_BLOB_SIZE + MAC_SIZE;
125*4882a593Smuzhiyun 	/* Setting HDR for blob */
126*4882a593Smuzhiyun 	uint8_t wrapped_key_hdr[8] = {HDR_TAG, 0x00, WRP_HDR_SIZE + out_sz,
127*4882a593Smuzhiyun 			     HDR_PAR, HAB_MOD, HAB_ALG, in_sz, HAB_FLG};
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	/* initialize the blob array */
130*4882a593Smuzhiyun 	memset(dek_blob, 0, out_sz + 8);
131*4882a593Smuzhiyun 	/* Copy the header into the DEK blob buffer */
132*4882a593Smuzhiyun 	memcpy(dek_blob, wrapped_key_hdr, sizeof(wrapped_key_hdr));
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	/* allocating secure memory */
135*4882a593Smuzhiyun 	ret = caam_page_alloc(PAGE_1, PARTITION_1);
136*4882a593Smuzhiyun 	if (ret)
137*4882a593Smuzhiyun 		return ret;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Write DEK to secure memory */
140*4882a593Smuzhiyun 	memcpy((uint32_t *)SEC_MEM_PAGE1, (uint32_t *)plain_txt, in_sz);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	unsigned long start = (unsigned long)SEC_MEM_PAGE1 &
143*4882a593Smuzhiyun 				~(ARCH_DMA_MINALIGN - 1);
144*4882a593Smuzhiyun 	unsigned long end = ALIGN(start + 0x1000, ARCH_DMA_MINALIGN);
145*4882a593Smuzhiyun 	flush_dcache_range(start, end);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	/* Now configure the access rights of the partition */
148*4882a593Smuzhiyun 	sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, PARTITION_1), KS_G1);
149*4882a593Smuzhiyun 	sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, PARTITION_1), 0);
150*4882a593Smuzhiyun 	sec_out32(CAAM_SMAPJR(sm_vid, jr_id, PARTITION_1), PERM);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	/* construct aad for AES */
153*4882a593Smuzhiyun 	aad_w1 = (in_sz << OP_ALG_ALGSEL_SHIFT) | KEY_AES_SRC | LD_CCM_MODE;
154*4882a593Smuzhiyun 	aad_w2 = 0x0;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	init_job_desc(desc, 0);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	append_cmd(desc, CMD_LOAD | CLASS_2 | KEY_IMM | KEY_ENC |
159*4882a593Smuzhiyun 				(0x0c << LDST_OFFSET_SHIFT) | 0x08);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	append_u32(desc, aad_w1);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	append_u32(desc, aad_w2);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	append_cmd_ptr(desc, (dma_addr_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	append_cmd_ptr(desc, (dma_addr_t)dek_blob + 8, out_sz, CMD_SEQ_OUT_PTR);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
170*4882a593Smuzhiyun 						OP_PCLID_SECMEM);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	return ret;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun #endif
175*4882a593Smuzhiyun 
inline_cnstr_jobdesc_hash(uint32_t * desc,const uint8_t * msg,uint32_t msgsz,uint8_t * digest,u32 alg_type,uint32_t alg_size,int sg_tbl)176*4882a593Smuzhiyun void inline_cnstr_jobdesc_hash(uint32_t *desc,
177*4882a593Smuzhiyun 			  const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
178*4882a593Smuzhiyun 			  u32 alg_type, uint32_t alg_size, int sg_tbl)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	/* SHA 256 , output is of length 32 words */
181*4882a593Smuzhiyun 	uint32_t storelen = alg_size;
182*4882a593Smuzhiyun 	u32 options;
183*4882a593Smuzhiyun 	dma_addr_t dma_addr_in, dma_addr_out;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	dma_addr_in = virt_to_phys((void *)msg);
186*4882a593Smuzhiyun 	dma_addr_out = virt_to_phys((void *)digest);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	init_job_desc(desc, 0);
189*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_CLASS2_ALG |
190*4882a593Smuzhiyun 			 OP_ALG_AAI_HASH | OP_ALG_AS_INITFINAL |
191*4882a593Smuzhiyun 			 OP_ALG_ENCRYPT | OP_ALG_ICV_OFF | alg_type);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	options = LDST_CLASS_2_CCB | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2;
194*4882a593Smuzhiyun 	if (sg_tbl)
195*4882a593Smuzhiyun 		options |= FIFOLDST_SGF;
196*4882a593Smuzhiyun 	if (msgsz > 0xffff) {
197*4882a593Smuzhiyun 		options |= FIFOLDST_EXT;
198*4882a593Smuzhiyun 		append_fifo_load(desc, dma_addr_in, 0, options);
199*4882a593Smuzhiyun 		append_cmd(desc, msgsz);
200*4882a593Smuzhiyun 	} else {
201*4882a593Smuzhiyun 		append_fifo_load(desc, dma_addr_in, msgsz, options);
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	append_store(desc, dma_addr_out, storelen,
205*4882a593Smuzhiyun 		     LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun #ifndef CONFIG_SPL_BUILD
inline_cnstr_jobdesc_blob_encap(uint32_t * desc,uint8_t * key_idnfr,uint8_t * plain_txt,uint8_t * enc_blob,uint32_t in_sz)208*4882a593Smuzhiyun void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
209*4882a593Smuzhiyun 				     uint8_t *plain_txt, uint8_t *enc_blob,
210*4882a593Smuzhiyun 				     uint32_t in_sz)
211*4882a593Smuzhiyun {
212*4882a593Smuzhiyun 	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
213*4882a593Smuzhiyun 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
214*4882a593Smuzhiyun 	/* output blob will have 32 bytes key blob in beginning and
215*4882a593Smuzhiyun 	 * 16 byte HMAC identifier at end of data blob */
216*4882a593Smuzhiyun 	uint32_t out_sz = in_sz + KEY_BLOB_SIZE + MAC_SIZE;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
219*4882a593Smuzhiyun 	dma_addr_in	= virt_to_phys((void *)plain_txt);
220*4882a593Smuzhiyun 	dma_addr_out	= virt_to_phys((void *)enc_blob);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	init_job_desc(desc, 0);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
inline_cnstr_jobdesc_blob_decap(uint32_t * desc,uint8_t * key_idnfr,uint8_t * enc_blob,uint8_t * plain_txt,uint32_t out_sz)233*4882a593Smuzhiyun void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
234*4882a593Smuzhiyun 				     uint8_t *enc_blob, uint8_t *plain_txt,
235*4882a593Smuzhiyun 				     uint32_t out_sz)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun 	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
238*4882a593Smuzhiyun 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
239*4882a593Smuzhiyun 	uint32_t in_sz = out_sz + KEY_BLOB_SIZE + MAC_SIZE;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
242*4882a593Smuzhiyun 	dma_addr_in	= virt_to_phys((void *)enc_blob);
243*4882a593Smuzhiyun 	dma_addr_out	= virt_to_phys((void *)plain_txt);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	init_job_desc(desc, 0);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun #endif
256*4882a593Smuzhiyun /*
257*4882a593Smuzhiyun  * Descriptor to instantiate RNG State Handle 0 in normal mode and
258*4882a593Smuzhiyun  * load the JDKEK, TDKEK and TDSK registers
259*4882a593Smuzhiyun  */
inline_cnstr_jobdesc_rng_instantiation(uint32_t * desc)260*4882a593Smuzhiyun void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	u32 *jump_cmd;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	init_job_desc(desc, 0);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	/* INIT RNG in non-test mode */
267*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
268*4882a593Smuzhiyun 			 OP_ALG_AS_INIT);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	/* wait for done */
271*4882a593Smuzhiyun 	jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
272*4882a593Smuzhiyun 	set_jump_tgt_here(desc, jump_cmd);
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	/*
275*4882a593Smuzhiyun 	 * load 1 to clear written reg:
276*4882a593Smuzhiyun 	 * resets the done interrrupt and returns the RNG to idle.
277*4882a593Smuzhiyun 	 */
278*4882a593Smuzhiyun 	append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	/* generate secure keys (non-test) */
281*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
282*4882a593Smuzhiyun 			 OP_ALG_RNG4_SK);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun /* Change key size to bytes form bits in calling function*/
inline_cnstr_jobdesc_pkha_rsaexp(uint32_t * desc,struct pk_in_params * pkin,uint8_t * out,uint32_t out_siz)286*4882a593Smuzhiyun void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
287*4882a593Smuzhiyun 				      struct pk_in_params *pkin, uint8_t *out,
288*4882a593Smuzhiyun 				      uint32_t out_siz)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun 	dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	dma_addr_e = virt_to_phys((void *)pkin->e);
293*4882a593Smuzhiyun 	dma_addr_a = virt_to_phys((void *)pkin->a);
294*4882a593Smuzhiyun 	dma_addr_n = virt_to_phys((void *)pkin->n);
295*4882a593Smuzhiyun 	dma_addr_out = virt_to_phys((void *)out);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	init_job_desc(desc, 0);
298*4882a593Smuzhiyun 	append_key(desc, dma_addr_e, pkin->e_siz, KEY_DEST_PKHA_E | CLASS_1);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	append_fifo_load(desc, dma_addr_a,
301*4882a593Smuzhiyun 			 pkin->a_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_A);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	append_fifo_load(desc, dma_addr_n,
304*4882a593Smuzhiyun 			 pkin->n_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_N);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	append_operation(desc, OP_TYPE_PK | OP_ALG_PK | OP_ALG_PKMODE_MOD_EXPO);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	append_fifo_store(desc, dma_addr_out, out_siz,
309*4882a593Smuzhiyun 			  LDST_CLASS_1_CCB | FIFOST_TYPE_PKHA_B);
310*4882a593Smuzhiyun }
311