OpenSSL error 2406C06E

Dear All,
I have been working on the development of Trusted Applications on Trusty TEE (using Jetson AGX Xavier). I am extending the basic functionalities of crypto-service from Hwkey-agent to encrypt and decrypt ciphers using RSA keys. But, when I call OpenSSL::RSA_private_decrypt or OpensSSL::RSA_private_encrypt they generate the following error:

error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy

My Trusted Application are cross-compiled with OpenSSL 1.1.1g.

Here is the code I am using:

#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>

int padding = RSA_PKCS1_PADDING;
static char publicKey[] = "-----BEGIN PUBLIC KEY-----\n"
						  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"
						  "..."
						  "-----END PUBLIC KEY-----\n";

static char privateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n"
						   "MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"
						   "..."
						   "-----END RSA PRIVATE KEY-----\n";
static RSA *createRSA(char *key, int pubtype)
{
	RSA *rsa = NULL;
	BIO *bio = NULL;

	bio = BIO_new(BIO_s_mem());
	if (bio == NULL)
	{
		TLOGI("bio is NULL!\n");
	}

	BIO_puts(bio, key);
	if (pubtype == 1)
	{
		rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
	}
	else
	{
		rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	}
	if (rsa == NULL)
	{
		TLOGI("wrong again\n");
	}
	BIO_free(bio);
	return rsa;
}
static int private_decrypt(unsigned char *enc_data, int data_len, char *key, unsigned char *decrypted)
{
	RSA *rsa = createRSA(key, 0);
	if (rsa != NULL)
	{
		int result = RSA_private_decrypt(data_len, enc_data, decrypted, rsa, RSA_PKCS1_PADDING);
		RSA_free(rsa);
		return result;
	}
	return 0;
}
int public_encrypt(unsigned char *data, int data_len, char *key, unsigned char *encrypted)
{
	RSA *rsa = createRSA(key, 1);
	if (rsa != NULL)
	{
		int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);
		RSA_free(rsa);
		return result;
	}
	return 0;
}

void crypto_srv_process_req(iovec_t *ipc_msg, int len)
{
	crypto_srv_msg_t *msg = ipc_msg[0].base;
	uint8_t *payload = ipc_msg[1].base;
	int payload_len = msg->payload_len;
	uint8_t *data = NULL;
	uint8_t *key_in_ekb;
	unsigned long err;

	key_in_ekb = ekb_get_key(EKB_USER_KEY_DISK_ENCRYPTION);
	if (key_in_ekb == NULL)
	{
		TLOGE("%s: get key in ekb failed\n", __func__);
		return;
	}

	data = malloc(CRYPTO_SRV_PAYLOAD_SIZE);
	if (data == NULL)
	{
		TLOGE("%s: malloc failed\n", __func__);
		return;
	}
	memcpy(data, payload, payload_len);
	if (msg->cmd == CRYPTO_SRV_CMD_ENCRYPT)
	{
		int size_ = public_encrypt(data, 1, publicKey, payload);
		msg->cmd = size_ #debug output to see if the encryption was succesful
	}
	else
	{
		int size_ = private_decrypt(data, 1, privateKey, payload);
		msg->cmd = size_ #debug output to see if the decryption was succesful
	}
	free(data);
}

Result:

After flashing and running the application inside Xavier. I see that the result of the encryption/decryption (I write it to a file after getting it on the CA side) is not different than the file I try to encrypt or decrypt. Also, when I print msg->cmd in the CA I get -1 which mean that there is an error with RSA_private_decrypt and RSA_private_encrypt.

Dumping OpenSSL errors:
While looking at RSA_private_encryptdocumentation, I found out that it is possible to dump the error OpenSSL returns using ERR_get_error& ERR_error_string. So, I tweaked the code to return this error and write it to the file.

