spu.h 8.0 KB

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