xref: /dpdk/drivers/common/dpaax/caamflib/rta/key_cmd.h (revision 882f25383499f422dc36cfd96ea688a92fb47d94)
1*c0ded849SHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2*c0ded849SHemant Agrawal  *
3*c0ded849SHemant Agrawal  * Copyright 2008-2016 Freescale Semiconductor Inc.
4*c0ded849SHemant Agrawal  * Copyright 2016,2019 NXP
5*c0ded849SHemant Agrawal  */
6*c0ded849SHemant Agrawal 
7*c0ded849SHemant Agrawal #ifndef __RTA_KEY_CMD_H__
8*c0ded849SHemant Agrawal #define __RTA_KEY_CMD_H__
9*c0ded849SHemant Agrawal 
10*c0ded849SHemant Agrawal extern enum rta_sec_era rta_sec_era;
11*c0ded849SHemant Agrawal 
12*c0ded849SHemant Agrawal /* Allowed encryption flags for each SEC Era */
13*c0ded849SHemant Agrawal static const uint32_t key_enc_flags[] = {
14*c0ded849SHemant Agrawal 	ENC,
15*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK,
16*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK,
17*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK,
18*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK,
19*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK,
20*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK | PTS,
21*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK | PTS,
22*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK | PTS,
23*c0ded849SHemant Agrawal 	ENC | NWB | EKT | TK | PTS
24*c0ded849SHemant Agrawal };
25*c0ded849SHemant Agrawal 
26*c0ded849SHemant Agrawal static inline int
rta_key(struct program * program,uint32_t key_dst,uint32_t encrypt_flags,uint64_t src,uint32_t length,uint32_t flags)27*c0ded849SHemant Agrawal rta_key(struct program *program, uint32_t key_dst,
28*c0ded849SHemant Agrawal 	uint32_t encrypt_flags, uint64_t src, uint32_t length,
29*c0ded849SHemant Agrawal 	uint32_t flags)
30*c0ded849SHemant Agrawal {
31*c0ded849SHemant Agrawal 	uint32_t opcode = 0;
32*c0ded849SHemant Agrawal 	bool is_seq_cmd = false;
33*c0ded849SHemant Agrawal 	unsigned int start_pc = program->current_pc;
34*c0ded849SHemant Agrawal 
35*c0ded849SHemant Agrawal 	if (encrypt_flags & ~key_enc_flags[rta_sec_era]) {
36*c0ded849SHemant Agrawal 		pr_err("KEY: Flag(s) not supported by SEC Era %d\n",
37*c0ded849SHemant Agrawal 		       USER_SEC_ERA(rta_sec_era));
38*c0ded849SHemant Agrawal 		goto err;
39*c0ded849SHemant Agrawal 	}
40*c0ded849SHemant Agrawal 
41*c0ded849SHemant Agrawal 	/* write cmd type */
42*c0ded849SHemant Agrawal 	if (flags & SEQ) {
43*c0ded849SHemant Agrawal 		opcode = CMD_SEQ_KEY;
44*c0ded849SHemant Agrawal 		is_seq_cmd = true;
45*c0ded849SHemant Agrawal 	} else {
46*c0ded849SHemant Agrawal 		opcode = CMD_KEY;
47*c0ded849SHemant Agrawal 	}
48*c0ded849SHemant Agrawal 
49*c0ded849SHemant Agrawal 	/* check parameters */
50*c0ded849SHemant Agrawal 	if (is_seq_cmd) {
51*c0ded849SHemant Agrawal 		if ((flags & IMMED) || (flags & SGF)) {
52*c0ded849SHemant Agrawal 			pr_err("SEQKEY: Invalid flag. SEC PC: %d; Instr: %d\n",
53*c0ded849SHemant Agrawal 			       program->current_pc,
54*c0ded849SHemant Agrawal 			       program->current_instruction);
55*c0ded849SHemant Agrawal 			goto err;
56*c0ded849SHemant Agrawal 		}
57*c0ded849SHemant Agrawal 	} else {
58*c0ded849SHemant Agrawal 		if ((flags & AIDF) || (flags & VLF)) {
59*c0ded849SHemant Agrawal 			pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
60*c0ded849SHemant Agrawal 			       program->current_pc,
61*c0ded849SHemant Agrawal 			       program->current_instruction);
62*c0ded849SHemant Agrawal 			goto err;
63*c0ded849SHemant Agrawal 		}
64*c0ded849SHemant Agrawal 		if ((flags & SGF) && (flags & IMMED)) {
65*c0ded849SHemant Agrawal 			pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
66*c0ded849SHemant Agrawal 			       program->current_pc,
67*c0ded849SHemant Agrawal 			       program->current_instruction);
68*c0ded849SHemant Agrawal 			goto err;
69*c0ded849SHemant Agrawal 		}
70*c0ded849SHemant Agrawal 	}
71*c0ded849SHemant Agrawal 
72*c0ded849SHemant Agrawal 	if ((encrypt_flags & PTS) &&
73*c0ded849SHemant Agrawal 	    ((encrypt_flags & ENC) || (encrypt_flags & NWB) ||
74*c0ded849SHemant Agrawal 	     (key_dst == PKE))) {
75*c0ded849SHemant Agrawal 		pr_err("KEY: Invalid flag / destination. SEC PC: %d; Instr: %d\n",
76*c0ded849SHemant Agrawal 		       program->current_pc, program->current_instruction);
77*c0ded849SHemant Agrawal 		goto err;
78*c0ded849SHemant Agrawal 	}
79*c0ded849SHemant Agrawal 
80*c0ded849SHemant Agrawal 	if (key_dst == AFHA_SBOX) {
81*c0ded849SHemant Agrawal 		if (flags & IMMED) {
82*c0ded849SHemant Agrawal 			pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
83*c0ded849SHemant Agrawal 			       program->current_pc,
84*c0ded849SHemant Agrawal 			       program->current_instruction);
85*c0ded849SHemant Agrawal 			goto err;
86*c0ded849SHemant Agrawal 		}
87*c0ded849SHemant Agrawal 
88*c0ded849SHemant Agrawal 		/*
89*c0ded849SHemant Agrawal 		 * Sbox data loaded into the ARC-4 processor must be exactly
90*c0ded849SHemant Agrawal 		 * 258 bytes long, or else a data sequence error is generated.
91*c0ded849SHemant Agrawal 		 */
92*c0ded849SHemant Agrawal 		if (length != 258) {
93*c0ded849SHemant Agrawal 			pr_err("KEY: Invalid length. SEC PC: %d; Instr: %d\n",
94*c0ded849SHemant Agrawal 			       program->current_pc,
95*c0ded849SHemant Agrawal 			       program->current_instruction);
96*c0ded849SHemant Agrawal 			goto err;
97*c0ded849SHemant Agrawal 		}
98*c0ded849SHemant Agrawal 	}
99*c0ded849SHemant Agrawal 
100*c0ded849SHemant Agrawal 	/* write key destination and class fields */
101*c0ded849SHemant Agrawal 	switch (key_dst) {
102*c0ded849SHemant Agrawal 	case (KEY1):
103*c0ded849SHemant Agrawal 		opcode |= KEY_DEST_CLASS1;
104*c0ded849SHemant Agrawal 		break;
105*c0ded849SHemant Agrawal 	case (KEY2):
106*c0ded849SHemant Agrawal 		opcode |= KEY_DEST_CLASS2;
107*c0ded849SHemant Agrawal 		break;
108*c0ded849SHemant Agrawal 	case (PKE):
109*c0ded849SHemant Agrawal 		opcode |= KEY_DEST_CLASS1 | KEY_DEST_PKHA_E;
110*c0ded849SHemant Agrawal 		break;
111*c0ded849SHemant Agrawal 	case (AFHA_SBOX):
112*c0ded849SHemant Agrawal 		opcode |= KEY_DEST_CLASS1 | KEY_DEST_AFHA_SBOX;
113*c0ded849SHemant Agrawal 		break;
114*c0ded849SHemant Agrawal 	case (MDHA_SPLIT_KEY):
115*c0ded849SHemant Agrawal 		opcode |= KEY_DEST_CLASS2 | KEY_DEST_MDHA_SPLIT;
116*c0ded849SHemant Agrawal 		break;
117*c0ded849SHemant Agrawal 	default:
118*c0ded849SHemant Agrawal 		pr_err("KEY: Invalid destination. SEC PC: %d; Instr: %d\n",
119*c0ded849SHemant Agrawal 		       program->current_pc, program->current_instruction);
120*c0ded849SHemant Agrawal 		goto err;
121*c0ded849SHemant Agrawal 	}
122*c0ded849SHemant Agrawal 
123*c0ded849SHemant Agrawal 	/* write key length */
124*c0ded849SHemant Agrawal 	length &= KEY_LENGTH_MASK;
125*c0ded849SHemant Agrawal 	opcode |= length;
126*c0ded849SHemant Agrawal 
127*c0ded849SHemant Agrawal 	/* write key command specific flags */
128*c0ded849SHemant Agrawal 	if (encrypt_flags & ENC) {
129*c0ded849SHemant Agrawal 		/* Encrypted (black) keys must be padded to 8 bytes (CCM) or
130*c0ded849SHemant Agrawal 		 * 16 bytes (ECB) depending on EKT bit. AES-CCM encrypted keys
131*c0ded849SHemant Agrawal 		 * (EKT = 1) have 6-byte nonce and 6-byte MAC after padding.
132*c0ded849SHemant Agrawal 		 */
133*c0ded849SHemant Agrawal 		opcode |= KEY_ENC;
134*c0ded849SHemant Agrawal 		if (encrypt_flags & EKT) {
135*c0ded849SHemant Agrawal 			opcode |= KEY_EKT;
136*c0ded849SHemant Agrawal 			length = ALIGN(length, 8);
137*c0ded849SHemant Agrawal 			length += 12;
138*c0ded849SHemant Agrawal 		} else {
139*c0ded849SHemant Agrawal 			length = ALIGN(length, 16);
140*c0ded849SHemant Agrawal 		}
141*c0ded849SHemant Agrawal 		if (encrypt_flags & TK)
142*c0ded849SHemant Agrawal 			opcode |= KEY_TK;
143*c0ded849SHemant Agrawal 	}
144*c0ded849SHemant Agrawal 	if (encrypt_flags & NWB)
145*c0ded849SHemant Agrawal 		opcode |= KEY_NWB;
146*c0ded849SHemant Agrawal 	if (encrypt_flags & PTS)
147*c0ded849SHemant Agrawal 		opcode |= KEY_PTS;
148*c0ded849SHemant Agrawal 
149*c0ded849SHemant Agrawal 	/* write general command flags */
150*c0ded849SHemant Agrawal 	if (!is_seq_cmd) {
151*c0ded849SHemant Agrawal 		if (flags & IMMED)
152*c0ded849SHemant Agrawal 			opcode |= KEY_IMM;
153*c0ded849SHemant Agrawal 		if (flags & SGF)
154*c0ded849SHemant Agrawal 			opcode |= KEY_SGF;
155*c0ded849SHemant Agrawal 	} else {
156*c0ded849SHemant Agrawal 		if (flags & AIDF)
157*c0ded849SHemant Agrawal 			opcode |= KEY_AIDF;
158*c0ded849SHemant Agrawal 		if (flags & VLF)
159*c0ded849SHemant Agrawal 			opcode |= KEY_VLF;
160*c0ded849SHemant Agrawal 	}
161*c0ded849SHemant Agrawal 
162*c0ded849SHemant Agrawal 	__rta_out32(program, opcode);
163*c0ded849SHemant Agrawal 	program->current_instruction++;
164*c0ded849SHemant Agrawal 
165*c0ded849SHemant Agrawal 	if (flags & IMMED)
166*c0ded849SHemant Agrawal 		__rta_inline_data(program, src, flags & __COPY_MASK, length);
167*c0ded849SHemant Agrawal 	else
168*c0ded849SHemant Agrawal 		__rta_out64(program, program->ps, src);
169*c0ded849SHemant Agrawal 
170*c0ded849SHemant Agrawal 	return (int)start_pc;
171*c0ded849SHemant Agrawal 
172*c0ded849SHemant Agrawal  err:
173*c0ded849SHemant Agrawal 	program->first_error_pc = start_pc;
174*c0ded849SHemant Agrawal 	program->current_instruction++;
175*c0ded849SHemant Agrawal 	return -EINVAL;
176*c0ded849SHemant Agrawal }
177*c0ded849SHemant Agrawal 
178*c0ded849SHemant Agrawal #endif /* __RTA_KEY_CMD_H__ */
179