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