...
		int size_ = public_encrypt(data, 1, publicKey, payload);
		err = ERR_get_error();
		payload = ERR_error_string(err, payload);
	}
	else
	{
		int size_ = private_decrypt(data, 1, privateKey, payload);
		err = ERR_get_error();
		payload = ERR_error_string(err, payload);
...

This outputs error:2406C06E:lib(36):func(108):reason(110).
After running openssl errstr 2406C06E inside trusty’s terminal.
I get error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy

Solution attempts:

Looking at the solutions possible to this issue. I changed the --rand-with-seed from none to devrandom,rdcpu,os and recompiled OpenSSL but it didn’t solve the issue.
Also, Trusty seems to use /dev/urandom to generate random seeds (u can see it running sudo strace node -e 'crypto.randomBytes(64)'inside trusty).

Questions:
Is there any solution to this issue?
Are there any known implementations to OpenSSL with rsa keys encryption/decryption?

I have been stuck for a almost a week now and I would be grateful if you can help me solving this issue so I can continue on with my project.
Thank you in advance for your help!

hello n3k0m4,

the TA would provide an RNG service (i.e. rng-srv) that the CA or other TAs can communicate with it to gather the random numbers.
please refer to atf_and_trusty/trusty/app/nvidia-sample/hwkey-agent/include/rng_srv.h for the IPC packet definition,
for example,

/**
 * \brief Holds an IPC packet for communication with the RNG.
 */
typedef struct rng_srv_msg {
        uint32_t rng_size;                      /**< Actual size of a requested
                                                 *   random number. */
        uint8_t rng_data[RNG_SRV_DATA_SIZE];    /**< Holds the random number
                                                 *   generated by RNG. */
} rng_srv_msg_t;

the maximum length in an RNG query is 2048 bytes,

/** \brief Maximum length of a random number. */
#define RNG_SRV_DATA_SIZE 2048

hope this helps.
Jerry

Hello JerryChang,
I would like to thank you for your quick reply. I am nevertheless unable to link RNG service from hwkey-agent to encrypting/decrypting using RSA keys.
Does RNG service provide a solution to error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy. If so, I would be grateful if you can lead me to a way to use it.
Thanks,

hello n3k0m4,

please include below patch, which can make the RNG working in the Trusty OpenSSL.

diff --git a/lib/lib/openssl/Crypto-config-trusty.mk b/lib/lib/openssl/Crypto-config-trusty.mk
index cca79e2..06ee404 100644
--- a/lib/lib/openssl/Crypto-config-trusty.mk
+++ b/lib/lib/openssl/Crypto-config-trusty.mk
@@ -13,6 +13,7 @@
#    LOCAL_ADDITIONAL_DEPENDENCIES
#    LOCAL_EXPORT_C_INCLUDE_DIRS

+ # -DOPENSSL_IS_BORINGSSL

 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Crypto-config-trusty.mk

@@ -52,6 +53,7 @@ common_src_files := \
   crypto/asn1/x_long.c \
   crypto/asn1/x_pubkey.c \
   crypto/asn1/x_sig.c \
+  crypto/asn1/d2i_pu.c \
   crypto/bio/b_print.c \
   crypto/bio/bio_lib.c \
   crypto/bio/bss_mem.c \
@@ -215,7 +217,7 @@ common_src_files := \
   crypto/pem/pem_x509.c \
   crypto/pem/pem_xaux.c \
   crypto/pem/pvkfmt.c \
-
+  crypto/rand/rand_lib.c\

 common_c_includes := \
   external/openssl/. \

you should use RAND_seed(rnd_seed, sizeof rnd_seed); to generate random seed.
thanks

Hello JerryChang,
Thanks for the quick answer.
I tried the changes your suggested but the issue persists.
If you can see it in the code I am compiling. I am not intentionally generating the seeds, I am calling RSA_private_encryptor RSA_private_decrypt that tried to generate random seeds based on OpenSSL implementation. So, I don’t think I have a way to manipulate OpenSSL to use RAND_seed.
I did try to follow the flow of OpenSSL and find out what method it uses to generate the seeds but I couldn’t get there.
Is there any other solutions to this?
Thanks,

hello n3k0m4,

may I know which L4T release sources you’re working with,
could you please also share simplest sample to let us reproduce the issue locally.
thanks

Hello JerryChang,
I am using r32_release_v6.1 as a version of l4t.
To be able to reproduce the error you can swipe the code of crypto_service from Hwkey-agent to this:

/*
 * Copyright (c) 2020, NVIDIA Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:

 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <crypto_service.h>
#include <ekb_helper.h>
#include <openssl/aes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>

int padding = RSA_PKCS1_PADDING;
static char publicKey[] = "-----BEGIN PUBLIC KEY-----\n"
						  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"
						  "ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n"
						  "vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n"
						  "fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n"
						  "i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n"
						  "PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n"
						  "wQIDAQAB\n"
						  "-----END PUBLIC KEY-----\n";

static char privateKey[] = "-----BEGIN RSA PRIVATE KEY-----\n"
						   "MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"
						   "vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9\n"
						   "Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9\n"
						   "yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l\n"
						   "WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q\n"
						   "gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8\n"
						   "omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e\n"
						   "N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG\n"
						   "X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd\n"
						   "gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl\n"
						   "vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF\n"
						   "1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu\n"
						   "m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ\n"
						   "uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D\n"
						   "JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D\n"
						   "4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV\n"
						   "WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5\n"
						   "nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG\n"
						   "PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA\n"
						   "SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1\n"
						   "I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96\n"
						   "ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF\n"
						   "yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5\n"
						   "w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX\n"
						   "uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw\n"
						   "-----END RSA PRIVATE KEY-----\n";
static RSA *createRSA(char *key, int pubtype)
{
	RSA *rsa = NULL;
	BIO *bio = NULL;

	bio = BIO_new(BIO_s_mem());
	if (bio == NULL)
	{
		TLOGI("bio is NULL!\n");
	}

	BIO_puts(bio, key);
	if (pubtype == 1)
	{
		rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
	}
	else
	{
		rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	}
	if (rsa == NULL)
	{
		TLOGI("wrong again\n");
	}
	BIO_free(bio);
	return rsa;
}
static int private_decrypt(unsigned char *enc_data, int data_len, char *key, unsigned char *decrypted)
{
	RSA *rsa = createRSA(key, 0);
	if (rsa != NULL)
	{
		int result = RSA_private_decrypt(data_len, enc_data, decrypted, rsa, RSA_PKCS1_PADDING);
		RSA_free(rsa);
		return result;
	}
	return 0;
}
int public_encrypt(unsigned char *data, int data_len, char *key, unsigned char *encrypted)
{
	RSA *rsa = createRSA(key, 1);
	if (rsa != NULL)
	{
		int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);
		RSA_free(rsa);
		return result;
	}
	return 0;
}

void crypto_srv_process_req(iovec_t *ipc_msg, int len)
{
	crypto_srv_msg_t *msg = ipc_msg[0].base;
	uint8_t *payload = ipc_msg[1].base;
	int payload_len = msg->payload_len;
	uint8_t *data = NULL;
	uint8_t *key_in_ekb;
	unsigned long err;
	/*
	AES_KEY aes_key;
	int aes_enc_flag;
	int idx;
	*/

	key_in_ekb = ekb_get_key(EKB_USER_KEY_DISK_ENCRYPTION);
	if (key_in_ekb == NULL)
	{
		TLOGE("%s: get key in ekb failed\n", __func__);
		return;
	}

	data = malloc(CRYPTO_SRV_PAYLOAD_SIZE);
	if (data == NULL)
	{
		TLOGE("%s: malloc failed\n", __func__);
		return;
	}
	memcpy(data, payload, payload_len);
	if (msg->cmd == CRYPTO_SRV_CMD_ENCRYPT)
	{
		int size_ = public_encrypt(data, 1, publicKey, payload);
	}
	else
	{
		int size_ = private_decrypt(data, 1, privateKey, payload);
		
	}
	free(data);
}

