When running the ECDSA Example from Nordic, the keys are generated successfully. But when I add the code for generating CSR it fails with the error code -134 which bby my knowledge is PSA_ERROR_NOT_SUPPORTED. Requesting help with this issue.
using NRF Connect v2.6.1 and board nrf5340 in secure environment.
# The Zephyr CMSIS emulation assumes that ticks are ms, currently CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 CONFIG_MAIN_STACK_SIZE=8192 CONFIG_HEAP_MEM_POOL_SIZE=8192 # 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 # Enable persistent storage APIs CONFIG_MBEDTLS_PSA_CRYPTO_STORAGE_C=y #CONFIG_PSA_NATIVE_ITS=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=8192 CONFIG_PSA_WANT_ALG_ECDSA=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR=y CONFIG_PSA_WANT_ECC_SECP_R1_256=y CONFIG_PSA_WANT_ALG_SHA_256=y # For key generation CONFIG_PSA_WANT_GENERATE_RANDOM=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_USE_PSA_CRYPTO=y CONFIG_MBEDTLS_PK_C=y CONFIG_MBEDTLS_TLS_LIBRARY=y CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y CONFIG_MBEDTLS_X509_USE_C=y CONFIG_MBEDTLS_X509_CSR_WRITE_C=y CONFIG_MBEDTLS_X509_LIBRARY=y CONFIG_MBEDTLS_PK_WRITE_C=y CONFIG_MBEDTLS_X509_CRT_PARSE_C=y CONFIG_MBEDTLS_X509_CREATE_C=y CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_PK_PARSE_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_KEY_EXCHANGE_ALL_ENABLED=y CONFIG_PSA_CRYPTO_DRIVER_OBERON=n CONFIG_PSA_CRYPTO_DRIVER_CC3XX=y CONFIG_MBEDTLS_LIBRARY_NRF_SECURITY=y CONFIG_MBEDTLS_SHA256_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_ECDSA_C=y CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_CTR_DRBG_C=y CONFIG_MBEDTLS_MD_C=y CONFIG_PSA_WANT_ALG_ECDSA_ANY=y
And my code is :
/* * 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 <stdlib.h> #include <psa/crypto.h> #include <psa/crypto_extra.h> #ifdef CONFIG_BUILD_WITH_TFM #include <tfm_ns_interface.h> #endif #include <mbedtls/pk.h> #include <mbedtls/x509.h> #include <mbedtls/x509_csr.h> #define APP_SUCCESS (0) #define APP_ERROR (-1) #define APP_SUCCESS_MESSAGE "Example finished successfully!" #define APP_ERROR_MESSAGE "Example exited with error!" #define SEC_LIB_CSR_SUBJECT_NAME "C=TIH Foundation for IoT and IoE,O=TIH,OU=Networking,CN=TIH-IoT" #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(ecdsa, LOG_LEVEL_DBG); /* ====================================================================== */ /* Global variables/defines for the ECDSA example */ #define NRF_CRYPTO_EXAMPLE_ECDSA_TEXT_SIZE (100) #define NRF_CRYPTO_EXAMPLE_ECDSA_PUBLIC_KEY_SIZE (65) #define NRF_CRYPTO_EXAMPLE_ECDSA_SIGNATURE_SIZE (64) #define NRF_CRYPTO_EXAMPLE_ECDSA_HASH_SIZE (32) /* Below text is used as plaintext for signing/verification */ //static uint8_t m_plain_text[NRF_CRYPTO_EXAMPLE_ECDSA_TEXT_SIZE] = { // "Example string to demonstrate basic usage of ECDSA." //}; static uint8_t m_pub_key[NRF_CRYPTO_EXAMPLE_ECDSA_PUBLIC_KEY_SIZE]; //static uint8_t m_signature[NRF_CRYPTO_EXAMPLE_ECDSA_SIGNATURE_SIZE]; //static uint8_t m_hash[NRF_CRYPTO_EXAMPLE_ECDSA_HASH_SIZE]; static psa_key_id_t keypair_id; static psa_key_id_t pub_key_id; /* ====================================================================== */ int crypto_init(void) { psa_status_t status; /* Initialize PSA Crypto */ status = psa_crypto_init(); if (status != PSA_SUCCESS) { LOG_INF("psa_crypto_init failed! (Error: %d)", status); return APP_ERROR; } return APP_SUCCESS; } int crypto_finish(void) { psa_status_t status; /* Destroy the key handle */ status = psa_destroy_key(keypair_id); if (status != PSA_SUCCESS) { LOG_INF("psa_destroy_key failed! (Error: %d)", status); return APP_ERROR; } status = psa_destroy_key(pub_key_id); if (status != PSA_SUCCESS) { LOG_INF("psa_destroy_key failed! (Error: %d)", status); return APP_ERROR; } return APP_SUCCESS; } int generate_ecdsa_keypair(void) { psa_status_t status; size_t olen; LOG_INF("Generating random ECDSA keypair..."); /* Configure the key attributes */ psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; /* Configure the key attributes */ psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH); psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&key_attributes, 256); /* Generate a random keypair. The keypair is not exposed to the application, * we can use it to sign hashes. */ #define SAMPLE_PERS_KEY_ID PSA_KEY_ID_USER_MIN psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_PERSISTENT); psa_set_key_id(&key_attributes, SAMPLE_PERS_KEY_ID); psa_destroy_key(SAMPLE_PERS_KEY_ID); status = psa_generate_key(&key_attributes, &keypair_id); if (status != PSA_SUCCESS) { LOG_INF("psa_generate_key failed! (Error: %d)", status); return APP_ERROR; } /* Export the public key */ status = psa_export_public_key(keypair_id, m_pub_key, sizeof(m_pub_key), &olen); if (status != PSA_SUCCESS) { LOG_INF("psa_export_public_key failed! (Error: %d)", status); return APP_ERROR; } /* Reset key attributes and free any allocated resources. */ psa_reset_key_attributes(&key_attributes); return APP_SUCCESS; } int import_ecdsa_pub_key(void) { /* Configure the key attributes */ psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; /* Configure the key attributes */ psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH); psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&key_attributes, 256); status = psa_import_key(&key_attributes, m_pub_key, sizeof(m_pub_key), &pub_key_id); if (status != PSA_SUCCESS) { LOG_INF("psa_import_key failed! (Error: %d)", status); return APP_ERROR; } /* Reset key attributes and free any allocated resources. */ psa_reset_key_attributes(&key_attributes); return APP_SUCCESS; } // int sign_message(void) // { // uint32_t output_len; // psa_status_t status; // LOG_INF("Signing a message using ECDSA..."); // /* Compute the SHA256 hash*/ // status = psa_hash_compute(PSA_ALG_SHA_256, // m_plain_text, // sizeof(m_plain_text), // m_hash, // sizeof(m_hash), // &output_len); // if (status != PSA_SUCCESS) { // LOG_INF("psa_hash_compute failed! (Error: %d)", status); // return APP_ERROR; // } // /* Sign the hash */ // status = psa_sign_hash(keypair_id, // PSA_ALG_ECDSA(PSA_ALG_SHA_256), // m_hash, // sizeof(m_hash), // m_signature, // sizeof(m_signature), // &output_len); // if (status != PSA_SUCCESS) { // LOG_INF("psa_sign_hash failed! (Error: %d)", status); // return APP_ERROR; // } // LOG_INF("Message signed successfully!"); // PRINT_HEX("Plaintext", m_plain_text, sizeof(m_plain_text)); // PRINT_HEX("SHA256 hash", m_hash, sizeof(m_hash)); // PRINT_HEX("Signature", m_signature, sizeof(m_signature)); // return APP_SUCCESS; // } // int verify_message(void) // { // psa_status_t status; // LOG_INF("Verifying ECDSA signature..."); // /* Verify the signature of the hash */ // status = psa_verify_hash(pub_key_id, // PSA_ALG_ECDSA(PSA_ALG_SHA_256), // m_hash, // sizeof(m_hash), // m_signature, // sizeof(m_signature)); // if (status != PSA_SUCCESS) { // LOG_INF("psa_verify_hash failed! (Error: %d)", status); // return APP_ERROR; // } // LOG_INF("Signature verification was successful!"); // return APP_SUCCESS; // } static int psa_rng_for_mbedtls(void *p_rng, unsigned char *output, size_t output_len) { (void)p_rng; return psa_generate_random(output, output_len); } int generate_csr() { psa_status_t status; //psa_key_handle_t key_handle; unsigned char output_buf[1024]; memset(output_buf, 0, sizeof(output_buf)); mbedtls_pk_context pk_key_container; mbedtls_x509write_csr csr_ctx; mbedtls_pk_init(&pk_key_container); // pk_key_container.private_pk_ctx=m_pub_key; // pk_key_container.private_pk_info=pub_key_id; mbedtls_pk_setup_opaque(&pk_key_container, keypair_id); //mbedtls_pk_setup(&pk_key_container, &key_handle); // Prepare CSR context mbedtls_x509write_csr_init(&csr_ctx); LOG_INF("Write CSR initialised"); mbedtls_x509write_csr_set_key_usage(&csr_ctx, MBEDTLS_X509_KU_DIGITAL_SIGNATURE); LOG_INF("Key usage of CSR is set"); mbedtls_x509write_csr_set_subject_name(&csr_ctx, SEC_LIB_CSR_SUBJECT_NAME); LOG_INF("Added subject name to CSR"); mbedtls_x509write_csr_set_md_alg(&csr_ctx, MBEDTLS_MD_SHA256); LOG_INF(" Hashing algorithm of CSR is set"); mbedtls_x509write_csr_set_key(&csr_ctx, &pk_key_container); // Create CSR status = mbedtls_x509write_csr_der(&csr_ctx,output_buf,sizeof(output_buf),psa_rng_for_mbedtls, NULL); if(status != 0) { return APP_ERROR; } mbedtls_x509write_csr_free(&csr_ctx); mbedtls_pk_free(&pk_key_container); printk("%s",&output_buf); return APP_SUCCESS; } int main(void) { int status; LOG_INF("Starting ECDSA example..."); status = crypto_init(); if (status != APP_SUCCESS) { LOG_INF(APP_ERROR_MESSAGE); return APP_ERROR; } status = generate_ecdsa_keypair(); if (status != APP_SUCCESS) { LOG_INF(APP_ERROR_MESSAGE); return APP_ERROR; } status = import_ecdsa_pub_key(); if (status != APP_SUCCESS) { LOG_INF(APP_ERROR_MESSAGE); return APP_ERROR; } status = generate_csr(); if (status != APP_SUCCESS) { LOG_INF(APP_ERROR_MESSAGE); return APP_ERROR; } // status = sign_message(); // if (status != APP_SUCCESS) { // LOG_INF(APP_ERROR_MESSAGE); // return APP_ERROR; // } // status = verify_message(); // 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; }