Beispiel #1
0
/* 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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}