nRF5 SDK v17.0.2
Test Example

The nrf_crypto Test Example verifies the functionality of the nrf_crypto operations by using known test vectors approved by the National Institute of Standards and Technology (NIST) and others. All available nrf_crypto backends can be tested by modifying the nrf_crypto section in the sdk_config file, as described in Configuring nrf_crypto frontend and backends.

Cryptographic mode Sub-mode Link to standard Test Vector Source
AES CBC NIST AES NIST AES
CFB NIST AES
ECB NIST AES
CTR NIST SP 800-38A NIST SP 800-38A
CBC MAC CBC MAC No official test vectors
CMAC NIST SP 800-38B NIST SP 800-38B
AEAD CCM NIST CCM NIST CCM
CCM* Formal Specification of the CCM* Mode of Operation - September 9, 2005 Formal Specification of the CCM* Mode of Operation - September 9, 2005
EAX The EAX Mode of Operation The EAX Mode of Operation
GCM NIST GCM NIST GCM
ChaCha-Poly RFC 7539 - ChaCha20 and Poly1305 for IETF Protocols RFC 7539 - ChaCha20 and Poly1305 for IETF Protocols
ECDH secp160r1 NIST - ECDH GEC 2: Test Vectors for SEC 1
secp160r2 No test vectors
secp192r1 NIST - ECDH
secp224r1 NIST - ECDH
secp256r1 NIST - ECDH
secp384r1 NIST - ECDH
secp521r1 NIST - ECDH
secp160k1 - No test vectors
secp192k1 - No test vectors
secp224k1 - No test vectors
secp256k1 - No test vectors
bp256r1 RFC 7027 - ECC Brainpool Curves for TLS RFC 7027 - ECC Brainpool Curves for TLS
bp384r1 RFC 7027 - ECC Brainpool Curves for TLS
bp512r1 RFC 7027 - ECC Brainpool Curves for TLS
Curve25519 RFC 7748 - Elliptic Curves for Security RFC 7748 - Elliptic Curves for Security
ECDSA secp160r1 NIST - ECDSA No test vectors
secp160r2 No test vectors
secp192r1 No test vectors
secp224r1 NIST - ECDSA
secp256r1 NIST - ECDSA
secp384r1 NIST - ECDSA
secp521r1 NIST - ECDSA
secp160k1 - No test vectors
secp192k1 - No test vectors
secp224k1 - No test vectors
secp256k1 - No test vectors
bp256r1 RFC 5639 - ECC Brainpool Standard Curves and Curve Generation No test vectors
bp384r1 No test vectors
bp512r1 No test vectors
EdDSA RFC 8032 - Edwards-Curve Digital Signature Algorithm (EdDSA) RFC 8032 - Edwards-Curve Digital Signature Algorithm (EdDSA)
Hash SHA256 NIST - SHA NIST - SHA
SHA512 NIST - SHA
HMAC HMAC SHA256 NIST - HMAC NIST - HMAC
HMAC SHA512 NIST - HMAC
HKDF HKDF SHA256 RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF) RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
HKDF SHA512 RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)

You can find the source code and the project file of the example in the following folder: <InstallFolder>\examples\crypto\nrf_crypto\test_app

Testing

Test the nrf_crypto test example application by performing the following steps:

  1. Compile and program the application.
  2. Observe the result of the different test vectors in the log using an RTT viewer or a terminal emulator. Make sure the test vector verdict is "passed".
        #0022 Test vector passed: SHA SHA256 message_len=64
  3. A summary stating the number of passed and failed test vectors will be printed in the end of execution. The total number of executed test cases and test vectors depends on the current nrf_crypto backend. Make sure no test vectors failed.
        ***************************************
        All Tests Done
        X test vectors passed
        0 test vectors failed
        ***************************************

Adding additional test cases and test vectors

Test cases and test vectors can be added to the test suite either by including additional source files or by extending the existing files.

Test Case

A test case is a function designed to verify parts of the functionality of an nrf_crypto operation. Most nrf_crypto operations, like hash calculations and ECDH, have multiple test cases to be able to cover all features. A typical test case loops over all related test vectors, and logs the verdict of each.