The client app will take the input file from (./hwkey-agent -e -i input -o output -t) and encrypts it using RSA public encrypt then writes the result into the output file. If the output file is the same as the input it means that the call to RSA_public_encrypt did not pass.
Thanks for following up.

hello n3k0m4,

I cannot reproduce 2406C06E error, instead, I saw some undefined reference after apply your code snippets.

Hello JerryChang,
I have faced 2 undefined reference errors before being able to compile the project successfully.
Undefined reference to UI_new:

  • This could be solved by updating the openssl.config inside trusty/trusty/trusty/lib/lib/openssl/and add the missing methods.

OPENSSL_CRYPTO_TRUSTY_INCLUDES="\
...
crypto/ui \
"
...
OPENSSL_CRYPTO_TRUSTY_SOURCES="\
...
crypto/ui/ui_err.c
crypto/ui/ui_lib.c
crypto/ui/ui_null.c
crypto/ui/ui_openssl.c
crypto/ui/ui_util.c
/"
  • Run sudo ./import_openssl.sh import openssl-1.1.1g.tar.gz to extract them from the gzip file.

Undefined reference to Strcspn:
This issue is due to the missing file Strcspn.c from libc/strings.

  • Run find / -name 'strcspn.c' -type f, and get one of the results (normally JetPack will have one in JetPack/source/gcc-linaro-7.3-2018.05/gcc/testsuite/gcc.c-torture/execute/builtins/lib/strcspn.c).

  • Copy it to /l4t-gcc/Linux_for_Tegra/source/public/atf_and_trusty/trusty/trusty/lk/common/lib/libc/string

  • Modify /l4t-gcc/Linux_for_Tegra/source/public/atf_and_trusty/trusty/trusty/lk/common/lib/libc/string/rules.mk
    and add Strcspn.

  • Compile your project.

