org_etsi_its_security_NativeSecurity.c 53.6 KB
Newer Older
/* system headers */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
//add whatever is needed
#include <jni.h>
#include "org_etsi_its_security_NativeSecurity.h"

#include "lib_its_security.h"

//if you use other memory allocation function, please inform me!
#ifdef WIN32
DLLAPI void* _tt_calloc(size_t, size_t);
#define calloc(NUM, SIZE) _tt_calloc(NUM, SIZE)
DLLAPI void _tt_free(void*);
#define free(PTR) _tt_free(PTR)
#else
#endif //WIN32

#ifdef WIN32
void* _tt_calloc(size_t num, size_t elemSize) {
#if (_MSC_VER >= 1700) // newer than Visual Studio 2012
    size_t size = num * elemSize;
    void* res = CoTaskMemAlloc(size);
    memset(res, 0, size);
    return res;
#else
    return HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, (num) * (elemSize));
#endif
}

void _tt_free(void* ptr) {
#if (_MSC_VER >= 1700) // newer than Visual Studio 2012
    CoTaskMemFree(ptr);
#else
    HeapFree(GetProcessHeap(), 0, ptr);
#endif
}
#endif //WIN32

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    hashWithSha384
 * Signature: ([B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_hashWithSha256(JNIEnv* env, jobject jobj, jbyteArray p_toBeHashedData) {
    jbyteArray java_hashed_data;
    int32_t result;

    // Extract buffers
    size_t to_be_hashed_data_length = (*env)->GetArrayLength(env, p_toBeHashedData);
    uint8_t* to_be_hashed_data = (uint8_t*)calloc(sizeof(uint8_t), to_be_hashed_data_length);
    (*env)->GetByteArrayRegion(env, p_toBeHashedData, 0, (jsize)to_be_hashed_data_length, (jbyte*)to_be_hashed_data);
    // Call lib_its_security implementation
    uint8_t* hashed_data = NULL;
    result = hash_with_sha256(to_be_hashed_data, to_be_hashed_data_length, &hashed_data);
    // Prepare return value
    java_hashed_data = (*env)->NewByteArray(env, (jsize)32);
    if (result == 0) {
        (*env)->SetByteArrayRegion(env, java_hashed_data, 0, (jsize)32, (jbyte*)hashed_data);
    }
    // Free allocated resources
    free(hashed_data);

    return java_hashed_data;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    hashWithSha384
 * Signature: ([B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_hashWithSha384(JNIEnv* env, jobject jobj, jbyteArray p_toBeHashedData) {
    jbyteArray java_hashed_data;
    int32_t result;

    // Extract buffers
    size_t to_be_hashed_data_length = (*env)->GetArrayLength(env, p_toBeHashedData);
    uint8_t* to_be_hashed_data = (uint8_t*)calloc(sizeof(uint8_t), to_be_hashed_data_length);
    (*env)->GetByteArrayRegion(env, p_toBeHashedData, 0, (jsize)to_be_hashed_data_length, (jbyte*)to_be_hashed_data);
    // Call lib_its_security implementation
    uint8_t* hashed_data = NULL;
    result = hash_with_sha384(to_be_hashed_data, to_be_hashed_data_length, &hashed_data);
    // Prepare return value
    java_hashed_data = (*env)->NewByteArray(env, (jsize)48);
    if (result == 0) {
        (*env)->SetByteArrayRegion(env, java_hashed_data, 0, (jsize)48, (jbyte*)hashed_data);
    }
    // Free allocated resources
    free(hashed_data);

    return java_hashed_data;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    hmacWithSha256
 * Signature: ([B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_hmacWithSha256(JNIEnv* env, jobject jobj, jbyteArray p_secretKey, jbyteArray p_message) {
    jbyteArray java_hmac;
    int32_t result;

    // Extract buffers
    size_t secret_key_length = (*env)->GetArrayLength(env, p_secretKey);
    uint8_t* secret_key = (uint8_t*)calloc(sizeof(uint8_t), secret_key_length);
    (*env)->GetByteArrayRegion(env, p_secretKey, 0, (jsize)secret_key_length, (jbyte*)secret_key);
    size_t message_length = (*env)->GetArrayLength(env, p_message);
    uint8_t* message = (uint8_t*)calloc(sizeof(uint8_t), message_length);
    (*env)->GetByteArrayRegion(env, p_message, 0, (jsize)message_length, (jbyte*)message);

    // Call lib_its_security implementation
    uint8_t* hmac = NULL;
    result = hmac_sha256(secret_key, secret_key_length, message, message_length, &hmac);
    // Prepare return value
    java_hmac = (*env)->NewByteArray(env, (jsize)16); // HMAC with SHA256 of the message resized to 16 bytes
    if (result == 0) {
        (*env)->SetByteArrayRegion(env, java_hmac, 0, (jsize)16, (jbyte*)hmac);
    }
    // Free allocated resources
    free(secret_key);
    free(message);
    free(hmac);

    return java_hmac;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    signWithEcdsaNistp256WithSha256
 * Signature: ([B[B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_signed_secured_message, jbyteArray p_certificate_issuer, jbyteArray p_private_key) {
    jbyteArray java_signature = NULL;

    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256\n");

    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(nist_p_256, &lib_its_security_context);
    // fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: result=%d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t to_be_signed_secured_message_length = (*env)->GetArrayLength(env, p_to_be_signed_secured_message);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: to_be_signed_secured_message_length=%ld\n", to_be_signed_secured_message_length);
        uint8_t* to_be_signed_secured_message = (uint8_t*)calloc(sizeof(uint8_t), to_be_signed_secured_message_length);
        (*env)->GetByteArrayRegion(env, p_to_be_signed_secured_message, 0, (jsize)to_be_signed_secured_message_length, (jbyte*)to_be_signed_secured_message);
        size_t certificate_issuer_length = 32;//(*env)->GetArrayLength(env, p_certificate_issuer);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: certificate_issuer_length=%ld\n", certificate_issuer_length);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: certificate_issuer=%02x%02x%02x%02x%02x%02x\n", *certificate_issuer, *(certificate_issuer + 1), *(certificate_issuer + 2), *(certificate_issuer + 3), *(certificate_issuer + 4), *(certificate_issuer + 5));
        size_t private_key_length = (*env)->GetArrayLength(env, p_private_key);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: private_key_length=%ld\n", private_key_length);
        uint8_t* private_key = (uint8_t*)calloc(sizeof(uint8_t), private_key_length);
        (*env)->GetByteArrayRegion(env, p_private_key, 0, (jsize)private_key_length, (jbyte*)private_key);
        uint8_t* signature = NULL;
        result = sign_with_ecdsa_nistp256_with_sha256(lib_its_security_context, to_be_signed_secured_message, to_be_signed_secured_message_length, certificate_issuer, private_key, &signature);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_signWithEcdsaNistp256WithSha256: result=%d\n", result);
        if (result == 0) {
            // Prepare return value
            java_signature = (*env)->NewByteArray(env, (jsize)64);
            (*env)->SetByteArrayRegion(env, java_signature, 0, (jsize)64, (jbyte*)signature);
            // Free allocated resources
            free(signature);
        }
        free(to_be_signed_secured_message);
        free(certificate_issuer);
        free(private_key);
        uninitialize(&lib_its_security_context);
    }

    return java_signature;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    signWithEcdsaBrainpoolp256r1WithSha256
 * Signature: ([B[B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_signWithEcdsaBrainpoolp256r1WithSha256
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_signed_secured_message, jbyteArray p_certificate_issuer, jbyteArray p_private_key) {
    jbyteArray java_signature = NULL;

    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(brainpool_p_256_r1, &lib_its_security_context);
    if (result == 0) {
        // Extract buffers
        size_t to_be_signed_secured_message_length = (*env)->GetArrayLength(env, p_to_be_signed_secured_message);
        uint8_t* to_be_signed_secured_message = (uint8_t*)calloc(sizeof(uint8_t), to_be_signed_secured_message_length);
        (*env)->GetByteArrayRegion(env, p_to_be_signed_secured_message, 0, (jsize)to_be_signed_secured_message_length, (jbyte*)to_be_signed_secured_message);
        size_t certificate_issuer_length = (*env)->GetArrayLength(env, p_certificate_issuer);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
        size_t private_key_length = (*env)->GetArrayLength(env, p_private_key);
        uint8_t* private_key = (uint8_t*)calloc(sizeof(uint8_t), private_key_length);
        (*env)->GetByteArrayRegion(env, p_private_key, 0, (jsize)private_key_length, (jbyte*)private_key);
        uint8_t* signature = NULL;
        result = sign_with_ecdsa_brainpoolp256r1_with_sha256(lib_its_security_context, to_be_signed_secured_message, to_be_signed_secured_message_length, certificate_issuer, private_key, &signature);
        if (result == 0) {
            // Prepare return value
            java_signature = (*env)->NewByteArray(env, (jsize)64);
            (*env)->SetByteArrayRegion(env, java_signature, 0, (jsize)64, (jbyte*)signature);
            // Free allocated resources
            free(signature);
        }
        free(to_be_signed_secured_message);
        free(certificate_issuer);
        free(private_key);
        uninitialize(&lib_its_security_context);
    }

    return java_signature;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    signWithEcdsaBrainpoolp384r1WithSha384
 * Signature: ([B[B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_signWithEcdsaBrainpoolp384r1WithSha384
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_signed_secured_message, jbyteArray p_certificate_issuer, jbyteArray p_private_key) {
    jbyteArray java_signature = NULL;

    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(brainpool_p_384_r1, &lib_its_security_context);
    if (result == 0) {
        // Extract buffers
        size_t to_be_signed_secured_message_length = (*env)->GetArrayLength(env, p_to_be_signed_secured_message);
        uint8_t* to_be_signed_secured_message = (uint8_t*)calloc(sizeof(uint8_t), to_be_signed_secured_message_length);
        (*env)->GetByteArrayRegion(env, p_to_be_signed_secured_message, 0, (jsize)to_be_signed_secured_message_length, (jbyte*)to_be_signed_secured_message);
        size_t certificate_issuer_length = (*env)->GetArrayLength(env, p_certificate_issuer);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
        size_t private_key_length = (*env)->GetArrayLength(env, p_private_key);
        uint8_t* private_key = (uint8_t*)calloc(sizeof(uint8_t), private_key_length);
        (*env)->GetByteArrayRegion(env, p_private_key, 0, (jsize)private_key_length, (jbyte*)private_key);
        uint8_t* signature = NULL;
        result = sign_with_ecdsa_brainpoolp384r1_with_sha384(lib_its_security_context, to_be_signed_secured_message, to_be_signed_secured_message_length, certificate_issuer, private_key, &signature);
        if (result == 0) {
            // Prepare return value
            java_signature = (*env)->NewByteArray(env, (jsize)96);
            (*env)->SetByteArrayRegion(env, java_signature, 0, (jsize)96, (jbyte*)signature);
            // Free allocated resources
            free(signature);
        }
        free(to_be_signed_secured_message);
        free(certificate_issuer);
        free(private_key);
        uninitialize(&lib_its_security_context);
    }

    return java_signature;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    verifyWithEcdsaNistp256WithSha256
 * Signature: ([B[B[B[BI)I
 */
JNIEXPORT jint JNICALL Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_verified_data, jbyteArray p_certificate_issuer, jbyteArray p_signature, jbyteArray p_ecdsaNistp256PublicKeyCompressed, jint p_compressed_mode) {
    fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256\n");

    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(nist_p_256, &lib_its_security_context);
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: result=%d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t to_be_verified_data_length = (*env)->GetArrayLength(env, p_to_be_verified_data);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: to_be_verified_data_length=%ld\n", to_be_verified_data_length);
        uint8_t* to_be_verified_data = (uint8_t*)calloc(sizeof(uint8_t), to_be_verified_data_length);
        (*env)->GetByteArrayRegion(env, p_to_be_verified_data, 0, (jsize)to_be_verified_data_length, (jbyte*)to_be_verified_data);
        size_t certificate_issuer_length = (*env)->GetArrayLength(env, p_certificate_issuer);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: certificate_issuer_length=%ld\n", certificate_issuer_length);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
        size_t signature_length = (*env)->GetArrayLength(env, p_signature);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: signature_length=%ld\n", signature_length);
        uint8_t* signature = (uint8_t*)calloc(sizeof(uint8_t), signature_length);
        (*env)->GetByteArrayRegion(env, p_signature, 0, (jsize)signature_length, (jbyte*)signature);
        size_t compressed_key_length = (*env)->GetArrayLength(env, p_ecdsaNistp256PublicKeyCompressed);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: compressed_key_length=%ld\n", compressed_key_length);
        uint8_t* compressed_key = (uint8_t*)calloc(sizeof(uint8_t), compressed_key_length);
        (*env)->GetByteArrayRegion(env, p_ecdsaNistp256PublicKeyCompressed, 0, (jsize)compressed_key_length, (jbyte*)compressed_key);
        result = verify_with_ecdsa_nistp256_with_sha256(lib_its_security_context, to_be_verified_data, to_be_verified_data_length, certificate_issuer, signature, compressed_key, (int32_t)p_compressed_mode);
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaNistp256WithSha256: result=%d\n", result);
        free(to_be_verified_data);
        free(certificate_issuer);
        free(signature);
        free(compressed_key);
        uninitialize(&lib_its_security_context);
    }

    return (jint)result;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    verifyWithEcdsaBrainpoolp256r1WithSha256
 * Signature: ([B[B[B[BI)I
 */
JNIEXPORT jint JNICALL Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaBrainpoolp256r1WithSha256
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_verified_data, jbyteArray p_certificate_issuer, jbyteArray p_signature, jbyteArray p_ecdsaNistp256PublicKeyCompressed, jint p_compressed_mode) {
    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(brainpool_p_256_r1, &lib_its_security_context);
    if (result == 0) {
        // Extract buffers
        size_t to_be_verified_data_length = (*env)->GetArrayLength(env, p_to_be_verified_data);
        uint8_t* to_be_verified_data = (uint8_t*)calloc(sizeof(uint8_t), to_be_verified_data_length);
        (*env)->GetByteArrayRegion(env, p_to_be_verified_data, 0, (jsize)to_be_verified_data_length, (jbyte*)to_be_verified_data);
        size_t certificate_issuer_length = (*env)->GetArrayLength(env, p_certificate_issuer);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
        size_t signature_length = (*env)->GetArrayLength(env, p_signature);
        uint8_t* signature = (uint8_t*)calloc(sizeof(uint8_t), signature_length);
        (*env)->GetByteArrayRegion(env, p_signature, 0, (jsize)signature_length, (jbyte*)signature);
        size_t compressed_key_length = (*env)->GetArrayLength(env, p_ecdsaNistp256PublicKeyCompressed);
        uint8_t* compressed_key = (uint8_t*)calloc(sizeof(uint8_t), compressed_key_length);
        (*env)->GetByteArrayRegion(env, p_ecdsaNistp256PublicKeyCompressed, 0, (jsize)compressed_key_length, (jbyte*)compressed_key);
        result = verify_with_ecdsa_brainpoolp256r1_with_sha256(lib_its_security_context, to_be_verified_data, to_be_verified_data_length, certificate_issuer, signature, compressed_key, (int32_t)p_compressed_mode);
        free(to_be_verified_data);
        free(certificate_issuer);
        free(signature);
        free(compressed_key);
        uninitialize(&lib_its_security_context);
    }

    return (jint)result;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    fx_verifyWithEcdsaBrainpoolp384r1WithSha384
 * Signature: ([B[B[B[BI)I
 */
JNIEXPORT jint JNICALL Java_org_etsi_its_security_NativeSecurity_verifyWithEcdsaBrainpoolp384r1WithSha384
(JNIEnv* env, jobject jobj, jbyteArray p_to_be_verified_data, jbyteArray p_certificate_issuer, jbyteArray p_signature, jbyteArray p_ecdsaNistp384PublicKeyCompressed, jint p_compressed_mode) {
    // Create intermal context
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(brainpool_p_384_r1, &lib_its_security_context);
    if (result == 0) {
        // Extract buffers
        size_t to_be_verified_data_length = (*env)->GetArrayLength(env, p_to_be_verified_data);
        uint8_t* to_be_verified_data = (uint8_t*)calloc(sizeof(uint8_t), to_be_verified_data_length);
        (*env)->GetByteArrayRegion(env, p_to_be_verified_data, 0, (jsize)to_be_verified_data_length, (jbyte*)to_be_verified_data);
        size_t certificate_issuer_length = (*env)->GetArrayLength(env, p_certificate_issuer);
        uint8_t* certificate_issuer = (uint8_t*)calloc(sizeof(uint8_t), certificate_issuer_length);
        (*env)->GetByteArrayRegion(env, p_certificate_issuer, 0, (jsize)certificate_issuer_length, (jbyte*)certificate_issuer);
        size_t signature_length = (*env)->GetArrayLength(env, p_signature);
        uint8_t* signature = (uint8_t*)calloc(sizeof(uint8_t), signature_length);
        (*env)->GetByteArrayRegion(env, p_signature, 0, (jsize)signature_length, (jbyte*)signature);
        size_t compressed_key_length = (*env)->GetArrayLength(env, p_ecdsaNistp384PublicKeyCompressed);
        uint8_t* compressed_key = (uint8_t*)calloc(sizeof(uint8_t), compressed_key_length);
        (*env)->GetByteArrayRegion(env, p_ecdsaNistp384PublicKeyCompressed, 0, (jsize)compressed_key_length, (jbyte*)compressed_key);
        result = verify_with_ecdsa_brainpoolp384r1_with_sha384(lib_its_security_context, to_be_verified_data, to_be_verified_data_length, certificate_issuer, signature, compressed_key, (int32_t)p_compressed_mode);
        free(to_be_verified_data);
        free(certificate_issuer);
        free(signature);
        free(compressed_key);
        uninitialize(&lib_its_security_context);
    }

    return (jint)result;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    generate_key_pair
 * Signature: (ILjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)I
 */
JNIEXPORT jint JNICALL Java_org_etsi_its_security_NativeSecurity_generate_1key_1pair(JNIEnv* env, jobject jobj, jint p_eccEllipticCurve, jobject p_private_key, jobject p_public_key_x, jobject p_public_key_y, jobject p_public_key_compressed) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_generate_1key_1pair_1\n");

    lib_its_security_context_t* lib_its_security_context = NULL;
    size_t length = 32;
    int32_t result = 0;
    switch ((int)p_eccEllipticCurve) {
    case 0: // Nist P256
        result = initialize(nist_p_256, &lib_its_security_context);
        break;
    case 1: // Brainpool P256 r1
        result = initialize(brainpool_p_256_r1, &lib_its_security_context);
        break;
    case 2: // Brainpool P384 r1
        result = initialize(brainpool_p_384_r1, &lib_its_security_context);
        length = 48;
        break;
    }
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_generate_1key_1pair_1: result=%d\n", result);
    if (result == 0) {
        uint8_t* private_key = NULL;
        uint8_t* public_key_x = NULL;
        uint8_t* public_key_y = NULL;
        uint8_t* public_key_compressed = NULL;
        ecc_compressed_mode_t public_key_compressed_mode;
        result = generate_key_pair(lib_its_security_context, &private_key, &public_key_x, &public_key_y, &public_key_compressed, &public_key_compressed_mode);
Yann Garcia's avatar
Yann Garcia committed
        //        fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_generate_1key_1pair_1: result=%d\n", result);
        if (result == 0) {
            // Copy all keys into Java buffers, assumimng the allocated memory is correct ;)
            uint8_t* p = (*env)->GetDirectBufferAddress(env, p_private_key);
            for (size_t i = 0; i < length; i++) {
                *p++ = *(private_key + i);
            }
            free(private_key);
            p = (*env)->GetDirectBufferAddress(env, p_public_key_x);
            for (size_t i = 0; i < length; i++) {
                *p++ = *(public_key_x + i);
            }
            free(public_key_x);
            p = (*env)->GetDirectBufferAddress(env, p_public_key_y);
            for (size_t i = 0; i < length; i++) {
                *p++ = *(public_key_y + i);
            }
            free(public_key_y);
            p = (*env)->GetDirectBufferAddress(env, p_public_key_compressed);
            fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_generate_1key_1pair_1: public_key_compressed_mode=%d\n", public_key_compressed_mode);
            *p++ = (public_key_compressed_mode == compressed_y_0) ? 0x02 : 0x03;
            for (size_t i = 0; i < length; i++) {
                *p++ = *(public_key_compressed + i);
            }
            free(public_key_compressed);
        }
    }
    uninitialize(&lib_its_security_context);

    return (jint)result;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    encrypt_with_ecies_nistp256_with_sha256
 * Signature: ([B[B[BLjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256(JNIEnv* env, jobject jobj, jbyteArray p_toBeEncryptedSecuredMessage, jbyteArray p_recipientsPublicKeyCompressed, jbyteArray p_salt, jobject p_public_ephemeral_key_compressed, jobject p_aes_sym_key, jobject p_encrypted_sym_key, jobject p_authentication_vector, jobject p_nonce) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256\n");

    jbyteArray java_ciphered_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    // Extract the recipient's public keys
    size_t compressed_key_length = (*env)->GetArrayLength(env, p_recipientsPublicKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: compressed_key_length = %zd\n", compressed_key_length);
    uint8_t* compressed_key = (uint8_t*)calloc(sizeof(uint8_t), compressed_key_length);
    (*env)->GetByteArrayRegion(env, p_recipientsPublicKeyCompressed, 0, (jsize)compressed_key_length, (jbyte*)compressed_key);
    ecc_compressed_mode_t compressed_mode = (ecc_compressed_mode_t)(*compressed_key);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: compressed_mode = %d\n", compressed_mode);
    int32_t result = initialize_with_public_key(nist_p_256, compressed_key + 1, compressed_mode, &lib_its_security_context);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: result = %d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t plain_text_message_length = (*env)->GetArrayLength(env, p_toBeEncryptedSecuredMessage);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: plain_text_message_length = %zd\n", plain_text_message_length);
        uint8_t* plain_text_message = (uint8_t*)calloc(sizeof(uint8_t), plain_text_message_length);
        (*env)->GetByteArrayRegion(env, p_toBeEncryptedSecuredMessage, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
        size_t salt_length = (*env)->GetArrayLength(env, p_salt);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: salt_length = %zd\n", salt_length);
        uint8_t* salt = (uint8_t*)calloc(sizeof(uint8_t), salt_length);
        (*env)->GetByteArrayRegion(env, p_salt, 0, (jsize)salt_length, (jbyte*)salt);
        uint8_t* ephemeral_key_compressed = NULL;
        ecc_compressed_mode_t ephemeral_compressed_mode = compressed_y_0;
        uint8_t* aes_sym_key = NULL;
        uint8_t* encrypted_sym_key = NULL;
        uint8_t* authentication_vector = NULL;
        uint8_t* nonce = NULL;
        uint8_t* ciphered_message = NULL;
        size_t ciphered_message_length = 0;
        result = encrypt_with_ecies_nistp256_with_sha256(lib_its_security_context/*recipient's public keys*/, plain_text_message, plain_text_message_length, lib_its_security_context->public_key_c, lib_its_security_context->compressed_mode, salt, salt_length, &ephemeral_key_compressed, &ephemeral_compressed_mode, &aes_sym_key, &encrypted_sym_key, &authentication_vector, &nonce, &ciphered_message, &ciphered_message_length);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: result = %d\n", result);
        if (result == 0) {
            // Copy encryption information into Java buffers, assumimng the allocated memory is correct ;)
Yann Garcia's avatar
Yann Garcia committed
            //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: ephemeral_compressed_mode = %d\n", ephemeral_compressed_mode);
            uint8_t* p = (*env)->GetDirectBufferAddress(env, p_public_ephemeral_key_compressed);
            *p++ = (ephemeral_compressed_mode == compressed_y_0) ? 0x02 : 0x03;
            for (size_t i = 0; i < 32; i++) {
                *p++ = *(ephemeral_key_compressed + i);
            }
            free(ephemeral_key_compressed);
            p = (*env)->GetDirectBufferAddress(env, p_aes_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(aes_sym_key + i);
            }
            free(aes_sym_key);
            p = (*env)->GetDirectBufferAddress(env, p_encrypted_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(encrypted_sym_key + i);
            }
            free(encrypted_sym_key);
            p = (*env)->GetDirectBufferAddress(env, p_authentication_vector);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(authentication_vector + i);
            }
            free(authentication_vector);
            p = (*env)->GetDirectBufferAddress(env, p_nonce);
            for (size_t i = 0; i < 12; i++) {
                *p++ = *(nonce + i);
            }
            free(nonce);
            // Prepare return value
Yann Garcia's avatar
Yann Garcia committed
            //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1nistp256_1with_1sha256: result = %d\n", (jsize)ciphered_message_length);
            java_ciphered_message = (*env)->NewByteArray(env, (jsize)ciphered_message_length);
            (*env)->SetByteArrayRegion(env, java_ciphered_message, 0, (jsize)ciphered_message_length, (jbyte*)ciphered_message);
            // Free allocated resources
            free(ciphered_message);
        }
        free(compressed_key);
        free(plain_text_message);
        free(salt);
        uninitialize(&lib_its_security_context);
    }

    return java_ciphered_message;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    encrypt_with_ecies_brainpoolp256r1_with_sha256
 * Signature: ([B[B[BLjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256(JNIEnv* env, jobject jobj, jbyteArray p_toBeEncryptedSecuredMessage, jbyteArray p_recipientsPublicKeyCompressed, jbyteArray p_salt, jobject p_public_ephemeral_key_compressed, jobject p_aes_sym_key, jobject p_encrypted_sym_key, jobject p_authentication_vector, jobject p_nonce) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256\n");

    jbyteArray java_ciphered_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    // Extract the recipient's public keys
    size_t compressed_key_length = (*env)->GetArrayLength(env, p_recipientsPublicKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: compressed_key_length = %zd\n", compressed_key_length);
    uint8_t* compressed_key = (uint8_t*)calloc(sizeof(uint8_t), compressed_key_length);
    (*env)->GetByteArrayRegion(env, p_recipientsPublicKeyCompressed, 0, (jsize)compressed_key_length, (jbyte*)compressed_key);
    ecc_compressed_mode_t compressed_mode = (ecc_compressed_mode_t)(*compressed_key);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: compressed_mode = %d\n", compressed_mode);
    int32_t result = initialize_with_public_key(brainpool_p_256_r1, compressed_key + 1, compressed_mode, &lib_its_security_context);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: result = %d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t plain_text_message_length = (*env)->GetArrayLength(env, p_toBeEncryptedSecuredMessage);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: plain_text_message_length = %zd\n", plain_text_message_length);
        uint8_t* plain_text_message = (uint8_t*)calloc(sizeof(uint8_t), plain_text_message_length);
        (*env)->GetByteArrayRegion(env, p_toBeEncryptedSecuredMessage, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
        size_t salt_length = (*env)->GetArrayLength(env, p_salt);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: salt_length = %zd\n", salt_length);
        uint8_t* salt = (uint8_t*)calloc(sizeof(uint8_t), salt_length);
        (*env)->GetByteArrayRegion(env, p_salt, 0, (jsize)salt_length, (jbyte*)salt);
        uint8_t* ephemeral_key_compressed = NULL;
        ecc_compressed_mode_t ephemeral_compressed_mode = compressed_y_0;
        uint8_t* aes_sym_key = NULL;
        uint8_t* encrypted_sym_key = NULL;
        uint8_t* authentication_vector = NULL;
        uint8_t* nonce = NULL;
        uint8_t* ciphered_message = NULL;
        size_t ciphered_message_length = 0;
        result = encrypt_with_ecies_brainpoolp256r1_with_sha256(lib_its_security_context/*recipient's public keys*/, plain_text_message, plain_text_message_length, lib_its_security_context->public_key_c, lib_its_security_context->compressed_mode, salt, salt_length, &ephemeral_key_compressed, &ephemeral_compressed_mode, &aes_sym_key, &encrypted_sym_key, &authentication_vector, &nonce, &ciphered_message, &ciphered_message_length);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: result = %d\n", result);
        if (result == 0) {
            // Copy encryption information into Java buffers, assumimng the allocated memory is correct ;)
            uint8_t* p = (*env)->GetDirectBufferAddress(env, p_public_ephemeral_key_compressed);
            *p = (ephemeral_compressed_mode == compressed_y_0) ? 0x02 : 0x03;
            for (size_t i = 0; i < 32; i++) {
                *p++ = *(ephemeral_key_compressed + i);
            }
            free(ephemeral_key_compressed);
            p = (*env)->GetDirectBufferAddress(env, p_aes_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(aes_sym_key + i);
            }
            free(aes_sym_key);
            p = (*env)->GetDirectBufferAddress(env, p_encrypted_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(encrypted_sym_key + i);
            }
            free(encrypted_sym_key);
            p = (*env)->GetDirectBufferAddress(env, p_authentication_vector);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(authentication_vector + i);
            }
            free(authentication_vector);
            p = (*env)->GetDirectBufferAddress(env, p_nonce);
            for (size_t i = 0; i < 12; i++) {
                *p++ = *(nonce + i);
            }
            free(nonce);
            // Prepare return value
            java_ciphered_message = (*env)->NewByteArray(env, (jsize)ciphered_message_length);
            (*env)->SetByteArrayRegion(env, java_ciphered_message, 0, (jsize)ciphered_message_length, (jbyte*)ciphered_message);
            // Free allocated resources
            free(ciphered_message);
        }
        free(compressed_key);
        free(plain_text_message);
        free(salt);
        uninitialize(&lib_its_security_context);
    }

    return java_ciphered_message;
}
/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    decrypt_with_ecies_nistp256_with_sha256
 * Signature: ([B[B[B[B[B[B[BLjava/nio/ByteBuffer;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256(JNIEnv* env, jobject jobj, jbyteArray p_encryptedSecuredMessage, jbyteArray p_privateEncKey, jbyteArray p_publicEphemeralKeyCompressed, jbyteArray p_encrypted_sym_key, jbyteArray p_authentication_vector, jbyteArray p_nonce, jbyteArray p_salt, jobject p_aes_enc_sym_key) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256\n");

    jbyteArray java_plain_text_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    // Extract the recipient's private key
    size_t recipient_private_key_length = (*env)->GetArrayLength(env, p_privateEncKey);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: recipient_private_key_length = %zd\n", recipient_private_key_length);
    uint8_t* recipient_private_key = (uint8_t*)calloc(sizeof(uint8_t), recipient_private_key_length);
    (*env)->GetByteArrayRegion(env, p_privateEncKey, 0, (jsize)recipient_private_key_length, (jbyte*)recipient_private_key);
    int32_t result = initialize_with_private_key(nist_p_256, recipient_private_key, &lib_its_security_context);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: result = %d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t encrypted_secured_message_length = (*env)->GetArrayLength(env, p_encryptedSecuredMessage);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: encrypted_secured_message_length = %zd\n", encrypted_secured_message_length);
        uint8_t* encrypted_secured_message = (uint8_t*)calloc(sizeof(uint8_t), encrypted_secured_message_length);
        (*env)->GetByteArrayRegion(env, p_encryptedSecuredMessage, 0, (jsize)encrypted_secured_message_length, (jbyte*)encrypted_secured_message);
        size_t ephemeral_key_compressed_length = (*env)->GetArrayLength(env, p_publicEphemeralKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: compressed_key_length = %zd\n", ephemeral_key_compressed_length);
        uint8_t* ephemeral_key_compressed = (uint8_t*)calloc(sizeof(uint8_t), ephemeral_key_compressed_length);
        (*env)->GetByteArrayRegion(env, p_publicEphemeralKeyCompressed, 0, (jsize)ephemeral_key_compressed_length, (jbyte*)ephemeral_key_compressed);
        ecc_compressed_mode_t ephemeral_compressed_mode = (ecc_compressed_mode_t)(*ephemeral_key_compressed);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: ephemeral_compressed_mode = %d\n", ephemeral_compressed_mode);
        size_t encrypted_sym_key_length = (*env)->GetArrayLength(env, p_encrypted_sym_key);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: encrypted_sym_key_length = %zd\n", encrypted_sym_key_length);
        uint8_t* encrypted_sym_key = (uint8_t*)calloc(sizeof(uint8_t), encrypted_sym_key_length);
        (*env)->GetByteArrayRegion(env, p_encrypted_sym_key, 0, (jsize)encrypted_sym_key_length, (jbyte*)encrypted_sym_key);
        size_t authentication_vector_length = (*env)->GetArrayLength(env, p_authentication_vector);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: authentication_vector_length = %zd\n", authentication_vector_length);
        uint8_t* authentication_vector = (uint8_t*)calloc(sizeof(uint8_t), authentication_vector_length);
        (*env)->GetByteArrayRegion(env, p_authentication_vector, 0, (jsize)authentication_vector_length, (jbyte*)authentication_vector);
        size_t nonce_length = (*env)->GetArrayLength(env, p_nonce);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: nonce_length = %zd\n", nonce_length);
        uint8_t* nonce = (uint8_t*)calloc(sizeof(uint8_t), nonce_length);
        (*env)->GetByteArrayRegion(env, p_nonce, 0, (jsize)nonce_length, (jbyte*)nonce);
        size_t salt_length = (*env)->GetArrayLength(env, p_salt);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1nistp256_1with_1sha256: salt_length = %zd\n", salt_length);
        uint8_t* salt = (uint8_t*)calloc(sizeof(uint8_t), salt_length);
        (*env)->GetByteArrayRegion(env, p_salt, 0, (jsize)salt_length, (jbyte*)salt);
        size_t plain_text_message_length = 0;
        uint8_t* plain_text_message = NULL;
        uint8_t* aes_enc_sym_key = NULL;
        result = decrypt_with_ecies_nistp256_with_sha256(lib_its_security_context, encrypted_secured_message, encrypted_secured_message_length, lib_its_security_context->private_key, ephemeral_key_compressed + 1, ephemeral_compressed_mode, encrypted_sym_key, authentication_vector, nonce, salt, salt_length, &aes_enc_sym_key, &plain_text_message, &plain_text_message_length);
        if (result == 0) {
            uint8_t* p = (*env)->GetDirectBufferAddress(env, p_aes_enc_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(aes_enc_sym_key + i);
            }
            free(aes_enc_sym_key);
            // Prepare return value
            java_plain_text_message = (*env)->NewByteArray(env, (jsize)plain_text_message_length);
            (*env)->SetByteArrayRegion(env, java_plain_text_message, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
            // Free allocated resources
            free(plain_text_message);
        }
        free(recipient_private_key);
        free(ephemeral_key_compressed);
        free(encrypted_sym_key);
        free(authentication_vector);
        free(nonce);
        free(salt);
        uninitialize(&lib_its_security_context);
    }

    return java_plain_text_message;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    decrypt_with_ecies_brainpoolp256r1_with_sha256
 * Signature: ([B[B[B[B[B[B[BLjava/nio/ByteBuffer;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256(JNIEnv* env, jobject jobj, jbyteArray p_encryptedSecuredMessage, jbyteArray p_privateEncKey, jbyteArray p_publicEphemeralKeyCompressed, jbyteArray p_encrypted_sym_key, jbyteArray p_authentication_vector, jbyteArray p_nonce, jbyteArray p_salt, jobject p_aes_enc_sym_key) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256\n");

    jbyteArray java_plain_text_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    // Extract the recipient's private key
    size_t recipient_private_key_length = (*env)->GetArrayLength(env, p_privateEncKey);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: recipient_private_key_length = %zd\n", recipient_private_key_length);
    uint8_t* recipient_private_key = (uint8_t*)calloc(sizeof(uint8_t), recipient_private_key_length);
    (*env)->GetByteArrayRegion(env, p_privateEncKey, 0, (jsize)recipient_private_key_length, (jbyte*)recipient_private_key);
    int32_t result = initialize_with_private_key(brainpool_p_256_r1, recipient_private_key, &lib_its_security_context);
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: result = %d\n", result);
    if (result == 0) {
        // Extract buffers
        size_t encrypted_secured_message_length = (*env)->GetArrayLength(env, p_encryptedSecuredMessage);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: encrypted_secured_message_length = %zd\n", encrypted_secured_message_length);
        uint8_t* encrypted_secured_message = (uint8_t*)calloc(sizeof(uint8_t), encrypted_secured_message_length);
        (*env)->GetByteArrayRegion(env, p_encryptedSecuredMessage, 0, (jsize)encrypted_secured_message_length, (jbyte*)encrypted_secured_message);
        size_t ephemeral_key_compressed_length = (*env)->GetArrayLength(env, p_publicEphemeralKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: compressed_key_length = %zd\n", ephemeral_key_compressed_length);
        uint8_t* ephemeral_key_compressed = (uint8_t*)calloc(sizeof(uint8_t), ephemeral_key_compressed_length);
        (*env)->GetByteArrayRegion(env, p_publicEphemeralKeyCompressed, 0, (jsize)ephemeral_key_compressed_length, (jbyte*)ephemeral_key_compressed);
        ecc_compressed_mode_t ephemeral_compressed_mode = (ecc_compressed_mode_t)(*ephemeral_key_compressed);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: ephemeral_compressed_mode = %d\n", ephemeral_compressed_mode);
        size_t encrypted_sym_key_length = (*env)->GetArrayLength(env, p_encrypted_sym_key);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: encrypted_sym_key_length = %zd\n", encrypted_sym_key_length);
        uint8_t* encrypted_sym_key = (uint8_t*)calloc(sizeof(uint8_t), encrypted_sym_key_length);
        (*env)->GetByteArrayRegion(env, p_encrypted_sym_key, 0, (jsize)encrypted_sym_key_length, (jbyte*)encrypted_sym_key);
        size_t authentication_vector_length = (*env)->GetArrayLength(env, p_authentication_vector);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: authentication_vector_length = %zd\n", authentication_vector_length);
        uint8_t* authentication_vector = (uint8_t*)calloc(sizeof(uint8_t), authentication_vector_length);
        (*env)->GetByteArrayRegion(env, p_authentication_vector, 0, (jsize)authentication_vector_length, (jbyte*)authentication_vector);
        size_t nonce_length = (*env)->GetArrayLength(env, p_nonce);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: nonce_length = %zd\n", nonce_length);
        uint8_t* nonce = (uint8_t*)calloc(sizeof(uint8_t), nonce_length);
        (*env)->GetByteArrayRegion(env, p_nonce, 0, (jsize)nonce_length, (jbyte*)nonce);
        size_t salt_length = (*env)->GetArrayLength(env, p_salt);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1with_1ecies_1brainpoolp256r1_1with_1sha256: salt_length = %zd\n", salt_length);
        uint8_t* salt = (uint8_t*)calloc(sizeof(uint8_t), salt_length);
        (*env)->GetByteArrayRegion(env, p_salt, 0, (jsize)salt_length, (jbyte*)salt);
        size_t plain_text_message_length = 0;
        uint8_t* plain_text_message = NULL;
        uint8_t* aes_enc_sym_key = NULL;
        result = decrypt_with_ecies_brainpoolp256r1_with_sha256(lib_its_security_context, encrypted_secured_message, encrypted_secured_message_length, lib_its_security_context->private_key, ephemeral_key_compressed + 1, ephemeral_compressed_mode, encrypted_sym_key, authentication_vector, nonce, salt, salt_length, &aes_enc_sym_key, &plain_text_message, &plain_text_message_length);
        if (result == 0) {
            uint8_t* p = (*env)->GetDirectBufferAddress(env, p_aes_enc_sym_key);
            for (size_t i = 0; i < 16; i++) {
                *p++ = *(aes_enc_sym_key + i);
            }
            free(aes_enc_sym_key);
            // Prepare return value
            java_plain_text_message = (*env)->NewByteArray(env, (jsize)plain_text_message_length);
            (*env)->SetByteArrayRegion(env, java_plain_text_message, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
            // Free allocated resources
            free(plain_text_message);
        }
        free(recipient_private_key);
        free(ephemeral_key_compressed);
        free(encrypted_sym_key);
        free(authentication_vector);
        free(nonce);
        free(salt);
        uninitialize(&lib_its_security_context);
    }

    return java_plain_text_message;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    encrypt_aes_128_ccm_test
 * Signature: ([B[B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test(JNIEnv* env, jobject jobj, jbyteArray p_k, jbyteArray p_n, jbyteArray p_pt) {
    fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test\n");

    jbyteArray java_ciphered_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(nist_p_256, &lib_its_security_context);
    if (result == 0) {
        lib_its_security_context->encryption_algorithm = aes_128_ccm;

        // Extract buffers
        lib_its_security_context->sym_key_length = (*env)->GetArrayLength(env, p_k);
        fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test: sym_key_length = %zd\n", lib_its_security_context->sym_key_length);
        lib_its_security_context->sym_key = (uint8_t*)calloc(sizeof(uint8_t), lib_its_security_context->sym_key_length);
        (*env)->GetByteArrayRegion(env, p_k, 0, (jsize)lib_its_security_context->sym_key_length, (jbyte*)lib_its_security_context->sym_key);
        lib_its_security_context->nonce_length = (*env)->GetArrayLength(env, p_n);
        fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test: nonce_length = %zd\n", lib_its_security_context->nonce_length);
        lib_its_security_context->nonce = (uint8_t*)calloc(sizeof(uint8_t), lib_its_security_context->nonce_length);
        (*env)->GetByteArrayRegion(env, p_n, 0, (jsize)lib_its_security_context->nonce_length, (jbyte*)lib_its_security_context->nonce);
        size_t plain_text_message_length = (*env)->GetArrayLength(env, p_pt);
        fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test: plain_text_message_length = %zd\n", plain_text_message_length);
        uint8_t* plain_text_message = (uint8_t*)calloc(sizeof(uint8_t), plain_text_message_length);
        (*env)->GetByteArrayRegion(env, p_pt, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
        size_t encrypted_secured_message_length = 0;
        uint8_t* encrypted_secured_message = NULL;
        result = encrypt_(lib_its_security_context, plain_text_message, plain_text_message_length, &encrypted_secured_message, &encrypted_secured_message_length);
Yann Garcia's avatar
Yann Garcia committed
        fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_encrypt_1aes_1128_1ccm_1test: result = %d\n", result);
        if (result == 0) {
            // Prepare return value
Yann Garcia's avatar
Yann Garcia committed
            java_ciphered_message = (*env)->NewByteArray(env, (jsize)encrypted_secured_message_length + lib_its_security_context->tag_length);
            (*env)->SetByteArrayRegion(env, java_ciphered_message, 0, (jsize)encrypted_secured_message_length, (jbyte*)encrypted_secured_message);
Yann Garcia's avatar
Yann Garcia committed
            (*env)->SetByteArrayRegion(env, java_ciphered_message, encrypted_secured_message_length, (jsize)lib_its_security_context->tag_length, (jbyte*)lib_its_security_context->tag);
            // Free allocated resources
            free(encrypted_secured_message);
        }
        // Free allocated resources
        free(plain_text_message);
        uninitialize(&lib_its_security_context);
    }

    return java_ciphered_message;
}

/*
 * Class:     org_etsi_its_security_NativeSecurity
 * Method:    decrypt_aes_128_ccm_test
 * Signature: ([B[B[B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test(JNIEnv* env, jobject jobj, jbyteArray p_k, jbyteArray p_n, jbyteArray p_ct) {
Yann Garcia's avatar
Yann Garcia committed
    //fprintf(stderr, ">>> Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test\n");

    jbyteArray java_plain_text_message = NULL;
    lib_its_security_context_t* lib_its_security_context = NULL;
    int32_t result = initialize(nist_p_256, &lib_its_security_context);
    if (result == 0) {
        lib_its_security_context->encryption_algorithm = aes_128_ccm;

        // Extract buffers
        lib_its_security_context->sym_key_length = (*env)->GetArrayLength(env, p_k);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test: sym_key_length= %zd\n", lib_its_security_context->sym_key_length);
        lib_its_security_context->sym_key = (uint8_t*)calloc(sizeof(uint8_t), lib_its_security_context->sym_key_length);
        (*env)->GetByteArrayRegion(env, p_k, 0, (jsize)lib_its_security_context->sym_key_length, (jbyte*)lib_its_security_context->sym_key);
        lib_its_security_context->nonce_length = (*env)->GetArrayLength(env, p_n);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test: nonce_length= %zd\n", lib_its_security_context->nonce_length);
        lib_its_security_context->nonce = (uint8_t*)calloc(sizeof(uint8_t), lib_its_security_context->nonce_length);
        (*env)->GetByteArrayRegion(env, p_n, 0, (jsize)lib_its_security_context->nonce_length, (jbyte*)lib_its_security_context->nonce);
        size_t encrypted_secured_message_length = (*env)->GetArrayLength(env, p_ct) - 16; // Extract the tag from the ciphered message
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test: encrypted_secured_message_length= %zd\n", encrypted_secured_message_length);
        uint8_t* encrypted_secured_message = (uint8_t*)calloc(sizeof(uint8_t), encrypted_secured_message_length); // Extract the ciphered message
        (*env)->GetByteArrayRegion(env, p_ct, 0, (jsize)encrypted_secured_message_length, (jbyte*)encrypted_secured_message);
        lib_its_security_context->tag_length = 16; // Extract the tag
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test: tag_length= %zd\n", lib_its_security_context->tag_length);
        lib_its_security_context->tag = (uint8_t*)calloc(sizeof(uint8_t), lib_its_security_context->tag_length);
        (*env)->GetByteArrayRegion(env, p_ct, encrypted_secured_message_length, (jsize)lib_its_security_context->tag_length, (jbyte*)lib_its_security_context->tag);
        size_t plain_text_message_length;
        uint8_t* plain_text_message = NULL;
        result = decrypt(lib_its_security_context, encrypted_secured_message, encrypted_secured_message_length, &plain_text_message, &plain_text_message_length);
Yann Garcia's avatar
Yann Garcia committed
        //fprintf(stderr, "Java_org_etsi_its_security_NativeSecurity_decrypt_1aes_1128_1ccm_1test: result= %d\n", result);
        if (result == 0) {
            // Prepare return value
            java_plain_text_message = (*env)->NewByteArray(env, (jsize)plain_text_message_length);
            (*env)->SetByteArrayRegion(env, java_plain_text_message, 0, (jsize)plain_text_message_length, (jbyte*)plain_text_message);
            // Free allocated resources
            free(plain_text_message);
        }
        // Free allocated resources
        free(encrypted_secured_message);
        uninitialize(&lib_its_security_context);
    }

    return java_plain_text_message;
}