An example of a hash test case in a simplified form is shown in the code block below.

NRF_SECTION_DEF(test_vector_hash_data, test_vector_hash_t);
#define TEST_VECTOR_GET(i) NRF_SECTION_ITEM_GET(test_vector_hash_data, test_vector_hash_t, (i)) /**< Get number of hash test vectors. */
#define TEST_VECTOR_COUNT NRF_SECTION_ITEM_COUNT(test_vector_hash_data, test_vector_hash_t) /**< Get test vector reference from array of test vectors. */
ret_code_t exec_test_case_hash(test_info_t * p_test_info)
{
uint32_t i;
ret_code_t err_code;
uint32_t hash_test_vector_count = TEST_VECTOR_COUNT;
for (i = 0; i < hash_test_vector_count; i++)
{
test_vector_hash_t * p_test_vector = TEST_VECTOR_GET(i);
// TODO: Add test code here.
// Will goto exit_test_vector if fails.
TEST_VECTOR_ASSERT(err_code);
p_test_info->tests_passed++;
exit_test_vector: ;
}
return NRF_SUCCESS;
}

Registering a test case

A new test case must be registered to the test_case_data section using Experimental: Section variables. The NRF_SECTION_ITEM_REGISTER macro below places the variable test_hash in a section named "test_case_data", which is initialized by main.

NRF_SECTION_ITEM_REGISTER(test_case_data, test_case_t test_hash) =
{
.p_test_case_name = "Hash test", /**< Pointer to hash test case name. */
.setup = setup_test_case_hash, /**< Pointer to hash test case setup function. */
.exec = exec_test_case_hash, /**< Pointer to hash test case execute function. */
.teardown = teardown_test_case_hash /**< Pointer to hash test case teardown function. */
};
Note
The macro call to NRF_SECTION_ITEM_REGISTER must be done in a .c file.

Test Vectors

A test vector is a set of inputs and expected outputs to verify the functionality provided in a test case. The p_test_vector_name variable is the only required member in the test_vector structures.

typedef const struct
{
const nrf_crypto_hash_info_t * p_hash_info; /**< Pointer to hash info type. */
const ret_code_t expected_err_code; /**< Expected error code from hash operation. */
const uint8_t expected_result; /**< Expected result of hash operation. */
const hash_mem_mode_t mode; /**< Hash memory operation. */
const uint32_t chunk_length; /**< Size of input chunks to hash function in bytes. */
const uint32_t update_iterations; /**< Number of update iterations of input. */
const char * p_test_vector_name; /**< Pointer to hash test vector name. */
const char * p_input; /**< Pointer to input message in hex string format. */
const char * p_expected_output; /**< Pointer to expected message digest in hex string format. */
}test_vector_hash_t;

Register a test vector

Test vectors are added by registering them for a section defined in the test case code. The test vector is registered in the section "test_vector_hash_data", which is defined in the test case example exec_test_case_hash. The test vector can reuse the already defined hash test vector structure test_vector_hash_t, as shown in the code block below.

// Register a test vector for sha256.
NRF_SECTION_ITEM_REGISTER(test_vector_hash_data, test_vector_hash_t test_vector_sha256) =
{
.p_hash_info = &g_nrf_crypto_hash_sha256_info, /**< Pointer to sha256 info type. */
.expected_err_code = NRF_SUCCESS, /**< The expected error code from the sha operation. */
.expected_result = EXPECTED_TO_PASS, /**< The expected result of the operation. */
.p_test_vector_name = "SHA256 test vector example", /**< Pointer to sha256 test vector name. */
.p_input = "c98c8e55", /**< Pointer to input message. */
.p_expected_output = "7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504" /**< Pointer to expected digest. */
};

Output logging

The test project generates a test log using RTT transport, as described in the Testing section. The new test case exec_test_case_hash and its test vector will be added to the test log when the test is executed. The additional test log output will look like the lines below.

***************************************
Test case Hash Test Started
#00XX Test vector passed: SHA256 test vector example
Test case Hash Test Done
***************************************

Documentation feedback | Developer Zone | Subscribe | Updated