ccp.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  3. *
  4. * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. *
  28. * $FreeBSD$
  29. */
  30. #pragma once
  31. /*
  32. * Keccak SHAKE128 (if supported by the device?) uses a 1344 bit block.
  33. * SHA3-224 is the next largest block size, at 1152 bits. However, crypto(4)
  34. * doesn't support any SHA3 hash, so SHA2 is the constraint:
  35. */
  36. #define CCP_HASH_MAX_BLOCK_SIZE (SHA2_512_BLOCK_LEN)
  37. #define CCP_AES_MAX_KEY_LEN (AES_XTS_MAX_KEY)
  38. #define CCP_MAX_CRYPTO_IV_LEN 32 /* GCM IV + GHASH context */
  39. #define MAX_HW_QUEUES 5
  40. #define MAX_LSB_REGIONS 8
  41. #ifndef __must_check
  42. #define __must_check __attribute__((__warn_unused_result__))
  43. #endif
  44. /*
  45. * Internal data structures.
  46. */
  47. enum sha_version {
  48. SHA1,
  49. #if 0
  50. SHA2_224,
  51. #endif
  52. SHA2_256, SHA2_384, SHA2_512
  53. };
  54. /*
  55. * XXX: The hmac.res, gmac.final_block, and blkcipher.iv fields are
  56. * used by individual requests meaning that sessions cannot have more
  57. * than a single request in flight at a time.
  58. */
  59. struct ccp_session_hmac {
  60. struct auth_hash *auth_hash;
  61. int hash_len;
  62. unsigned int auth_mode;
  63. char ipad[CCP_HASH_MAX_BLOCK_SIZE];
  64. char opad[CCP_HASH_MAX_BLOCK_SIZE];
  65. char res[CCP_HASH_MAX_BLOCK_SIZE];
  66. };
  67. struct ccp_session_gmac {
  68. int hash_len;
  69. char final_block[GMAC_BLOCK_LEN];
  70. };
  71. struct ccp_session_blkcipher {
  72. unsigned cipher_mode;
  73. unsigned cipher_type;
  74. unsigned key_len;
  75. char enckey[CCP_AES_MAX_KEY_LEN];
  76. char iv[CCP_MAX_CRYPTO_IV_LEN];
  77. };
  78. struct ccp_session {
  79. bool active;
  80. int pending;
  81. enum { HMAC, BLKCIPHER, AUTHENC, GCM } mode;
  82. unsigned queue;
  83. union {
  84. struct ccp_session_hmac hmac;
  85. struct ccp_session_gmac gmac;
  86. };
  87. struct ccp_session_blkcipher blkcipher;
  88. };
  89. struct ccp_softc;
  90. struct ccp_queue {
  91. struct mtx cq_lock;
  92. unsigned cq_qindex;
  93. struct ccp_softc *cq_softc;
  94. /* Host memory and tracking structures for descriptor ring. */
  95. bus_dma_tag_t ring_desc_tag;
  96. bus_dmamap_t ring_desc_map;
  97. struct ccp_desc *desc_ring;
  98. bus_addr_t desc_ring_bus_addr;
  99. /* Callbacks and arguments ring; indices correspond to above ring. */
  100. struct ccp_completion_ctx *completions_ring;
  101. uint32_t qcontrol; /* Cached register value */
  102. unsigned lsb_mask; /* LSBs available to queue */
  103. int private_lsb; /* Reserved LSB #, or -1 */
  104. unsigned cq_head;
  105. unsigned cq_tail;
  106. unsigned cq_acq_tail;
  107. bool cq_waiting; /* Thread waiting for space */
  108. struct sglist *cq_sg_crp;
  109. struct sglist *cq_sg_ulptx;
  110. struct sglist *cq_sg_dst;
  111. };
  112. struct ccp_completion_ctx {
  113. void (*callback_fn)(struct ccp_queue *qp, struct ccp_session *s,
  114. void *arg, int error);
  115. void *callback_arg;
  116. struct ccp_session *session;
  117. };
  118. struct ccp_softc {
  119. device_t dev;
  120. int32_t cid;
  121. struct mtx lock;
  122. bool detaching;
  123. unsigned ring_size_order;
  124. /*
  125. * Each command queue is either public or private. "Private"
  126. * (PSP-only) by default. PSP grants access to some queues to host via
  127. * QMR (Queue Mask Register). Set bits are host accessible.
  128. */
  129. uint8_t valid_queues;
  130. uint8_t hw_version;
  131. uint8_t num_queues;
  132. uint16_t hw_features;
  133. uint16_t num_lsb_entries;
  134. /* Primary BAR (RID 2) used for register access */
  135. bus_space_tag_t pci_bus_tag;
  136. bus_space_handle_t pci_bus_handle;
  137. int pci_resource_id;
  138. struct resource *pci_resource;
  139. /* Secondary BAR (RID 5) apparently used for MSI-X */
  140. int pci_resource_id_msix;
  141. struct resource *pci_resource_msix;
  142. /* Interrupt resources */
  143. void *intr_tag[2];
  144. struct resource *intr_res[2];
  145. unsigned intr_count;
  146. struct ccp_queue queues[MAX_HW_QUEUES];
  147. };
  148. /* Internal globals */
  149. SYSCTL_DECL(_hw_ccp);
  150. MALLOC_DECLARE(M_CCP);
  151. extern bool g_debug_print;
  152. extern struct ccp_softc *g_ccp_softc;
  153. /*
  154. * Debug macros.
  155. */
  156. #define DPRINTF(dev, ...) do { \
  157. if (!g_debug_print) \
  158. break; \
  159. if ((dev) != NULL) \
  160. device_printf((dev), "XXX " __VA_ARGS__); \
  161. else \
  162. printf("ccpXXX: " __VA_ARGS__); \
  163. } while (0)
  164. #if 0
  165. #define INSECURE_DEBUG(dev, ...) do { \
  166. if (!g_debug_print) \
  167. break; \
  168. if ((dev) != NULL) \
  169. device_printf((dev), "XXX " __VA_ARGS__); \
  170. else \
  171. printf("ccpXXX: " __VA_ARGS__); \
  172. } while (0)
  173. #else
  174. #define INSECURE_DEBUG(dev, ...)
  175. #endif
  176. /*
  177. * Internal hardware manipulation routines.
  178. */
  179. int ccp_hw_attach(device_t dev);
  180. void ccp_hw_detach(device_t dev);
  181. void ccp_queue_write_tail(struct ccp_queue *qp);
  182. #ifdef DDB
  183. void db_ccp_show_hw(struct ccp_softc *sc);
  184. void db_ccp_show_queue_hw(struct ccp_queue *qp);
  185. #endif
  186. /*
  187. * Internal hardware crypt-op submission routines.
  188. */
  189. int ccp_authenc(struct ccp_queue *sc, struct ccp_session *s,
  190. struct cryptop *crp) __must_check;
  191. int ccp_blkcipher(struct ccp_queue *sc, struct ccp_session *s,
  192. struct cryptop *crp) __must_check;
  193. int ccp_gcm(struct ccp_queue *sc, struct ccp_session *s, struct cryptop *crp)
  194. __must_check;
  195. int ccp_hmac(struct ccp_queue *sc, struct ccp_session *s, struct cryptop *crp)
  196. __must_check;
  197. /*
  198. * Internal hardware TRNG read routine.
  199. */
  200. u_int random_ccp_read(void *v, u_int c);
  201. /* XXX */
  202. int ccp_queue_acquire_reserve(struct ccp_queue *qp, unsigned n, int mflags)
  203. __must_check;
  204. void ccp_queue_abort(struct ccp_queue *qp);
  205. void ccp_queue_release(struct ccp_queue *qp);
  206. /*
  207. * Internal inline routines.
  208. */
  209. static inline unsigned
  210. ccp_queue_get_active(struct ccp_queue *qp)
  211. {
  212. struct ccp_softc *sc;
  213. sc = qp->cq_softc;
  214. return ((qp->cq_tail - qp->cq_head) & ((1 << sc->ring_size_order) - 1));
  215. }
  216. static inline unsigned
  217. ccp_queue_get_ring_space(struct ccp_queue *qp)
  218. {
  219. struct ccp_softc *sc;
  220. sc = qp->cq_softc;
  221. return ((1 << sc->ring_size_order) - ccp_queue_get_active(qp) - 1);
  222. }