1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright 2016 Broadcom
7 * This file contains the definition of SPU messages. There are currently two
8 * SPU message formats: SPU-M and SPU2. The hardware uses different values to
9 * identify the same things in SPU-M vs SPU2. So this file defines values that
10 * are hardware independent. Software can use these values for any version of
11 * SPU hardware. These values are used in APIs in spu.c. Functions internal to
12 * spu.c and spu2.c convert these to hardware-specific values.
18 #include <linux/types.h>
19 #include <linux/scatterlist.h>
20 #include <crypto/sha1.h>
21 #include <crypto/sha2.h>
24 CIPHER_ALG_NONE
= 0x0,
27 CIPHER_ALG_3DES
= 0x3,
32 enum spu_cipher_mode
{
33 CIPHER_MODE_NONE
= 0x0,
34 CIPHER_MODE_ECB
= 0x0,
35 CIPHER_MODE_CBC
= 0x1,
36 CIPHER_MODE_OFB
= 0x2,
37 CIPHER_MODE_CFB
= 0x3,
38 CIPHER_MODE_CTR
= 0x4,
39 CIPHER_MODE_CCM
= 0x5,
40 CIPHER_MODE_GCM
= 0x6,
41 CIPHER_MODE_XTS
= 0x7,
42 CIPHER_MODE_LAST
= 0x8
45 enum spu_cipher_type
{
46 CIPHER_TYPE_NONE
= 0x0,
47 CIPHER_TYPE_DES
= 0x0,
48 CIPHER_TYPE_3DES
= 0x0,
49 CIPHER_TYPE_INIT
= 0x0, /* used for ARC4 */
50 CIPHER_TYPE_AES128
= 0x0,
51 CIPHER_TYPE_AES192
= 0x1,
52 CIPHER_TYPE_UPDT
= 0x1, /* used for ARC4 */
53 CIPHER_TYPE_AES256
= 0x2,
60 HASH_ALG_SHA224
= 0x3,
61 HASH_ALG_SHA256
= 0x4,
63 HASH_ALG_SHA384
= 0x6,
64 HASH_ALG_SHA512
= 0x7,
65 /* Keep SHA3 algorithms at the end always */
66 HASH_ALG_SHA3_224
= 0x8,
67 HASH_ALG_SHA3_256
= 0x9,
68 HASH_ALG_SHA3_384
= 0xa,
69 HASH_ALG_SHA3_512
= 0xb,
80 HASH_MODE_RABIN
= 0x4,
81 HASH_MODE_FHMAC
= 0x6,
92 HASH_TYPE_AES128
= 0x0,
93 HASH_TYPE_AES192
= 0x1,
94 HASH_TYPE_AES256
= 0x2
104 extern char *hash_alg_name
[HASH_ALG_LAST
];
105 extern char *aead_alg_name
[AEAD_TYPE_LAST
];
107 struct spu_request_opts
{
116 struct spu_cipher_parms
{
117 enum spu_cipher_alg alg
;
118 enum spu_cipher_mode mode
;
119 enum spu_cipher_type type
;
122 /* iv_buf and iv_len include salt, if applicable */
127 struct spu_hash_parms
{
135 /* length of hash pad. signed, needs to handle roll-overs */
139 struct spu_aead_parms
{
141 u16 iv_len
; /* length of IV field between assoc data and data */
142 u8 aad_pad_len
; /* For AES GCM/CCM, length of padding after AAD */
143 u8 data_pad_len
;/* For AES GCM/CCM, length of padding after data */
144 bool return_iv
; /* True if SPU should return an IV */
145 u32 ret_iv_len
; /* Length in bytes of returned IV */
146 u32 ret_iv_off
; /* Offset into full IV if partial IV returned */
149 /************** SPU sizes ***************/
151 #define SPU_RX_STATUS_LEN 4
153 /* Max length of padding for 4-byte alignment of STATUS field */
154 #define SPU_STAT_PAD_MAX 4
156 /* Max length of pad fragment. 4 is for 4-byte alignment of STATUS field */
157 #define SPU_PAD_LEN_MAX (SPU_GCM_CCM_ALIGN + MAX_HASH_BLOCK_SIZE + \
160 /* GCM and CCM require 16-byte alignment */
161 #define SPU_GCM_CCM_ALIGN 16
163 /* Length up SUPDT field in SPU response message for RC4 */
164 #define SPU_SUPDT_LEN 260
166 /* SPU status error codes. These used as common error codes across all
169 #define SPU_INVALID_ICV 1
171 /* Indicates no limit to the length of the payload in a SPU message */
172 #define SPU_MAX_PAYLOAD_INF 0xFFFFFFFF
174 /* Size of XTS tweak ("i" parameter), in bytes */
175 #define SPU_XTS_TWEAK_SIZE 16
177 /* CCM B_0 field definitions, common for SPU-M and SPU2 */
178 #define CCM_B0_ADATA 0x40
179 #define CCM_B0_ADATA_SHIFT 6
180 #define CCM_B0_M_PRIME 0x38
181 #define CCM_B0_M_PRIME_SHIFT 3
182 #define CCM_B0_L_PRIME 0x07
183 #define CCM_B0_L_PRIME_SHIFT 0
184 #define CCM_ESP_L_VALUE 4
187 * spu_req_incl_icv() - Return true if SPU request message should include the
188 * ICV as a separate buffer.
189 * @cipher_mode: the cipher mode being requested
190 * @is_encrypt: true if encrypting. false if decrypting.
192 * Return: true if ICV to be included as separate buffer
194 static __always_inline
bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode
,
197 if ((cipher_mode
== CIPHER_MODE_GCM
) && !is_encrypt
)
199 if ((cipher_mode
== CIPHER_MODE_CCM
) && !is_encrypt
)
205 static __always_inline u32
spu_real_db_size(u32 assoc_size
,
213 return assoc_size
+ aead_iv_buf_len
+ prebuf_len
+ data_size
+
214 aad_pad_len
+ gcm_pad_len
+ hash_pad_len
;
217 /************** SPU Functions Prototypes **************/
219 void spum_dump_msg_hdr(u8
*buf
, unsigned int buf_len
);
221 u32
spum_ns2_ctx_max_payload(enum spu_cipher_alg cipher_alg
,
222 enum spu_cipher_mode cipher_mode
,
223 unsigned int blocksize
);
224 u32
spum_nsp_ctx_max_payload(enum spu_cipher_alg cipher_alg
,
225 enum spu_cipher_mode cipher_mode
,
226 unsigned int blocksize
);
227 u32
spum_payload_length(u8
*spu_hdr
);
228 u16
spum_response_hdr_len(u16 auth_key_len
, u16 enc_key_len
, bool is_hash
);
229 u16
spum_hash_pad_len(enum hash_alg hash_alg
, enum hash_mode hash_mode
,
230 u32 chunksize
, u16 hash_block_size
);
231 u32
spum_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode
,
232 unsigned int data_size
);
233 u32
spum_assoc_resp_len(enum spu_cipher_mode cipher_mode
,
234 unsigned int assoc_len
, unsigned int iv_len
,
236 u8
spum_aead_ivlen(enum spu_cipher_mode cipher_mode
, u16 iv_len
);
237 bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode
, bool is_encrypt
);
238 enum hash_type
spum_hash_type(u32 src_sent
);
239 u32
spum_digest_size(u32 alg_digest_size
, enum hash_alg alg
,
240 enum hash_type htype
);
242 u32
spum_create_request(u8
*spu_hdr
,
243 struct spu_request_opts
*req_opts
,
244 struct spu_cipher_parms
*cipher_parms
,
245 struct spu_hash_parms
*hash_parms
,
246 struct spu_aead_parms
*aead_parms
,
247 unsigned int data_size
);
249 u16
spum_cipher_req_init(u8
*spu_hdr
, struct spu_cipher_parms
*cipher_parms
);
251 void spum_cipher_req_finish(u8
*spu_hdr
,
253 unsigned int is_inbound
,
254 struct spu_cipher_parms
*cipher_parms
,
255 unsigned int data_size
);
257 void spum_request_pad(u8
*pad_start
,
260 enum hash_alg auth_alg
,
261 enum hash_mode auth_mode
,
262 unsigned int total_sent
, u32 status_padding
);
264 u8
spum_xts_tweak_in_payload(void);
265 u8
spum_tx_status_len(void);
266 u8
spum_rx_status_len(void);
267 int spum_status_process(u8
*statp
);
269 void spum_ccm_update_iv(unsigned int digestsize
,
270 struct spu_cipher_parms
*cipher_parms
,
271 unsigned int assoclen
,
272 unsigned int chunksize
,
275 u32
spum_wordalign_padlen(u32 data_size
);