f-stack/dpdk/drivers/crypto/dpaa2_sec/hw/rta/operation_cmd.h

571 lines
14 KiB
C

/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
* Copyright 2016 NXP
*
*/
#ifndef __RTA_OPERATION_CMD_H__
#define __RTA_OPERATION_CMD_H__
#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 70000)
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
extern enum rta_sec_era rta_sec_era;
static inline int
__rta_alg_aai_aes(uint16_t aai)
{
uint16_t aes_mode = aai & OP_ALG_AESA_MODE_MASK;
if (aai & OP_ALG_AAI_C2K) {
if (rta_sec_era < RTA_SEC_ERA_5)
return -1;
if ((aes_mode != OP_ALG_AAI_CCM) &&
(aes_mode != OP_ALG_AAI_GCM))
return -EINVAL;
}
switch (aes_mode) {
case OP_ALG_AAI_CBC_CMAC:
case OP_ALG_AAI_CTR_CMAC_LTE:
case OP_ALG_AAI_CTR_CMAC:
if (rta_sec_era < RTA_SEC_ERA_2)
return -EINVAL;
/* no break */
case OP_ALG_AAI_CTR:
case OP_ALG_AAI_CBC:
case OP_ALG_AAI_ECB:
case OP_ALG_AAI_OFB:
case OP_ALG_AAI_CFB:
case OP_ALG_AAI_XTS:
case OP_ALG_AAI_CMAC:
case OP_ALG_AAI_XCBC_MAC:
case OP_ALG_AAI_CCM:
case OP_ALG_AAI_GCM:
case OP_ALG_AAI_CBC_XCBCMAC:
case OP_ALG_AAI_CTR_XCBCMAC:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_des(uint16_t aai)
{
uint16_t aai_code = (uint16_t)(aai & ~OP_ALG_AAI_CHECKODD);
switch (aai_code) {
case OP_ALG_AAI_CBC:
case OP_ALG_AAI_ECB:
case OP_ALG_AAI_CFB:
case OP_ALG_AAI_OFB:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_md5(uint16_t aai)
{
switch (aai) {
case OP_ALG_AAI_HMAC:
if (rta_sec_era < RTA_SEC_ERA_2)
return -EINVAL;
/* no break */
case OP_ALG_AAI_SMAC:
case OP_ALG_AAI_HASH:
case OP_ALG_AAI_HMAC_PRECOMP:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_sha(uint16_t aai)
{
switch (aai) {
case OP_ALG_AAI_HMAC:
if (rta_sec_era < RTA_SEC_ERA_2)
return -EINVAL;
/* no break */
case OP_ALG_AAI_HASH:
case OP_ALG_AAI_HMAC_PRECOMP:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_rng(uint16_t aai)
{
uint16_t rng_mode = aai & OP_ALG_RNG_MODE_MASK;
uint16_t rng_sh = aai & OP_ALG_AAI_RNG4_SH_MASK;
switch (rng_mode) {
case OP_ALG_AAI_RNG:
case OP_ALG_AAI_RNG_NZB:
case OP_ALG_AAI_RNG_OBP:
break;
default:
return -EINVAL;
}
/* State Handle bits are valid only for SEC Era >= 5 */
if ((rta_sec_era < RTA_SEC_ERA_5) && rng_sh)
return -EINVAL;
/* PS, AI, SK bits are also valid only for SEC Era >= 5 */
if ((rta_sec_era < RTA_SEC_ERA_5) && (aai &
(OP_ALG_AAI_RNG4_PS | OP_ALG_AAI_RNG4_AI | OP_ALG_AAI_RNG4_SK)))
return -EINVAL;
switch (rng_sh) {
case OP_ALG_AAI_RNG4_SH_0:
case OP_ALG_AAI_RNG4_SH_1:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_crc(uint16_t aai)
{
uint16_t aai_code = aai & OP_ALG_CRC_POLY_MASK;
switch (aai_code) {
case OP_ALG_AAI_802:
case OP_ALG_AAI_3385:
case OP_ALG_AAI_CUST_POLY:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_kasumi(uint16_t aai)
{
switch (aai) {
case OP_ALG_AAI_GSM:
case OP_ALG_AAI_EDGE:
case OP_ALG_AAI_F8:
case OP_ALG_AAI_F9:
return 0;
}
return -EINVAL;
}
static inline int
__rta_alg_aai_snow_f9(uint16_t aai)
{
if (aai == OP_ALG_AAI_F9)
return 0;
return -EINVAL;
}
static inline int
__rta_alg_aai_snow_f8(uint16_t aai)
{
if (aai == OP_ALG_AAI_F8)
return 0;
return -EINVAL;
}
static inline int
__rta_alg_aai_zuce(uint16_t aai)
{
if (aai == OP_ALG_AAI_F8)
return 0;
return -EINVAL;
}
static inline int
__rta_alg_aai_zuca(uint16_t aai)
{
if (aai == OP_ALG_AAI_F9)
return 0;
return -EINVAL;
}
struct alg_aai_map {
uint32_t chipher_algo;
int (*aai_func)(uint16_t);
uint32_t class;
};
static const struct alg_aai_map alg_table[] = {
/*1*/ { OP_ALG_ALGSEL_AES, __rta_alg_aai_aes, OP_TYPE_CLASS1_ALG },
{ OP_ALG_ALGSEL_DES, __rta_alg_aai_des, OP_TYPE_CLASS1_ALG },
{ OP_ALG_ALGSEL_3DES, __rta_alg_aai_des, OP_TYPE_CLASS1_ALG },
{ OP_ALG_ALGSEL_MD5, __rta_alg_aai_md5, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_SHA1, __rta_alg_aai_md5, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_SHA224, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_SHA256, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_SHA384, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_SHA512, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_RNG, __rta_alg_aai_rng, OP_TYPE_CLASS1_ALG },
/*11*/ { OP_ALG_ALGSEL_CRC, __rta_alg_aai_crc, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_ARC4, NULL, OP_TYPE_CLASS1_ALG },
{ OP_ALG_ALGSEL_SNOW_F8, __rta_alg_aai_snow_f8, OP_TYPE_CLASS1_ALG },
/*14*/ { OP_ALG_ALGSEL_KASUMI, __rta_alg_aai_kasumi, OP_TYPE_CLASS1_ALG },
{ OP_ALG_ALGSEL_SNOW_F9, __rta_alg_aai_snow_f9, OP_TYPE_CLASS2_ALG },
{ OP_ALG_ALGSEL_ZUCE, __rta_alg_aai_zuce, OP_TYPE_CLASS1_ALG },
/*17*/ { OP_ALG_ALGSEL_ZUCA, __rta_alg_aai_zuca, OP_TYPE_CLASS2_ALG }
};
/*
* Allowed OPERATION algorithms for each SEC Era.
* Values represent the number of entries from alg_table[] that are supported.
*/
static const unsigned int alg_table_sz[] = {14, 15, 15, 15, 17, 17, 11, 17};
static inline int
rta_operation(struct program *program, uint32_t cipher_algo,
uint16_t aai, uint8_t algo_state,
int icv_checking, int enc)
{
uint32_t opcode = CMD_OPERATION;
unsigned int i, found = 0;
unsigned int start_pc = program->current_pc;
int ret;
for (i = 0; i < alg_table_sz[rta_sec_era]; i++) {
if (alg_table[i].chipher_algo == cipher_algo) {
opcode |= cipher_algo | alg_table[i].class;
/* nothing else to verify */
if (alg_table[i].aai_func == NULL) {
found = 1;
break;
}
aai &= OP_ALG_AAI_MASK;
ret = (*alg_table[i].aai_func)(aai);
if (ret < 0) {
pr_err("OPERATION: Bad AAI Type. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
opcode |= aai;
found = 1;
break;
}
}
if (!found) {
pr_err("OPERATION: Invalid Command. SEC Program Line: %d\n",
program->current_pc);
ret = -EINVAL;
goto err;
}
switch (algo_state) {
case OP_ALG_AS_UPDATE:
case OP_ALG_AS_INIT:
case OP_ALG_AS_FINALIZE:
case OP_ALG_AS_INITFINAL:
opcode |= algo_state;
break;
default:
pr_err("Invalid Operation Command\n");
ret = -EINVAL;
goto err;
}
switch (icv_checking) {
case ICV_CHECK_DISABLE:
/*
* opcode |= OP_ALG_ICV_OFF;
* OP_ALG_ICV_OFF is 0
*/
break;
case ICV_CHECK_ENABLE:
opcode |= OP_ALG_ICV_ON;
break;
default:
pr_err("Invalid Operation Command\n");
ret = -EINVAL;
goto err;
}
switch (enc) {
case DIR_DEC:
/*
* opcode |= OP_ALG_DECRYPT;
* OP_ALG_DECRYPT is 0
*/
break;
case DIR_ENC:
opcode |= OP_ALG_ENCRYPT;
break;
default:
pr_err("Invalid Operation Command\n");
ret = -EINVAL;
goto err;
}
__rta_out32(program, opcode);
program->current_instruction++;
return (int)start_pc;
err:
program->first_error_pc = start_pc;
return ret;
}
/*
* OPERATION PKHA routines
*/
static inline int
__rta_pkha_clearmem(uint32_t pkha_op)
{
switch (pkha_op) {
case (OP_ALG_PKMODE_CLEARMEM_ALL):
case (OP_ALG_PKMODE_CLEARMEM_ABE):
case (OP_ALG_PKMODE_CLEARMEM_ABN):
case (OP_ALG_PKMODE_CLEARMEM_AB):
case (OP_ALG_PKMODE_CLEARMEM_AEN):
case (OP_ALG_PKMODE_CLEARMEM_AE):
case (OP_ALG_PKMODE_CLEARMEM_AN):
case (OP_ALG_PKMODE_CLEARMEM_A):
case (OP_ALG_PKMODE_CLEARMEM_BEN):
case (OP_ALG_PKMODE_CLEARMEM_BE):
case (OP_ALG_PKMODE_CLEARMEM_BN):
case (OP_ALG_PKMODE_CLEARMEM_B):
case (OP_ALG_PKMODE_CLEARMEM_EN):
case (OP_ALG_PKMODE_CLEARMEM_N):
case (OP_ALG_PKMODE_CLEARMEM_E):
return 0;
}
return -EINVAL;
}
static inline int
__rta_pkha_mod_arithmetic(uint32_t pkha_op)
{
pkha_op &= (uint32_t)~OP_ALG_PKMODE_OUT_A;
switch (pkha_op) {
case (OP_ALG_PKMODE_MOD_ADD):
case (OP_ALG_PKMODE_MOD_SUB_AB):
case (OP_ALG_PKMODE_MOD_SUB_BA):
case (OP_ALG_PKMODE_MOD_MULT):
case (OP_ALG_PKMODE_MOD_MULT_IM):
case (OP_ALG_PKMODE_MOD_MULT_IM_OM):
case (OP_ALG_PKMODE_MOD_EXPO):
case (OP_ALG_PKMODE_MOD_EXPO_TEQ):
case (OP_ALG_PKMODE_MOD_EXPO_IM):
case (OP_ALG_PKMODE_MOD_EXPO_IM_TEQ):
case (OP_ALG_PKMODE_MOD_REDUCT):
case (OP_ALG_PKMODE_MOD_INV):
case (OP_ALG_PKMODE_MOD_MONT_CNST):
case (OP_ALG_PKMODE_MOD_CRT_CNST):
case (OP_ALG_PKMODE_MOD_GCD):
case (OP_ALG_PKMODE_MOD_PRIMALITY):
case (OP_ALG_PKMODE_MOD_SML_EXP):
case (OP_ALG_PKMODE_F2M_ADD):
case (OP_ALG_PKMODE_F2M_MUL):
case (OP_ALG_PKMODE_F2M_MUL_IM):
case (OP_ALG_PKMODE_F2M_MUL_IM_OM):
case (OP_ALG_PKMODE_F2M_EXP):
case (OP_ALG_PKMODE_F2M_EXP_TEQ):
case (OP_ALG_PKMODE_F2M_AMODN):
case (OP_ALG_PKMODE_F2M_INV):
case (OP_ALG_PKMODE_F2M_R2):
case (OP_ALG_PKMODE_F2M_GCD):
case (OP_ALG_PKMODE_F2M_SML_EXP):
case (OP_ALG_PKMODE_ECC_F2M_ADD):
case (OP_ALG_PKMODE_ECC_F2M_ADD_IM_OM_PROJ):
case (OP_ALG_PKMODE_ECC_F2M_DBL):
case (OP_ALG_PKMODE_ECC_F2M_DBL_IM_OM_PROJ):
case (OP_ALG_PKMODE_ECC_F2M_MUL):
case (OP_ALG_PKMODE_ECC_F2M_MUL_TEQ):
case (OP_ALG_PKMODE_ECC_F2M_MUL_R2):
case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_TEQ):
case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ):
case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ_TEQ):
case (OP_ALG_PKMODE_ECC_MOD_ADD):
case (OP_ALG_PKMODE_ECC_MOD_ADD_IM_OM_PROJ):
case (OP_ALG_PKMODE_ECC_MOD_DBL):
case (OP_ALG_PKMODE_ECC_MOD_DBL_IM_OM_PROJ):
case (OP_ALG_PKMODE_ECC_MOD_MUL):
case (OP_ALG_PKMODE_ECC_MOD_MUL_TEQ):
case (OP_ALG_PKMODE_ECC_MOD_MUL_R2):
case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_TEQ):
case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ):
case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ_TEQ):
return 0;
}
return -EINVAL;
}
static inline int
__rta_pkha_copymem(uint32_t pkha_op)
{
switch (pkha_op) {
case (OP_ALG_PKMODE_COPY_NSZ_A0_B0):
case (OP_ALG_PKMODE_COPY_NSZ_A0_B1):
case (OP_ALG_PKMODE_COPY_NSZ_A0_B2):
case (OP_ALG_PKMODE_COPY_NSZ_A0_B3):
case (OP_ALG_PKMODE_COPY_NSZ_A1_B0):
case (OP_ALG_PKMODE_COPY_NSZ_A1_B1):
case (OP_ALG_PKMODE_COPY_NSZ_A1_B2):
case (OP_ALG_PKMODE_COPY_NSZ_A1_B3):
case (OP_ALG_PKMODE_COPY_NSZ_A2_B0):
case (OP_ALG_PKMODE_COPY_NSZ_A2_B1):
case (OP_ALG_PKMODE_COPY_NSZ_A2_B2):
case (OP_ALG_PKMODE_COPY_NSZ_A2_B3):
case (OP_ALG_PKMODE_COPY_NSZ_A3_B0):
case (OP_ALG_PKMODE_COPY_NSZ_A3_B1):
case (OP_ALG_PKMODE_COPY_NSZ_A3_B2):
case (OP_ALG_PKMODE_COPY_NSZ_A3_B3):
case (OP_ALG_PKMODE_COPY_NSZ_B0_A0):
case (OP_ALG_PKMODE_COPY_NSZ_B0_A1):
case (OP_ALG_PKMODE_COPY_NSZ_B0_A2):
case (OP_ALG_PKMODE_COPY_NSZ_B0_A3):
case (OP_ALG_PKMODE_COPY_NSZ_B1_A0):
case (OP_ALG_PKMODE_COPY_NSZ_B1_A1):
case (OP_ALG_PKMODE_COPY_NSZ_B1_A2):
case (OP_ALG_PKMODE_COPY_NSZ_B1_A3):
case (OP_ALG_PKMODE_COPY_NSZ_B2_A0):
case (OP_ALG_PKMODE_COPY_NSZ_B2_A1):
case (OP_ALG_PKMODE_COPY_NSZ_B2_A2):
case (OP_ALG_PKMODE_COPY_NSZ_B2_A3):
case (OP_ALG_PKMODE_COPY_NSZ_B3_A0):
case (OP_ALG_PKMODE_COPY_NSZ_B3_A1):
case (OP_ALG_PKMODE_COPY_NSZ_B3_A2):
case (OP_ALG_PKMODE_COPY_NSZ_B3_A3):
case (OP_ALG_PKMODE_COPY_NSZ_A_E):
case (OP_ALG_PKMODE_COPY_NSZ_A_N):
case (OP_ALG_PKMODE_COPY_NSZ_B_E):
case (OP_ALG_PKMODE_COPY_NSZ_B_N):
case (OP_ALG_PKMODE_COPY_NSZ_N_A):
case (OP_ALG_PKMODE_COPY_NSZ_N_B):
case (OP_ALG_PKMODE_COPY_NSZ_N_E):
case (OP_ALG_PKMODE_COPY_SSZ_A0_B0):
case (OP_ALG_PKMODE_COPY_SSZ_A0_B1):
case (OP_ALG_PKMODE_COPY_SSZ_A0_B2):
case (OP_ALG_PKMODE_COPY_SSZ_A0_B3):
case (OP_ALG_PKMODE_COPY_SSZ_A1_B0):
case (OP_ALG_PKMODE_COPY_SSZ_A1_B1):
case (OP_ALG_PKMODE_COPY_SSZ_A1_B2):
case (OP_ALG_PKMODE_COPY_SSZ_A1_B3):
case (OP_ALG_PKMODE_COPY_SSZ_A2_B0):
case (OP_ALG_PKMODE_COPY_SSZ_A2_B1):
case (OP_ALG_PKMODE_COPY_SSZ_A2_B2):
case (OP_ALG_PKMODE_COPY_SSZ_A2_B3):
case (OP_ALG_PKMODE_COPY_SSZ_A3_B0):
case (OP_ALG_PKMODE_COPY_SSZ_A3_B1):
case (OP_ALG_PKMODE_COPY_SSZ_A3_B2):
case (OP_ALG_PKMODE_COPY_SSZ_A3_B3):
case (OP_ALG_PKMODE_COPY_SSZ_B0_A0):
case (OP_ALG_PKMODE_COPY_SSZ_B0_A1):
case (OP_ALG_PKMODE_COPY_SSZ_B0_A2):
case (OP_ALG_PKMODE_COPY_SSZ_B0_A3):
case (OP_ALG_PKMODE_COPY_SSZ_B1_A0):
case (OP_ALG_PKMODE_COPY_SSZ_B1_A1):
case (OP_ALG_PKMODE_COPY_SSZ_B1_A2):
case (OP_ALG_PKMODE_COPY_SSZ_B1_A3):
case (OP_ALG_PKMODE_COPY_SSZ_B2_A0):
case (OP_ALG_PKMODE_COPY_SSZ_B2_A1):
case (OP_ALG_PKMODE_COPY_SSZ_B2_A2):
case (OP_ALG_PKMODE_COPY_SSZ_B2_A3):
case (OP_ALG_PKMODE_COPY_SSZ_B3_A0):
case (OP_ALG_PKMODE_COPY_SSZ_B3_A1):
case (OP_ALG_PKMODE_COPY_SSZ_B3_A2):
case (OP_ALG_PKMODE_COPY_SSZ_B3_A3):
case (OP_ALG_PKMODE_COPY_SSZ_A_E):
case (OP_ALG_PKMODE_COPY_SSZ_A_N):
case (OP_ALG_PKMODE_COPY_SSZ_B_E):
case (OP_ALG_PKMODE_COPY_SSZ_B_N):
case (OP_ALG_PKMODE_COPY_SSZ_N_A):
case (OP_ALG_PKMODE_COPY_SSZ_N_B):
case (OP_ALG_PKMODE_COPY_SSZ_N_E):
return 0;
}
return -EINVAL;
}
static inline int
rta_pkha_operation(struct program *program, uint32_t op_pkha)
{
uint32_t opcode = CMD_OPERATION | OP_TYPE_PK | OP_ALG_PK;
uint32_t pkha_func;
unsigned int start_pc = program->current_pc;
int ret = -EINVAL;
pkha_func = op_pkha & OP_ALG_PK_FUN_MASK;
switch (pkha_func) {
case (OP_ALG_PKMODE_CLEARMEM):
ret = __rta_pkha_clearmem(op_pkha);
if (ret < 0) {
pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
break;
case (OP_ALG_PKMODE_MOD_ADD):
case (OP_ALG_PKMODE_MOD_SUB_AB):
case (OP_ALG_PKMODE_MOD_SUB_BA):
case (OP_ALG_PKMODE_MOD_MULT):
case (OP_ALG_PKMODE_MOD_EXPO):
case (OP_ALG_PKMODE_MOD_REDUCT):
case (OP_ALG_PKMODE_MOD_INV):
case (OP_ALG_PKMODE_MOD_MONT_CNST):
case (OP_ALG_PKMODE_MOD_CRT_CNST):
case (OP_ALG_PKMODE_MOD_GCD):
case (OP_ALG_PKMODE_MOD_PRIMALITY):
case (OP_ALG_PKMODE_MOD_SML_EXP):
case (OP_ALG_PKMODE_ECC_MOD_ADD):
case (OP_ALG_PKMODE_ECC_MOD_DBL):
case (OP_ALG_PKMODE_ECC_MOD_MUL):
ret = __rta_pkha_mod_arithmetic(op_pkha);
if (ret < 0) {
pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
break;
case (OP_ALG_PKMODE_COPY_NSZ):
case (OP_ALG_PKMODE_COPY_SSZ):
ret = __rta_pkha_copymem(op_pkha);
if (ret < 0) {
pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
program->current_pc);
goto err;
}
break;
default:
pr_err("Invalid Operation Command\n");
goto err;
}
opcode |= op_pkha;
__rta_out32(program, opcode);
program->current_instruction++;
return (int)start_pc;
err:
program->first_error_pc = start_pc;
program->current_instruction++;
return ret;
}
#endif /* __RTA_OPERATION_CMD_H__ */