18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2016 Broadcom 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci/* 78c2ecf20Sopenharmony_ci * This file contains the definition of SPU messages. There are currently two 88c2ecf20Sopenharmony_ci * SPU message formats: SPU-M and SPU2. The hardware uses different values to 98c2ecf20Sopenharmony_ci * identify the same things in SPU-M vs SPU2. So this file defines values that 108c2ecf20Sopenharmony_ci * are hardware independent. Software can use these values for any version of 118c2ecf20Sopenharmony_ci * SPU hardware. These values are used in APIs in spu.c. Functions internal to 128c2ecf20Sopenharmony_ci * spu.c and spu2.c convert these to hardware-specific values. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#ifndef _SPU_H 168c2ecf20Sopenharmony_ci#define _SPU_H 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/types.h> 198c2ecf20Sopenharmony_ci#include <linux/scatterlist.h> 208c2ecf20Sopenharmony_ci#include <crypto/sha.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cienum spu_cipher_alg { 238c2ecf20Sopenharmony_ci CIPHER_ALG_NONE = 0x0, 248c2ecf20Sopenharmony_ci CIPHER_ALG_RC4 = 0x1, 258c2ecf20Sopenharmony_ci CIPHER_ALG_DES = 0x2, 268c2ecf20Sopenharmony_ci CIPHER_ALG_3DES = 0x3, 278c2ecf20Sopenharmony_ci CIPHER_ALG_AES = 0x4, 288c2ecf20Sopenharmony_ci CIPHER_ALG_LAST = 0x5 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cienum spu_cipher_mode { 328c2ecf20Sopenharmony_ci CIPHER_MODE_NONE = 0x0, 338c2ecf20Sopenharmony_ci CIPHER_MODE_ECB = 0x0, 348c2ecf20Sopenharmony_ci CIPHER_MODE_CBC = 0x1, 358c2ecf20Sopenharmony_ci CIPHER_MODE_OFB = 0x2, 368c2ecf20Sopenharmony_ci CIPHER_MODE_CFB = 0x3, 378c2ecf20Sopenharmony_ci CIPHER_MODE_CTR = 0x4, 388c2ecf20Sopenharmony_ci CIPHER_MODE_CCM = 0x5, 398c2ecf20Sopenharmony_ci CIPHER_MODE_GCM = 0x6, 408c2ecf20Sopenharmony_ci CIPHER_MODE_XTS = 0x7, 418c2ecf20Sopenharmony_ci CIPHER_MODE_LAST = 0x8 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cienum spu_cipher_type { 458c2ecf20Sopenharmony_ci CIPHER_TYPE_NONE = 0x0, 468c2ecf20Sopenharmony_ci CIPHER_TYPE_DES = 0x0, 478c2ecf20Sopenharmony_ci CIPHER_TYPE_3DES = 0x0, 488c2ecf20Sopenharmony_ci CIPHER_TYPE_INIT = 0x0, /* used for ARC4 */ 498c2ecf20Sopenharmony_ci CIPHER_TYPE_AES128 = 0x0, 508c2ecf20Sopenharmony_ci CIPHER_TYPE_AES192 = 0x1, 518c2ecf20Sopenharmony_ci CIPHER_TYPE_UPDT = 0x1, /* used for ARC4 */ 528c2ecf20Sopenharmony_ci CIPHER_TYPE_AES256 = 0x2, 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cienum hash_alg { 568c2ecf20Sopenharmony_ci HASH_ALG_NONE = 0x0, 578c2ecf20Sopenharmony_ci HASH_ALG_MD5 = 0x1, 588c2ecf20Sopenharmony_ci HASH_ALG_SHA1 = 0x2, 598c2ecf20Sopenharmony_ci HASH_ALG_SHA224 = 0x3, 608c2ecf20Sopenharmony_ci HASH_ALG_SHA256 = 0x4, 618c2ecf20Sopenharmony_ci HASH_ALG_AES = 0x5, 628c2ecf20Sopenharmony_ci HASH_ALG_SHA384 = 0x6, 638c2ecf20Sopenharmony_ci HASH_ALG_SHA512 = 0x7, 648c2ecf20Sopenharmony_ci /* Keep SHA3 algorithms at the end always */ 658c2ecf20Sopenharmony_ci HASH_ALG_SHA3_224 = 0x8, 668c2ecf20Sopenharmony_ci HASH_ALG_SHA3_256 = 0x9, 678c2ecf20Sopenharmony_ci HASH_ALG_SHA3_384 = 0xa, 688c2ecf20Sopenharmony_ci HASH_ALG_SHA3_512 = 0xb, 698c2ecf20Sopenharmony_ci HASH_ALG_LAST 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cienum hash_mode { 738c2ecf20Sopenharmony_ci HASH_MODE_NONE = 0x0, 748c2ecf20Sopenharmony_ci HASH_MODE_HASH = 0x0, 758c2ecf20Sopenharmony_ci HASH_MODE_XCBC = 0x0, 768c2ecf20Sopenharmony_ci HASH_MODE_CMAC = 0x1, 778c2ecf20Sopenharmony_ci HASH_MODE_CTXT = 0x1, 788c2ecf20Sopenharmony_ci HASH_MODE_HMAC = 0x2, 798c2ecf20Sopenharmony_ci HASH_MODE_RABIN = 0x4, 808c2ecf20Sopenharmony_ci HASH_MODE_FHMAC = 0x6, 818c2ecf20Sopenharmony_ci HASH_MODE_CCM = 0x5, 828c2ecf20Sopenharmony_ci HASH_MODE_GCM = 0x6, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cienum hash_type { 868c2ecf20Sopenharmony_ci HASH_TYPE_NONE = 0x0, 878c2ecf20Sopenharmony_ci HASH_TYPE_FULL = 0x0, 888c2ecf20Sopenharmony_ci HASH_TYPE_INIT = 0x1, 898c2ecf20Sopenharmony_ci HASH_TYPE_UPDT = 0x2, 908c2ecf20Sopenharmony_ci HASH_TYPE_FIN = 0x3, 918c2ecf20Sopenharmony_ci HASH_TYPE_AES128 = 0x0, 928c2ecf20Sopenharmony_ci HASH_TYPE_AES192 = 0x1, 938c2ecf20Sopenharmony_ci HASH_TYPE_AES256 = 0x2 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cienum aead_type { 978c2ecf20Sopenharmony_ci AES_CCM, 988c2ecf20Sopenharmony_ci AES_GCM, 998c2ecf20Sopenharmony_ci AUTHENC, 1008c2ecf20Sopenharmony_ci AEAD_TYPE_LAST 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ciextern char *hash_alg_name[HASH_ALG_LAST]; 1048c2ecf20Sopenharmony_ciextern char *aead_alg_name[AEAD_TYPE_LAST]; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistruct spu_request_opts { 1078c2ecf20Sopenharmony_ci bool is_inbound; 1088c2ecf20Sopenharmony_ci bool auth_first; 1098c2ecf20Sopenharmony_ci bool is_aead; 1108c2ecf20Sopenharmony_ci bool is_esp; 1118c2ecf20Sopenharmony_ci bool bd_suppress; 1128c2ecf20Sopenharmony_ci bool is_rfc4543; 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistruct spu_cipher_parms { 1168c2ecf20Sopenharmony_ci enum spu_cipher_alg alg; 1178c2ecf20Sopenharmony_ci enum spu_cipher_mode mode; 1188c2ecf20Sopenharmony_ci enum spu_cipher_type type; 1198c2ecf20Sopenharmony_ci u8 *key_buf; 1208c2ecf20Sopenharmony_ci u16 key_len; 1218c2ecf20Sopenharmony_ci /* iv_buf and iv_len include salt, if applicable */ 1228c2ecf20Sopenharmony_ci u8 *iv_buf; 1238c2ecf20Sopenharmony_ci u16 iv_len; 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistruct spu_hash_parms { 1278c2ecf20Sopenharmony_ci enum hash_alg alg; 1288c2ecf20Sopenharmony_ci enum hash_mode mode; 1298c2ecf20Sopenharmony_ci enum hash_type type; 1308c2ecf20Sopenharmony_ci u8 digestsize; 1318c2ecf20Sopenharmony_ci u8 *key_buf; 1328c2ecf20Sopenharmony_ci u16 key_len; 1338c2ecf20Sopenharmony_ci u16 prebuf_len; 1348c2ecf20Sopenharmony_ci /* length of hash pad. signed, needs to handle roll-overs */ 1358c2ecf20Sopenharmony_ci int pad_len; 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistruct spu_aead_parms { 1398c2ecf20Sopenharmony_ci u32 assoc_size; 1408c2ecf20Sopenharmony_ci u16 iv_len; /* length of IV field between assoc data and data */ 1418c2ecf20Sopenharmony_ci u8 aad_pad_len; /* For AES GCM/CCM, length of padding after AAD */ 1428c2ecf20Sopenharmony_ci u8 data_pad_len;/* For AES GCM/CCM, length of padding after data */ 1438c2ecf20Sopenharmony_ci bool return_iv; /* True if SPU should return an IV */ 1448c2ecf20Sopenharmony_ci u32 ret_iv_len; /* Length in bytes of returned IV */ 1458c2ecf20Sopenharmony_ci u32 ret_iv_off; /* Offset into full IV if partial IV returned */ 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/************** SPU sizes ***************/ 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci#define SPU_RX_STATUS_LEN 4 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/* Max length of padding for 4-byte alignment of STATUS field */ 1538c2ecf20Sopenharmony_ci#define SPU_STAT_PAD_MAX 4 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/* Max length of pad fragment. 4 is for 4-byte alignment of STATUS field */ 1568c2ecf20Sopenharmony_ci#define SPU_PAD_LEN_MAX (SPU_GCM_CCM_ALIGN + MAX_HASH_BLOCK_SIZE + \ 1578c2ecf20Sopenharmony_ci SPU_STAT_PAD_MAX) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* GCM and CCM require 16-byte alignment */ 1608c2ecf20Sopenharmony_ci#define SPU_GCM_CCM_ALIGN 16 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/* Length up SUPDT field in SPU response message for RC4 */ 1638c2ecf20Sopenharmony_ci#define SPU_SUPDT_LEN 260 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* SPU status error codes. These used as common error codes across all 1668c2ecf20Sopenharmony_ci * SPU variants. 1678c2ecf20Sopenharmony_ci */ 1688c2ecf20Sopenharmony_ci#define SPU_INVALID_ICV 1 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci/* Indicates no limit to the length of the payload in a SPU message */ 1718c2ecf20Sopenharmony_ci#define SPU_MAX_PAYLOAD_INF 0xFFFFFFFF 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* Size of XTS tweak ("i" parameter), in bytes */ 1748c2ecf20Sopenharmony_ci#define SPU_XTS_TWEAK_SIZE 16 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* CCM B_0 field definitions, common for SPU-M and SPU2 */ 1778c2ecf20Sopenharmony_ci#define CCM_B0_ADATA 0x40 1788c2ecf20Sopenharmony_ci#define CCM_B0_ADATA_SHIFT 6 1798c2ecf20Sopenharmony_ci#define CCM_B0_M_PRIME 0x38 1808c2ecf20Sopenharmony_ci#define CCM_B0_M_PRIME_SHIFT 3 1818c2ecf20Sopenharmony_ci#define CCM_B0_L_PRIME 0x07 1828c2ecf20Sopenharmony_ci#define CCM_B0_L_PRIME_SHIFT 0 1838c2ecf20Sopenharmony_ci#define CCM_ESP_L_VALUE 4 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci/** 1868c2ecf20Sopenharmony_ci * spu_req_incl_icv() - Return true if SPU request message should include the 1878c2ecf20Sopenharmony_ci * ICV as a separate buffer. 1888c2ecf20Sopenharmony_ci * @cipher_mode: the cipher mode being requested 1898c2ecf20Sopenharmony_ci * @is_encrypt: true if encrypting. false if decrypting. 1908c2ecf20Sopenharmony_ci * 1918c2ecf20Sopenharmony_ci * Return: true if ICV to be included as separate buffer 1928c2ecf20Sopenharmony_ci */ 1938c2ecf20Sopenharmony_cistatic __always_inline bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode, 1948c2ecf20Sopenharmony_ci bool is_encrypt) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci if ((cipher_mode == CIPHER_MODE_GCM) && !is_encrypt) 1978c2ecf20Sopenharmony_ci return true; 1988c2ecf20Sopenharmony_ci if ((cipher_mode == CIPHER_MODE_CCM) && !is_encrypt) 1998c2ecf20Sopenharmony_ci return true; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci return false; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic __always_inline u32 spu_real_db_size(u32 assoc_size, 2058c2ecf20Sopenharmony_ci u32 aead_iv_buf_len, 2068c2ecf20Sopenharmony_ci u32 prebuf_len, 2078c2ecf20Sopenharmony_ci u32 data_size, 2088c2ecf20Sopenharmony_ci u32 aad_pad_len, 2098c2ecf20Sopenharmony_ci u32 gcm_pad_len, 2108c2ecf20Sopenharmony_ci u32 hash_pad_len) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci return assoc_size + aead_iv_buf_len + prebuf_len + data_size + 2138c2ecf20Sopenharmony_ci aad_pad_len + gcm_pad_len + hash_pad_len; 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci/************** SPU Functions Prototypes **************/ 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_civoid spum_dump_msg_hdr(u8 *buf, unsigned int buf_len); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ciu32 spum_ns2_ctx_max_payload(enum spu_cipher_alg cipher_alg, 2218c2ecf20Sopenharmony_ci enum spu_cipher_mode cipher_mode, 2228c2ecf20Sopenharmony_ci unsigned int blocksize); 2238c2ecf20Sopenharmony_ciu32 spum_nsp_ctx_max_payload(enum spu_cipher_alg cipher_alg, 2248c2ecf20Sopenharmony_ci enum spu_cipher_mode cipher_mode, 2258c2ecf20Sopenharmony_ci unsigned int blocksize); 2268c2ecf20Sopenharmony_ciu32 spum_payload_length(u8 *spu_hdr); 2278c2ecf20Sopenharmony_ciu16 spum_response_hdr_len(u16 auth_key_len, u16 enc_key_len, bool is_hash); 2288c2ecf20Sopenharmony_ciu16 spum_hash_pad_len(enum hash_alg hash_alg, enum hash_mode hash_mode, 2298c2ecf20Sopenharmony_ci u32 chunksize, u16 hash_block_size); 2308c2ecf20Sopenharmony_ciu32 spum_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode, 2318c2ecf20Sopenharmony_ci unsigned int data_size); 2328c2ecf20Sopenharmony_ciu32 spum_assoc_resp_len(enum spu_cipher_mode cipher_mode, 2338c2ecf20Sopenharmony_ci unsigned int assoc_len, unsigned int iv_len, 2348c2ecf20Sopenharmony_ci bool is_encrypt); 2358c2ecf20Sopenharmony_ciu8 spum_aead_ivlen(enum spu_cipher_mode cipher_mode, u16 iv_len); 2368c2ecf20Sopenharmony_cibool spu_req_incl_icv(enum spu_cipher_mode cipher_mode, bool is_encrypt); 2378c2ecf20Sopenharmony_cienum hash_type spum_hash_type(u32 src_sent); 2388c2ecf20Sopenharmony_ciu32 spum_digest_size(u32 alg_digest_size, enum hash_alg alg, 2398c2ecf20Sopenharmony_ci enum hash_type htype); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ciu32 spum_create_request(u8 *spu_hdr, 2428c2ecf20Sopenharmony_ci struct spu_request_opts *req_opts, 2438c2ecf20Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 2448c2ecf20Sopenharmony_ci struct spu_hash_parms *hash_parms, 2458c2ecf20Sopenharmony_ci struct spu_aead_parms *aead_parms, 2468c2ecf20Sopenharmony_ci unsigned int data_size); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ciu16 spum_cipher_req_init(u8 *spu_hdr, struct spu_cipher_parms *cipher_parms); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_civoid spum_cipher_req_finish(u8 *spu_hdr, 2518c2ecf20Sopenharmony_ci u16 spu_req_hdr_len, 2528c2ecf20Sopenharmony_ci unsigned int is_inbound, 2538c2ecf20Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 2548c2ecf20Sopenharmony_ci unsigned int data_size); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_civoid spum_request_pad(u8 *pad_start, 2578c2ecf20Sopenharmony_ci u32 gcm_padding, 2588c2ecf20Sopenharmony_ci u32 hash_pad_len, 2598c2ecf20Sopenharmony_ci enum hash_alg auth_alg, 2608c2ecf20Sopenharmony_ci enum hash_mode auth_mode, 2618c2ecf20Sopenharmony_ci unsigned int total_sent, u32 status_padding); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ciu8 spum_xts_tweak_in_payload(void); 2648c2ecf20Sopenharmony_ciu8 spum_tx_status_len(void); 2658c2ecf20Sopenharmony_ciu8 spum_rx_status_len(void); 2668c2ecf20Sopenharmony_ciint spum_status_process(u8 *statp); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_civoid spum_ccm_update_iv(unsigned int digestsize, 2698c2ecf20Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 2708c2ecf20Sopenharmony_ci unsigned int assoclen, 2718c2ecf20Sopenharmony_ci unsigned int chunksize, 2728c2ecf20Sopenharmony_ci bool is_encrypt, 2738c2ecf20Sopenharmony_ci bool is_esp); 2748c2ecf20Sopenharmony_ciu32 spum_wordalign_padlen(u32 data_size); 2758c2ecf20Sopenharmony_ci#endif 276