162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2016 Broadcom 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * This file contains the definition of SPU messages. There are currently two 862306a36Sopenharmony_ci * SPU message formats: SPU-M and SPU2. The hardware uses different values to 962306a36Sopenharmony_ci * identify the same things in SPU-M vs SPU2. So this file defines values that 1062306a36Sopenharmony_ci * are hardware independent. Software can use these values for any version of 1162306a36Sopenharmony_ci * SPU hardware. These values are used in APIs in spu.c. Functions internal to 1262306a36Sopenharmony_ci * spu.c and spu2.c convert these to hardware-specific values. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#ifndef _SPU_H 1662306a36Sopenharmony_ci#define _SPU_H 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <linux/types.h> 1962306a36Sopenharmony_ci#include <linux/scatterlist.h> 2062306a36Sopenharmony_ci#include <crypto/sha1.h> 2162306a36Sopenharmony_ci#include <crypto/sha2.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cienum spu_cipher_alg { 2462306a36Sopenharmony_ci CIPHER_ALG_NONE = 0x0, 2562306a36Sopenharmony_ci CIPHER_ALG_RC4 = 0x1, 2662306a36Sopenharmony_ci CIPHER_ALG_DES = 0x2, 2762306a36Sopenharmony_ci CIPHER_ALG_3DES = 0x3, 2862306a36Sopenharmony_ci CIPHER_ALG_AES = 0x4, 2962306a36Sopenharmony_ci CIPHER_ALG_LAST = 0x5 3062306a36Sopenharmony_ci}; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cienum spu_cipher_mode { 3362306a36Sopenharmony_ci CIPHER_MODE_NONE = 0x0, 3462306a36Sopenharmony_ci CIPHER_MODE_ECB = 0x0, 3562306a36Sopenharmony_ci CIPHER_MODE_CBC = 0x1, 3662306a36Sopenharmony_ci CIPHER_MODE_OFB = 0x2, 3762306a36Sopenharmony_ci CIPHER_MODE_CFB = 0x3, 3862306a36Sopenharmony_ci CIPHER_MODE_CTR = 0x4, 3962306a36Sopenharmony_ci CIPHER_MODE_CCM = 0x5, 4062306a36Sopenharmony_ci CIPHER_MODE_GCM = 0x6, 4162306a36Sopenharmony_ci CIPHER_MODE_XTS = 0x7, 4262306a36Sopenharmony_ci CIPHER_MODE_LAST = 0x8 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cienum spu_cipher_type { 4662306a36Sopenharmony_ci CIPHER_TYPE_NONE = 0x0, 4762306a36Sopenharmony_ci CIPHER_TYPE_DES = 0x0, 4862306a36Sopenharmony_ci CIPHER_TYPE_3DES = 0x0, 4962306a36Sopenharmony_ci CIPHER_TYPE_INIT = 0x0, /* used for ARC4 */ 5062306a36Sopenharmony_ci CIPHER_TYPE_AES128 = 0x0, 5162306a36Sopenharmony_ci CIPHER_TYPE_AES192 = 0x1, 5262306a36Sopenharmony_ci CIPHER_TYPE_UPDT = 0x1, /* used for ARC4 */ 5362306a36Sopenharmony_ci CIPHER_TYPE_AES256 = 0x2, 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cienum hash_alg { 5762306a36Sopenharmony_ci HASH_ALG_NONE = 0x0, 5862306a36Sopenharmony_ci HASH_ALG_MD5 = 0x1, 5962306a36Sopenharmony_ci HASH_ALG_SHA1 = 0x2, 6062306a36Sopenharmony_ci HASH_ALG_SHA224 = 0x3, 6162306a36Sopenharmony_ci HASH_ALG_SHA256 = 0x4, 6262306a36Sopenharmony_ci HASH_ALG_AES = 0x5, 6362306a36Sopenharmony_ci HASH_ALG_SHA384 = 0x6, 6462306a36Sopenharmony_ci HASH_ALG_SHA512 = 0x7, 6562306a36Sopenharmony_ci /* Keep SHA3 algorithms at the end always */ 6662306a36Sopenharmony_ci HASH_ALG_SHA3_224 = 0x8, 6762306a36Sopenharmony_ci HASH_ALG_SHA3_256 = 0x9, 6862306a36Sopenharmony_ci HASH_ALG_SHA3_384 = 0xa, 6962306a36Sopenharmony_ci HASH_ALG_SHA3_512 = 0xb, 7062306a36Sopenharmony_ci HASH_ALG_LAST 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cienum hash_mode { 7462306a36Sopenharmony_ci HASH_MODE_NONE = 0x0, 7562306a36Sopenharmony_ci HASH_MODE_HASH = 0x0, 7662306a36Sopenharmony_ci HASH_MODE_XCBC = 0x0, 7762306a36Sopenharmony_ci HASH_MODE_CMAC = 0x1, 7862306a36Sopenharmony_ci HASH_MODE_CTXT = 0x1, 7962306a36Sopenharmony_ci HASH_MODE_HMAC = 0x2, 8062306a36Sopenharmony_ci HASH_MODE_RABIN = 0x4, 8162306a36Sopenharmony_ci HASH_MODE_FHMAC = 0x6, 8262306a36Sopenharmony_ci HASH_MODE_CCM = 0x5, 8362306a36Sopenharmony_ci HASH_MODE_GCM = 0x6, 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cienum hash_type { 8762306a36Sopenharmony_ci HASH_TYPE_NONE = 0x0, 8862306a36Sopenharmony_ci HASH_TYPE_FULL = 0x0, 8962306a36Sopenharmony_ci HASH_TYPE_INIT = 0x1, 9062306a36Sopenharmony_ci HASH_TYPE_UPDT = 0x2, 9162306a36Sopenharmony_ci HASH_TYPE_FIN = 0x3, 9262306a36Sopenharmony_ci HASH_TYPE_AES128 = 0x0, 9362306a36Sopenharmony_ci HASH_TYPE_AES192 = 0x1, 9462306a36Sopenharmony_ci HASH_TYPE_AES256 = 0x2 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cienum aead_type { 9862306a36Sopenharmony_ci AES_CCM, 9962306a36Sopenharmony_ci AES_GCM, 10062306a36Sopenharmony_ci AUTHENC, 10162306a36Sopenharmony_ci AEAD_TYPE_LAST 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciextern char *hash_alg_name[HASH_ALG_LAST]; 10562306a36Sopenharmony_ciextern char *aead_alg_name[AEAD_TYPE_LAST]; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistruct spu_request_opts { 10862306a36Sopenharmony_ci bool is_inbound; 10962306a36Sopenharmony_ci bool auth_first; 11062306a36Sopenharmony_ci bool is_aead; 11162306a36Sopenharmony_ci bool is_esp; 11262306a36Sopenharmony_ci bool bd_suppress; 11362306a36Sopenharmony_ci bool is_rfc4543; 11462306a36Sopenharmony_ci}; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistruct spu_cipher_parms { 11762306a36Sopenharmony_ci enum spu_cipher_alg alg; 11862306a36Sopenharmony_ci enum spu_cipher_mode mode; 11962306a36Sopenharmony_ci enum spu_cipher_type type; 12062306a36Sopenharmony_ci u8 *key_buf; 12162306a36Sopenharmony_ci u16 key_len; 12262306a36Sopenharmony_ci /* iv_buf and iv_len include salt, if applicable */ 12362306a36Sopenharmony_ci u8 *iv_buf; 12462306a36Sopenharmony_ci u16 iv_len; 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistruct spu_hash_parms { 12862306a36Sopenharmony_ci enum hash_alg alg; 12962306a36Sopenharmony_ci enum hash_mode mode; 13062306a36Sopenharmony_ci enum hash_type type; 13162306a36Sopenharmony_ci u8 digestsize; 13262306a36Sopenharmony_ci u8 *key_buf; 13362306a36Sopenharmony_ci u16 key_len; 13462306a36Sopenharmony_ci u16 prebuf_len; 13562306a36Sopenharmony_ci /* length of hash pad. signed, needs to handle roll-overs */ 13662306a36Sopenharmony_ci int pad_len; 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistruct spu_aead_parms { 14062306a36Sopenharmony_ci u32 assoc_size; 14162306a36Sopenharmony_ci u16 iv_len; /* length of IV field between assoc data and data */ 14262306a36Sopenharmony_ci u8 aad_pad_len; /* For AES GCM/CCM, length of padding after AAD */ 14362306a36Sopenharmony_ci u8 data_pad_len;/* For AES GCM/CCM, length of padding after data */ 14462306a36Sopenharmony_ci bool return_iv; /* True if SPU should return an IV */ 14562306a36Sopenharmony_ci u32 ret_iv_len; /* Length in bytes of returned IV */ 14662306a36Sopenharmony_ci u32 ret_iv_off; /* Offset into full IV if partial IV returned */ 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/************** SPU sizes ***************/ 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci#define SPU_RX_STATUS_LEN 4 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* Max length of padding for 4-byte alignment of STATUS field */ 15462306a36Sopenharmony_ci#define SPU_STAT_PAD_MAX 4 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* Max length of pad fragment. 4 is for 4-byte alignment of STATUS field */ 15762306a36Sopenharmony_ci#define SPU_PAD_LEN_MAX (SPU_GCM_CCM_ALIGN + MAX_HASH_BLOCK_SIZE + \ 15862306a36Sopenharmony_ci SPU_STAT_PAD_MAX) 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci/* GCM and CCM require 16-byte alignment */ 16162306a36Sopenharmony_ci#define SPU_GCM_CCM_ALIGN 16 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci/* Length up SUPDT field in SPU response message for RC4 */ 16462306a36Sopenharmony_ci#define SPU_SUPDT_LEN 260 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci/* SPU status error codes. These used as common error codes across all 16762306a36Sopenharmony_ci * SPU variants. 16862306a36Sopenharmony_ci */ 16962306a36Sopenharmony_ci#define SPU_INVALID_ICV 1 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci/* Indicates no limit to the length of the payload in a SPU message */ 17262306a36Sopenharmony_ci#define SPU_MAX_PAYLOAD_INF 0xFFFFFFFF 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/* Size of XTS tweak ("i" parameter), in bytes */ 17562306a36Sopenharmony_ci#define SPU_XTS_TWEAK_SIZE 16 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/* CCM B_0 field definitions, common for SPU-M and SPU2 */ 17862306a36Sopenharmony_ci#define CCM_B0_ADATA 0x40 17962306a36Sopenharmony_ci#define CCM_B0_ADATA_SHIFT 6 18062306a36Sopenharmony_ci#define CCM_B0_M_PRIME 0x38 18162306a36Sopenharmony_ci#define CCM_B0_M_PRIME_SHIFT 3 18262306a36Sopenharmony_ci#define CCM_B0_L_PRIME 0x07 18362306a36Sopenharmony_ci#define CCM_B0_L_PRIME_SHIFT 0 18462306a36Sopenharmony_ci#define CCM_ESP_L_VALUE 4 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci/** 18762306a36Sopenharmony_ci * spu_req_incl_icv() - Return true if SPU request message should include the 18862306a36Sopenharmony_ci * ICV as a separate buffer. 18962306a36Sopenharmony_ci * @cipher_mode: the cipher mode being requested 19062306a36Sopenharmony_ci * @is_encrypt: true if encrypting. false if decrypting. 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * Return: true if ICV to be included as separate buffer 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_cistatic __always_inline bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode, 19562306a36Sopenharmony_ci bool is_encrypt) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci if ((cipher_mode == CIPHER_MODE_GCM) && !is_encrypt) 19862306a36Sopenharmony_ci return true; 19962306a36Sopenharmony_ci if ((cipher_mode == CIPHER_MODE_CCM) && !is_encrypt) 20062306a36Sopenharmony_ci return true; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci return false; 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic __always_inline u32 spu_real_db_size(u32 assoc_size, 20662306a36Sopenharmony_ci u32 aead_iv_buf_len, 20762306a36Sopenharmony_ci u32 prebuf_len, 20862306a36Sopenharmony_ci u32 data_size, 20962306a36Sopenharmony_ci u32 aad_pad_len, 21062306a36Sopenharmony_ci u32 gcm_pad_len, 21162306a36Sopenharmony_ci u32 hash_pad_len) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci return assoc_size + aead_iv_buf_len + prebuf_len + data_size + 21462306a36Sopenharmony_ci aad_pad_len + gcm_pad_len + hash_pad_len; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/************** SPU Functions Prototypes **************/ 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_civoid spum_dump_msg_hdr(u8 *buf, unsigned int buf_len); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ciu32 spum_ns2_ctx_max_payload(enum spu_cipher_alg cipher_alg, 22262306a36Sopenharmony_ci enum spu_cipher_mode cipher_mode, 22362306a36Sopenharmony_ci unsigned int blocksize); 22462306a36Sopenharmony_ciu32 spum_nsp_ctx_max_payload(enum spu_cipher_alg cipher_alg, 22562306a36Sopenharmony_ci enum spu_cipher_mode cipher_mode, 22662306a36Sopenharmony_ci unsigned int blocksize); 22762306a36Sopenharmony_ciu32 spum_payload_length(u8 *spu_hdr); 22862306a36Sopenharmony_ciu16 spum_response_hdr_len(u16 auth_key_len, u16 enc_key_len, bool is_hash); 22962306a36Sopenharmony_ciu16 spum_hash_pad_len(enum hash_alg hash_alg, enum hash_mode hash_mode, 23062306a36Sopenharmony_ci u32 chunksize, u16 hash_block_size); 23162306a36Sopenharmony_ciu32 spum_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode, 23262306a36Sopenharmony_ci unsigned int data_size); 23362306a36Sopenharmony_ciu32 spum_assoc_resp_len(enum spu_cipher_mode cipher_mode, 23462306a36Sopenharmony_ci unsigned int assoc_len, unsigned int iv_len, 23562306a36Sopenharmony_ci bool is_encrypt); 23662306a36Sopenharmony_ciu8 spum_aead_ivlen(enum spu_cipher_mode cipher_mode, u16 iv_len); 23762306a36Sopenharmony_cibool spu_req_incl_icv(enum spu_cipher_mode cipher_mode, bool is_encrypt); 23862306a36Sopenharmony_cienum hash_type spum_hash_type(u32 src_sent); 23962306a36Sopenharmony_ciu32 spum_digest_size(u32 alg_digest_size, enum hash_alg alg, 24062306a36Sopenharmony_ci enum hash_type htype); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ciu32 spum_create_request(u8 *spu_hdr, 24362306a36Sopenharmony_ci struct spu_request_opts *req_opts, 24462306a36Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 24562306a36Sopenharmony_ci struct spu_hash_parms *hash_parms, 24662306a36Sopenharmony_ci struct spu_aead_parms *aead_parms, 24762306a36Sopenharmony_ci unsigned int data_size); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ciu16 spum_cipher_req_init(u8 *spu_hdr, struct spu_cipher_parms *cipher_parms); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_civoid spum_cipher_req_finish(u8 *spu_hdr, 25262306a36Sopenharmony_ci u16 spu_req_hdr_len, 25362306a36Sopenharmony_ci unsigned int is_inbound, 25462306a36Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 25562306a36Sopenharmony_ci unsigned int data_size); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_civoid spum_request_pad(u8 *pad_start, 25862306a36Sopenharmony_ci u32 gcm_padding, 25962306a36Sopenharmony_ci u32 hash_pad_len, 26062306a36Sopenharmony_ci enum hash_alg auth_alg, 26162306a36Sopenharmony_ci enum hash_mode auth_mode, 26262306a36Sopenharmony_ci unsigned int total_sent, u32 status_padding); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ciu8 spum_xts_tweak_in_payload(void); 26562306a36Sopenharmony_ciu8 spum_tx_status_len(void); 26662306a36Sopenharmony_ciu8 spum_rx_status_len(void); 26762306a36Sopenharmony_ciint spum_status_process(u8 *statp); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_civoid spum_ccm_update_iv(unsigned int digestsize, 27062306a36Sopenharmony_ci struct spu_cipher_parms *cipher_parms, 27162306a36Sopenharmony_ci unsigned int assoclen, 27262306a36Sopenharmony_ci unsigned int chunksize, 27362306a36Sopenharmony_ci bool is_encrypt, 27462306a36Sopenharmony_ci bool is_esp); 27562306a36Sopenharmony_ciu32 spum_wordalign_padlen(u32 data_size); 27662306a36Sopenharmony_ci#endif 277