/* ECC Public x963 Import */ int CRYPT_ECC_PublicImport(CRYPT_ECC_CTX* ecc, const unsigned char* in, unsigned int inSz) { if (ecc == NULL || in == NULL) return BAD_FUNC_ARG; return wc_ecc_import_x963(in, inSz, (ecc_key*)ecc->holder); }
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_ECC_doVerify (JNIEnv* jenv, jobject jcl, jobject sig, jlong sigSz, jobject hash, jlong hashSz, jobject keyDer, jlong keySz, jintArray result) { int ret; int tmpResult; ecc_key myKey; if ((sigSz < 0) || (hashSz < 0) || (keySz < 0)) { return -1; } /* get pointers to our buffers */ unsigned char* sigBuf = (*jenv)->GetDirectBufferAddress(jenv, sig); if (sigBuf == NULL) { printf("problem getting sig buffer address\n"); return -1; } unsigned char* hashBuf = (*jenv)->GetDirectBufferAddress(jenv, hash); if (hashBuf == NULL) { printf("problem getting hash buffer address\n"); return -1; } unsigned char* keyBuf = (*jenv)->GetDirectBufferAddress(jenv, keyDer); if (keyBuf == NULL) { printf("problem getting key buffer address\n"); return -1; } wc_ecc_init(&myKey); ret = wc_ecc_import_x963(keyBuf, (unsigned int)keySz, &myKey); if (ret == 0) { ret = wc_ecc_verify_hash(sigBuf, (unsigned int)sigSz, hashBuf, (unsigned int)hashSz, &tmpResult, &myKey); if (ret != 0) { printf("wc_ecc_verify_hash failed, ret = %d\n", ret); wc_ecc_free(&myKey); return -1; } } else { printf("wc_ecc_import_x963 failed, ret = %d\n", ret); return -1; } wc_ecc_free(&myKey); (*jenv)->SetIntArrayRegion(jenv, result, 0, 1, &tmpResult); return ret; }
static int fw_message_process(MQTTCtx *mqttCtx, byte* buffer, word32 len) { int rc; FirmwareHeader* header = (FirmwareHeader*)buffer; byte *sigBuf, *pubKeyBuf, *fwBuf; ecc_key eccKey; word32 check_len = sizeof(FirmwareHeader) + header->sigLen + header->pubKeyLen + header->fwLen; /* Verify entire message was received */ if (len != check_len) { PRINTF("Message header vs. actual size mismatch! %d != %d", len, check_len); return EXIT_FAILURE; } /* Get pointers to structure elements */ sigBuf = (buffer + sizeof(FirmwareHeader)); pubKeyBuf = (buffer + sizeof(FirmwareHeader) + header->sigLen); fwBuf = (buffer + sizeof(FirmwareHeader) + header->sigLen + header->pubKeyLen); /* Import the public key */ wc_ecc_init(&eccKey); rc = wc_ecc_import_x963(pubKeyBuf, header->pubKeyLen, &eccKey); if (rc == 0) { /* Perform signature verification using public key */ rc = wc_SignatureVerify( FIRMWARE_HASH_TYPE, FIRMWARE_SIG_TYPE, fwBuf, header->fwLen, sigBuf, header->sigLen, &eccKey, sizeof(eccKey)); PRINTF("Firmware Signature Verification: %s (%d)", (rc == 0) ? "Pass" : "Fail", rc); if (rc == 0) { /* TODO: Process firmware image */ /* For example, save to disk using topic name */ fwfile_save(mqttCtx->pub_file, fwBuf, header->fwLen); } } else { PRINTF("ECC public key import failed! %d", rc); } wc_ecc_free(&eccKey); return rc; }
int main(int argc, char** argv) { int ret; WC_RNG rng; ecEncCtx* srvCtx = NULL; void* devCtx = NULL; const byte* mySalt; byte peerSalt[EXCHANGE_SALT_SZ]; byte buffer[BTLE_MSG_MAX_SIZE]; word32 bufferSz; byte plain[BTLE_MSG_MAX_SIZE]; word32 plainSz; ecc_key myKey, peerKey; int type; wolfSSL_Init(); #ifdef DEBUG_WOLFSSL wolfSSL_Debugging_ON(); #endif /* make my session key */ ret = wc_ecc_init(&myKey); ret |= wc_ecc_init(&peerKey); if (ret != 0) { printf("wc_ecc_init failed!\n"); goto cleanup; } /* open BTLE */ ret = btle_open(&devCtx, BTLE_ROLE_SERVER); if (ret != 0) { printf("btle_open failed %d! errno %d\n", ret, errno); goto cleanup; } ret = wc_InitRng(&rng); if (ret != 0) { printf("wc_InitRng failed! %d\n", ret); goto cleanup; } ret = wc_ecc_make_key(&rng, 32, &myKey); if (ret != 0) { printf("wc_ecc_make_key failed %d\n", ret); goto cleanup; } srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng); if (srvCtx == NULL) { printf("wc_ecc_ctx_new failed!\n"); ret = -1; goto cleanup; } /* exchange public keys */ /* Get peer key */ ret = btle_recv(buffer, sizeof(buffer), &type, devCtx); if (ret < 0) { printf("btle_recv key failed %d! errno %d\n", ret, errno); goto cleanup; } if (type != BTLE_PKT_TYPE_KEY) { printf("btle_recv expected key!\n"); ret = -1; goto cleanup; } bufferSz = ret; ret = wc_ecc_import_x963(buffer, bufferSz, &peerKey); if (ret != 0) { printf("wc_ecc_import_x963 failed %d!\n", ret); goto cleanup; } /* send my public key */ /* export my public key */ bufferSz = sizeof(buffer); ret = wc_ecc_export_x963(&myKey, buffer, &bufferSz); if (ret != 0) { printf("wc_ecc_export_x963 failed %d\n", ret); goto cleanup; } /* TODO: Server should hash and sign this public key with a trust ceritifcate (already exchanged) */ /* ECC signature is about 65 bytes */ ret = btle_send(buffer, bufferSz, BTLE_PKT_TYPE_KEY, devCtx); if (ret != bufferSz) { printf("btle_send key failed %d!\n", ret); goto cleanup; } while (1) { mySalt = wc_ecc_ctx_get_own_salt(srvCtx); if (mySalt == NULL) { printf("wc_ecc_ctx_get_own_salt failed!\n"); ret = -1; goto cleanup; } /* Get peer salt */ ret = btle_recv(peerSalt, EXCHANGE_SALT_SZ, &type, devCtx); if (ret <= 0) { printf("btle_recv salt failed %d! errno %d\n", ret, errno); goto cleanup; } if (type != BTLE_PKT_TYPE_SALT) { printf("btle_recv expected salt!\n"); ret = -1; goto cleanup; } /* Send my salt */ /* You must send mySalt before set_peer_salt, because buffer changes */ ret = btle_send(mySalt, EXCHANGE_SALT_SZ, BTLE_PKT_TYPE_SALT, devCtx); if (ret != EXCHANGE_SALT_SZ) { printf("btle_send salt failed %d!\n", ret); goto cleanup; } ret = wc_ecc_ctx_set_peer_salt(srvCtx, peerSalt); if (ret != 0) { printf("wc_ecc_ctx_set_peer_salt failed %d\n", ret); goto cleanup; } /* Get message */ bufferSz = sizeof(buffer); ret = btle_recv(buffer, bufferSz, &type, devCtx); if (ret <= 0) { printf("btle_recv msg failed %d! errno %d\n", ret, errno); goto cleanup; } if (type != BTLE_PKT_TYPE_MSG) { printf("btle_recv expected msg!\n"); ret = -1; goto cleanup; } /* Decrypt message */ bufferSz = ret; plainSz = sizeof(plain); ret = wc_ecc_decrypt(&myKey, &peerKey, buffer, bufferSz, plain, &plainSz, srvCtx); if (ret != 0) { printf("wc_ecc_decrypt failed %d!\n", ret); goto cleanup; } printf("Recv %d: %s\n", plainSz, plain); /* Encrypt message */ bufferSz = sizeof(buffer); ret = wc_ecc_encrypt(&myKey, &peerKey, plain, plainSz, buffer, &bufferSz, srvCtx); if (ret != 0) { printf("wc_ecc_encrypt failed %d!\n", ret); goto cleanup; } /* Send message */ ret = btle_send(buffer, bufferSz, BTLE_PKT_TYPE_MSG, devCtx); if (ret != bufferSz) { printf("btle_send failed %d!\n", ret); goto cleanup; } /* check for exit flag */ if (strstr((char*)plain, "EXIT")) break; /* reset context (reset my salt) */ ret = wc_ecc_ctx_reset(srvCtx, &rng); if (ret != 0) { printf("wc_ecc_ctx_reset failed %d\n", ret); goto cleanup; } } cleanup: if (devCtx != NULL) btle_close(devCtx); wolfSSL_Cleanup(); return ret; }