wolfcaam_qnx.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* wolfcaam_qnx.h
  2. *
  3. * Copyright (C) 2006-2020 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #if defined(WOLFSSL_QNX_CAAM)
  26. #include <wolfssl/wolfcrypt/logging.h>
  27. #include <wolfssl/wolfcrypt/error-crypt.h>
  28. #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
  29. #include <fcntl.h>
  30. #include <sys/ioctl.h>
  31. #include <devctl.h>
  32. /* for devctl use */
  33. int caamFd = -1;
  34. wolfSSL_Mutex caamMutex;
  35. /* return 0 on success */
  36. int wc_CAAMInitInterface()
  37. {
  38. if (wc_InitMutex(&caamMutex) != 0) {
  39. WOLFSSL_MSG("Could not init mutex");
  40. return -1;
  41. }
  42. caamFd = open("/dev/wolfCrypt", O_RDWR);
  43. if (caamFd < 0) {
  44. WOLFSSL_MSG("Could not open /dev/wolfCrypt");
  45. return -1;
  46. }
  47. return 0;
  48. }
  49. void wc_CAAMFreeInterface()
  50. {
  51. wc_FreeMutex(&caamMutex);
  52. if (caamFd >= 0)
  53. close(caamFd);
  54. }
  55. #define WC_TRNG_CMD __DIOTF(_DCMD_ALL, CAAM_ENTROPY, iov_t)
  56. #define WC_CAAM_GET_PART __DIOTF(_DCMD_ALL, CAAM_GET_PART, iov_t)
  57. #define WC_CAAM_FREE_PART __DIOT(_DCMD_ALL, CAAM_FREE_PART, iov_t)
  58. #define WC_CAAM_FIND_PART __DIOTF(_DCMD_ALL, CAAM_FIND_PART, iov_t)
  59. #define WC_CAAM_READ_PART __DIOTF(_DCMD_ALL, CAAM_READ_PART, iov_t)
  60. #define WC_CAAM_WRITE_PART __DIOT(_DCMD_ALL, CAAM_WRITE_PART, iov_t)
  61. #define WC_CAAM_ECDSA_KEYPAIR __DIOTF(_DCMD_ALL, CAAM_ECDSA_KEYPAIR, iov_t)
  62. #define WC_CAAM_ECDSA_VERIFY __DIOT(_DCMD_ALL, CAAM_ECDSA_VERIFY, iov_t)
  63. #define WC_CAAM_ECDSA_SIGN __DIOTF(_DCMD_ALL, CAAM_ECDSA_SIGN, iov_t)
  64. #define WC_CAAM_ECDSA_ECDH __DIOTF(_DCMD_ALL, CAAM_ECDSA_ECDH, iov_t)
  65. #define WC_CAAM_BLOB_ENCAP __DIOTF(_DCMD_ALL, CAAM_BLOB_ENCAP, iov_t)
  66. #define WC_CAAM_BLOB_DECAP __DIOTF(_DCMD_ALL, CAAM_BLOB_DECAP, iov_t)
  67. #define WC_CAAM_CMAC __DIOTF(_DCMD_ALL, CAAM_CMAC, iov_t)
  68. #define WC_CAAM_FIFO_S __DIOTF(_DCMD_ALL, CAAM_FIFO_S, iov_t)
  69. #define MAX_IN_IOVS 5
  70. #define MAX_OUT_IOVS 3
  71. /* Do a synchronous operations and block till done
  72. * returns 0 on success */
  73. int SynchronousSendRequest(int type, unsigned int args[4], CAAM_BUFFER *buf,
  74. int sz)
  75. {
  76. int ret, inIdx = 0, outIdx = 0;
  77. int cmd = 0;
  78. iov_t in[MAX_IN_IOVS], out[MAX_OUT_IOVS];
  79. CAAM_ADDRESS pubkey, privkey;
  80. if (args != NULL) {
  81. SETIOV(&in[inIdx], args, sizeof(unsigned int) * 4);
  82. inIdx = inIdx + 1;
  83. }
  84. else {
  85. unsigned int localArgs[4] = {0};
  86. SETIOV(&in[inIdx], localArgs, sizeof(unsigned int) * 4);
  87. inIdx = inIdx + 1;
  88. }
  89. switch (type) {
  90. case CAAM_ENTROPY:
  91. SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
  92. outIdx = outIdx + 1;
  93. cmd = WC_TRNG_CMD;
  94. break;
  95. case CAAM_GET_PART:
  96. SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
  97. outIdx = outIdx + 1;
  98. cmd = WC_CAAM_GET_PART;
  99. break;
  100. case CAAM_FREE_PART:
  101. cmd = WC_CAAM_FREE_PART;
  102. break;
  103. case CAAM_FIND_PART:
  104. SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
  105. outIdx = outIdx + 1;
  106. cmd = WC_CAAM_FIND_PART;
  107. break;
  108. case CAAM_READ_PART:
  109. SETIOV(&out[outIdx], (buf->TheAddress), (buf->Length));
  110. outIdx = outIdx + 1;
  111. cmd = WC_CAAM_READ_PART;
  112. break;
  113. case CAAM_WRITE_PART:
  114. SETIOV(&in[inIdx], (buf->TheAddress), (buf->Length));
  115. inIdx = inIdx + 1;
  116. cmd = WC_CAAM_WRITE_PART;
  117. break;
  118. case CAAM_ECDSA_KEYPAIR:
  119. /* set input to get lengths */
  120. SETIOV(&in[inIdx], &buf[0], sizeof(CAAM_BUFFER));
  121. inIdx = inIdx + 1;
  122. SETIOV(&in[inIdx], &buf[1], sizeof(CAAM_BUFFER));
  123. inIdx = inIdx + 1;
  124. /* set output to store directly to CAAM_BUFFER's */
  125. SETIOV(&out[outIdx], &buf[0], sizeof(CAAM_BUFFER));
  126. outIdx = outIdx + 1;
  127. SETIOV(&out[outIdx], &buf[1], sizeof(CAAM_BUFFER));
  128. outIdx = outIdx + 1;
  129. /* get args for updated partition number used */
  130. SETIOV(&out[outIdx], args, sizeof(unsigned int) * 4);
  131. outIdx = outIdx + 1;
  132. cmd = WC_CAAM_ECDSA_KEYPAIR;
  133. break;
  134. case CAAM_ECDSA_VERIFY:
  135. /* public key */
  136. if (args[0] == 1) {
  137. pubkey = buf[0].TheAddress;
  138. SETIOV(&in[inIdx], &pubkey, sizeof(CAAM_ADDRESS));
  139. inIdx = inIdx + 1;
  140. }
  141. else {
  142. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  143. inIdx = inIdx + 1;
  144. }
  145. /* msg */
  146. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  147. inIdx = inIdx + 1;
  148. /* r */
  149. SETIOV(&in[inIdx], buf[2].TheAddress, buf[2].Length);
  150. inIdx = inIdx + 1;
  151. /* s */
  152. SETIOV(&in[inIdx], buf[3].TheAddress, buf[3].Length);
  153. inIdx = inIdx + 1;
  154. cmd = WC_CAAM_ECDSA_VERIFY;
  155. break;
  156. case CAAM_ECDSA_SIGN:
  157. /* private key */
  158. if (args[0] == 1) {
  159. privkey = buf[0].TheAddress;
  160. SETIOV(&in[inIdx], &privkey, sizeof(CAAM_ADDRESS));
  161. inIdx = inIdx + 1;
  162. }
  163. else {
  164. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  165. inIdx = inIdx + 1;
  166. }
  167. /* msg */
  168. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  169. inIdx = inIdx + 1;
  170. /* r out */
  171. SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
  172. outIdx = outIdx + 1;
  173. /* s out */
  174. SETIOV(&out[outIdx], buf[3].TheAddress, buf[3].Length);
  175. outIdx = outIdx + 1;
  176. cmd = WC_CAAM_ECDSA_SIGN;
  177. break;
  178. case CAAM_ECDSA_ECDH:
  179. /* when using memory in secure partition just send the address */
  180. if (args[1] == 1) {
  181. pubkey = buf[0].TheAddress;
  182. SETIOV(&in[inIdx], &pubkey, sizeof(CAAM_ADDRESS));
  183. inIdx = inIdx + 1;
  184. }
  185. else {
  186. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  187. inIdx = inIdx + 1;
  188. }
  189. /* private key */
  190. if (args[0] == 1) {
  191. privkey = buf[1].TheAddress;
  192. SETIOV(&in[inIdx], &privkey, sizeof(CAAM_ADDRESS));
  193. inIdx = inIdx + 1;
  194. }
  195. else {
  196. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  197. inIdx = inIdx + 1;
  198. }
  199. /* shared secret */
  200. SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
  201. outIdx = outIdx + 1;
  202. cmd = WC_CAAM_ECDSA_ECDH;
  203. break;
  204. case CAAM_BLOB_ENCAP:
  205. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  206. inIdx = inIdx + 1;
  207. if (args[0] == 1) {
  208. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length + WC_CAAM_MAC_SZ);
  209. inIdx = inIdx + 1;
  210. }
  211. else {
  212. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  213. inIdx = inIdx + 1;
  214. }
  215. SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
  216. outIdx = outIdx + 1;
  217. cmd = WC_CAAM_BLOB_ENCAP;
  218. break;
  219. case CAAM_BLOB_DECAP:
  220. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  221. inIdx = inIdx + 1;
  222. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  223. inIdx = inIdx + 1;
  224. if (args[0] == 1) {
  225. SETIOV(&out[outIdx], buf[2].TheAddress,
  226. buf[2].Length + WC_CAAM_MAC_SZ);
  227. outIdx = outIdx + 1;
  228. }
  229. else {
  230. SETIOV(&out[outIdx], buf[2].TheAddress, buf[2].Length);
  231. outIdx = outIdx + 1;
  232. }
  233. cmd = WC_CAAM_BLOB_DECAP;
  234. break;
  235. case CAAM_CMAC:
  236. {
  237. int i;
  238. if (args[2] == 1) {
  239. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length + 16);
  240. inIdx = inIdx + 1;
  241. }
  242. else {
  243. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  244. inIdx = inIdx + 1;
  245. }
  246. SETIOV(&in[inIdx], buf[1].TheAddress, buf[1].Length);
  247. inIdx = inIdx + 1;
  248. /* get input buffers */
  249. args[3] = 0;
  250. for (i = 2; i < sz && i < MAX_IN_IOVS; i++) {
  251. SETIOV(&in[inIdx], buf[i].TheAddress, buf[i].Length);
  252. inIdx = inIdx + 1;
  253. args[3] += buf[i].Length;
  254. }
  255. SETIOV(&out[outIdx], buf[1].TheAddress, buf[1].Length);
  256. outIdx = outIdx + 1;
  257. }
  258. cmd = WC_CAAM_CMAC;
  259. break;
  260. case CAAM_FIFO_S:
  261. SETIOV(&in[inIdx], buf[0].TheAddress, buf[0].Length);
  262. inIdx = inIdx + 1;
  263. SETIOV(&out[outIdx], buf[1].TheAddress, buf[1].Length + WC_CAAM_MAC_SZ);
  264. outIdx = outIdx + 1;
  265. cmd = WC_CAAM_FIFO_S;
  266. break;
  267. default:
  268. WOLFSSL_MSG("Unknown/unsupported type");
  269. return -1;
  270. }
  271. wc_LockMutex(&caamMutex);
  272. ret = devctlv(caamFd, cmd, inIdx, outIdx, in, out, NULL);
  273. wc_UnLockMutex(&caamMutex);
  274. if (ret != 0) {
  275. if (ret == EFAULT) {
  276. WOLFSSL_MSG("bad address on one of the in/out buffers");
  277. return -1;
  278. }
  279. if (ret == EAGAIN && type == CAAM_ENTROPY) {
  280. return CAAM_WAITING;
  281. }
  282. return -1;
  283. }
  284. return Success;
  285. }
  286. #endif