AES CBC (or EBC) on nRF52832 & nRF54L05

So I need to decrypt a single 16 byte block of data using AES128 and a pre-shared key on the above SoCs. But PSA doesn't seem to work (I'm currently working using the nRF52DK). Even the AES CBC example application fails with an error when I run it

Booting nRF Connect SDK v2.9.0-7787b2649840 ***
*** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
[00:00:00.265,533] <inf> aes_cbc: Starting AES-CBC-NO-PADDING example...
[00:00:00.265,594] <inf> aes_cbc: Generating random AES key...
[00:00:00.265,625] <inf> aes_cbc: psa_generate_key failed! (Error: -141)
[00:00:00.265,625] <inf> aes_cbc: Example exited with error!

I notice there is a config option CONFIG_MBEDTLS_LEGACY_CRYPTO_C, but the description suggests it's not a great option

Enable support for legacy mbed TLS APIs.
Note that this is a configuration that may be removed at some point.
It is only provided during a transition period while PSA Crypto APIs become
the defacto front-end. Enabling this will enable nrf_oberon for all features that
are supported and builtin for the remaining functionality.

Any advice on the way forward?

Parents
  • Hi,

    The sample does not support nRF52832 out of the box, so you need to add a few configuartions for it. If you add these to prj.conf, the sample should run successfully:

    CONFIG_MBEDTLS_ENABLE_HEAP=y
    CONFIG_MBEDTLS_HEAP_SIZE=4096
    CONFIG_ENTROPY_GENERATOR=y

  • Still fails unfortunately this time with error -134 which looks like it is PSA_ERROR_NOT_SUPPORTED

    *** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    [00:00:00.481,872] <inf> aes_cbc: Starting AES-CBC-NO-PADDING example...
    [00:00:00.481,903] <inf> aes_cbc: Generating random AES key...
    [00:00:00.481,994] <inf> aes_cbc: psa_generate_key failed! (Error: -134)
    [00:00:00.481,994] <inf> aes_cbc: Example exited with error!

    Here is the entire prj.conf, it's the virgin file from the sample with just the lines you suggested added

    #
    # Copyright (c) 2024 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    # The Zephyr CMSIS emulation assumes that ticks are ms, currently
    CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
    
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=4096
    
    # Enable logging
    CONFIG_CONSOLE=y
    CONFIG_LOG=y
    
    # Enable nordic security backend and PSA APIs
    #CONFIG_NRF_SECURITY=y
    #CONFIG_MBEDTLS_PSA_CRYPTO_C=y
    
    #CONFIG_PSA_WANT_GENERATE_RANDOM=y
    #CONFIG_PSA_WANT_KEY_TYPE_AES=y
    #CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y
    
    CONFIG_NORDIC_SECURITY_BACKEND=y
    CONFIG_MBEDTLS_ENABLE_HEAP=y
    CONFIG_MBEDTLS_HEAP_SIZE=4096
    CONFIG_ENTROPY_GENERATOR=y
    

    This was pretty simple using SDK17 using nrf_crypto_aes_crypt()...

    What about using a PSK? I was trying to use psa_import_key() but getting errors like the above, until I gave up as I think there's something fundamentally wrong (which seems to be the case as the sample doesn't work)

    For reference, here's the main.c. I want to use my custom board, but for the sake of testing I'm using nRF52DK PCA10040

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/logging/log.h>
    #include <stdio.h>
    #include <psa/crypto.h>
    #include <psa/crypto_extra.h>
    
    
    #ifdef CONFIG_BUILD_WITH_TFM
    #include <tfm_ns_interface.h>
    #endif
    
    #define APP_SUCCESS		(0)
    #define APP_ERROR		(-1)
    #define APP_SUCCESS_MESSAGE "Example finished successfully!"
    #define APP_ERROR_MESSAGE "Example exited with error!"
    
    #define PRINT_HEX(p_label, p_text, len)\
    	({\
    		LOG_INF("---- %s (len: %u): ----", p_label, len);\
    		LOG_HEXDUMP_INF(p_text, len, "Content:");\
    		LOG_INF("---- %s end  ----", p_label);\
    	})
    
    LOG_MODULE_REGISTER(aes_cbc, LOG_LEVEL_DBG);
    
    /* ====================================================================== */
    /* Global variables/defines for the AES-CBC-NO-PADDING example */
    
    #define NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE (64)
    #define NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE (16)
    
    static uint8_t m_iv[NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE];
    
    /* Below text is used as plaintext for encryption/decryption */
    static uint8_t m_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE] = {
    	"Example string to demonstrate basic usage of AES CBC mode."
    };
    
    static uint8_t m_encrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    static uint8_t m_decrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    
    static psa_key_id_t key_id;
    /* ====================================================================== */
    
    int crypto_init(void)
    {
    	psa_status_t status;
    
    	/* Initialize PSA Crypto */
    	status = psa_crypto_init();
    	if (status != PSA_SUCCESS)
    		return APP_ERROR;
    
    	return APP_SUCCESS;
    }
    
    int crypto_finish(void)
    {
    	psa_status_t status;
    
    	/* Destroy the key handle */
    	status = psa_destroy_key(key_id);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_destroy_key failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	return APP_SUCCESS;
    }
    
    int generate_key(void)
    {
    	psa_status_t status;
    
    	LOG_INF("Generating random AES key...");
    
    	/* Configure the key attributes */
    	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
    
    	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
    	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
    	psa_set_key_algorithm(&key_attributes, PSA_ALG_CBC_NO_PADDING);
    	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
    	psa_set_key_bits(&key_attributes, 128);
    
    	/* Generate a random key. The key is not exposed to the application,
    	 * we can use it to encrypt/decrypt using the key handle
    	 */
    	status = psa_generate_key(&key_attributes, &key_id);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_generate_key failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* After the key handle is acquired the attributes are not needed */
    	psa_reset_key_attributes(&key_attributes);
    
    	LOG_INF("AES key generated successfully!");
    
    	return APP_SUCCESS;
    }
    
    int encrypt_cbc_aes(void)
    {
    	uint32_t olen;
    	psa_status_t status;
    	psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
    	LOG_INF("Encrypting using AES CBC MODE...");
    
    	/* Setup the encryption operation */
    	status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_encrypt_setup failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Generate an IV */
    	status = psa_cipher_generate_iv(&operation, m_iv, sizeof(m_iv), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_generate_iv failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Perform the encryption */
    	status = psa_cipher_update(&operation, m_plain_text,
    				   sizeof(m_plain_text), m_encrypted_text,
    				   sizeof(m_encrypted_text), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_update failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Finalize the encryption */
    	status = psa_cipher_finish(&operation, m_encrypted_text + olen,
    				   sizeof(m_encrypted_text) - olen,
    				   &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	LOG_INF("Encryption successful!");
    	PRINT_HEX("IV", m_iv, sizeof(m_iv));
    	PRINT_HEX("Plaintext", m_plain_text, sizeof(m_plain_text));
    	PRINT_HEX("Encrypted text", m_encrypted_text, sizeof(m_encrypted_text));
    
    	/* Clean up cipher operation context */
    	psa_cipher_abort(&operation);
    
    	return APP_SUCCESS;
    }
    
    int decrypt_cbc_aes(void)
    {
    	uint32_t olen;
    	psa_status_t status;
    	psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
    	LOG_INF("Decrypting using AES CBC MODE...");
    
    	/* Setup the decryption operation */
    	status = psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_decrypt_setup failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Set the IV generated in encryption */
    	status = psa_cipher_set_iv(&operation, m_iv, sizeof(m_iv));
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_set_iv failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Perform the decryption */
    	status = psa_cipher_update(&operation, m_encrypted_text,
    				   sizeof(m_encrypted_text), m_decrypted_text,
    				   sizeof(m_decrypted_text), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_update failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Finalize the decryption */
    	status = psa_cipher_finish(&operation, m_decrypted_text + olen,
    				   sizeof(m_decrypted_text) - olen,
    				   &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	PRINT_HEX("Decrypted text", m_decrypted_text, sizeof(m_decrypted_text));
    
    	/* Check the validity of the decryption */
    	if (memcmp(m_decrypted_text,
    				m_plain_text,
    				NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE) != 0){
    
    		LOG_INF("Error: Decrypted text doesn't match the plaintext");
    		return APP_ERROR;
    	}
    
    	LOG_INF("Decryption successful!");
    
    	/*  Clean up cipher operation context */
    	psa_cipher_abort(&operation);
    
    	return APP_SUCCESS;
    }
    
    
    int main(void)
    {
    	int status;
    
    	LOG_INF("Starting AES-CBC-NO-PADDING example...");
    
    	status = crypto_init();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = generate_key();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = encrypt_cbc_aes();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = decrypt_cbc_aes();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = crypto_finish();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	LOG_INF(APP_SUCCESS_MESSAGE);
    
    	return APP_SUCCESS;
    }
    

Reply
  • Still fails unfortunately this time with error -134 which looks like it is PSA_ERROR_NOT_SUPPORTED

    *** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    [00:00:00.481,872] <inf> aes_cbc: Starting AES-CBC-NO-PADDING example...
    [00:00:00.481,903] <inf> aes_cbc: Generating random AES key...
    [00:00:00.481,994] <inf> aes_cbc: psa_generate_key failed! (Error: -134)
    [00:00:00.481,994] <inf> aes_cbc: Example exited with error!

    Here is the entire prj.conf, it's the virgin file from the sample with just the lines you suggested added

    #
    # Copyright (c) 2024 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    # The Zephyr CMSIS emulation assumes that ticks are ms, currently
    CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
    
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=4096
    
    # Enable logging
    CONFIG_CONSOLE=y
    CONFIG_LOG=y
    
    # Enable nordic security backend and PSA APIs
    #CONFIG_NRF_SECURITY=y
    #CONFIG_MBEDTLS_PSA_CRYPTO_C=y
    
    #CONFIG_PSA_WANT_GENERATE_RANDOM=y
    #CONFIG_PSA_WANT_KEY_TYPE_AES=y
    #CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y
    
    CONFIG_NORDIC_SECURITY_BACKEND=y
    CONFIG_MBEDTLS_ENABLE_HEAP=y
    CONFIG_MBEDTLS_HEAP_SIZE=4096
    CONFIG_ENTROPY_GENERATOR=y
    

    This was pretty simple using SDK17 using nrf_crypto_aes_crypt()...

    What about using a PSK? I was trying to use psa_import_key() but getting errors like the above, until I gave up as I think there's something fundamentally wrong (which seems to be the case as the sample doesn't work)

    For reference, here's the main.c. I want to use my custom board, but for the sake of testing I'm using nRF52DK PCA10040

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/logging/log.h>
    #include <stdio.h>
    #include <psa/crypto.h>
    #include <psa/crypto_extra.h>
    
    
    #ifdef CONFIG_BUILD_WITH_TFM
    #include <tfm_ns_interface.h>
    #endif
    
    #define APP_SUCCESS		(0)
    #define APP_ERROR		(-1)
    #define APP_SUCCESS_MESSAGE "Example finished successfully!"
    #define APP_ERROR_MESSAGE "Example exited with error!"
    
    #define PRINT_HEX(p_label, p_text, len)\
    	({\
    		LOG_INF("---- %s (len: %u): ----", p_label, len);\
    		LOG_HEXDUMP_INF(p_text, len, "Content:");\
    		LOG_INF("---- %s end  ----", p_label);\
    	})
    
    LOG_MODULE_REGISTER(aes_cbc, LOG_LEVEL_DBG);
    
    /* ====================================================================== */
    /* Global variables/defines for the AES-CBC-NO-PADDING example */
    
    #define NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE (64)
    #define NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE (16)
    
    static uint8_t m_iv[NRF_CRYPTO_EXAMPLE_AES_BLOCK_SIZE];
    
    /* Below text is used as plaintext for encryption/decryption */
    static uint8_t m_plain_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE] = {
    	"Example string to demonstrate basic usage of AES CBC mode."
    };
    
    static uint8_t m_encrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    static uint8_t m_decrypted_text[NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE];
    
    static psa_key_id_t key_id;
    /* ====================================================================== */
    
    int crypto_init(void)
    {
    	psa_status_t status;
    
    	/* Initialize PSA Crypto */
    	status = psa_crypto_init();
    	if (status != PSA_SUCCESS)
    		return APP_ERROR;
    
    	return APP_SUCCESS;
    }
    
    int crypto_finish(void)
    {
    	psa_status_t status;
    
    	/* Destroy the key handle */
    	status = psa_destroy_key(key_id);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_destroy_key failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	return APP_SUCCESS;
    }
    
    int generate_key(void)
    {
    	psa_status_t status;
    
    	LOG_INF("Generating random AES key...");
    
    	/* Configure the key attributes */
    	psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
    
    	psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
    	psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
    	psa_set_key_algorithm(&key_attributes, PSA_ALG_CBC_NO_PADDING);
    	psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
    	psa_set_key_bits(&key_attributes, 128);
    
    	/* Generate a random key. The key is not exposed to the application,
    	 * we can use it to encrypt/decrypt using the key handle
    	 */
    	status = psa_generate_key(&key_attributes, &key_id);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_generate_key failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* After the key handle is acquired the attributes are not needed */
    	psa_reset_key_attributes(&key_attributes);
    
    	LOG_INF("AES key generated successfully!");
    
    	return APP_SUCCESS;
    }
    
    int encrypt_cbc_aes(void)
    {
    	uint32_t olen;
    	psa_status_t status;
    	psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
    	LOG_INF("Encrypting using AES CBC MODE...");
    
    	/* Setup the encryption operation */
    	status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_encrypt_setup failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Generate an IV */
    	status = psa_cipher_generate_iv(&operation, m_iv, sizeof(m_iv), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_generate_iv failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Perform the encryption */
    	status = psa_cipher_update(&operation, m_plain_text,
    				   sizeof(m_plain_text), m_encrypted_text,
    				   sizeof(m_encrypted_text), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_update failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Finalize the encryption */
    	status = psa_cipher_finish(&operation, m_encrypted_text + olen,
    				   sizeof(m_encrypted_text) - olen,
    				   &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	LOG_INF("Encryption successful!");
    	PRINT_HEX("IV", m_iv, sizeof(m_iv));
    	PRINT_HEX("Plaintext", m_plain_text, sizeof(m_plain_text));
    	PRINT_HEX("Encrypted text", m_encrypted_text, sizeof(m_encrypted_text));
    
    	/* Clean up cipher operation context */
    	psa_cipher_abort(&operation);
    
    	return APP_SUCCESS;
    }
    
    int decrypt_cbc_aes(void)
    {
    	uint32_t olen;
    	psa_status_t status;
    	psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
    
    	LOG_INF("Decrypting using AES CBC MODE...");
    
    	/* Setup the decryption operation */
    	status = psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_decrypt_setup failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Set the IV generated in encryption */
    	status = psa_cipher_set_iv(&operation, m_iv, sizeof(m_iv));
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_set_iv failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Perform the decryption */
    	status = psa_cipher_update(&operation, m_encrypted_text,
    				   sizeof(m_encrypted_text), m_decrypted_text,
    				   sizeof(m_decrypted_text), &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_update failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	/* Finalize the decryption */
    	status = psa_cipher_finish(&operation, m_decrypted_text + olen,
    				   sizeof(m_decrypted_text) - olen,
    				   &olen);
    	if (status != PSA_SUCCESS) {
    		LOG_INF("psa_cipher_finish failed! (Error: %d)", status);
    		return APP_ERROR;
    	}
    
    	PRINT_HEX("Decrypted text", m_decrypted_text, sizeof(m_decrypted_text));
    
    	/* Check the validity of the decryption */
    	if (memcmp(m_decrypted_text,
    				m_plain_text,
    				NRF_CRYPTO_EXAMPLE_AES_MAX_TEXT_SIZE) != 0){
    
    		LOG_INF("Error: Decrypted text doesn't match the plaintext");
    		return APP_ERROR;
    	}
    
    	LOG_INF("Decryption successful!");
    
    	/*  Clean up cipher operation context */
    	psa_cipher_abort(&operation);
    
    	return APP_SUCCESS;
    }
    
    
    int main(void)
    {
    	int status;
    
    	LOG_INF("Starting AES-CBC-NO-PADDING example...");
    
    	status = crypto_init();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = generate_key();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = encrypt_cbc_aes();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = decrypt_cbc_aes();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	status = crypto_finish();
    	if (status != APP_SUCCESS) {
    		LOG_INF(APP_ERROR_MESSAGE);
    		return APP_ERROR;
    	}
    
    	LOG_INF(APP_SUCCESS_MESSAGE);
    
    	return APP_SUCCESS;
    }
    

Children
No Data
Related