1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2016,2019 NXP
7 #ifndef __RTA_KEY_CMD_H__
8 #define __RTA_KEY_CMD_H__
10 extern enum rta_sec_era rta_sec_era;
12 /* Allowed encryption flags for each SEC Era */
13 static const uint32_t key_enc_flags[] = {
20 ENC | NWB | EKT | TK | PTS,
21 ENC | NWB | EKT | TK | PTS,
22 ENC | NWB | EKT | TK | PTS,
23 ENC | NWB | EKT | TK | PTS
27 rta_key(struct program *program, uint32_t key_dst,
28 uint32_t encrypt_flags, uint64_t src, uint32_t length,
32 bool is_seq_cmd = false;
33 unsigned int start_pc = program->current_pc;
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));
49 /* check parameters */
51 if ((flags & IMMED) || (flags & SGF)) {
52 pr_err("SEQKEY: Invalid flag. SEC PC: %d; Instr: %d\n",
54 program->current_instruction);
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));
64 if ((flags & AIDF) || (flags & VLF)) {
65 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
67 program->current_instruction);
70 if ((flags & SGF) && (flags & IMMED)) {
71 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
73 program->current_instruction);
78 if ((encrypt_flags & PTS) &&
79 ((encrypt_flags & ENC) || (encrypt_flags & NWB) ||
81 pr_err("KEY: Invalid flag / destination. SEC PC: %d; Instr: %d\n",
82 program->current_pc, program->current_instruction);
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));
94 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
96 program->current_instruction);
101 * Sbox data loaded into the ARC-4 processor must be exactly
102 * 258 bytes long, or else a data sequence error is generated.
105 pr_err("KEY: Invalid length. SEC PC: %d; Instr: %d\n",
107 program->current_instruction);
112 /* write key destination and class fields */
115 opcode |= KEY_DEST_CLASS1;
118 opcode |= KEY_DEST_CLASS2;
121 opcode |= KEY_DEST_CLASS1 | KEY_DEST_PKHA_E;
124 opcode |= KEY_DEST_CLASS1 | KEY_DEST_AFHA_SBOX;
126 case (MDHA_SPLIT_KEY):
127 opcode |= KEY_DEST_CLASS2 | KEY_DEST_MDHA_SPLIT;
130 pr_err("KEY: Invalid destination. SEC PC: %d; Instr: %d\n",
131 program->current_pc, program->current_instruction);
135 /* write key length */
136 length &= KEY_LENGTH_MASK;
139 /* write key command specific flags */
140 if (encrypt_flags & ENC) {
141 /* Encrypted (black) keys must be padded to 8 bytes (CCM) or
142 * 16 bytes (ECB) depending on EKT bit. AES-CCM encrypted keys
143 * (EKT = 1) have 6-byte nonce and 6-byte MAC after padding.
146 if (encrypt_flags & EKT) {
148 length = ALIGN(length, 8);
151 length = ALIGN(length, 16);
153 if (encrypt_flags & TK)
156 if (encrypt_flags & NWB)
158 if (encrypt_flags & PTS)
161 /* write general command flags */
174 __rta_out32(program, opcode);
175 program->current_instruction++;
178 __rta_inline_data(program, src, flags & __COPY_MASK, length);
180 __rta_out64(program, program->ps, src);
182 return (int)start_pc;
185 program->first_error_pc = start_pc;
186 program->current_instruction++;
190 #endif /* __RTA_KEY_CMD_H__ */