Also, notice that you won’t see the error 2406c06e but the output file won’t be encrypted. Once the project is compiled I can follow up with the code to display the error.
I hope you will be able to solve the issue using the methods showed on top.
Thanks,

hello n3k0m4,

please refer to the code snippets for adding these two lines for confirmation,
for example,

diff --git a/hwkey-agent/crypto_service.c b/hwkey-agent/crypto_service.c
index a77767e..8d3a146 100644
--- a/hwkey-agent/crypto_service.c
+++ b/hwkey-agent/crypto_service.c
@@ -38,6 +38,9 @@ void crypto_srv_process_req(iovec_t *ipc_msg, int len)
        int aes_enc_flag;
        int idx;

+       static const char rnd_seed[] =
+               "string to make the random number generator think it has entropy";
+
        key_in_ekb = ekb_get_key(EKB_USER_KEY_DISK_ENCRYPTION);
        if (key_in_ekb == NULL) {
                TLOGE("%s: get key in ekb failed\n", __func__);
@@ -51,6 +54,7 @@ void crypto_srv_process_req(iovec_t *ipc_msg, int len)
        }
        memcpy(data, payload, payload_len);

+       RAND_seed(rnd_seed, sizeof rnd_seed);
        if (msg->cmd == CRYPTO_SRV_CMD_ENCRYPT) {
                AES_set_encrypt_key(key_in_ekb, AES_KEY_128_SIZE * 8, &aes_key);

Hello JerryChang,
I tried the modifications with my code (using RSA_private_decrypt and RSA_prublic_encrypt) the code compiles fine. But, I still get error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy.
Thanks,

hello n3k0m4,

we have verified RSA_public_encrypt on TX2, it worked.
since we’ve retrieved the rsa key (*.pem ) from eks. you’ve hardcode the key in source code, had you try any different key formats?

in addition, could you please…

  1. verify the private_decrypt/ public_encrypt function in CA? Then implement in TA.
  2. you may share the whole trusty/app/nvidia-sample as a tar file, let us have a debug.

Hello JerryChang,
I would like to thank you for following up.
I have tried DER format in the past but faced weird errors. So, I decided to stick to PEM because it was easier to debug.
Also, I am using hard-coded keys because my project is going to be simple and I don’t want to deal with the overhead of managing the keys and the space.
Please find attached a version of the full application I developed (You need to remove line 45: /trusty/trusty/trusty/lk/common/lib/libc/string/strcspn.c from rules.mk).
Thanks again,
Dec.tar.gz (34.3 KB)

hello n3k0m4,

we’ve try your Dec.tar.gz with some changes to fix compile issues
please check attachment for reference, i.e. 0001-Fixed-some-compile-error-issues.patch (14.6 KB)

the process looks doing correctly, here’re steps for your reference,

  1. delete t194ref folder to avoid some dependency issue,
    $ rm -rf t194ref

  2. comamnds to compile the sources,
    $ make t186 PROJECT=t186 TARGET=t186 BUILDROOT=./t194ref \ TOOLCHAIN_PREFIX="${CROSS_COMPILE_AARCH64}" \ ARCH_arm_TOOLCHAIN_PREFIX="${CROSS_COMPILE_ARM}" \ ARCH_arm64_TOOLCHAIN_PREFIX="${CROSS_COMPILE_AARCH64}" \ DEBUG=0 DEBUG_LVL=0 DEFAULT_OTE_APP_DEBUGLEVEL=1 NOECHO=@ \ TRUSTY_VARIANT=l4t-public TRUSTY_MULTI_GUEST_CONFIGURATION= \ TARGET_SOC=t194

  3. then, flash the new secure os image: (we’ve test with Xavier-8g devkit)
    $ sudo ./flash.sh -r -k secure-os jetson-xavier-8gb mmcblk0p1

  4. test with hwkey-app, the infile is a length 256 random file, used dd command generated.
    $ ./hwkey-app -e -i infile -o outfile -t

  5. you may also use gdb debug it
    gdb --args ./hwkey-app -e -i infile -o outfile -t
    for example,
    (gdb) p *msg $5 = {cmd = (unknown: 4294967196), iv = "6\353\071\376:\317\032\365h\301\270\346\364\216\\y", payload_len = 256, payload = 0x48f028 "error:00000000:lib(0):func(0):reason(0)"}

Hello JerryChang,
I would like to thank you for your reply.
I followed the steps you provided and the error still persists.
From the patch it seems to me that you used my code without any modifcations. Is it the case or did you change some files?
Would it be possible to send me the whole project?

hello n3k0m4,

that’s all changes, you may include the changes and compile the sources for confirmation.