spu.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright 2016 Broadcom
  4. */
  5. /*
  6. * This file contains the definition of SPU messages. There are currently two
  7. * SPU message formats: SPU-M and SPU2. The hardware uses different values to
  8. * identify the same things in SPU-M vs SPU2. So this file defines values that
  9. * are hardware independent. Software can use these values for any version of
  10. * SPU hardware. These values are used in APIs in spu.c. Functions internal to
  11. * spu.c and spu2.c convert these to hardware-specific values.
  12. */
  13. #ifndef _SPU_H
  14. #define _SPU_H
  15. #include <linux/types.h>
  16. #include <linux/scatterlist.h>
  17. #include <crypto/sha1.h>
  18. #include <crypto/sha2.h>
  19. enum spu_cipher_alg {
  20. CIPHER_ALG_NONE = 0x0,
  21. CIPHER_ALG_RC4 = 0x1,
  22. CIPHER_ALG_DES = 0x2,
  23. CIPHER_ALG_3DES = 0x3,
  24. CIPHER_ALG_AES = 0x4,
  25. CIPHER_ALG_LAST = 0x5
  26. };
  27. enum spu_cipher_mode {
  28. CIPHER_MODE_NONE = 0x0,
  29. CIPHER_MODE_ECB = 0x0,
  30. CIPHER_MODE_CBC = 0x1,
  31. CIPHER_MODE_OFB = 0x2,
  32. CIPHER_MODE_CFB = 0x3,
  33. CIPHER_MODE_CTR = 0x4,
  34. CIPHER_MODE_CCM = 0x5,
  35. CIPHER_MODE_GCM = 0x6,
  36. CIPHER_MODE_XTS = 0x7,
  37. CIPHER_MODE_LAST = 0x8
  38. };
  39. enum spu_cipher_type {
  40. CIPHER_TYPE_NONE = 0x0,
  41. CIPHER_TYPE_DES = 0x0,
  42. CIPHER_TYPE_3DES = 0x0,
  43. CIPHER_TYPE_INIT = 0x0, /* used for ARC4 */
  44. CIPHER_TYPE_AES128 = 0x0,
  45. CIPHER_TYPE_AES192 = 0x1,
  46. CIPHER_TYPE_UPDT = 0x1, /* used for ARC4 */
  47. CIPHER_TYPE_AES256 = 0x2,
  48. };
  49. enum hash_alg {
  50. HASH_ALG_NONE = 0x0,
  51. HASH_ALG_MD5 = 0x1,
  52. HASH_ALG_SHA1 = 0x2,
  53. HASH_ALG_SHA224 = 0x3,
  54. HASH_ALG_SHA256 = 0x4,
  55. HASH_ALG_AES = 0x5,
  56. HASH_ALG_SHA384 = 0x6,
  57. HASH_ALG_SHA512 = 0x7,
  58. /* Keep SHA3 algorithms at the end always */
  59. HASH_ALG_SHA3_224 = 0x8,
  60. HASH_ALG_SHA3_256 = 0x9,
  61. HASH_ALG_SHA3_384 = 0xa,
  62. HASH_ALG_SHA3_512 = 0xb,
  63. HASH_ALG_LAST
  64. };
  65. enum hash_mode {
  66. HASH_MODE_NONE = 0x0,
  67. HASH_MODE_HASH = 0x0,
  68. HASH_MODE_XCBC = 0x0,
  69. HASH_MODE_CMAC = 0x1,
  70. HASH_MODE_CTXT = 0x1,
  71. HASH_MODE_HMAC = 0x2,
  72. HASH_MODE_RABIN = 0x4,
  73. HASH_MODE_FHMAC = 0x6,
  74. HASH_MODE_CCM = 0x5,
  75. HASH_MODE_GCM = 0x6,
  76. };
  77. enum hash_type {
  78. HASH_TYPE_NONE = 0x0,
  79. HASH_TYPE_FULL = 0x0,
  80. HASH_TYPE_INIT = 0x1,
  81. HASH_TYPE_UPDT = 0x2,
  82. HASH_TYPE_FIN = 0x3,
  83. HASH_TYPE_AES128 = 0x0,
  84. HASH_TYPE_AES192 = 0x1,
  85. HASH_TYPE_AES256 = 0x2
  86. };
  87. enum aead_type {
  88. AES_CCM,
  89. AES_GCM,
  90. AUTHENC,
  91. AEAD_TYPE_LAST
  92. };
  93. extern char *hash_alg_name[HASH_ALG_LAST];
  94. extern char *aead_alg_name[AEAD_TYPE_LAST];
  95. struct spu_request_opts {
  96. bool is_inbound;
  97. bool auth_first;
  98. bool is_aead;
  99. bool is_esp;
  100. bool bd_suppress;
  101. bool is_rfc4543;
  102. };
  103. struct spu_cipher_parms {
  104. enum spu_cipher_alg alg;
  105. enum spu_cipher_mode mode;
  106. enum spu_cipher_type type;
  107. u8 *key_buf;
  108. u16 key_len;
  109. /* iv_buf and iv_len include salt, if applicable */
  110. u8 *iv_buf;
  111. u16 iv_len;
  112. };
  113. struct spu_hash_parms {
  114. enum hash_alg alg;
  115. enum hash_mode mode;
  116. enum hash_type type;
  117. u8 digestsize;
  118. u8 *key_buf;
  119. u16 key_len;
  120. u16 prebuf_len;
  121. /* length of hash pad. signed, needs to handle roll-overs */
  122. int pad_len;
  123. };
  124. struct spu_aead_parms {
  125. u32 assoc_size;
  126. u16 iv_len; /* length of IV field between assoc data and data */
  127. u8 aad_pad_len; /* For AES GCM/CCM, length of padding after AAD */
  128. u8 data_pad_len;/* For AES GCM/CCM, length of padding after data */
  129. bool return_iv; /* True if SPU should return an IV */
  130. u32 ret_iv_len; /* Length in bytes of returned IV */
  131. u32 ret_iv_off; /* Offset into full IV if partial IV returned */
  132. };
  133. /************** SPU sizes ***************/
  134. #define SPU_RX_STATUS_LEN 4
  135. /* Max length of padding for 4-byte alignment of STATUS field */
  136. #define SPU_STAT_PAD_MAX 4
  137. /* Max length of pad fragment. 4 is for 4-byte alignment of STATUS field */
  138. #define SPU_PAD_LEN_MAX (SPU_GCM_CCM_ALIGN + MAX_HASH_BLOCK_SIZE + \
  139. SPU_STAT_PAD_MAX)
  140. /* GCM and CCM require 16-byte alignment */
  141. #define SPU_GCM_CCM_ALIGN 16
  142. /* Length up SUPDT field in SPU response message for RC4 */
  143. #define SPU_SUPDT_LEN 260
  144. /* SPU status error codes. These used as common error codes across all
  145. * SPU variants.
  146. */
  147. #define SPU_INVALID_ICV 1
  148. /* Indicates no limit to the length of the payload in a SPU message */
  149. #define SPU_MAX_PAYLOAD_INF 0xFFFFFFFF
  150. /* Size of XTS tweak ("i" parameter), in bytes */
  151. #define SPU_XTS_TWEAK_SIZE 16
  152. /* CCM B_0 field definitions, common for SPU-M and SPU2 */
  153. #define CCM_B0_ADATA 0x40
  154. #define CCM_B0_ADATA_SHIFT 6
  155. #define CCM_B0_M_PRIME 0x38
  156. #define CCM_B0_M_PRIME_SHIFT 3
  157. #define CCM_B0_L_PRIME 0x07
  158. #define CCM_B0_L_PRIME_SHIFT 0
  159. #define CCM_ESP_L_VALUE 4
  160. /**
  161. * spu_req_incl_icv() - Return true if SPU request message should include the
  162. * ICV as a separate buffer.
  163. * @cipher_mode: the cipher mode being requested
  164. * @is_encrypt: true if encrypting. false if decrypting.
  165. *
  166. * Return: true if ICV to be included as separate buffer
  167. */
  168. static __always_inline bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode,
  169. bool is_encrypt)
  170. {
  171. if ((cipher_mode == CIPHER_MODE_GCM) && !is_encrypt)
  172. return true;
  173. if ((cipher_mode == CIPHER_MODE_CCM) && !is_encrypt)
  174. return true;
  175. return false;
  176. }
  177. static __always_inline u32 spu_real_db_size(u32 assoc_size,
  178. u32 aead_iv_buf_len,
  179. u32 prebuf_len,
  180. u32 data_size,
  181. u32 aad_pad_len,
  182. u32 gcm_pad_len,
  183. u32 hash_pad_len)
  184. {
  185. return assoc_size + aead_iv_buf_len + prebuf_len + data_size +
  186. aad_pad_len + gcm_pad_len + hash_pad_len;
  187. }
  188. /************** SPU Functions Prototypes **************/
  189. void spum_dump_msg_hdr(u8 *buf, unsigned int buf_len);
  190. u32 spum_ns2_ctx_max_payload(enum spu_cipher_alg cipher_alg,
  191. enum spu_cipher_mode cipher_mode,
  192. unsigned int blocksize);
  193. u32 spum_nsp_ctx_max_payload(enum spu_cipher_alg cipher_alg,
  194. enum spu_cipher_mode cipher_mode,
  195. unsigned int blocksize);
  196. u32 spum_payload_length(u8 *spu_hdr);
  197. u16 spum_response_hdr_len(u16 auth_key_len, u16 enc_key_len, bool is_hash);
  198. u16 spum_hash_pad_len(enum hash_alg hash_alg, enum hash_mode hash_mode,
  199. u32 chunksize, u16 hash_block_size);
  200. u32 spum_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode,
  201. unsigned int data_size);
  202. u32 spum_assoc_resp_len(enum spu_cipher_mode cipher_mode,
  203. unsigned int assoc_len, unsigned int iv_len,
  204. bool is_encrypt);
  205. u8 spum_aead_ivlen(enum spu_cipher_mode cipher_mode, u16 iv_len);
  206. bool spu_req_incl_icv(enum spu_cipher_mode cipher_mode, bool is_encrypt);
  207. enum hash_type spum_hash_type(u32 src_sent);
  208. u32 spum_digest_size(u32 alg_digest_size, enum hash_alg alg,
  209. enum hash_type htype);
  210. u32 spum_create_request(u8 *spu_hdr,
  211. struct spu_request_opts *req_opts,
  212. struct spu_cipher_parms *cipher_parms,
  213. struct spu_hash_parms *hash_parms,
  214. struct spu_aead_parms *aead_parms,
  215. unsigned int data_size);
  216. u16 spum_cipher_req_init(u8 *spu_hdr, struct spu_cipher_parms *cipher_parms);
  217. void spum_cipher_req_finish(u8 *spu_hdr,
  218. u16 spu_req_hdr_len,
  219. unsigned int is_inbound,
  220. struct spu_cipher_parms *cipher_parms,
  221. unsigned int data_size);
  222. void spum_request_pad(u8 *pad_start,
  223. u32 gcm_padding,
  224. u32 hash_pad_len,
  225. enum hash_alg auth_alg,
  226. enum hash_mode auth_mode,
  227. unsigned int total_sent, u32 status_padding);
  228. u8 spum_xts_tweak_in_payload(void);
  229. u8 spum_tx_status_len(void);
  230. u8 spum_rx_status_len(void);
  231. int spum_status_process(u8 *statp);
  232. void spum_ccm_update_iv(unsigned int digestsize,
  233. struct spu_cipher_parms *cipher_parms,
  234. unsigned int assoclen,
  235. unsigned int chunksize,
  236. bool is_encrypt,
  237. bool is_esp);
  238. u32 spum_wordalign_padlen(u32 data_size);
  239. #endif