1
2
3
4
5
6
7#ifndef __RTA_KEY_CMD_H__
8#define __RTA_KEY_CMD_H__
9
10extern enum rta_sec_era rta_sec_era;
11
12
13static const uint32_t key_enc_flags[] = {
14 ENC,
15 ENC | NWB | EKT | TK,
16 ENC | NWB | EKT | TK,
17 ENC | NWB | EKT | TK,
18 ENC | NWB | EKT | TK,
19 ENC | NWB | EKT | TK,
20 ENC | NWB | EKT | TK | PTS,
21 ENC | NWB | EKT | TK | PTS,
22 ENC | NWB | EKT | TK | PTS,
23 ENC | NWB | EKT | TK | PTS
24};
25
26static inline int
27rta_key(struct program *program, uint32_t key_dst,
28 uint32_t encrypt_flags, uint64_t src, uint32_t length,
29 uint32_t flags)
30{
31 uint32_t opcode = 0;
32 bool is_seq_cmd = false;
33 unsigned int start_pc = program->current_pc;
34
35 if (encrypt_flags & ~key_enc_flags[rta_sec_era]) {
36 pr_err("KEY: Flag(s) not supported by SEC Era %d\n",
37 USER_SEC_ERA(rta_sec_era));
38 goto err;
39 }
40
41
42 if (flags & SEQ) {
43 opcode = CMD_SEQ_KEY;
44 is_seq_cmd = true;
45 } else {
46 opcode = CMD_KEY;
47 }
48
49
50 if (is_seq_cmd) {
51 if ((flags & IMMED) || (flags & SGF)) {
52 pr_err("SEQKEY: Invalid flag. SEC PC: %d; Instr: %d\n",
53 program->current_pc,
54 program->current_instruction);
55 goto err;
56 }
57 if ((rta_sec_era <= RTA_SEC_ERA_5) &&
58 ((flags & VLF) || (flags & AIDF))) {
59 pr_err("SEQKEY: Flag(s) not supported by SEC Era %d\n",
60 USER_SEC_ERA(rta_sec_era));
61 goto err;
62 }
63 } else {
64 if ((flags & AIDF) || (flags & VLF)) {
65 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
66 program->current_pc,
67 program->current_instruction);
68 goto err;
69 }
70 if ((flags & SGF) && (flags & IMMED)) {
71 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
72 program->current_pc,
73 program->current_instruction);
74 goto err;
75 }
76 }
77
78 if ((encrypt_flags & PTS) &&
79 ((encrypt_flags & ENC) || (encrypt_flags & NWB) ||
80 (key_dst == PKE))) {
81 pr_err("KEY: Invalid flag / destination. SEC PC: %d; Instr: %d\n",
82 program->current_pc, program->current_instruction);
83 goto err;
84 }
85
86 if (key_dst == AFHA_SBOX) {
87 if (rta_sec_era == RTA_SEC_ERA_7) {
88 pr_err("KEY: AFHA S-box not supported by SEC Era %d\n",
89 USER_SEC_ERA(rta_sec_era));
90 goto err;
91 }
92
93 if (flags & IMMED) {
94 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
95 program->current_pc,
96 program->current_instruction);
97 goto err;
98 }
99
100
101
102
103
104 if (length != 258) {
105 pr_err("KEY: Invalid length. SEC PC: %d; Instr: %d\n",
106 program->current_pc,
107 program->current_instruction);
108 goto err;
109 }
110 }
111
112
113 switch (key_dst) {
114 case (KEY1):
115 opcode |= KEY_DEST_CLASS1;
116 break;
117 case (KEY2):
118 opcode |= KEY_DEST_CLASS2;
119 break;
120 case (PKE):
121 opcode |= KEY_DEST_CLASS1 | KEY_DEST_PKHA_E;
122 break;
123 case (AFHA_SBOX):
124 opcode |= KEY_DEST_CLASS1 | KEY_DEST_AFHA_SBOX;
125 break;
126 case (MDHA_SPLIT_KEY):
127 opcode |= KEY_DEST_CLASS2 | KEY_DEST_MDHA_SPLIT;
128 break;
129 default:
130 pr_err("KEY: Invalid destination. SEC PC: %d; Instr: %d\n",
131 program->current_pc, program->current_instruction);
132 goto err;
133 }
134
135
136 length &= KEY_LENGTH_MASK;
137 opcode |= length;
138
139
140 if (encrypt_flags & ENC) {
141
142
143
144
145 opcode |= KEY_ENC;
146 if (encrypt_flags & EKT) {
147 opcode |= KEY_EKT;
148 length = ALIGN(length, 8);
149 length += 12;
150 } else {
151 length = ALIGN(length, 16);
152 }
153 if (encrypt_flags & TK)
154 opcode |= KEY_TK;
155 }
156 if (encrypt_flags & NWB)
157 opcode |= KEY_NWB;
158 if (encrypt_flags & PTS)
159 opcode |= KEY_PTS;
160
161
162 if (!is_seq_cmd) {
163 if (flags & IMMED)
164 opcode |= KEY_IMM;
165 if (flags & SGF)
166 opcode |= KEY_SGF;
167 } else {
168 if (flags & AIDF)
169 opcode |= KEY_AIDF;
170 if (flags & VLF)
171 opcode |= KEY_VLF;
172 }
173
174 __rta_out32(program, opcode);
175 program->current_instruction++;
176
177 if (flags & IMMED)
178 __rta_inline_data(program, src, flags & __COPY_MASK, length);
179 else
180 __rta_out64(program, program->ps, src);
181
182 return (int)start_pc;
183
184 err:
185 program->first_error_pc = start_pc;
186 program->current_instruction++;
187 return -EINVAL;
188}
189
190#endif
191