1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2008-2016 Freescale Semiconductor Inc. 4 * Copyright 2016,2019 NXP 5 */ 6 7 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__ 8 #define __RTA_FIFO_LOAD_STORE_CMD_H__ 9 10 extern enum rta_sec_era rta_sec_era; 11 12 static const uint32_t fifo_load_table[][2] = { 13 /*1*/ { PKA0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A0 }, 14 { PKA1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A1 }, 15 { PKA2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A2 }, 16 { PKA3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A3 }, 17 { PKB0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B0 }, 18 { PKB1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B1 }, 19 { PKB2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B2 }, 20 { PKB3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B3 }, 21 { PKA, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A }, 22 { PKB, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B }, 23 { PKN, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_N }, 24 { SKIP, FIFOLD_CLASS_SKIP }, 25 { MSG1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG }, 26 { MSG2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG }, 27 { MSGOUTSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG1OUT2 }, 28 { MSGINSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG }, 29 { IV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV }, 30 { IV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_IV }, 31 { AAD1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_AAD }, 32 { ICV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_ICV }, 33 { ICV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV }, 34 { BIT_DATA, FIFOLD_TYPE_BITDATA }, 35 /*23*/ { IFIFO, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_NOINFOFIFO } 36 }; 37 38 /* 39 * Allowed FIFO_LOAD input data types for each SEC Era. 40 * Values represent the number of entries from fifo_load_table[] that are 41 * supported. 42 */ 43 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23, 44 23, 23, 23, 23, 45 23, 23}; 46 47 static inline int 48 rta_fifo_load(struct program *program, uint32_t src, 49 uint64_t loc, uint32_t length, uint32_t flags) 50 { 51 uint32_t opcode = 0; 52 uint32_t ext_length = 0, val = 0; 53 int ret = -EINVAL; 54 bool is_seq_cmd = false; 55 unsigned int start_pc = program->current_pc; 56 57 /* write command type field */ 58 if (flags & SEQ) { 59 opcode = CMD_SEQ_FIFO_LOAD; 60 is_seq_cmd = true; 61 } else { 62 opcode = CMD_FIFO_LOAD; 63 } 64 65 /* Parameters checking */ 66 if (is_seq_cmd) { 67 if ((flags & IMMED) || (flags & SGF)) { 68 pr_err("SEQ FIFO LOAD: Invalid command\n"); 69 goto err; 70 } 71 if ((rta_sec_era <= RTA_SEC_ERA_5) && (flags & AIDF)) { 72 pr_err("SEQ FIFO LOAD: Flag(s) not supported by SEC Era %d\n", 73 USER_SEC_ERA(rta_sec_era)); 74 goto err; 75 } 76 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) { 77 pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n"); 78 goto err; 79 } 80 } else { 81 if (src == SKIP) { 82 pr_err("FIFO LOAD: Invalid src\n"); 83 goto err; 84 } 85 if ((flags & AIDF) || (flags & VLF)) { 86 pr_err("FIFO LOAD: Invalid command\n"); 87 goto err; 88 } 89 if ((flags & IMMED) && (flags & SGF)) { 90 pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n"); 91 goto err; 92 } 93 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) { 94 pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n"); 95 goto err; 96 } 97 } 98 99 /* write input data type field */ 100 ret = __rta_map_opcode(src, fifo_load_table, 101 fifo_load_table_sz[rta_sec_era], &val); 102 if (ret < 0) { 103 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n", 104 program->current_pc); 105 goto err; 106 } 107 opcode |= val; 108 109 if (flags & CLASS1) 110 opcode |= FIFOLD_CLASS_CLASS1; 111 if (flags & CLASS2) 112 opcode |= FIFOLD_CLASS_CLASS2; 113 if (flags & BOTH) 114 opcode |= FIFOLD_CLASS_BOTH; 115 116 /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */ 117 if (flags & FLUSH1) 118 opcode |= FIFOLD_TYPE_FLUSH1; 119 if (flags & LAST1) 120 opcode |= FIFOLD_TYPE_LAST1; 121 if (flags & LAST2) 122 opcode |= FIFOLD_TYPE_LAST2; 123 if (!is_seq_cmd) { 124 if (flags & SGF) 125 opcode |= FIFOLDST_SGF; 126 if (flags & IMMED) 127 opcode |= FIFOLD_IMM; 128 } else { 129 if (flags & VLF) 130 opcode |= FIFOLDST_VLF; 131 if (flags & AIDF) 132 opcode |= FIFOLD_AIDF; 133 } 134 135 /* 136 * Verify if extended length is required. In case of BITDATA, calculate 137 * number of full bytes and additional valid bits. 138 */ 139 if ((flags & EXT) || (length >> 16)) { 140 opcode |= FIFOLDST_EXT; 141 if (src == BIT_DATA) { 142 ext_length = (length / 8); 143 length = (length % 8); 144 } else { 145 ext_length = length; 146 length = 0; 147 } 148 } 149 opcode |= (uint16_t) length; 150 151 __rta_out32(program, opcode); 152 program->current_instruction++; 153 154 /* write pointer or immediate data field */ 155 if (flags & IMMED) 156 __rta_inline_data(program, loc, flags & __COPY_MASK, length); 157 else if (!is_seq_cmd) 158 __rta_out64(program, program->ps, loc); 159 160 /* write extended length field */ 161 if (opcode & FIFOLDST_EXT) 162 __rta_out32(program, ext_length); 163 164 return (int)start_pc; 165 166 err: 167 program->first_error_pc = start_pc; 168 program->current_instruction++; 169 return ret; 170 } 171 172 static const uint32_t fifo_store_table[][2] = { 173 /*1*/ { PKA0, FIFOST_TYPE_PKHA_A0 }, 174 { PKA1, FIFOST_TYPE_PKHA_A1 }, 175 { PKA2, FIFOST_TYPE_PKHA_A2 }, 176 { PKA3, FIFOST_TYPE_PKHA_A3 }, 177 { PKB0, FIFOST_TYPE_PKHA_B0 }, 178 { PKB1, FIFOST_TYPE_PKHA_B1 }, 179 { PKB2, FIFOST_TYPE_PKHA_B2 }, 180 { PKB3, FIFOST_TYPE_PKHA_B3 }, 181 { PKA, FIFOST_TYPE_PKHA_A }, 182 { PKB, FIFOST_TYPE_PKHA_B }, 183 { PKN, FIFOST_TYPE_PKHA_N }, 184 { PKE, FIFOST_TYPE_PKHA_E_JKEK }, 185 { RNG, FIFOST_TYPE_RNGSTORE }, 186 { RNGOFIFO, FIFOST_TYPE_RNGFIFO }, 187 { AFHA_SBOX, FIFOST_TYPE_AF_SBOX_JKEK }, 188 { MDHA_SPLIT_KEY, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_SPLIT_KEK }, 189 { MSG, FIFOST_TYPE_MESSAGE_DATA }, 190 { KEY1, FIFOST_CLASS_CLASS1KEY | FIFOST_TYPE_KEY_KEK }, 191 { KEY2, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_KEY_KEK }, 192 { OFIFO, FIFOST_TYPE_OUTFIFO_KEK}, 193 { SKIP, FIFOST_TYPE_SKIP }, 194 /*22*/ { METADATA, FIFOST_TYPE_METADATA}, 195 { MSG_CKSUM, FIFOST_TYPE_MESSAGE_DATA2 } 196 }; 197 198 /* 199 * Allowed FIFO_STORE output data types for each SEC Era. 200 * Values represent the number of entries from fifo_store_table[] that are 201 * supported. 202 */ 203 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21, 204 22, 22, 22, 23, 205 23, 23}; 206 207 static inline int 208 rta_fifo_store(struct program *program, uint32_t src, 209 uint32_t encrypt_flags, uint64_t dst, 210 uint32_t length, uint32_t flags) 211 { 212 uint32_t opcode = 0; 213 uint32_t val = 0; 214 int ret = -EINVAL; 215 bool is_seq_cmd = false; 216 unsigned int start_pc = program->current_pc; 217 218 /* write command type field */ 219 if (flags & SEQ) { 220 opcode = CMD_SEQ_FIFO_STORE; 221 is_seq_cmd = true; 222 } else { 223 opcode = CMD_FIFO_STORE; 224 } 225 226 /* Parameter checking */ 227 if (is_seq_cmd) { 228 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) { 229 pr_err("SEQ FIFO STORE: Invalid usage of VLF\n"); 230 goto err; 231 } 232 if (dst) { 233 pr_err("SEQ FIFO STORE: Invalid command\n"); 234 goto err; 235 } 236 if ((src == METADATA) && (flags & (CONT | EXT))) { 237 pr_err("SEQ FIFO STORE: Invalid flags\n"); 238 goto err; 239 } 240 } else { 241 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) || 242 (src == METADATA)) { 243 pr_err("FIFO STORE: Invalid destination\n"); 244 goto err; 245 } 246 } 247 if ((rta_sec_era == RTA_SEC_ERA_7) && (src == AFHA_SBOX)) { 248 pr_err("FIFO STORE: AFHA S-box not supported by SEC Era %d\n", 249 USER_SEC_ERA(rta_sec_era)); 250 goto err; 251 } 252 253 /* write output data type field */ 254 ret = __rta_map_opcode(src, fifo_store_table, 255 fifo_store_table_sz[rta_sec_era], &val); 256 if (ret < 0) { 257 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n", 258 program->current_pc); 259 goto err; 260 } 261 opcode |= val; 262 263 if (encrypt_flags & TK) 264 opcode |= (0x1 << FIFOST_TYPE_SHIFT); 265 if (encrypt_flags & EKT) { 266 if (rta_sec_era == RTA_SEC_ERA_1) { 267 pr_err("FIFO STORE: AES-CCM source types not supported\n"); 268 ret = -EINVAL; 269 goto err; 270 } 271 opcode |= (0x10 << FIFOST_TYPE_SHIFT); 272 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT); 273 } 274 275 /* write flags fields */ 276 if (flags & CONT) 277 opcode |= FIFOST_CONT; 278 if ((flags & VLF) && (is_seq_cmd)) 279 opcode |= FIFOLDST_VLF; 280 if ((flags & SGF) && (!is_seq_cmd)) 281 opcode |= FIFOLDST_SGF; 282 if (flags & CLASS1) 283 opcode |= FIFOST_CLASS_CLASS1KEY; 284 if (flags & CLASS2) 285 opcode |= FIFOST_CLASS_CLASS2KEY; 286 if (flags & BOTH) 287 opcode |= FIFOST_CLASS_BOTH; 288 289 /* Verify if extended length is required */ 290 if ((length >> 16) || (flags & EXT)) 291 opcode |= FIFOLDST_EXT; 292 else 293 opcode |= (uint16_t) length; 294 295 __rta_out32(program, opcode); 296 program->current_instruction++; 297 298 /* write pointer field */ 299 if ((!is_seq_cmd) && (dst)) 300 __rta_out64(program, program->ps, dst); 301 302 /* write extended length field */ 303 if (opcode & FIFOLDST_EXT) 304 __rta_out32(program, length); 305 306 return (int)start_pc; 307 308 err: 309 program->first_error_pc = start_pc; 310 program->current_instruction++; 311 return ret; 312 } 313 314 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */ 315