dpdk/drivers/common/dpaax/caamflib/rta/key_cmd.h
<<
>>
Prefs
   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
  10extern enum rta_sec_era rta_sec_era;
  11
  12/* Allowed encryption flags for each SEC Era */
  13static 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
  26static inline int
  27rta_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        unsigned int start_pc = program->current_pc;
  34
  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));
  38                goto err;
  39        }
  40
  41        /* write cmd type */
  42        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                if ((flags & IMMED) || (flags & SGF)) {
  52                        pr_err("SEQKEY: Invalid flag. SEC PC: %d; Instr: %d\n",
  53                               program->current_pc,
  54                               program->current_instruction);
  55                        goto err;
  56                }
  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));
  61                        goto err;
  62                }
  63        } else {
  64                if ((flags & AIDF) || (flags & VLF)) {
  65                        pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
  66                               program->current_pc,
  67                               program->current_instruction);
  68                        goto err;
  69                }
  70                if ((flags & SGF) && (flags & IMMED)) {
  71                        pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
  72                               program->current_pc,
  73                               program->current_instruction);
  74                        goto err;
  75                }
  76        }
  77
  78        if ((encrypt_flags & PTS) &&
  79            ((encrypt_flags & ENC) || (encrypt_flags & NWB) ||
  80             (key_dst == PKE))) {
  81                pr_err("KEY: Invalid flag / destination. SEC PC: %d; Instr: %d\n",
  82                       program->current_pc, program->current_instruction);
  83                goto err;
  84        }
  85
  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));
  90                        goto err;
  91                }
  92
  93                if (flags & IMMED) {
  94                        pr_err("KEY: Invalid flag. SEC PC: %d; Instr: %d\n",
  95                               program->current_pc,
  96                               program->current_instruction);
  97                        goto err;
  98                }
  99
 100                /*
 101                 * Sbox data loaded into the ARC-4 processor must be exactly
 102                 * 258 bytes long, or else a data sequence error is generated.
 103                 */
 104                if (length != 258) {
 105                        pr_err("KEY: Invalid length. SEC PC: %d; Instr: %d\n",
 106                               program->current_pc,
 107                               program->current_instruction);
 108                        goto err;
 109                }
 110        }
 111
 112        /* write key destination and class fields */
 113        switch (key_dst) {
 114        case (KEY1):
 115                opcode |= KEY_DEST_CLASS1;
 116                break;
 117        case (KEY2):
 118                opcode |= KEY_DEST_CLASS2;
 119                break;
 120        case (PKE):
 121                opcode |= KEY_DEST_CLASS1 | KEY_DEST_PKHA_E;
 122                break;
 123        case (AFHA_SBOX):
 124                opcode |= KEY_DEST_CLASS1 | KEY_DEST_AFHA_SBOX;
 125                break;
 126        case (MDHA_SPLIT_KEY):
 127                opcode |= KEY_DEST_CLASS2 | KEY_DEST_MDHA_SPLIT;
 128                break;
 129        default:
 130                pr_err("KEY: Invalid destination. SEC PC: %d; Instr: %d\n",
 131                       program->current_pc, program->current_instruction);
 132                goto err;
 133        }
 134
 135        /* write key length */
 136        length &= KEY_LENGTH_MASK;
 137        opcode |= length;
 138
 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.
 144                 */
 145                opcode |= KEY_ENC;
 146                if (encrypt_flags & EKT) {
 147                        opcode |= KEY_EKT;
 148                        length = ALIGN(length, 8);
 149                        length += 12;
 150                } else {
 151                        length = ALIGN(length, 16);
 152                }
 153                if (encrypt_flags & TK)
 154                        opcode |= KEY_TK;
 155        }
 156        if (encrypt_flags & NWB)
 157                opcode |= KEY_NWB;
 158        if (encrypt_flags & PTS)
 159                opcode |= KEY_PTS;
 160
 161        /* write general command flags */
 162        if (!is_seq_cmd) {
 163                if (flags & IMMED)
 164                        opcode |= KEY_IMM;
 165                if (flags & SGF)
 166                        opcode |= KEY_SGF;
 167        } else {
 168                if (flags & AIDF)
 169                        opcode |= KEY_AIDF;
 170                if (flags & VLF)
 171                        opcode |= KEY_VLF;
 172        }
 173
 174        __rta_out32(program, opcode);
 175        program->current_instruction++;
 176
 177        if (flags & IMMED)
 178                __rta_inline_data(program, src, flags & __COPY_MASK, length);
 179        else
 180                __rta_out64(program, program->ps, src);
 181
 182        return (int)start_pc;
 183
 184 err:
 185        program->first_error_pc = start_pc;
 186        program->current_instruction++;
 187        return -EINVAL;
 188}
 189
 190#endif /* __RTA_KEY_CMD_H__ */
 191