1
0

iotsafe.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*!
  2. \ingroup IoTSafe
  3. \brief This function enables the IoT-Safe support on the given context.
  4. \param ctx pointer to the WOLFSSL_CTX object on which the IoT-safe support must be enabled
  5. \return 0 on success
  6. \return WC_HW_E on hardware error
  7. _Example_
  8. \code
  9. WOLFSSL_CTX *ctx;
  10. ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  11. if (!ctx)
  12. return NULL;
  13. wolfSSL_CTX_iotsafe_enable(ctx);
  14. \endcode
  15. \sa wolfSSL_iotsafe_on
  16. \sa wolfIoTSafe_SetCSIM_read_cb
  17. \sa wolfIoTSafe_SetCSIM_write_cb
  18. */
  19. int wolfSSL_CTX_iotsafe_enable(WOLFSSL_CTX *ctx);
  20. /*!
  21. \ingroup IoTSafe
  22. \brief This function connects the IoT-Safe TLS callbacks to the given SSL session.
  23. \brief This should be called to connect a SSL session to IoT-Safe applet when the
  24. ID of the slots are one-byte long.
  25. If IoT-SAFE slots have an ID of two or more bytes, \ref wolfSSL_iotsafe_on_ex "wolfSSL_iotsafe_on_ex()"
  26. should be used instead.
  27. \param ssl pointer to the WOLFSSL object where the callbacks will be enabled
  28. \param privkey_id id of the iot-safe applet slot containing the private key for the host
  29. \param ecdh_keypair_slot id of the iot-safe applet slot to store the ECDH keypair
  30. \param peer_pubkey_slot id of the iot-safe applet slot to store the other endpoint's public key for ECDH
  31. \param peer_cert_slot id of the iot-safe applet slot to store the other endpoint's public key for verification
  32. \return 0 upon success
  33. \return NOT_COMPILED_IN if HAVE_PK_CALLBACKS is disabled
  34. \return BAD_FUNC_ARG if the ssl pointer is invalid
  35. _Example_
  36. \code
  37. // Define key ids for IoT-Safe
  38. #define PRIVKEY_ID 0x02
  39. #define ECDH_KEYPAIR_ID 0x03
  40. #define PEER_PUBKEY_ID 0x04
  41. #define PEER_CERT_ID 0x05
  42. // Create new ssl session
  43. WOLFSSL *ssl;
  44. ssl = wolfSSL_new(ctx);
  45. if (!ssl)
  46. return NULL;
  47. // Enable IoT-Safe and associate key slots
  48. ret = wolfSSL_CTX_iotsafe_enable(ctx);
  49. if (ret == 0) {
  50. ret = wolfSSL_iotsafe_on(ssl, PRIVKEY_ID, ECDH_KEYPAIR_ID, PEER_PUBKEY_ID, PEER_CERT_ID);
  51. }
  52. \endcode
  53. \sa wolfSSL_iotsafe_on_ex
  54. \sa wolfSSL_CTX_iotsafe_enable
  55. */
  56. int wolfSSL_iotsafe_on(WOLFSSL *ssl, byte privkey_id,
  57. byte ecdh_keypair_slot, byte peer_pubkey_slot, byte peer_cert_slot);
  58. /*!
  59. \ingroup IoTSafe
  60. \brief This function connects the IoT-Safe TLS callbacks to the given SSL session.
  61. This is equivalent to \ref wolfSSL_iotsafe_on "wolfSSL_iotsafe_on" except that the IDs for the IoT-SAFE
  62. slots can be passed by reference, and the length of the ID fields can be specified via
  63. the parameter "id_size".
  64. \param ssl pointer to the WOLFSSL object where the callbacks will be enabled
  65. \param privkey_id pointer to the id of the iot-safe applet slot containing the private key for the host
  66. \param ecdh_keypair_slot pointer to the id of the iot-safe applet slot to store the ECDH keypair
  67. \param peer_pubkey_slot pointer to the of id the iot-safe applet slot to store the other endpoint's public key for ECDH
  68. \param peer_cert_slot pointer to the id of the iot-safe applet slot to store the other endpoint's public key for verification
  69. \param id_size size of each slot ID
  70. \return 0 upon success
  71. \return NOT_COMPILED_IN if HAVE_PK_CALLBACKS is disabled
  72. \return BAD_FUNC_ARG if the ssl pointer is invalid
  73. _Example_
  74. \code
  75. // Define key ids for IoT-Safe (16 bit, little endian)
  76. #define PRIVKEY_ID 0x0201
  77. #define ECDH_KEYPAIR_ID 0x0301
  78. #define PEER_PUBKEY_ID 0x0401
  79. #define PEER_CERT_ID 0x0501
  80. #define ID_SIZE (sizeof(word16))
  81. word16 privkey = PRIVKEY_ID,
  82. ecdh_keypair = ECDH_KEYPAIR_ID,
  83. peer_pubkey = PEER_PUBKEY_ID,
  84. peer_cert = PEER_CERT_ID;
  85. // Create new ssl session
  86. WOLFSSL *ssl;
  87. ssl = wolfSSL_new(ctx);
  88. if (!ssl)
  89. return NULL;
  90. // Enable IoT-Safe and associate key slots
  91. ret = wolfSSL_CTX_iotsafe_enable(ctx);
  92. if (ret == 0) {
  93. ret = wolfSSL_CTX_iotsafe_on_ex(ssl, &privkey, &ecdh_keypair, &peer_pubkey, &peer_cert, ID_SIZE);
  94. }
  95. \endcode
  96. \sa wolfSSL_iotsafe_on
  97. \sa wolfSSL_CTX_iotsafe_enable
  98. */
  99. int wolfSSL_iotsafe_on_ex(WOLFSSL *ssl, byte *privkey_id,
  100. byte *ecdh_keypair_slot, byte *peer_pubkey_slot, byte *peer_cert_slot, word16 id_size);
  101. /*!
  102. \ingroup IoTSafe
  103. \brief Associates a read callback for the AT+CSIM commands. This input function is
  104. usually associated to a read event of a UART channel communicating with the modem.
  105. The read callback associated is global and changes for all the contexts that use
  106. IoT-safe support at the same time.
  107. \param rf Read callback associated to a UART read event. The callback function takes
  108. two arguments (buf, len) and return the number of characters read, up to len. When a
  109. newline is encountered, the callback should return the number of characters received
  110. so far, including the newline character.
  111. _Example_
  112. \code
  113. // USART read function, defined elsewhere
  114. int usart_read(char *buf, int len);
  115. wolfIoTSafe_SetCSIM_read_cb(usart_read);
  116. \endcode
  117. \sa wolfIoTSafe_SetCSIM_write_cb
  118. */
  119. void wolfIoTSafe_SetCSIM_read_cb(wolfSSL_IOTSafe_CSIM_read_cb rf);
  120. /*!
  121. \ingroup IoTSafe
  122. \brief Associates a write callback for the AT+CSIM commands. This output function is
  123. usually associated to a write event on a UART channel communicating with the modem.
  124. The write callback associated is global and changes for all the contexts that use
  125. IoT-safe support at the same time.
  126. \param rf Write callback associated to a UART write event. The callback function takes
  127. two arguments (buf, len) and return the number of characters written, up to len.
  128. _Example_
  129. \code
  130. // USART write function, defined elsewhere
  131. int usart_write(const char *buf, int len);
  132. wolfIoTSafe_SetCSIM_write_cb(usart_write);
  133. \endcode
  134. \sa wolfIoTSafe_SetCSIM_read_cb
  135. */
  136. void wolfIoTSafe_SetCSIM_write_cb(wolfSSL_IOTSafe_CSIM_write_cb wf);
  137. /*!
  138. \ingroup IoTSafe
  139. \brief Generate a random buffer of given size, using the IoT-Safe function
  140. GetRandom. This function is automatically used by the wolfCrypt RNG object.
  141. \param out the buffer where the random sequence of bytes is stored.
  142. \param sz the size of the random sequence to generate, in bytes
  143. \return 0 upon success
  144. */
  145. int wolfIoTSafe_GetRandom(unsigned char* out, word32 sz);
  146. /*!
  147. \ingroup IoTSafe
  148. \brief Import a certificate stored in a file on IoT-Safe applet, and
  149. store it locally in memory. Works with one-byte file ID field.
  150. \param id The file id in the IoT-Safe applet where the certificate is stored
  151. \param output the buffer where the certificate will be imported
  152. \param sz the maximum size available in the buffer output
  153. \return the length of the certificate imported
  154. \return < 0 in case of failure
  155. _Example_
  156. \code
  157. #define CRT_CLIENT_FILE_ID 0x03
  158. unsigned char cert_buffer[2048];
  159. // Get the certificate into the buffer
  160. cert_buffer_size = wolfIoTSafe_GetCert(CRT_CLIENT_FILE_ID, cert_buffer, 2048);
  161. if (cert_buffer_size < 1) {
  162. printf("Bad cli cert\n");
  163. return -1;
  164. }
  165. printf("Loaded Client certificate from IoT-Safe, size = %lu\n", cert_buffer_size);
  166. // Use the certificate buffer as identity for the TLS client context
  167. if (wolfSSL_CTX_use_certificate_buffer(cli_ctx, cert_buffer,
  168. cert_buffer_size, SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
  169. printf("Cannot load client cert\n");
  170. return -1;
  171. }
  172. printf("Client certificate successfully imported.\n");
  173. \endcode
  174. */
  175. int wolfIoTSafe_GetCert(uint8_t id, unsigned char *output, unsigned long sz);
  176. /*!
  177. \ingroup IoTSafe
  178. \brief Import a certificate stored in a file on IoT-Safe applet, and
  179. store it locally in memory. Equivalent to \ref wolfIoTSafe_GetCert "wolfIoTSafe_GetCert",
  180. except that it can be invoked with a file ID of two or more bytes.
  181. \param id Pointer to the file id in the IoT-Safe applet where the certificate is stored
  182. \param id_sz Size of the file id in bytes
  183. \param output the buffer where the certificate will be imported
  184. \param sz the maximum size available in the buffer output
  185. \return the length of the certificate imported
  186. \return < 0 in case of failure
  187. _Example_
  188. \code
  189. #define CRT_CLIENT_FILE_ID 0x0302
  190. #define ID_SIZE (sizeof(word16))
  191. unsigned char cert_buffer[2048];
  192. word16 client_file_id = CRT_CLIENT_FILE_ID;
  193. // Get the certificate into the buffer
  194. cert_buffer_size = wolfIoTSafe_GetCert_ex(&client_file_id, ID_SIZE, cert_buffer, 2048);
  195. if (cert_buffer_size < 1) {
  196. printf("Bad cli cert\n");
  197. return -1;
  198. }
  199. printf("Loaded Client certificate from IoT-Safe, size = %lu\n", cert_buffer_size);
  200. // Use the certificate buffer as identity for the TLS client context
  201. if (wolfSSL_CTX_use_certificate_buffer(cli_ctx, cert_buffer,
  202. cert_buffer_size, SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
  203. printf("Cannot load client cert\n");
  204. return -1;
  205. }
  206. printf("Client certificate successfully imported.\n");
  207. \endcode
  208. */
  209. int wolfIoTSafe_GetCert_ex(uint8_t *id, uint16_t id_sz, unsigned char *output, unsigned long sz);
  210. /*!
  211. \ingroup IoTSafe
  212. \brief Import an ECC 256-bit public key, stored in the IoT-Safe applet, into an ecc_key
  213. object.
  214. \param key the ecc_key object that will contain the key imported from the IoT-Safe applet
  215. \param id The key id in the IoT-Safe applet where the public key is stored
  216. \return 0 upon success
  217. \return < 0 in case of failure
  218. \sa wc_iotsafe_ecc_export_public
  219. \sa wc_iotsafe_ecc_export_private
  220. */
  221. int wc_iotsafe_ecc_import_public(ecc_key *key, byte key_id);
  222. /*!
  223. \ingroup IoTSafe
  224. \brief Export an ECC 256-bit public key, from ecc_key object to a writable public-key slot into the IoT-Safe applet.
  225. \param key the ecc_key object containing the key to be exported
  226. \param id The key id in the IoT-Safe applet where the public key will be stored
  227. \return 0 upon success
  228. \return < 0 in case of failure
  229. \sa wc_iotsafe_ecc_import_public_ex
  230. \sa wc_iotsafe_ecc_export_private
  231. */
  232. int wc_iotsafe_ecc_export_public(ecc_key *key, byte key_id);
  233. /*!
  234. \ingroup IoTSafe
  235. \brief Export an ECC 256-bit public key, from ecc_key object to a writable public-key slot into the IoT-Safe applet.
  236. Equivalent to \ref wc_iotsafe_ecc_import_public "wc_iotsafe_ecc_import_public",
  237. except that it can be invoked with a key ID of two or more bytes.
  238. \param key the ecc_key object containing the key to be exported
  239. \param id The pointer to the key id in the IoT-Safe applet where the public key will be stored
  240. \param id_size The key id size
  241. \return 0 upon success
  242. \return < 0 in case of failure
  243. \sa wc_iotsafe_ecc_import_public
  244. \sa wc_iotsafe_ecc_export_private
  245. */
  246. int wc_iotsafe_ecc_import_public_ex(ecc_key *key, byte *key_id, word16 id_size);
  247. /*!
  248. \ingroup IoTSafe
  249. \brief Export an ECC 256-bit key, from ecc_key object to a writable private-key slot into the IoT-Safe applet.
  250. \param key the ecc_key object containing the key to be exported
  251. \param id The key id in the IoT-Safe applet where the private key will be stored
  252. \return 0 upon success
  253. \return < 0 in case of failure
  254. \sa wc_iotsafe_ecc_export_private_ex
  255. \sa wc_iotsafe_ecc_import_public
  256. \sa wc_iotsafe_ecc_export_public
  257. */
  258. int wc_iotsafe_ecc_export_private(ecc_key *key, byte key_id);
  259. /*!
  260. \ingroup IoTSafe
  261. \brief Export an ECC 256-bit key, from ecc_key object to a writable private-key slot into the IoT-Safe applet.
  262. Equivalent to \ref wc_iotsafe_ecc_export_private "wc_iotsafe_ecc_export_private",
  263. except that it can be invoked with a key ID of two or more bytes.
  264. \param key the ecc_key object containing the key to be exported
  265. \param id The pointer to the key id in the IoT-Safe applet where the private key will be stored
  266. \param id_size The key id size
  267. \return 0 upon success
  268. \return < 0 in case of failure
  269. \sa wc_iotsafe_ecc_export_private
  270. \sa wc_iotsafe_ecc_import_public
  271. \sa wc_iotsafe_ecc_export_public
  272. */
  273. int wc_iotsafe_ecc_export_private_ex(ecc_key *key, byte *key_id, word16 id_size);
  274. /*!
  275. \ingroup IoTSafe
  276. \brief Sign a pre-computed HASH, using a private key previously stored, or pre-provisioned,
  277. in the IoT-Safe applet.
  278. \param in pointer to the buffer containing the message hash to sign
  279. \param inlen length of the message hash to sign
  280. \param out buffer in which to store the generated signature
  281. \param outlen max length of the output buffer. Will store the bytes
  282. \param id key id in the IoT-Safe applet for the slot containing the private key to sign the payload
  283. written to out upon successfully generating a message signature
  284. \return 0 upon success
  285. \return < 0 in case of failure
  286. \sa wc_iotsafe_ecc_sign_hash_ex
  287. \sa wc_iotsafe_ecc_verify_hash
  288. \sa wc_iotsafe_ecc_gen_k
  289. */
  290. int wc_iotsafe_ecc_sign_hash(byte *in, word32 inlen, byte *out, word32 *outlen, byte key_id);
  291. /*!
  292. \ingroup IoTSafe
  293. \brief Sign a pre-computed HASH, using a private key previously stored, or pre-provisioned,
  294. in the IoT-Safe applet. Equivalent to \ref wc_iotsafe_ecc_sign_hash "wc_iotsafe_ecc_sign_hash",
  295. except that it can be invoked with a key ID of two or more bytes.
  296. \param in pointer to the buffer containing the message hash to sign
  297. \param inlen length of the message hash to sign
  298. \param out buffer in which to store the generated signature
  299. \param outlen max length of the output buffer. Will store the bytes
  300. \param id pointer to a key id in the IoT-Safe applet for the slot containing the private key to sign the payload
  301. written to out upon successfully generating a message signature
  302. \param id_size The key id size
  303. \return 0 upon success
  304. \return < 0 in case of failure
  305. \sa wc_iotsafe_ecc_sign_hash
  306. \sa wc_iotsafe_ecc_verify_hash
  307. \sa wc_iotsafe_ecc_gen_k
  308. */
  309. int wc_iotsafe_ecc_sign_hash_ex(byte *in, word32 inlen, byte *out, word32 *outlen, byte *key_id, word16 id_size);
  310. /*!
  311. \ingroup IoTSafe
  312. \brief Verify an ECC signature against a pre-computed HASH, using a public key previously stored, or pre-provisioned,
  313. in the IoT-Safe applet. Result is written to res. 1 is valid, 0 is invalid.
  314. Note: Do not use the return value to test for valid. Only use res.
  315. \return 0 upon success (even if the signature is not valid)
  316. \return < 0 in case of failure.
  317. \param sig buffer containing the signature to verify
  318. \param hash The hash (message digest) that was signed
  319. \param hashlen The length of the hash (octets)
  320. \param res Result of signature, 1==valid, 0==invalid
  321. \param key_id The id of the slot where the public ECC key is stored in the IoT-Safe applet
  322. \sa wc_iotsafe_ecc_verify_hash_ex
  323. \sa wc_iotsafe_ecc_sign_hash
  324. \sa wc_iotsafe_ecc_gen_k
  325. */
  326. int wc_iotsafe_ecc_verify_hash(byte *sig, word32 siglen, byte *hash, word32 hashlen, int *res, byte key_id);
  327. /*!
  328. \ingroup IoTSafe
  329. \brief Verify an ECC signature against a pre-computed HASH, using a public key previously stored, or pre-provisioned,
  330. in the IoT-Safe applet. Result is written to res. 1 is valid, 0 is invalid.
  331. Note: Do not use the return value to test for valid. Only use res.
  332. Equivalent to \ref wc_iotsafe_ecc_verify_hash "wc_iotsafe_ecc_verify_hash",
  333. except that it can be invoked with a key ID of two or more bytes.
  334. \return 0 upon success (even if the signature is not valid)
  335. \return < 0 in case of failure.
  336. \param sig buffer containing the signature to verify
  337. \param hash The hash (message digest) that was signed
  338. \param hashlen The length of the hash (octets)
  339. \param res Result of signature, 1==valid, 0==invalid
  340. \param key_id The id of the slot where the public ECC key is stored in the IoT-Safe applet
  341. \param id_size The key id size
  342. \sa wc_iotsafe_ecc_verify_hash
  343. \sa wc_iotsafe_ecc_sign_hash
  344. \sa wc_iotsafe_ecc_gen_k
  345. */
  346. int wc_iotsafe_ecc_verify_hash_ex(byte *sig, word32 siglen, byte *hash, word32 hashlen, int *res, byte *key_id, word16 id_size);
  347. /*!
  348. \ingroup IoTSafe
  349. \brief Generate an ECC 256-bit keypair and store it in a (writable) slot into the IoT-Safe applet.
  350. \param key_id The id of the slot where the ECC key pair is stored in the IoT-Safe applet.
  351. \return 0 upon success
  352. \return < 0 in case of failure.
  353. \sa wc_iotsafe_ecc_gen_k_ex
  354. \sa wc_iotsafe_ecc_sign_hash
  355. \sa wc_iotsafe_ecc_verify_hash
  356. */
  357. int wc_iotsafe_ecc_gen_k(byte key_id);
  358. /*!
  359. \ingroup IoTSafe
  360. \brief Generate an ECC 256-bit keypair and store it in a (writable) slot into the IoT-Safe applet.
  361. Equivalent to \ref wc_iotsafe_ecc_gen_k "wc_iotsafe_ecc_gen_k",
  362. except that it can be invoked with a key ID of two or more bytes.
  363. \param key_id The id of the slot where the ECC key pair is stored in the IoT-Safe applet.
  364. \param id_size The key id size
  365. \return 0 upon success
  366. \return < 0 in case of failure.
  367. \sa wc_iotsafe_ecc_gen_k
  368. \sa wc_iotsafe_ecc_sign_hash_ex
  369. \sa wc_iotsafe_ecc_verify_hash_ex
  370. */
  371. int wc_iotsafe_ecc_gen_k(byte key_id);