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