2 * Copyright 2008-2016 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
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
25 rta_key(struct program *program, uint32_t key_dst,
26 uint32_t encrypt_flags, uint64_t src, uint32_t length,
30 bool is_seq_cmd = false;
31 unsigned int start_pc = program->current_pc;
33 if (encrypt_flags & ~key_enc_flags[rta_sec_era]) {
34 pr_err("KEY: Flag(s) not supported by SEC Era %d\n",
35 USER_SEC_ERA(rta_sec_era));
47 /* check parameters */
49 if ((flags & IMMED) || (flags & SGF)) {
50 pr_err("SEQKEY: Invalid flag. SEC PC: %d; Instr: %d\n",
52 program->current_instruction);
55 if ((rta_sec_era <= RTA_SEC_ERA_5) &&
56 ((flags & VLF) || (flags & AIDF))) {
57 pr_err("SEQKEY: Flag(s) not supported by SEC Era %d\n",
58 USER_SEC_ERA(rta_sec_era));
62 if ((flags & AIDF) || (flags & VLF)) {
63 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
65 program->current_instruction);
68 if ((flags & SGF) && (flags & IMMED)) {
69 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
71 program->current_instruction);
76 if ((encrypt_flags & PTS) &&
77 ((encrypt_flags & ENC) || (encrypt_flags & NWB) ||
79 pr_err("KEY: Invalid flag / destination. SEC PC: %d; Instr: %d\n",
80 program->current_pc, program->current_instruction);
84 if (key_dst == AFHA_SBOX) {
85 if (rta_sec_era == RTA_SEC_ERA_7) {
86 pr_err("KEY: AFHA S-box not supported by SEC Era %d\n",
87 USER_SEC_ERA(rta_sec_era));
92 pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
94 program->current_instruction);
99 * Sbox data loaded into the ARC-4 processor must be exactly
100 * 258 bytes long, or else a data sequence error is generated.
103 pr_err("KEY: Invalid length. SEC PC: %d; Instr: %d\n",
105 program->current_instruction);
110 /* write key destination and class fields */
113 opcode |= KEY_DEST_CLASS1;
116 opcode |= KEY_DEST_CLASS2;
119 opcode |= KEY_DEST_CLASS1 | KEY_DEST_PKHA_E;
122 opcode |= KEY_DEST_CLASS1 | KEY_DEST_AFHA_SBOX;
124 case (MDHA_SPLIT_KEY):
125 opcode |= KEY_DEST_CLASS2 | KEY_DEST_MDHA_SPLIT;
128 pr_err("KEY: Invalid destination. SEC PC: %d; Instr: %d\n",
129 program->current_pc, program->current_instruction);
133 /* write key length */
134 length &= KEY_LENGTH_MASK;
137 /* write key command specific flags */
138 if (encrypt_flags & ENC) {
139 /* Encrypted (black) keys must be padded to 8 bytes (CCM) or
140 * 16 bytes (ECB) depending on EKT bit. AES-CCM encrypted keys
141 * (EKT = 1) have 6-byte nonce and 6-byte MAC after padding.
144 if (encrypt_flags & EKT) {
146 length = ALIGN(length, 8);
149 length = ALIGN(length, 16);
151 if (encrypt_flags & TK)
154 if (encrypt_flags & NWB)
156 if (encrypt_flags & PTS)
159 /* write general command flags */
172 __rta_out32(program, opcode);
173 program->current_instruction++;
176 __rta_inline_data(program, src, flags & __COPY_MASK, length);
178 __rta_out64(program, program->ps, src);
180 return (int)start_pc;
183 program->first_error_pc = start_pc;
184 program->current_instruction++;
188 #endif /* __RTA_KEY_CMD_H__ */