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