From cecc2e762b54c070fc80d3bb598e729cbd134e82 Mon Sep 17 00:00:00 2001 From: Andre Heinemans Date: Fri, 19 Apr 2024 12:29:05 +0200 Subject: [PATCH] controlse: add accesslib for the se05x secure element --- crypto/controlse/CMakeLists.txt | 45 ++ crypto/controlse/Kconfig | 5 +- crypto/controlse/Makefile | 7 +- crypto/controlse/ccertificate.cxx | 532 +++++++++++++ crypto/controlse/ccsr.cxx | 212 +++++ crypto/controlse/chex_util.cxx | 100 +++ crypto/controlse/cmbedtls_se05x_extension.hxx | 188 +++++ crypto/controlse/controlse_main.c | 737 ------------------ crypto/controlse/controlse_main.cxx | 711 +++++++++++++++++ crypto/controlse/cpublic_key.cxx | 243 ++++++ crypto/controlse/csan_builder.cxx | 124 +++ crypto/controlse/csecure_element.cxx | 189 +++++ crypto/controlse/cserial_number.cxx | 94 +++ crypto/controlse/cstring.cxx | 141 ++++ crypto/controlse/mbedtls_extension.c | 310 -------- crypto/controlse/mbedtls_extension.h | 40 - crypto/controlse/x509_utils.c | 350 --------- crypto/controlse/x509_utils.h | 54 -- include/crypto/controlse/ccertificate.hxx | 122 +++ include/crypto/controlse/ccsr.hxx | 92 +++ include/crypto/controlse/chex_util.hxx | 62 ++ include/crypto/controlse/cpublic_key.hxx | 82 ++ include/crypto/controlse/csan_builder.hxx | 69 ++ include/crypto/controlse/csecure_element.hxx | 73 ++ include/crypto/controlse/cserial_number.hxx | 62 ++ include/crypto/controlse/cstring.hxx | 64 ++ include/crypto/controlse/isecure_element.hxx | 71 ++ .../controlse/isecure_element_object.hxx | 51 ++ 28 files changed, 3335 insertions(+), 1495 deletions(-) create mode 100644 crypto/controlse/CMakeLists.txt create mode 100644 crypto/controlse/ccertificate.cxx create mode 100644 crypto/controlse/ccsr.cxx create mode 100644 crypto/controlse/chex_util.cxx create mode 100644 crypto/controlse/cmbedtls_se05x_extension.hxx delete mode 100644 crypto/controlse/controlse_main.c create mode 100644 crypto/controlse/controlse_main.cxx create mode 100644 crypto/controlse/cpublic_key.cxx create mode 100644 crypto/controlse/csan_builder.cxx create mode 100644 crypto/controlse/csecure_element.cxx create mode 100644 crypto/controlse/cserial_number.cxx create mode 100644 crypto/controlse/cstring.cxx delete mode 100644 crypto/controlse/mbedtls_extension.c delete mode 100644 crypto/controlse/mbedtls_extension.h delete mode 100644 crypto/controlse/x509_utils.c delete mode 100644 crypto/controlse/x509_utils.h create mode 100644 include/crypto/controlse/ccertificate.hxx create mode 100644 include/crypto/controlse/ccsr.hxx create mode 100644 include/crypto/controlse/chex_util.hxx create mode 100644 include/crypto/controlse/cpublic_key.hxx create mode 100644 include/crypto/controlse/csan_builder.hxx create mode 100644 include/crypto/controlse/csecure_element.hxx create mode 100644 include/crypto/controlse/cserial_number.hxx create mode 100644 include/crypto/controlse/cstring.hxx create mode 100644 include/crypto/controlse/isecure_element.hxx create mode 100644 include/crypto/controlse/isecure_element_object.hxx diff --git a/crypto/controlse/CMakeLists.txt b/crypto/controlse/CMakeLists.txt new file mode 100644 index 000000000..72fb36e01 --- /dev/null +++ b/crypto/controlse/CMakeLists.txt @@ -0,0 +1,45 @@ +# ############################################################################## +# apps/crypto/controlse/CMakeLists.txt +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_CRYPTO_CONTROLSE) + + set(MBEDTLS_DIR ${CMAKE_BINARY_DIR}/apps/include/mbedtls) + + nuttx_add_application( + NAME + ${CONFIG_CRYPTO_CONTROLSE_PROGNAME} + STACKSIZE + ${CONFIG_CRYPTO_CONTROLSE_STACKSIZE} + MODULE + ${CONFIG_CRYPTO_CONTROLSE} + SRCS + controlse_main.cxx + chex_util.cxx + csecure_element.cxx + cstring.cxx + ccertificate.cxx + ccsr.cxx + cpublic_key.cxx + cserial_number.cxx + csan_builder.cxx + INCLUDE_DIRECTORIES + ${MBEDTLS_DIR}) + +endif() diff --git a/crypto/controlse/Kconfig b/crypto/controlse/Kconfig index 550d09260..e1da37dcd 100644 --- a/crypto/controlse/Kconfig +++ b/crypto/controlse/Kconfig @@ -18,8 +18,9 @@ config CRYPTO_CONTROLSE select MBEDTLS_X509_CSR_WRITE_C select MBEDTLS_X509_CRT_WRITE_C ---help--- - Enable the controlse utility. This program is used control the - secure element device + Enable the controlse library and utility. It provides an + access library to the secure element device. The utility can + control the secure element device from the nuttx shell if CRYPTO_CONTROLSE diff --git a/crypto/controlse/Makefile b/crypto/controlse/Makefile index 6ad484059..c338507d1 100644 --- a/crypto/controlse/Makefile +++ b/crypto/controlse/Makefile @@ -18,6 +18,8 @@ # ############################################################################ +# Copyright 2023, 2024 NXP + include $(APPDIR)/Make.defs # controlse built-in application info @@ -28,7 +30,8 @@ STACKSIZE = $(CONFIG_CRYPTO_CONTROLSE_STACKSIZE) # controlse main source -MAINSRC = controlse_main.c -CSRCS = x509_utils.c mbedtls_extension.c +MAINSRC = controlse_main.cxx +CXXSRCS = chex_util.cxx csecure_element.cxx cstring.cxx ccertificate.cxx\ + ccsr.cxx cpublic_key.cxx cserial_number.cxx csan_builder.cxx include $(APPDIR)/Application.mk diff --git a/crypto/controlse/ccertificate.cxx b/crypto/controlse/ccertificate.cxx new file mode 100644 index 000000000..5731c4ddd --- /dev/null +++ b/crypto/controlse/ccertificate.cxx @@ -0,0 +1,532 @@ +//*************************************************************************** +// apps/crypto/controlse/ccertificate.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//*************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "crypto/controlse/ccertificate.hxx" + +#include "cmbedtls_se05x_extension.hxx" +#include "crypto/controlse/chex_util.hxx" +#include "crypto/controlse/cpublic_key.hxx" +#include "crypto/controlse/cserial_number.hxx" +#include "crypto/controlse/isecure_element.hxx" +#include +#include +#include +#include +#include +#include + +namespace Controlse +{ + +//*************************************************************************** +// Private Data +//*************************************************************************** + +static constexpr int SECONDS_IN_DAY = (60 * 60 * 24); +static constexpr size_t TBS_HASH_BUFFER_SIZE = 32; + +static constexpr char certificate_header[] = "-----BEGIN CERTIFICATE-----\n"; +static constexpr char certificate_footer[] = "-----END CERTIFICATE-----\n"; +static constexpr size_t datetime_size = 15; + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CCertificate::CCertificate(const ISecureElement &se, uint32_t keystore_id) +{ + mbedtls_x509_crt_init(&crt); + is_loaded = LoadFromSecureElement(se, keystore_id); +} + +CCertificate::CCertificate(const uint8_t *crt_der_or_pem, size_t crt_size) +{ + mbedtls_x509_crt_init(&crt); + is_loaded = LoadFromDerOrPem(crt_der_or_pem, crt_size); +} + +static void GetCurrentDateTime(char datetime[datetime_size], int seconds) +{ + time_t rawtime; + struct tm tm_info; + time(&rawtime); + rawtime += seconds; + strftime(datetime, datetime_size, "%Y%m%d%H%M%S", + gmtime_r(&rawtime, &tm_info)); +} + +CCertificate::CCertificate(const ISecureElement &se, + const uint8_t *csr_der_or_pem, size_t csr_size, + uint32_t keystore_id) +{ + mbedtls_x509_crt_init(&crt); + char from_datetime[datetime_size]; + char to_datetime[datetime_size]; + GetCurrentDateTime(from_datetime, 0); + GetCurrentDateTime(to_datetime, SECONDS_IN_DAY); + is_loaded = LoadFromCsrDerOrPem(se, csr_der_or_pem, csr_size, keystore_id, + from_datetime, to_datetime); +} + +CCertificate::CCertificate(const ISecureElement &se, + const uint8_t *csr_der_or_pem, size_t csr_size, + uint32_t keystore_id, const char *from_datetime, + const char *to_datetime) +{ + mbedtls_x509_crt_init(&crt); + is_loaded = LoadFromCsrDerOrPem(se, csr_der_or_pem, csr_size, keystore_id, + from_datetime, to_datetime); +} + +CCertificate::~CCertificate() { mbedtls_x509_crt_free(&crt); } + +bool CCertificate::IsLoaded() const { return is_loaded; } + +bool CCertificate::StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const +{ + struct se05x_key_transmission_s args; + args.entry.id = keystore_id; + args.content.buffer = crt.raw.p; + args.content.buffer_size = crt.raw.len; + args.content.buffer_content_size = crt.raw.len; + return se.SetData(args); +} + +bool CCertificate::LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) +{ + size_t certificate_der_size = 1000; + uint8_t *certificate_der = new uint8_t[certificate_der_size]; + struct se05x_key_transmission_s args + = { .entry = { .id = keystore_id }, + .content = { .buffer = certificate_der, + .buffer_size = certificate_der_size } }; + bool result = se.GetData(args); + + if (result) + { + result = 0 + == mbedtls_x509_crt_parse(&crt, certificate_der, + args.content.buffer_content_size); + } + + delete[] certificate_der; + return result; +} + +bool CCertificate::LoadFromDerOrPem(const uint8_t *crt_der_or_pem, + size_t crt_size) +{ + return 0 == mbedtls_x509_crt_parse(&crt, crt_der_or_pem, crt_size); +} + +bool CCertificate::LoadFromCsrDerOrPem(const ISecureElement &se, + const uint8_t *csr_der_or_pem, + size_t csr_size, uint32_t keystore_id, + const char *from_datetime, + const char *to_datetime) +{ + mbedtls_x509_csr csr; + mbedtls_x509_csr_init(&csr); + auto result = 0 == mbedtls_x509_csr_parse(&csr, csr_der_or_pem, csr_size); + + mbedtls_x509write_cert crt_builder; + mbedtls_x509write_crt_init(&crt_builder); + char subject_name[200]; + if (result) + { + mbedtls_x509write_crt_set_version(&crt_builder, + MBEDTLS_X509_CRT_VERSION_3); + result = 0 < mbedtls_x509_dn_gets(subject_name, sizeof(subject_name), + &csr.subject); + } + + mbedtls_pk_context key; + mbedtls_pk_init(&key); + if (result) + { + result = 0 + == MbedtlsSe05xExtension::mbedtls_pk_setup_key_se05x( + key, se, keystore_id); + } + + mbedtls_pk_context public_key; + public_key.pk_ctx = csr.pk.pk_ctx; + public_key.pk_info = csr.pk.pk_info; + + // Invalidate the public key in CSR + // The public key is transferred to CRT so the CSR may not free the memory + csr.pk.pk_ctx = nullptr; + csr.pk.pk_info = nullptr; + mbedtls_x509_csr_free(&csr); + + if (result) + { + mbedtls_x509write_crt_set_subject_key(&crt_builder, &public_key); + mbedtls_x509write_crt_set_issuer_key(&crt_builder, &key); + result = 0 + == mbedtls_x509write_crt_set_subject_name(&crt_builder, + subject_name); + } + + if (result) + { + result = 0 + == mbedtls_x509write_crt_set_issuer_name(&crt_builder, + "CN=CA,O=controlse,C=NL"); + } + + mbedtls_mpi serial; + mbedtls_mpi_init(&serial); + if (result) + { + mbedtls_x509write_crt_set_md_alg(&crt_builder, MBEDTLS_MD_SHA256); + result = 0 == mbedtls_mpi_read_string(&serial, 10, "1"); + } + + if (result) + { + result = 0 == mbedtls_x509write_crt_set_serial(&crt_builder, &serial); + } + + if (result) + { + result = 0 + == mbedtls_x509write_crt_set_validity( + &crt_builder, from_datetime, to_datetime); + } + + size_t buf_size = 1000; + uint8_t *buf = nullptr; + if (result) + { + buf = new uint8_t[buf_size]; + result = buf != nullptr; + } + + size_t buf_content_size; + if (result) + { + auto der_result + = mbedtls_x509write_crt_der(&crt_builder, buf, buf_size, nullptr, 0); + buf_content_size = der_result; + result = 0 < der_result; + } + + mbedtls_x509write_crt_free(&crt_builder); + MbedtlsSe05xExtension::mbedtls_pk_free_se05x(key); + mbedtls_pk_free(&key); + mbedtls_pk_free(&public_key); + mbedtls_mpi_free(&serial); + + if (result) + { + result = LoadFromDerOrPem(buf + buf_size - buf_content_size, + buf_content_size); + } + + if (buf) + { + delete[] buf; + } + return result; +} + +bool CCertificate::VerifyAgainst(const ISecureElement &se, + uint32_t verify_against_id) const +{ + if (!is_loaded) + { + return false; + } + + uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; + bool result = 0 == mbedtls_sha256(crt.tbs.p, crt.tbs.len, tbs_buffer, 0); + + if (result) + { + struct se05x_signature_s verify_args = { + .key_id = verify_against_id, + .algorithm = SE05X_ALGORITHM_SHA256, + .tbs = { .buffer = tbs_buffer, + .buffer_size = sizeof(tbs_buffer), + .buffer_content_size = sizeof(tbs_buffer) }, + .signature = { .buffer = crt.sig.p, + .buffer_size = crt.sig.len, + .buffer_content_size = crt.sig.len }, + }; + result = se.Verify(verify_args); + } + + return result; +} + +static bool check_time(const mbedtls_x509_time *before, + const mbedtls_x509_time *after) +{ + if (before->year > after->year) + return false; + + if (before->year == after->year && before->mon > after->mon) + return false; + + if (before->year == after->year && before->mon == after->mon + && before->day > after->day) + return false; + + if (before->year == after->year && before->mon == after->mon + && before->day == after->day && before->hour > after->hour) + return false; + + if (before->year == after->year && before->mon == after->mon + && before->day == after->day && before->hour == after->hour + && before->min > after->min) + return false; + + if (before->year == after->year && before->mon == after->mon + && before->day == after->day && before->hour == after->hour + && before->min == after->min && before->sec > after->sec) + return false; + + return true; +} + +int CCertificate::TestValidTimerange(time_t now) const +{ + + auto lt = gmtime(&now); + + mbedtls_x509_time mbedtls_now; + mbedtls_now.year = lt->tm_year + 1900; + mbedtls_now.mon = lt->tm_mon + 1; + mbedtls_now.day = lt->tm_mday; + mbedtls_now.hour = lt->tm_hour; + mbedtls_now.min = lt->tm_min; + mbedtls_now.sec = lt->tm_sec; + + if (!check_time(&mbedtls_now, &crt.valid_to)) + { + return -1; + } + if (!check_time(&crt.valid_from, &mbedtls_now)) + { + return 1; + } + + return 0; +} + +CPublicKey *CCertificate::GetPublicKey() const +{ + if (!is_loaded) + { + return nullptr; + } + + size_t root_key_buf_size = 100; + uint8_t *root_key_buf = new uint8_t[root_key_buf_size]; + + bool result = false; + if (root_key_buf) + { + mbedtls_ecp_keypair *keypair + = reinterpret_cast(crt.pk.pk_ctx); + result = 0 + == mbedtls_ecp_point_write_binary( + &keypair->grp, &keypair->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, + &root_key_buf_size, root_key_buf, root_key_buf_size); + } + + CPublicKey *public_key + = result ? new CPublicKey(root_key_buf, root_key_buf_size) : nullptr; + + if (root_key_buf) + { + delete[] root_key_buf; + } + + return public_key; +} + +char *CCertificate::GetOid(const char *oid) const +{ + if (!is_loaded) + { + return nullptr; + } + auto item = mbedtls_asn1_find_named_data(&crt.subject, oid, 3); + + if (item) + { + auto data = new char[item->val.len + 1]; + memcpy(data, item->val.p, item->val.len); + data[item->val.len] = 0; + return data; + } + return nullptr; +} + +CSerialNumber *CCertificate::GetSerialNumber() const +{ + if (!is_loaded) + { + return nullptr; + } + + if (crt.serial.len == CSerialNumber::SERIAL_NUMBER_SIZE) + { + auto serial = new CSerialNumber(crt.serial.p); + return serial; + } + return nullptr; +} + +size_t CCertificate::GetNumberOfSubjectAlternativeNames() const +{ + if (!is_loaded) + { + return 0; + } + size_t size = 0; + auto current = &crt.subject_alt_names; + + do + { + if (current->buf.tag + == (MBEDTLS_ASN1_CONTEXT_SPECIFIC + | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER)) + { + size++; + } + current = current->next; + } + while (current); + return size; +} + +char *CCertificate::GetSubjectAlternativeName(int item) const +{ + if (!is_loaded) + { + return nullptr; + } + + auto current = &crt.subject_alt_names; + + // go to first uri + while (current->buf.tag + != (MBEDTLS_ASN1_CONTEXT_SPECIFIC + | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER)) + { + current = current->next; + if (current == nullptr) + { + return nullptr; + } + } + + // go the next uri until we get to the correct item + for (int i = 0; i < item; i++) + { + do + { + current = current->next; + if (current == nullptr) + { + return nullptr; + } + } + while (current->buf.tag + != (MBEDTLS_ASN1_CONTEXT_SPECIFIC + | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER)); + } + + auto san = new char[current->buf.len + 1]; + if (san) + { + memcpy(san, current->buf.p, current->buf.len); + san[current->buf.len] = 0; + } + return san; +} + +size_t CCertificate::GetDer(uint8_t **der) const +{ + if (!is_loaded) + { + return 0; + } + *der = new uint8_t[crt.raw.len]; + memcpy(*der, crt.raw.p, crt.raw.len); + return crt.raw.len; +} + +char *CCertificate::GetPem() const +{ + if (!is_loaded) + { + return 0; + } + + char pem_buf[1000]; + size_t pem_content_size; + auto result = mbedtls_pem_write_buffer( + certificate_header, certificate_footer, crt.raw.p, crt.raw.len, + (uint8_t *)pem_buf, sizeof(pem_buf), &pem_content_size); + if (result != 0) + { + return nullptr; + } + + auto pem = new char[pem_content_size + 1]; + memcpy(pem, pem_buf, pem_content_size); + pem[pem_content_size] = 0; + return pem; +} + +bool CCertificate::ContainsSan(const char *name, size_t size) const +{ + auto san_amount = GetNumberOfSubjectAlternativeNames(); + for (size_t i = 0; i < san_amount; i++) + { + auto san = GetSubjectAlternativeName(i); + if (!san) + { + return false; + } + auto found = (memcmp(name, san, size) == 0); + delete[] san; + if (found) + { + return true; + } + } + return false; +} + +} // namespace Controlse diff --git a/crypto/controlse/ccsr.cxx b/crypto/controlse/ccsr.cxx new file mode 100644 index 000000000..e57f7b0d1 --- /dev/null +++ b/crypto/controlse/ccsr.cxx @@ -0,0 +1,212 @@ +//*************************************************************************** +// apps/crypto/controlse/ccsr.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "crypto/controlse/ccsr.hxx" + +#include "cmbedtls_se05x_extension.hxx" +#include "crypto/controlse/cpublic_key.hxx" +#include "crypto/controlse/csecure_element.hxx" +#include +#include + +using Controlse::MbedtlsSe05xExtension; + +namespace Controlse +{ + +//*************************************************************************** +// Private Data +//*************************************************************************** + +static const char certificate_request_header[] + = "-----BEGIN CERTIFICATE REQUEST-----\n"; +static const char certificate_request_footer[] + = "-----END CERTIFICATE REQUEST-----\n"; + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CCsr::CCsr(const ISecureElement &se, uint32_t keystore_id) +{ + mbedtls_x509_csr_init(&csr); + is_loaded = LoadFromSecureElement(se, keystore_id); +} + +CCsr::CCsr(const uint8_t *der_or_pem, const size_t size) +{ + mbedtls_x509_csr_init(&csr); + is_loaded = 0 == mbedtls_x509_csr_parse(&csr, der_or_pem, size); +} + +CCsr::~CCsr() { mbedtls_x509_csr_free(&csr); } + +bool CCsr::IsLoaded() const { return is_loaded; } + +bool CCsr::StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const +{ + struct se05x_key_transmission_s args; + args.entry.id = keystore_id; + args.content.buffer = csr.raw.p; + args.content.buffer_size = csr.raw.len; + args.content.buffer_content_size = csr.raw.len; + return se.SetData(args); +} + +bool CCsr::LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) +{ + size_t csr_der_size = 1000; + uint8_t *csr_der = new uint8_t[csr_der_size]; + struct se05x_key_transmission_s args + = { .entry = { .id = keystore_id }, + .content = { .buffer = csr_der, .buffer_size = csr_der_size } }; + bool result = se.GetData(args); + + if (result) + { + result = 0 + == mbedtls_x509_csr_parse(&csr, csr_der, + args.content.buffer_content_size); + } + + delete[] csr_der; + return result; +} + +size_t CCsr::GetDer(uint8_t **der) const +{ + if (!IsLoaded()) + { + return 0; + } + *der = new uint8_t[csr.raw.len]; + memcpy(*der, csr.raw.p, csr.raw.len); + return csr.raw.len; +} + +char *CCsr::GetPem() const +{ + if (!IsLoaded()) + { + return nullptr; + } + + char pem_buf[1000]; + size_t pem_content_size; + auto result = mbedtls_pem_write_buffer( + certificate_request_header, certificate_request_footer, csr.raw.p, + csr.raw.len, (uint8_t *)pem_buf, sizeof(pem_buf), &pem_content_size); + if (result != 0) + { + return nullptr; + } + + auto pem = new char[pem_content_size + 1]; + memcpy(pem, pem_buf, pem_content_size); + pem[pem_content_size] = 0; + return pem; +} + +CCsr::CsrBuilder::CsrBuilder(ISecureElement &se, const char *subject, + uint32_t key_slot_id) +{ + mbedtls_x509write_csr_init(&csr_w); + mbedtls_pk_init(&key); + + ready = 0 + == MbedtlsSe05xExtension::mbedtls_pk_setup_key_se05x(key, se, + key_slot_id); + + if (ready) + { + mbedtls_x509write_csr_set_key(&csr_w, &key); + ready = 0 == mbedtls_x509write_csr_set_subject_name(&csr_w, subject); + } + + if (ready) + { + mbedtls_x509write_csr_set_md_alg(&csr_w, MBEDTLS_MD_SHA256); + ready = 0 + == mbedtls_x509write_csr_set_key_usage( + &csr_w, MBEDTLS_X509_KU_KEY_CERT_SIGN); + } +} + +CCsr::CsrBuilder *CCsr::CsrBuilder::AddExtension(const char *oid, + size_t oid_size, + const uint8_t *value, + size_t value_size) +{ + if (ready) + { + ready = 0 + == mbedtls_x509write_csr_set_extension(&csr_w, oid, oid_size, 0, + value, value_size); + } + + return this; +} + +CCsr *CCsr::CsrBuilder::Build() +{ + size_t buf_size = 1000; + uint8_t *buf = nullptr; + if (ready) + { + buf = new uint8_t[buf_size]; + ready = nullptr != buf; + } + + int write_result_size = 0; + if (ready) + { + write_result_size + = mbedtls_x509write_csr_der(&csr_w, buf, buf_size, nullptr, 0); + ready = write_result_size > 0; + } + + MbedtlsSe05xExtension::mbedtls_pk_free_se05x(key); + mbedtls_x509write_csr_free(&csr_w); + + CCsr *result_csr = nullptr; + if (ready) + { + result_csr + = new CCsr(buf + buf_size - write_result_size, write_result_size); + } + + if (buf) + { + delete[] buf; + } + + return result_csr; +} + +} // namespace Controlse diff --git a/crypto/controlse/chex_util.cxx b/crypto/controlse/chex_util.cxx new file mode 100644 index 000000000..e2aebae76 --- /dev/null +++ b/crypto/controlse/chex_util.cxx @@ -0,0 +1,100 @@ +//*************************************************************************** +// apps/crypto/controlse/chex_util.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/chex_util.hxx" +#include +#include +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +size_t CHexUtil::GetByteArraySizeFromHexString(const char *hex_buffer) +{ + auto hex_buffer_size = strcspn(hex_buffer, " \r\n"); + return GetByteArraySizeFromHexStringSize(hex_buffer_size); +} + +size_t CHexUtil::GetByteArraySizeFromHexStringSize(size_t hex_buffer_size) +{ + return hex_buffer_size / AMOUNT_OF_HEXDIGITS_PER_BYTE; +} + +size_t CHexUtil::GetHexStringSizeFromByteArraySize(size_t byte_array_size) +{ + return byte_array_size * AMOUNT_OF_HEXDIGITS_PER_BYTE; +} + +uint8_t *CHexUtil::ConvertHexStringToByteArray(const char *hex_buffer) +{ + auto hex_buffer_size = strcspn(hex_buffer, " \r\n"); + if (hex_buffer_size & 1) + { + return nullptr; + } + + return ConvertHexStringToByteArray(hex_buffer, hex_buffer_size); +} + +uint8_t *CHexUtil::ConvertHexStringToByteArray(const char *hex_buffer, + size_t hex_buffer_size) +{ + auto bin_buffer + = new uint8_t[GetByteArraySizeFromHexStringSize(hex_buffer_size)]; + if (bin_buffer) + { + size_t hex_buffer_pos; + size_t bin_buffer_pos = 0; + for (hex_buffer_pos = 0; (hex_buffer_pos < hex_buffer_size); + hex_buffer_pos += AMOUNT_OF_HEXDIGITS_PER_BYTE) + { + sscanf(&hex_buffer[hex_buffer_pos], "%2hhx", + &bin_buffer[bin_buffer_pos]); + bin_buffer_pos++; + } + } + return bin_buffer; +} + +char *CHexUtil::ByteArrayToHexString(const uint8_t bytearray[], size_t size) +{ + auto string = new char[GetHexStringSizeFromByteArraySize(size) + 1]; + if (string) + { + char *ptr = string; + for (size_t i = 0; i < size; i++) + { + ptr += sprintf(ptr, "%02x", bytearray[i]); + } + } + return string; +} + +} // namespace Controlse diff --git a/crypto/controlse/cmbedtls_se05x_extension.hxx b/crypto/controlse/cmbedtls_se05x_extension.hxx new file mode 100644 index 000000000..9568ad667 --- /dev/null +++ b/crypto/controlse/cmbedtls_se05x_extension.hxx @@ -0,0 +1,188 @@ +//*************************************************************************** +// apps/crypto/controlse/cmbedtls_se05x_extensions.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "crypto/controlse/cpublic_key.hxx" +#include "crypto/controlse/isecure_element.hxx" +#include <../crypto/mbedtls/mbedtls/library/pk_wrap.h> +#include +#include +#include +#include +#include + +using Controlse::ISecureElement; + +struct mbedtls_se05x_ctx +{ + const ISecureElement *se; + uint32_t private_key_slot_id; +}; + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class MbedtlsSe05xExtension +{ +public: + static int mbedtls_pk_parse_se05x_public_key(mbedtls_pk_context &key, + CPublicKey &se05x_key) + { + mbedtls_ecp_keypair *keypair; + uint8_t *key_buffer = nullptr; + size_t key_buffer_size = 0; + if (se05x_key.IsLoaded()) + { + key_buffer_size = se05x_key.GetRawSize(); + key_buffer = new uint8_t[key_buffer_size]; + keypair = (mbedtls_ecp_keypair *)key.pk_ctx; + } + + int result = -ENOMEM; + if (key_buffer) + { + se05x_key.GetRaw(key_buffer); + result + = mbedtls_ecp_group_load(&keypair->grp, MBEDTLS_ECP_DP_SECP256R1); + } + + if (result == 0) + { + result = mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, + key_buffer, key_buffer_size); + } + + if (key_buffer) + { + delete[] key_buffer; + } + + return result; + } + + static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t sig_size, + size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) + { + + mbedtls_ecp_keypair *key = reinterpret_cast(ctx); + auto se05x_ctx = reinterpret_cast(key->d.p); + + struct se05x_signature_s args + = { se05x_ctx->private_key_slot_id, + SE05X_ALGORITHM_SHA256, + { const_cast(hash), hash_len, hash_len }, + { sig, sig_size, sig_size } }; + auto result = se05x_ctx->se->CreateSignature(args); + + if (result) + { + *sig_len = args.signature.buffer_content_size; + } + + return result ? 0 : -EPERM; + } + + // return value is allocated ptr to mbedtls_pk_info_t (need to be deleted) + // otherwise nulltpr + static mbedtls_pk_info_t *CreatePkInfoSe05x() + { + auto info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); + auto se05x_ec_info = new mbedtls_pk_info_t; + if (se05x_ec_info) + { + *se05x_ec_info = *info; + se05x_ec_info->sign_func = ecdsa_sign_wrap; + } + return se05x_ec_info; + } + + static int mbedtls_pk_setup_key_se05x(mbedtls_pk_context &key, + const ISecureElement &se, + uint32_t key_slot_id) + { + auto se05x_ec_info = CreatePkInfoSe05x(); + if (se05x_ec_info) + { + key.pk_info = se05x_ec_info; + key.pk_ctx = se05x_ec_info->ctx_alloc_func(); + } + + int result = -ENOMEM; + if (key.pk_ctx) + { + auto se05x_key = CPublicKey(se, key_slot_id); + result = mbedtls_pk_parse_se05x_public_key(key, se05x_key); + } + + mbedtls_se05x_ctx *se05x_ctx = nullptr; + if (result == 0) + { + se05x_ctx = new mbedtls_se05x_ctx; + result = se05x_ctx ? 0 : -ENOMEM; + } + + if (result == 0) + { + se05x_ctx->private_key_slot_id = key_slot_id; + se05x_ctx->se = &se; + } + + ((mbedtls_ecp_keypair *)key.pk_ctx)->d.p + = reinterpret_cast(se05x_ctx); + return result; + } + + static void mbedtls_pk_free_se05x(mbedtls_pk_context &key) + { + auto key_ctx = reinterpret_cast(key.pk_ctx); + if (key_ctx) + { + auto se05x_ctx = reinterpret_cast(key_ctx->d.p); + if (se05x_ctx) + { + delete se05x_ctx; + key_ctx->d.p = nullptr; + } + } + auto pk_info = key.pk_info; + if (pk_info) + { + mbedtls_pk_free(&key); + delete pk_info; + } + } +}; +} // namespace Controlse diff --git a/crypto/controlse/controlse_main.c b/crypto/controlse/controlse_main.c deleted file mode 100644 index f2ed327b8..000000000 --- a/crypto/controlse/controlse_main.c +++ /dev/null @@ -1,737 +0,0 @@ -/**************************************************************************** - * apps/crypto/controlse/controlse_main.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/* Copyright 2023 NXP */ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include -#define MBEDTLS_ALLOW_PRIVATE_ACCESS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_STACK_COLORATION -#include -#include -#endif - -#include "x509_utils.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define EOT 0x04 - -#define DEFAULT_SETTINGS \ - { \ - .se05x_dev_filename = default_se05x_device, 0 \ - } - -#define TBS_HASH_BUFFER_SIZE 32 -#define SIGNATURE_BUFFER_SIZE 300 -#define SYMM_KEY_BUFFER_SIZE 300 -#define RAW_KEY_BUFFER_SIZE 600 -#define DEFAULT_BUFFER_SIZE 1000 - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -typedef enum -{ - KEYSTORE_NO_ACTION = 0, - KEYSTORE_READ, - KEYSTORE_WRITE, - KEYSTORE_GENERATE, - KEYSTORE_DELETE, - KEYSTORE_DERIVE_SYMM_KEY, - KEYSTORE_CREATE_SIGNATURE, - KEYSTORE_VERIFY_SIGNATURE, - KEYSTORE_SIGN_CSR, - KEYSTORE_VERIFY_CERTIFICATE, - KEYSTORE_GET_INFO, - KEYSTORE_GET_UID, -} keystore_operation; - -struct settings_t -{ - FAR const char *se05x_dev_filename; - FAR char *input_filename; - FAR char *signature_filename; - bool skip_process; - keystore_operation operation; - bool raw_data_in_device; - bool interface_with_pem; - uint32_t key_id; - uint32_t private_key_id; - bool show_stack_used; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const char default_se05x_device[] = "/dev/se05x"; -static const char enter_key_hex[] = "enter key(hex)"; -static const char enter_data_pem[] = "enter data(pem)"; -static const char enter_data_raw[] = "enter data(raw)"; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void print_usage(FAR FILE *f, FAR char *prg) -{ - fprintf(f, "%s - Control SE05x Secure Element\n", prg); - fprintf(f, "\nUsage: %s [options] \n", prg); - fprintf(f, "Options:\n"); - fprintf(f, " -r (read item from keystore at )\n"); - fprintf(f, " -w (set item in keystore at )\n"); - fprintf(f, " -g (generate keypair at )\n"); - fprintf(f, " -d (delete key at )\n"); - fprintf(f, " -s (create signature for data\n"); - fprintf(f, " with key at )\n"); - fprintf(f, " -S (Sign CSR with key at )\n"); - fprintf(f, " -v (verify signature for data\n"); - fprintf(f, " with key at )\n"); - fprintf(f, " -V (verify CRT with key at \n"); - fprintf(f, " -a (derive symm key\n"); - fprintf(f, " from public key \n"); - fprintf(f, " and private key)\n"); - fprintf(f, " -t (interface using raw data\n"); - fprintf(f, " use with -r, -w)\n"); - fprintf(f, " -c (interface with PEM format\n"); - fprintf(f, " internally using DER\n"); - fprintf(f, " use with -r, -w)\n"); - fprintf(f, " -p (select private key\n"); - fprintf(f, " use with -a)\n"); - fprintf(f, " -n (Read input from file)\n"); - fprintf(f, " -N (Read signature from file)\n"); - fprintf(f, " -i (show generic information)\n"); - fprintf(f, " -u (show UID)\n"); - fprintf(f, " -m (show used stack memory space)\n"); - fprintf(f, " -h (show this help)\n"); - fprintf(f, "\n"); -} - -static int set_operation(FAR struct settings_t *settings, - keystore_operation operation, FAR char *key_id_text) -{ - int result = -EPERM; - if (settings->operation == KEYSTORE_NO_ACTION) - { - settings->operation = operation; - settings->key_id = 0; - if (key_id_text != NULL) - { - settings->key_id = (uint32_t)strtoul(key_id_text, NULL, 0); - } - - result = 0; - } - - return result; -} - -static int parse_arguments(int argc, FAR char *argv[], - FAR struct settings_t *settings) -{ - int result = 0; - int opt; - FAR char *prg = basename(argv[0]); - while ( - ((opt = getopt(argc, argv, "iug:w:r:d:s:v:S:V:tca:p:n:N:mh")) != -1) && - (result == 0)) - { - switch (opt) - { - case 'i': - result = set_operation(settings, KEYSTORE_GET_INFO, optarg); - break; - case 'u': - result = set_operation(settings, KEYSTORE_GET_UID, optarg); - break; - case 'g': - result = set_operation(settings, KEYSTORE_GENERATE, optarg); - break; - case 'r': - result = set_operation(settings, KEYSTORE_READ, optarg); - break; - case 'w': - result = set_operation(settings, KEYSTORE_WRITE, optarg); - break; - case 't': - settings->raw_data_in_device = TRUE; - break; - case 'c': - settings->interface_with_pem = TRUE; - settings->raw_data_in_device = TRUE; - break; - case 'd': - result = set_operation(settings, KEYSTORE_DELETE, optarg); - break; - case 's': - result = - set_operation(settings, KEYSTORE_CREATE_SIGNATURE, optarg); - break; - case 'v': - result = - set_operation(settings, KEYSTORE_VERIFY_SIGNATURE, optarg); - break; - case 'S': - result = set_operation(settings, KEYSTORE_SIGN_CSR, optarg); - break; - case 'V': - result = - set_operation(settings, KEYSTORE_VERIFY_CERTIFICATE, optarg); - break; - case 'a': - result = set_operation(settings, KEYSTORE_DERIVE_SYMM_KEY, optarg); - break; - case 'p': - settings->private_key_id = (uint32_t)strtoul(optarg, NULL, 0); - break; - case 'n': - settings->input_filename = optarg; - break; - case 'N': - settings->signature_filename = optarg; - break; - case 'm': - settings->show_stack_used = TRUE; - break; - case 'h': - print_usage(stdout, prg); - settings->skip_process = TRUE; - break; - default: - print_usage(stderr, prg); - result = -EINVAL; - break; - } - } - - if ((result == 0) && (!settings->skip_process)) - { - if (settings->operation == KEYSTORE_NO_ACTION) - { - print_usage(stderr, prg); - result = -EINVAL; - } - - /* if device is specified as positional argument */ - - if (optind != argc) - { - settings->se05x_dev_filename = argv[optind]; - } - } - - return result; -} - -static int convert_array_hex_to_bin(FAR char *hex_buffer, - size_t hex_buffer_size, - FAR uint8_t *bin_buffer, - size_t bin_buffer_size, - FAR size_t *bin_buffer_content_size) -{ - hex_buffer_size = strcspn(hex_buffer, " \r\n"); - if (hex_buffer_size & 1) - { - return -1; - } - - *bin_buffer_content_size = 0; - size_t hex_buffer_pos; - for (hex_buffer_pos = 0; (hex_buffer_pos < hex_buffer_size) && - (*bin_buffer_content_size < bin_buffer_size); - hex_buffer_pos += 2) - { - sscanf(&hex_buffer[hex_buffer_pos], "%2hhx", - &bin_buffer[*bin_buffer_content_size]); - (*bin_buffer_content_size)++; - } - - return hex_buffer_pos == hex_buffer_size ? 0 : -1; -} - -static int read_from_file(FAR const char *prompt, FAR char *filename, - FAR char *buffer, size_t buffer_size) -{ - FAR FILE *f = stdin; - if (filename != NULL) - { - f = fopen(filename, "r"); - } - else - { - puts(prompt); - } - - size_t buffer_content_size = 0; - if (f != NULL) - { - FAR char *c = buffer; - int result = fgetc(f); - while ((result != EOF) && (result != EOT) && - (buffer_content_size < buffer_size)) - { - *c = result & 0xff; - c++; - buffer_content_size++; - result = fgetc(f); - } - } - - if (filename != NULL) - { - fclose(f); - } - - return buffer_content_size; -} - -static int read_from_file_and_convert(FAR const char *prompt, - FAR char *filename, - FAR uint8_t *buffer, - size_t buffer_size, - FAR size_t *buffer_content_size) -{ - char file_buffer[DEFAULT_BUFFER_SIZE]; - size_t file_buffer_content_size; - int result; - - file_buffer_content_size = read_from_file( - prompt, filename, (FAR char *)file_buffer, sizeof(file_buffer)); - result = convert_array_hex_to_bin(file_buffer, file_buffer_content_size, - buffer, buffer_size, buffer_content_size - ); - - return result; -} - -static size_t add_zero_termination_character(char *data, size_t content_size, - size_t buf_size) -{ - size_t zero_termination_char_position = content_size - 1; - if ((content_size + 1) <= buf_size) - { - zero_termination_char_position = content_size; - content_size++; - } - - data[zero_termination_char_position] = 0; - return content_size; -} - -static int process(int se05x_fd, FAR struct settings_t *settings) -{ - int result = 0; - if (settings->operation == KEYSTORE_GET_INFO) - { - struct se05x_info_s info; - result = ioctl(se05x_fd, SEIOC_GET_INFO, &info); - - if (result == 0) - { - printf("OEF ID: %04x\n", info.oef_id); - } - } - - else if (settings->operation == KEYSTORE_GET_UID) - { - struct se05x_uid_s uid; - result = ioctl(se05x_fd, SEIOC_GET_UID, &uid); - - if (result == 0) - { - printf("UID: "); - for (size_t i = 0; i < SE05X_MODULE_UNIQUE_ID_LEN; i++) - { - printf("%02x", uid.uid[i]); - } - - printf("\n"); - } - } - else if (settings->operation == KEYSTORE_GENERATE) - { - struct se05x_generate_keypair_s args = { - .id = settings->key_id, .cipher = SE05X_ASYM_CIPHER_EC_NIST_P_256 - }; - - result = ioctl(se05x_fd, SEIOC_GENERATE_KEYPAIR, &args); - - if (result == 0) - { - printf("Keypair generated successfully\n"); - } - } - else if (settings->operation == KEYSTORE_WRITE) - { - char pem_buf[DEFAULT_BUFFER_SIZE]; - FAR const char *prompt = enter_key_hex; - if (settings->raw_data_in_device) - { - prompt = - settings->interface_with_pem ? enter_data_pem : enter_data_raw; - } - - size_t pem_content_size = read_from_file( - prompt, settings->input_filename, pem_buf, sizeof(pem_buf)); - - uint8_t rawkey[RAW_KEY_BUFFER_SIZE]; - size_t rawkey_size = sizeof(rawkey); - - FAR uint8_t *data = (FAR uint8_t *)pem_buf; - size_t data_size = pem_content_size; - if (!settings->raw_data_in_device) - { - result = convert_public_key_pem_to_raw(rawkey, rawkey_size, - &rawkey_size, pem_buf); - if (result == 0) - { - data = rawkey; - data_size = rawkey_size; - } - } - - if (settings->interface_with_pem) - { - pem_content_size = add_zero_termination_character( - pem_buf, pem_content_size, sizeof(pem_buf)); - result = convert_pem_certificate_or_csr_to_der( - rawkey, rawkey_size, &rawkey_size, pem_buf, pem_content_size); - if (result == 0) - { - data = rawkey; - data_size = rawkey_size; - } - } - - if (result == 0) - { - struct se05x_key_transmission_s args = { - .entry = {.id = settings->key_id, - .cipher = SE05X_ASYM_CIPHER_EC_NIST_P_256}, - .content = {.buffer = data, - .buffer_size = data_size, - .buffer_content_size = data_size} - }; - - result = ioctl(se05x_fd, - settings->raw_data_in_device ? SEIOC_SET_DATA - : SEIOC_SET_KEY, - &args); - } - - if (result == 0) - { - printf("Data stored successfully\n"); - } - } - else if (settings->operation == KEYSTORE_READ) - { - uint8_t buffer[DEFAULT_BUFFER_SIZE]; - struct se05x_key_transmission_s args = { - .entry = {.id = settings->key_id}, - .content = {.buffer = buffer, .buffer_size = sizeof(buffer)} - }; - - result = - ioctl(se05x_fd, - settings->raw_data_in_device ? SEIOC_GET_DATA : SEIOC_GET_KEY, - &args); - - FAR char *data = (FAR char *)args.content.buffer; - if ((result == 0) - && settings->raw_data_in_device - && !settings->interface_with_pem) - { - args.content.buffer_content_size = add_zero_termination_character( - data, args.content.buffer_content_size, - args.content.buffer_size); - } - - char pem_buf[DEFAULT_BUFFER_SIZE]; - if ((result == 0) && !settings->raw_data_in_device) - { - result = convert_public_key_raw_to_pem( - pem_buf, sizeof(pem_buf), args.content.buffer, - args.content.buffer_content_size); - - data = pem_buf; - } - - if ((result == 0) && settings->interface_with_pem) - { - size_t pem_content_size; - result = convert_der_certificate_or_csr_to_pem( - pem_buf, sizeof(pem_buf), &pem_content_size, - args.content.buffer, args.content.buffer_content_size); - - data = pem_buf; - } - - if (result == 0) - { - puts(data); - } - } - else if (settings->operation == KEYSTORE_DELETE) - { - result = ioctl(se05x_fd, SEIOC_DELETE_KEY, settings->key_id); - - if (result == 0) - { - printf("Deleted key successfully\n"); - } - } - else if (settings->operation == KEYSTORE_DERIVE_SYMM_KEY) - { - uint8_t buffer[SYMM_KEY_BUFFER_SIZE]; - struct se05x_derive_key_s args = { - .private_key_id = settings->private_key_id, - .public_key_id = settings->key_id, - .content = {.buffer = buffer, .buffer_size = sizeof(buffer)}, - }; - - result = ioctl(se05x_fd, SEIOC_DERIVE_SYMM_KEY, &args); - - if (result == 0) - { - for (size_t i = 0; i < args.content.buffer_content_size; i++) - { - printf("%02x", args.content.buffer[i]); - } - - printf("\n"); - } - } - else if (settings->operation == KEYSTORE_CREATE_SIGNATURE) - { - uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; - size_t tbs_content_size; - read_from_file_and_convert("Enter tbs(hex):", settings->input_filename, - tbs_buffer, sizeof(tbs_buffer), - &tbs_content_size); - uint8_t signature_buffer[SIGNATURE_BUFFER_SIZE]; - size_t signature_content_len = 0; - if (result == 0) - { - struct se05x_signature_s args = { - .key_id = settings->key_id, - .algorithm = SE05X_ALGORITHM_SHA256, - .tbs = {.buffer = tbs_buffer, - .buffer_size = tbs_content_size, - .buffer_content_size = tbs_content_size}, - .signature = {.buffer = signature_buffer, - .buffer_size = sizeof(signature_buffer)}, - }; - - result = ioctl(se05x_fd, SEIOC_CREATE_SIGNATURE, &args); - signature_content_len = args.signature.buffer_content_size; - } - - if (result == 0) - { - for (size_t i = 0; i < signature_content_len; i++) - { - printf("%02x", signature_buffer[i]); - } - - printf("\n"); - } - } - else if (settings->operation == KEYSTORE_VERIFY_SIGNATURE) - { - uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; - size_t tbs_content_size; - result = read_from_file_and_convert( - "Enter tbs(hex):", settings->input_filename, tbs_buffer, - sizeof(tbs_buffer), &tbs_content_size); - - uint8_t signature_buffer[SIGNATURE_BUFFER_SIZE]; - size_t signature_content_size; - if (result == 0) - { - result = read_from_file_and_convert( - "Enter signature(hex):", settings->signature_filename, - signature_buffer, sizeof(signature_buffer), - &signature_content_size); - } - - if (result == 0) - { - struct se05x_signature_s args = { - .key_id = settings->key_id, - .algorithm = SE05X_ALGORITHM_SHA256, - .tbs = {.buffer = tbs_buffer, - .buffer_size = tbs_content_size, - .buffer_content_size = tbs_content_size}, - .signature = {.buffer = signature_buffer, - .buffer_size = signature_content_size, - .buffer_content_size = signature_content_size}, - }; - - result = ioctl(se05x_fd, SEIOC_VERIFY_SIGNATURE, &args); - } - - if (result == 0) - { - printf("Signature verified successfully\n"); - } - } - else if (settings->operation == KEYSTORE_SIGN_CSR) - { - char csr_pem_buf[DEFAULT_BUFFER_SIZE]; - size_t csr_pem_buf_content_size = - read_from_file("enter csr(pem)", settings->input_filename, - csr_pem_buf, sizeof(csr_pem_buf)); - - csr_pem_buf_content_size = add_zero_termination_character(csr_pem_buf, - csr_pem_buf_content_size, sizeof(csr_pem_buf)); - - char crt_pem_buf[DEFAULT_BUFFER_SIZE]; - result = sign_csr(se05x_fd, settings->key_id, crt_pem_buf, - sizeof(crt_pem_buf), csr_pem_buf, - csr_pem_buf_content_size); - if (result == 0) - { - puts(crt_pem_buf); - } - } - else if (settings->operation == KEYSTORE_VERIFY_CERTIFICATE) - { - char pem_buf[DEFAULT_BUFFER_SIZE]; - size_t pem_content_size = - read_from_file("enter crt(pem)", settings->input_filename, pem_buf, - sizeof(pem_buf)); - - pem_content_size = add_zero_termination_character(pem_buf, - pem_content_size, sizeof(pem_buf)); - - mbedtls_x509_crt crt; - mbedtls_x509_crt_init(&crt); - result = mbedtls_x509_crt_parse(&crt, (FAR uint8_t *)pem_buf, - pem_content_size); - - uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; - - if (result == 0) - { - result = mbedtls_sha256(crt.tbs.p, - crt.tbs.len, tbs_buffer, 0 - ); - } - - if (result == 0) - { - struct se05x_signature_s args = { - .key_id = settings->key_id, - .algorithm = SE05X_ALGORITHM_SHA256, - .tbs = {.buffer = tbs_buffer, - .buffer_size = sizeof(tbs_buffer), - .buffer_content_size = sizeof(tbs_buffer)}, - .signature = {.buffer = crt.sig.p, - .buffer_size = crt.sig.len, - .buffer_content_size = - crt.sig.len}, - }; - - result = ioctl(se05x_fd, SEIOC_VERIFY_SIGNATURE, &args); - } - - if (result == 0) - { - printf("Signature verified successfully\n"); - } - - mbedtls_x509_crt_free(&crt); - } - - return result; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int main(int argc, FAR char *argv[]) -{ - struct settings_t settings = DEFAULT_SETTINGS; - int result = parse_arguments(argc, argv, &settings); - - if ((result == 0) && (!settings.skip_process)) - { - int fd = open(settings.se05x_dev_filename, O_RDONLY); - if (fd == -1) - { - result = -ENODEV; - } - else - { - result = process(fd, &settings); - close(fd); - } - } - - if (result != 0) - { - fprintf(stderr, "err %i: %s\n", -result, strerror(-result)); - } - - if (settings.show_stack_used) - { -#ifdef CONFIG_STACK_COLORATION - FAR struct tcb_s *tcb; - tcb = nxsched_get_tcb(getpid()); - fprintf(stderr, "\nStack used: %zu / %zu\n", - up_check_tcbstack(tcb), tcb->adj_stack_size); -#else - fprintf(stderr, "\nStack used: unknown" - " (STACK_COLORATION must be enabled)\n"); -#endif - } - - return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/crypto/controlse/controlse_main.cxx b/crypto/controlse/controlse_main.cxx new file mode 100644 index 000000000..238a85233 --- /dev/null +++ b/crypto/controlse/controlse_main.cxx @@ -0,0 +1,711 @@ +//*************************************************************************** +// apps/crypto/controlse/controlse_main.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2023, 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/ccertificate.hxx" +#include "crypto/controlse/ccsr.hxx" +#include "crypto/controlse/chex_util.hxx" +#include "crypto/controlse/cpublic_key.hxx" +#include "crypto/controlse/csecure_element.hxx" +#include "crypto/controlse/cstring.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_STACK_COLORATION +#include +#include +#endif + +//*************************************************************************** +// Pre-processor Definitions +//************************************************************************** + +#define EOT 0x04 + +#define DEFAULT_SETTINGS \ + { \ + .se05x_dev_filename = default_se05x_device, 0 \ + } + +#define TBS_HASH_BUFFER_SIZE 32 +#define SIGNATURE_BUFFER_SIZE 300 +#define SYMM_KEY_BUFFER_SIZE 300 +#define RAW_KEY_BUFFER_SIZE 600 +#define DEFAULT_BUFFER_SIZE 1000 + +//*************************************************************************** +// Private Types +//************************************************************************** + +typedef enum +{ + KEYSTORE_NO_ACTION = 0, + KEYSTORE_READ, + KEYSTORE_WRITE, + KEYSTORE_GENERATE, + KEYSTORE_DELETE, + KEYSTORE_DERIVE_SYMM_KEY, + KEYSTORE_CREATE_SIGNATURE, + KEYSTORE_VERIFY_SIGNATURE, + KEYSTORE_SIGN_CSR, + KEYSTORE_VERIFY_CERTIFICATE, + KEYSTORE_GET_INFO, + KEYSTORE_GET_UID, +} EKeystoreOperation; + +typedef enum +{ + KEYSTORE_DATA_TYPE_KEY = 0, + KEYSTORE_DATA_TYPE_CERT_OR_CSR, + KEYSTORE_DATA_TYPE_STRING, +} EKeystoreDataType; + +struct SSettings +{ + FAR const char *se05x_dev_filename; + FAR char *input_filename; + FAR char *signature_filename; + bool skip_process; + EKeystoreOperation operation; + EKeystoreDataType data_type; + uint32_t key_id; + uint32_t private_key_id; + bool show_stack_used; +}; + +//*************************************************************************** +// Private Function Prototypes +//************************************************************************** + +extern "C" int main(int argc, FAR char *argv[]); + +//*************************************************************************** +// Private Data +//************************************************************************** + +static const char default_se05x_device[] = "/dev/se05x"; +static const char enter_key_hex[] = "enter key(hex)"; +static const char enter_data_pem[] = "enter data(pem)"; +static const char enter_data_raw[] = "enter data(raw)"; + +//*************************************************************************** +// Public Data +//************************************************************************** + +//*************************************************************************** +// Private Functions +//************************************************************************** + +static void printUsage(FAR FILE *f, FAR char *prg) +{ + fprintf(f, "%s - Control SE05x Secure Element\n", prg); + fprintf(f, "\nUsage: %s [options] \n", prg); + fprintf(f, "Options:\n"); + fprintf(f, " -r (read item from keystore at )\n"); + fprintf(f, " -w (set item in keystore at )\n"); + fprintf(f, " -g (generate keypair at )\n"); + fprintf(f, " -d (delete key at )\n"); + fprintf(f, " -s (create signature for data\n"); + fprintf(f, " with key at )\n"); + fprintf(f, " -S (Sign CSR with key at )\n"); + fprintf(f, " -v (verify signature for data\n"); + fprintf(f, " with key at )\n"); + fprintf(f, " -V (verify CRT with key at \n"); + fprintf(f, " -a (derive symm key\n"); + fprintf(f, " from public key \n"); + fprintf(f, " and private key)\n"); + fprintf(f, " -t (interface using raw data\n"); + fprintf(f, " use with -r, -w)\n"); + fprintf(f, " -c (interface with PEM format\n"); + fprintf(f, " internally using DER\n"); + fprintf(f, " use with -r, -w)\n"); + fprintf(f, " -p (select private key\n"); + fprintf(f, " use with -a)\n"); + fprintf(f, " -n (Read input from file)\n"); + fprintf(f, " -N (Read signature from file)\n"); + fprintf(f, " -i (show generic information)\n"); + fprintf(f, " -u (show UID)\n"); + fprintf(f, " -m (show used stack memory space)\n"); + fprintf(f, " -h (show this help)\n"); + fprintf(f, "\n"); +} + +static int setOperation(FAR struct SSettings *settings, + EKeystoreOperation operation, FAR char *key_id_text) +{ + int result = -EPERM; + if (settings->operation == KEYSTORE_NO_ACTION) + { + settings->operation = operation; + settings->key_id = 0; + if (key_id_text != NULL) + { + settings->key_id = (uint32_t)strtoul(key_id_text, NULL, 0); + } + + result = 0; + } + + return result; +} + +static int parseArguments(int argc, FAR char *argv[], + FAR struct SSettings *settings) +{ + int result = 0; + int opt; + FAR char *prg = basename(argv[0]); + while (((opt = getopt(argc, argv, "iug:w:r:d:s:v:S:V:tca:p:n:N:mh")) != -1) + && (result == 0)) + { + switch (opt) + { + case 'i': + result = setOperation(settings, KEYSTORE_GET_INFO, optarg); + break; + case 'u': + result = setOperation(settings, KEYSTORE_GET_UID, optarg); + break; + case 'g': + result = setOperation(settings, KEYSTORE_GENERATE, optarg); + break; + case 'r': + result = setOperation(settings, KEYSTORE_READ, optarg); + break; + case 'w': + result = setOperation(settings, KEYSTORE_WRITE, optarg); + break; + case 't': + settings->data_type = KEYSTORE_DATA_TYPE_STRING; + break; + case 'c': + settings->data_type = KEYSTORE_DATA_TYPE_CERT_OR_CSR; + break; + case 'd': + result = setOperation(settings, KEYSTORE_DELETE, optarg); + break; + case 's': + result = setOperation(settings, KEYSTORE_CREATE_SIGNATURE, optarg); + break; + case 'v': + result = setOperation(settings, KEYSTORE_VERIFY_SIGNATURE, optarg); + break; + case 'S': + result = setOperation(settings, KEYSTORE_SIGN_CSR, optarg); + break; + case 'V': + result = setOperation(settings, KEYSTORE_VERIFY_CERTIFICATE, optarg); + break; + case 'a': + result = setOperation(settings, KEYSTORE_DERIVE_SYMM_KEY, optarg); + break; + case 'p': + settings->private_key_id = (uint32_t)strtoul(optarg, NULL, 0); + break; + case 'n': + settings->input_filename = optarg; + break; + case 'N': + settings->signature_filename = optarg; + break; + case 'm': + settings->show_stack_used = TRUE; + break; + case 'h': + printUsage(stdout, prg); + settings->skip_process = TRUE; + break; + default: + printUsage(stderr, prg); + result = -EINVAL; + break; + } + } + + if ((result == 0) && (!settings->skip_process)) + { + if (settings->operation == KEYSTORE_NO_ACTION) + { + printUsage(stderr, prg); + result = -EINVAL; + } + + // if device is specified as positional argument + + if (optind != argc) + { + settings->se05x_dev_filename = argv[optind]; + } + } + + return result; +} + +// TODO: use chexutil +static int convert_array_hex_to_bin(FAR char *hex_buffer, + size_t hex_buffer_size, + FAR uint8_t *bin_buffer, + size_t bin_buffer_size, + FAR size_t *bin_buffer_content_size) +{ + hex_buffer_size = strcspn(hex_buffer, " \r\n"); + if (hex_buffer_size & 1) + { + return -1; + } + + *bin_buffer_content_size = 0; + size_t hex_buffer_pos; + for (hex_buffer_pos = 0; (hex_buffer_pos < hex_buffer_size) + && (*bin_buffer_content_size < bin_buffer_size); + hex_buffer_pos += 2) + { + sscanf(&hex_buffer[hex_buffer_pos], "%2hhx", + &bin_buffer[*bin_buffer_content_size]); + (*bin_buffer_content_size)++; + } + + return hex_buffer_pos == hex_buffer_size ? 0 : -1; +} + +static int readFromFile(FAR const char *prompt, FAR char *filename, + FAR char *buffer, size_t buffer_size) +{ + FAR FILE *f = stdin; + if (filename != NULL) + { + f = fopen(filename, "r"); + } + else + { + puts(prompt); + } + + size_t buffer_content_size = 0; + if (f != NULL) + { + FAR char *c = buffer; + int result = fgetc(f); + // keep looping until EOF or EOT are received or the buffer has only 1 + // space left (needed for the zero termination character) + while ((result != EOF) && (result != EOT) + && ((buffer_content_size + 1) < buffer_size)) + { + *c = result & 0xff; + c++; + buffer_content_size++; + result = fgetc(f); + } + // Add zero termination character + *c = 0; + buffer_content_size++; + } + + puts("\n"); + + if (filename != NULL) + { + fclose(f); + } + + return buffer_content_size; +} + +static int readFromFileAndConvert(FAR const char *prompt, FAR char *filename, + FAR uint8_t *buffer, size_t buffer_size, + FAR size_t *buffer_content_size) +{ + char file_buffer[DEFAULT_BUFFER_SIZE]; + size_t file_buffer_content_size; + int result; + + file_buffer_content_size = readFromFile( + prompt, filename, (FAR char *)file_buffer, sizeof(file_buffer)); + result = convert_array_hex_to_bin(file_buffer, file_buffer_content_size, + buffer, buffer_size, buffer_content_size); + + return result; +} + +static size_t addZeroTerminationCharacter(char *data, size_t content_size, + size_t buf_size) +{ + size_t zero_termination_char_position = content_size - 1; + if ((content_size + 1) <= buf_size) + { + zero_termination_char_position = content_size; + content_size++; + } + + data[zero_termination_char_position] = 0; + return content_size; +} + +static int process(int se05x_fd, FAR struct SSettings *settings) +{ + int result = 0; + Controlse::CSecureElement se(se05x_fd); + if (settings->operation == KEYSTORE_GET_INFO) + { + struct se05x_info_s info; + result = se.GetInfo(info) ? 0 : -EPERM; + + if (result == 0) + { + printf("OEF ID: %04x\n", info.oef_id); + } + } + else if (settings->operation == KEYSTORE_GET_UID) + { + struct se05x_uid_s uid; + result = se.GetUid(uid) ? 0 : -EPERM; + if (result == 0) + { + printf("UID: "); + for (size_t i = 0; i < SE05X_MODULE_UNIQUE_ID_LEN; i++) + { + printf("%02x", uid.uid[i]); + } + + printf("\n"); + } + } + else if (settings->operation == KEYSTORE_GENERATE) + { + struct se05x_generate_keypair_s args + = { .id = settings->key_id, + .cipher = SE05X_ASYM_CIPHER_EC_NIST_P_256 }; + + result = se.GenerateKey(args) ? 0 : -EPERM; + + if (result == 0) + { + printf("Keypair generated successfully\n"); + } + } + else if (settings->operation == KEYSTORE_WRITE) + { + char data[DEFAULT_BUFFER_SIZE]; + FAR const char *prompt = settings->data_type == KEYSTORE_DATA_TYPE_STRING + ? enter_data_raw + : enter_data_pem; + + size_t data_size + = readFromFile(prompt, settings->input_filename, data, sizeof(data)); + + result = -EINVAL; + if (data_size != 0) + { + Controlse::ISecureElementObject *object = nullptr; + if (settings->data_type == KEYSTORE_DATA_TYPE_STRING) + { + object = new Controlse::CString( + data, + data_size - 1); // -1 because no zero termination character + // required + } + else if (settings->data_type == KEYSTORE_DATA_TYPE_KEY) + { + object = new Controlse::CPublicKey(data); + } + else if (settings->data_type == KEYSTORE_DATA_TYPE_CERT_OR_CSR) + { + object = new Controlse::CCertificate( + reinterpret_cast(data), data_size); + if (object) + { + if (!object->IsLoaded()) + { + delete object; + object = new Controlse::CCsr( + reinterpret_cast(data), data_size); + } + } + } + + result = -EPERM; + if (object) + { + if (object->IsLoaded()) + { + result = object->StoreOnSecureElement(se, settings->key_id) + ? 0 + : -EPERM; + } + delete object; + } + } + + if (result == 0) + { + printf("Data stored successfully\n"); + } + } + else if (settings->operation == KEYSTORE_READ) + { + char *data = nullptr; + if (settings->data_type == KEYSTORE_DATA_TYPE_STRING) + { + Controlse::CString string(se, settings->key_id); + if (string.IsLoaded()) + { + data = string.c_str(); + } + } + else if (settings->data_type == KEYSTORE_DATA_TYPE_KEY) + { + Controlse::CPublicKey key(se, settings->key_id); + if (key.IsLoaded()) + { + data = key.GetPem(); + } + } + else if (settings->data_type == KEYSTORE_DATA_TYPE_CERT_OR_CSR) + { + Controlse::CCertificate cert(se, settings->key_id); + if (cert.IsLoaded()) + { + data = cert.GetPem(); + } + else + { + Controlse::CCsr csr(se, settings->key_id); + if (csr.IsLoaded()) + { + data = csr.GetPem(); + } + } + } + if (data) + { + puts(data); + delete[] data; + } + else + { + result = -EPERM; + } + } + else if (settings->operation == KEYSTORE_DELETE) + { + result = se.DeleteKey(settings->key_id) ? 0 : -EPERM; + if (result == 0) + { + printf("Deleted key successfully\n"); + } + } + else if (settings->operation == KEYSTORE_DERIVE_SYMM_KEY) + { + uint8_t buffer[SYMM_KEY_BUFFER_SIZE]; + struct se05x_derive_key_s args = { + .private_key_id = settings->private_key_id, + .public_key_id = settings->key_id, + .content = { .buffer = buffer, .buffer_size = sizeof(buffer) }, + }; + + result = se.DeriveSymmetricalKey(args) ? 0 : -EPERM; + + if (result == 0) + { + for (size_t i = 0; i < args.content.buffer_content_size; i++) + { + printf("%02x", args.content.buffer[i]); + } + printf("\n"); + } + } + else if (settings->operation == KEYSTORE_CREATE_SIGNATURE) + { + uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; + size_t tbs_content_size; + readFromFileAndConvert("Enter tbs(hex):", settings->input_filename, + tbs_buffer, sizeof(tbs_buffer), + &tbs_content_size); + uint8_t signature_buffer[SIGNATURE_BUFFER_SIZE]; + size_t signature_content_len = 0; + if (result == 0) + { + struct se05x_signature_s args = { + .key_id = settings->key_id, + .algorithm = SE05X_ALGORITHM_SHA256, + .tbs = { .buffer = tbs_buffer, + .buffer_size = tbs_content_size, + .buffer_content_size = tbs_content_size }, + .signature = { .buffer = signature_buffer, + .buffer_size = sizeof(signature_buffer) }, + }; + + result = se.CreateSignature(args) ? 0 : -EPERM; + signature_content_len = args.signature.buffer_content_size; + } + + if (result == 0) + { + for (size_t i = 0; i < signature_content_len; i++) + { + printf("%02x", signature_buffer[i]); + } + + printf("\n"); + } + } + else if (settings->operation == KEYSTORE_VERIFY_SIGNATURE) + { + uint8_t tbs_buffer[TBS_HASH_BUFFER_SIZE]; + size_t tbs_content_size; + result = readFromFileAndConvert( + "Enter tbs(hex):", settings->input_filename, tbs_buffer, + sizeof(tbs_buffer), &tbs_content_size); + + uint8_t signature_buffer[SIGNATURE_BUFFER_SIZE]; + size_t signature_content_size; + if (result == 0) + { + result = readFromFileAndConvert( + "Enter signature(hex):", settings->signature_filename, + signature_buffer, sizeof(signature_buffer), + &signature_content_size); + } + + if (result == 0) + { + struct se05x_signature_s args = { + .key_id = settings->key_id, + .algorithm = SE05X_ALGORITHM_SHA256, + .tbs = { .buffer = tbs_buffer, + .buffer_size = tbs_content_size, + .buffer_content_size = tbs_content_size }, + .signature = { .buffer = signature_buffer, + .buffer_size = signature_content_size, + .buffer_content_size = signature_content_size }, + }; + + result = se.Verify(args) ? 0 : -EPERM; + } + + if (result == 0) + { + printf("Signature verified successfully\n"); + } + } + else if (settings->operation == KEYSTORE_SIGN_CSR) + { + char csr_pem_buf[DEFAULT_BUFFER_SIZE]; + size_t csr_pem_buf_content_size + = readFromFile("enter csr(pem)", settings->input_filename, + csr_pem_buf, sizeof(csr_pem_buf)); + + csr_pem_buf_content_size = addZeroTerminationCharacter( + csr_pem_buf, csr_pem_buf_content_size, sizeof(csr_pem_buf)); + + auto certificate = Controlse::CCertificate( + se, reinterpret_cast(csr_pem_buf), + csr_pem_buf_content_size, settings->key_id); + + auto crt_pem = certificate.GetPem(); + if (crt_pem) + { + puts(crt_pem); + delete[] crt_pem; + } + else + { + result = -EPERM; + } + } + else if (settings->operation == KEYSTORE_VERIFY_CERTIFICATE) + { + char pem_buf[DEFAULT_BUFFER_SIZE]; + size_t pem_content_size + = readFromFile("enter crt(pem)", settings->input_filename, pem_buf, + sizeof(pem_buf)); + + pem_content_size = addZeroTerminationCharacter(pem_buf, pem_content_size, + sizeof(pem_buf)); + + auto certificate = Controlse::CCertificate( + reinterpret_cast(pem_buf), pem_content_size); + + result = certificate.VerifyAgainst(se, settings->key_id) ? 0 : -EPERM; + + if (result == 0) + { + printf("Signature verified successfully\n"); + } + } + + return result; +} + +//*************************************************************************** +// Public Functions +//************************************************************************** + +int main(int argc, FAR char *argv[]) +{ + struct SSettings settings = DEFAULT_SETTINGS; + int result = parseArguments(argc, argv, &settings); + + if ((result == 0) && (!settings.skip_process)) + { + int fd = open(settings.se05x_dev_filename, O_RDONLY); + if (fd == -1) + { + result = -ENODEV; + } + else + { + result = process(fd, &settings); + close(fd); + } + } + + if (result != 0) + { + fprintf(stderr, "err %i: %s\n", -result, strerror(-result)); + } + + if (settings.show_stack_used) + { +#ifdef CONFIG_STACK_COLORATION + FAR struct tcb_s *tcb; + tcb = nxsched_get_tcb(getpid()); + fprintf(stderr, "\nStack used: %zu / %zu\n", up_check_tcbstack(tcb), + tcb->adj_stack_size); +#else + fprintf(stderr, "\nStack used: unknown" + " (STACK_COLORATION must be enabled)\n"); +#endif + } + + return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/crypto/controlse/cpublic_key.cxx b/crypto/controlse/cpublic_key.cxx new file mode 100644 index 000000000..10a7aad91 --- /dev/null +++ b/crypto/controlse/cpublic_key.cxx @@ -0,0 +1,243 @@ +//*************************************************************************** +// apps/crypto/controlse/cpublic_key.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "crypto/controlse/cpublic_key.hxx" +#include "crypto/controlse/isecure_element.hxx" +#include "crypto/controlse/isecure_element_object.hxx" +#include +#include +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CPublicKey::CPublicKey(const ISecureElement &se, uint32_t keystore_id) +{ + (void)LoadFromSecureElement(se, keystore_id); +} + +CPublicKey::CPublicKey(const char *pem) +{ + uint8_t key_buf[300]; + m_key = nullptr; + if (0 + == convert_public_key_pem_to_raw(key_buf, sizeof(key_buf), &m_size, pem)) + { + m_key = new uint8_t[m_size]; + memcpy(m_key, key_buf, m_size); + } +} + +CPublicKey::CPublicKey(const uint8_t *buffer, size_t buffer_size) + : m_key(new uint8_t[buffer_size]), m_size(buffer_size) +{ + memcpy(m_key, buffer, m_size); +} + +CPublicKey::CPublicKey(const CPublicKey &p1) : CPublicKey(p1.m_key, p1.m_size) +{ +} + +CPublicKey::~CPublicKey() { Unload(); } + +CPublicKey &CPublicKey::operator=(const CPublicKey &other) +{ + if (this != &other) + { + auto new_key = new uint8_t[other.m_size]; + memcpy(new_key, other.m_key, other.m_size); + + delete[] m_key; + + m_key = new_key; + m_size = other.m_size; + } + return *this; +} + +void CPublicKey::Unload() +{ + if (IsLoaded()) + { + delete[] m_key; + m_key = NULL; + m_size = 0; + } +} + +bool CPublicKey::IsLoaded() const { return m_key != NULL; } + +bool CPublicKey::StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const +{ + if (!IsLoaded()) + { + return false; + } + + struct se05x_key_transmission_s args = { + .entry = { .id = keystore_id, .cipher = SE05X_ASYM_CIPHER_EC_NIST_P_256 }, + .content + = { .buffer = m_key, .buffer_size = m_size, .buffer_content_size = m_size } + }; + return se.SetKey(args); +} + +bool CPublicKey::LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) +{ + Unload(); + + m_size = 100; + m_key = new uint8_t[m_size]; + struct se05x_key_transmission_s args = { + .entry = { .id = keystore_id, .cipher = SE05X_ASYM_CIPHER_EC_NIST_P_256 }, + .content + = { .buffer = m_key, .buffer_size = m_size, .buffer_content_size = m_size } + }; + + bool result = se.GetKey(args); + + m_size = args.content.buffer_content_size; + if (!result) + { + Unload(); + } + + return result; +} + +bool CPublicKey::operator==(const CPublicKey &a) const +{ + if (this->m_size != a.m_size) + { + return false; + } + return 0 == memcmp(this->m_key, a.m_key, m_size); +} + +bool CPublicKey::operator!=(const CPublicKey &a) const +{ + return !operator==(a); +} + +size_t CPublicKey::GetRawSize() const { return m_size; } + +void CPublicKey::GetRaw(uint8_t *raw_buffer) const +{ + memcpy(raw_buffer, m_key, m_size); +} + +char *CPublicKey::GetPem() const +{ + char pem_buf[500]; + auto res + = convert_public_key_raw_to_pem(pem_buf, sizeof(pem_buf), m_key, m_size); + if (res < 0) + { + return nullptr; + } + auto pem_size = strlen(pem_buf); + auto pem = new char[pem_size + 1]; + memcpy(pem, pem_buf, pem_size); + pem[pem_size] = 0; + return pem; +} + +int CPublicKey::convert_public_key_raw_to_pem(char *pem_buf, + size_t pem_buf_size, + const uint8_t *key_buf, + size_t key_buf_size) +{ + mbedtls_pk_context key = { 0 }; + + mbedtls_pk_init(&key); + const mbedtls_pk_info_t *info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); + + int result = -1; + if (info != NULL) + { + result = mbedtls_pk_setup(&key, info); + } + + mbedtls_ecp_keypair *keypair = (mbedtls_ecp_keypair *)key.pk_ctx; + if (result == 0) + { + result = mbedtls_ecp_group_load(&keypair->grp, MBEDTLS_ECP_DP_SECP256R1); + } + + if (result == 0) + { + result = mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, + key_buf, key_buf_size); + } + + if (result == 0) + { + result = mbedtls_pk_write_pubkey_pem(&key, (uint8_t *)pem_buf, + pem_buf_size); + } + + mbedtls_pk_free(&key); + return result < 0 ? -EINVAL : 0; +} + +int CPublicKey::convert_public_key_pem_to_raw(uint8_t *key_buf, + size_t key_buf_size, + size_t *key_size, + const char *pem_buf) +{ + int result = -1; + mbedtls_pk_context key = { 0 }; + + mbedtls_pk_init(&key); + + result = mbedtls_pk_parse_public_key(&key, (uint8_t *)pem_buf, + strlen(pem_buf) + 1); + + if (result == 0) + { + result = mbedtls_pk_can_do(&key, MBEDTLS_PK_ECKEY) == 1 ? 0 : -1; + } + + if (result == 0) + { + mbedtls_ecp_keypair *keypair = (mbedtls_ecp_keypair *)key.pk_ctx; + result = mbedtls_ecp_point_write_binary(&keypair->grp, &keypair->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + key_size, key_buf, key_buf_size); + } + + mbedtls_pk_free(&key); + return result < 0 ? -EINVAL : 0; +} + +} // namespace Controlse diff --git a/crypto/controlse/csan_builder.cxx b/crypto/controlse/csan_builder.cxx new file mode 100644 index 000000000..60a9040ae --- /dev/null +++ b/crypto/controlse/csan_builder.cxx @@ -0,0 +1,124 @@ +//*************************************************************************** +// apps/crypto/controlse/csan_builder.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/csan_builder.hxx" +#include "mbedtls/asn1write.h" +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CSanBuilder::~CSanBuilder() +{ + while (entry != nullptr) + { + delete[] entry->p; + auto next_entry = entry->next; + delete entry; + entry = next_entry; + } +} + +CSanBuilder *CSanBuilder::AddSan(uint8_t type, const char *value, + size_t value_size) +{ + auto old_entry = entry; + entry = new List(); + if (entry) + { + entry->type = type; + entry->p = new char[value_size]; + if (entry->p) + { + memcpy(entry->p, value, value_size); + entry->size = value_size; + entry->next = old_entry; + total_size += value_size; + total_size += 2; + } + else + { + delete entry; + } + } + return this; +} + +//* +// result: pointer to dynamically allocated san (to be deleted with delete[]) +// or error when size == 0 +/// +size_t CSanBuilder::Build(uint8_t **san) +{ + if (!entry) + { + return 0; + } + + const size_t reservation_for_additional_length_bytes = 8; + const size_t buffer_size + = total_size + reservation_for_additional_length_bytes; + auto *buffer = new uint8_t[buffer_size]; + auto current = entry; + const unsigned char *start = buffer; + unsigned char *p = buffer + buffer_size; + int ret = 0; + size_t len = 0; + while (current) + { + ret = mbedtls_asn1_write_tagged_string(&p, start, current->type, + current->p, current->size); + current = current->next; + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, start, total_size)); + MBEDTLS_ASN1_CHK_ADD( + len, mbedtls_asn1_write_tag( + &p, start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); + + *san = new uint8_t[total_size + len]; + memcpy(*san, p, total_size + len); + delete[] buffer; + return total_size + len; +} + +uint32_t CSanBuilder::GetNumberOfSan() +{ + auto e = entry; + uint32_t amount = 0; + while (e != nullptr) + { + e = e->next; + amount++; + } + return amount; +} + +} diff --git a/crypto/controlse/csecure_element.cxx b/crypto/controlse/csecure_element.cxx new file mode 100644 index 000000000..e6c11d894 --- /dev/null +++ b/crypto/controlse/csecure_element.cxx @@ -0,0 +1,189 @@ +//*************************************************************************** +// apps/crypto/controlse/csecure_element.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/csecure_element.hxx" + +#include "crypto/controlse/ccertificate.hxx" +#include "crypto/controlse/cpublic_key.hxx" +#include +#include +#include +#include +#include +extern "C" +{ +#include +} + +namespace Controlse +{ + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CSecureElement::CSecureElement(const char *se05x_device) + : se05x_fd(open(se05x_device, O_RDONLY)), close_device_at_destructor(true) +{ +} + +CSecureElement::CSecureElement(int fd) + : se05x_fd(fd), close_device_at_destructor(false) +{ +} + +CSecureElement::~CSecureElement() +{ + if ((se05x_fd >= 0) && close_device_at_destructor) + { + close(se05x_fd); + } +} + +bool CSecureElement::IsReady() const { return se05x_fd >= 0; } + +bool CSecureElement::GenerateKey(struct se05x_generate_keypair_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_GENERATE_KEYPAIR, &args); + } + return result; +} + +bool CSecureElement::SetKey(struct se05x_key_transmission_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_SET_KEY, &args); + } + return result; +} + +bool CSecureElement::GetKey(struct se05x_key_transmission_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_GET_KEY, &args); + } + return result; +} + +bool CSecureElement::DeleteKey(uint32_t id) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_DELETE_KEY, id); + } + return result; +} + +bool CSecureElement::SetData(struct se05x_key_transmission_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_SET_DATA, &args); + } + return result; +} + +bool CSecureElement::GetData(struct se05x_key_transmission_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_GET_DATA, &args); + } + return result; +} + +bool CSecureElement::CreateSignature(struct se05x_signature_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_CREATE_SIGNATURE, &args); + } + return result; +} + +bool CSecureElement::Verify(struct se05x_signature_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_VERIFY_SIGNATURE, &args); + } + return result; +} + +bool CSecureElement::DeriveSymmetricalKey( + struct se05x_derive_key_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_DERIVE_SYMM_KEY, &args); + } + return result; +} + +bool CSecureElement::GetUid(struct se05x_uid_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_GET_UID, &args); + } + return result; +} + +bool CSecureElement::GetInfo(struct se05x_info_s &args) const +{ + bool result = false; + if (se05x_fd >= 0) + { + result = 0 == ioctl(se05x_fd, SEIOC_GET_INFO, &args); + } + return result; +} + +CCertificate *CSecureElement::GetCertificate(uint32_t keystore_id) +{ + return new CCertificate(*this, keystore_id); +} + +CPublicKey *CSecureElement::GetPublicKey(uint32_t keystore_id) +{ + return new CPublicKey(*this, keystore_id); +} + +} // namespace Controlse diff --git a/crypto/controlse/cserial_number.cxx b/crypto/controlse/cserial_number.cxx new file mode 100644 index 000000000..517d1b229 --- /dev/null +++ b/crypto/controlse/cserial_number.cxx @@ -0,0 +1,94 @@ +//*************************************************************************** +// apps/crypto/controlse/cserial_number.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/cserial_number.hxx" +#include "crypto/controlse/isecure_element.hxx" +#include + +namespace Controlse +{ +constexpr size_t CSerialNumber::SERIAL_NUMBER_SIZE; + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CSerialNumber::CSerialNumber(const ISecureElement &se, uint32_t keystore_id) +{ + is_loaded = LoadFromSecureElement(se, keystore_id); +} + +CSerialNumber::CSerialNumber(uint8_t const *serial_number_byte_array) +{ + memcpy(serial_number, serial_number_byte_array, SERIAL_NUMBER_SIZE); + is_loaded = true; +} + +bool CSerialNumber::operator==(CSerialNumber &a) const +{ + return 0 == (memcmp(a.serial_number, serial_number, SERIAL_NUMBER_SIZE)); +} + +bool CSerialNumber::operator!=(CSerialNumber &a) const +{ + return !operator==(a); +} + +bool CSerialNumber::operator<(const CSerialNumber &a) const +{ + return 0 < (memcmp(a.serial_number, serial_number, SERIAL_NUMBER_SIZE)); +} + +bool CSerialNumber::IsLoaded() const { return is_loaded; } + +bool CSerialNumber::GetSerialNumber( + uint8_t serial_number_destination[SERIAL_NUMBER_SIZE]) const +{ + if (!is_loaded) + { + return false; + } + + memcpy(serial_number_destination, serial_number, SERIAL_NUMBER_SIZE); + return true; +} + +bool CSerialNumber::StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const +{ + return false; +} + +bool CSerialNumber::LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) +{ + struct se05x_key_transmission_s args + = { .entry = { .id = keystore_id }, + .content + = { .buffer = serial_number, .buffer_size = SERIAL_NUMBER_SIZE } }; + return se.GetData(args); +} +} // namespace Controlse diff --git a/crypto/controlse/cstring.cxx b/crypto/controlse/cstring.cxx new file mode 100644 index 000000000..ff7637005 --- /dev/null +++ b/crypto/controlse/cstring.cxx @@ -0,0 +1,141 @@ +//*************************************************************************** +// apps/crypto/controlse/cstring.cxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/cstring.hxx" +#include "crypto/controlse/csecure_element.hxx" +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class Method Implementations +//*************************************************************************** + +CString::CString(const ISecureElement &se, uint32_t keystore_id) +{ + (void)LoadFromSecureElement(se, keystore_id); +} + +CString::CString(char *string, size_t size) : m_size(size) +{ + m_string = new char[m_size]; + memcpy(m_string, string, m_size); +} + +CString::CString(const CString &p1) : CString(p1.m_string, p1.m_size) {} + +CString::~CString() +{ + if (m_string != nullptr) + { + delete[] m_string; + m_size = 0; + } +} + +CString &CString::operator=(const CString &other) +{ + if (this != &other) + { + auto new_string = new char[other.m_size]; + memcpy(new_string, other.m_string, other.m_size); + + delete[] m_string; + + m_string = new_string; + m_size = other.m_size; + } + return *this; +} + +bool CString::operator==(CString &a) const +{ + if (a.m_size != m_size) + { + return false; + } + return 0 == (memcmp(a.m_string, m_string, m_size)); +} + +bool CString::operator!=(CString &a) const { return !operator==(a); } + +char *CString::c_str(void) const +{ + char *c_str = nullptr; + if (IsLoaded() && (m_size > 0)) + { + bool add_termination_character = false; + if (m_string[m_size - 1] != 0) + { + add_termination_character = true; + } + c_str = new char[m_size + (add_termination_character ? 1 : 0)]; + memcpy(c_str, m_string, m_size); + if (add_termination_character) + { + c_str[m_size] = 0; + } + } + return c_str; +} + +bool CString::IsLoaded() const { return m_string != nullptr; } + +bool CString::StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const +{ + auto result = false; + if (IsLoaded()) + { + struct se05x_key_transmission_s args + = { .entry = { .id = keystore_id }, + .content = { .buffer = reinterpret_cast(m_string), + .buffer_size = m_size } }; + result = se.SetData(args); + } + return result; +} + +bool CString::LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) +{ + uint8_t buffer[1000]; + struct se05x_key_transmission_s args + = { .entry = { .id = keystore_id }, + .content = { .buffer = buffer, .buffer_size = sizeof(buffer) } }; + auto result = se.GetData(args); + + if (result) + { + m_size = args.content.buffer_content_size; + m_string = new char[m_size + 1]; + memcpy(m_string, buffer, m_size); + m_string[m_size] = 0; + } + return result; +} +} // namespace Controlse diff --git a/crypto/controlse/mbedtls_extension.c b/crypto/controlse/mbedtls_extension.c deleted file mode 100644 index 3ec58ae74..000000000 --- a/crypto/controlse/mbedtls_extension.c +++ /dev/null @@ -1,310 +0,0 @@ -/**************************************************************************** - * apps/crypto/controlse/mbedtls_extension.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/* Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The source code in this file is based on - * mbedtls_x509write_crt_der() method from x509write_crt.c in Mbed TLS - */ - -/* Copyright 2023 NXP */ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#define MBEDTLS_ALLOW_PRIVATE_ACCESS -#include -#include -#include -#include -#include -#include -#include - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int x509_write_time(FAR unsigned char **p, FAR unsigned char *start, - FAR const char *t, size_t size) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - - /* write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) */ - - if (t[0] == '2' && t[1] == '0' && t[2] < '5') - { - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_raw_buffer( - p, start, (FAR const unsigned char *)t + 2, size - 2)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_UTC_TIME)); - } - else - { - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_raw_buffer( - p, start, (FAR const unsigned char *)t, size)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag( - p, start, MBEDTLS_ASN1_GENERALIZED_TIME)); - } - - return ((int)len); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int mbedtls_x509write_crt_der_se05x(FAR mbedtls_x509write_cert *ctx, - FAR unsigned char *buf, size_t size, - int se05x_fd, uint32_t private_key_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - FAR const char *sig_oid; - size_t sig_oid_len = 0; - FAR unsigned char *c; - FAR unsigned char *c2; - unsigned char hash[64]; - unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; - size_t sub_len = 0; - size_t pub_len = 0; - size_t sig_and_oid_len = 0; - size_t sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; - - /* Prepare data to be signed at the end of the target buffer */ - - c = buf + size; - - /* Signature algorithm needed in TBS, and later for actual signature */ - - /* There's no direct way of extracting a signature algorithm - * (represented as an element of mbedtls_pk_type_t) from a PK instance. - */ - - if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_RSA)) - { - pk_alg = MBEDTLS_PK_RSA; - } - else if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_ECDSA)) - { - pk_alg = MBEDTLS_PK_ECDSA; - } - else - { - return (MBEDTLS_ERR_X509_INVALID_ALG); - } - - if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg, &sig_oid, - &sig_oid_len)) != 0) - { - return (ret); - } - - /* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension */ - - /* Only for v3 */ - - if (ctx->version == MBEDTLS_X509_CRT_VERSION_3) - { - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_x509_write_extensions(&c, buf, ctx->extensions)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3)); - } - - /* SubjectPublicKeyInfo */ - - MBEDTLS_ASN1_CHK_ADD( - pub_len, mbedtls_pk_write_pubkey_der(ctx->subject_key, buf, c - buf)); - c -= pub_len; - len += pub_len; - - /* Subject ::= Name */ - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, ctx->subject)); - - /* Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ - - sub_len = 0; - - MBEDTLS_ASN1_CHK_ADD(sub_len, - x509_write_time(&c, buf, ctx->not_after, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); - - MBEDTLS_ASN1_CHK_ADD(sub_len, - x509_write_time(&c, buf, ctx->not_before, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); - - len += sub_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag( - &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - /* Issuer ::= Name */ - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, ctx->issuer)); - - /* Signature ::= AlgorithmIdentifier */ - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier( - &c, buf, sig_oid, strlen(sig_oid), 0)); - - /* Serial ::= INTEGER - * - * Written data is: - * - "ctx->serial_len" bytes for the raw serial buffer - * - if MSb of "serial" is 1, then prepend an extra 0x00 byte - * - 1 byte for the length - * - 1 byte for the TAG - */ - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, - ctx->serial, ctx->serial_len)); - if (*c & 0x80) - { - if (c - buf < 1) - { - return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - } - - *(--c) = 0x0; - len++; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, - ctx->serial_len + 1)); - } - else - { - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, - ctx->serial_len)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_INTEGER)); - - /* Version ::= INTEGER { v1(0), v2(1), v3(2) } */ - - /* Can be omitted for v1 */ - - if (ctx->version != MBEDTLS_X509_CRT_VERSION_1) - { - sub_len = 0; - MBEDTLS_ASN1_CHK_ADD(sub_len, - mbedtls_asn1_write_int(&c, buf, ctx->version)); - len += sub_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag(&c, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0)); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag( - &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - /* Make signature - */ - - /* Compute hash of CRT. */ - - if ((ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, len, - hash)) != 0) - { - return (ret); - } - - { - struct se05x_signature_s args = { - .key_id = private_key_id, - .algorithm = SE05X_ALGORITHM_SHA256, - .tbs = { - .buffer = hash, - .buffer_size = 32, - .buffer_content_size = 32 - }, - .signature = {.buffer = sig, .buffer_size = sizeof(sig)}, - }; - - ret = ioctl(se05x_fd, SEIOC_CREATE_SIGNATURE, &args); - if (ret != 0) - { - return ret; - } - - sig_len = args.signature.buffer_content_size; - } - - /* Move CRT to the front of the buffer to have space - * for the signature. - */ - - memmove(buf, c, len); - c = buf + len; - - /* Add signature at the end of the buffer, - * making sure that it doesn't underflow - * into the CRT buffer. - */ - - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( - sig_and_oid_len, - mbedtls_x509_write_sig(&c2, c, sig_oid, sig_oid_len, sig, sig_len)); - - /* Memory layout after this step: - * - * buf c=buf+len c2 buf+size - * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] - */ - - /* Move raw CRT to just before the signature. */ - - c = c2 - len; - memmove(c, buf, len); - - len += sig_and_oid_len; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD( - len, mbedtls_asn1_write_tag( - &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - - return ((int)len); -} diff --git a/crypto/controlse/mbedtls_extension.h b/crypto/controlse/mbedtls_extension.h deleted file mode 100644 index 74a1c0349..000000000 --- a/crypto/controlse/mbedtls_extension.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** - * apps/crypto/controlse/mbedtls_extension.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/* Copyright 2023 NXP */ - -#ifndef __INCLUDE_APPS_CRYPTO_CONTROLSE_MBEDTLS_EXTENSION_H_ -#define __INCLUDE_APPS_CRYPTO_CONTROLSE_MBEDTLS_EXTENSION_H_ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -int mbedtls_x509write_crt_der_se05x(mbedtls_x509write_cert *ctx, - unsigned char *buf, size_t size, - int se05x_fd, uint32_t private_key_id); - -#endif /* __INCLUDE_APPS_CRYPTO_CONTROLSE_MBEDTLS_EXTENSION_H_ */ diff --git a/crypto/controlse/x509_utils.c b/crypto/controlse/x509_utils.c deleted file mode 100644 index 873b54ec6..000000000 --- a/crypto/controlse/x509_utils.c +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** - * apps/crypto/controlse/x509_utils.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/* Copyright 2023 NXP */ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#define MBEDTLS_ALLOW_PRIVATE_ACCESS -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/ecp.h" -#include "mbedtls/entropy.h" -#include "mbedtls/pem.h" -#include "mbedtls/pk.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_csr.h" -#include "mbedtls_extension.h" -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define SECONDS_IN_DAY (60 * 60 * 24) - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const char certificate_header[] = "-----BEGIN CERTIFICATE-----\n"; -static const char certificate_footer[] = "-----END CERTIFICATE-----\n"; - -static const char certificate_request_header[] = - "-----BEGIN CERTIFICATE REQUEST-----\n"; -static const char certificate_request_footer[] = - "-----END CERTIFICATE REQUEST-----\n"; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int convert_der_certificate_to_pem(FAR char *pem_buf, - size_t pem_buf_size, - FAR size_t *pem_content_size, - FAR uint8_t *der_buf, - size_t der_buf_size) -{ - int result; - - { - mbedtls_x509_crt crt; - mbedtls_x509_crt_init(&crt); - result = mbedtls_x509_crt_parse(&crt, der_buf, der_buf_size); - mbedtls_x509_crt_free(&crt); - } - - if (result == 0) - { - result = mbedtls_pem_write_buffer( - certificate_header, certificate_footer, der_buf, der_buf_size, - (FAR uint8_t *)pem_buf, pem_buf_size, pem_content_size); - } - - return result; -} - -static int convert_der_csr_to_pem(FAR char *pem_buf, size_t pem_buf_size, - FAR size_t *pem_content_size, - FAR uint8_t *der_buf, size_t der_buf_size) -{ - int result; - - { - mbedtls_x509_csr csr; - mbedtls_x509_csr_init(&csr); - result = - mbedtls_x509_csr_parse(&csr, (FAR uint8_t *)der_buf, der_buf_size); - mbedtls_x509_csr_free(&csr); - } - - if (result == 0) - { - result = mbedtls_pem_write_buffer(certificate_request_header, - certificate_request_footer, der_buf, - der_buf_size, (FAR uint8_t *)pem_buf, - pem_buf_size, pem_content_size); - } - - return result; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int convert_public_key_raw_to_pem(FAR char *pem_buf, size_t pem_buf_size, - FAR uint8_t *key_buf, size_t key_buf_size) -{ - mbedtls_pk_context key = - { - 0 - }; - - mbedtls_pk_init(&key); - FAR const mbedtls_pk_info_t *info = - mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); - - int result = -1; - if (info != NULL) - { - result = mbedtls_pk_setup(&key, info); - } - - FAR mbedtls_ecp_keypair *keypair = (mbedtls_ecp_keypair *)key.pk_ctx; - if (result == 0) - { - result = - mbedtls_ecp_group_load(&keypair->grp, MBEDTLS_ECP_DP_SECP256R1); - } - - if (result == 0) - { - result = mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, - key_buf, key_buf_size); - } - - if (result == 0) - { - result = mbedtls_pk_write_pubkey_pem(&key, (FAR uint8_t *)pem_buf, - pem_buf_size); - } - - mbedtls_pk_free(&key); - return result < 0 ? -EINVAL : 0; -} - -int convert_public_key_pem_to_raw(FAR uint8_t *key_buf, size_t key_buf_size, - FAR size_t *key_size, FAR char *pem_buf) -{ - int result = -1; - mbedtls_pk_context key = - { - 0 - }; - - mbedtls_pk_init(&key); - - result = mbedtls_pk_parse_public_key(&key, (FAR uint8_t *)pem_buf, - strlen(pem_buf) + 1); - - if (result == 0) - { - result = mbedtls_pk_can_do(&key, MBEDTLS_PK_ECKEY) == 1 ? 0 : -1; - } - - if (result == 0) - { - FAR mbedtls_ecp_keypair *keypair = (mbedtls_ecp_keypair *)key.pk_ctx; - result = mbedtls_ecp_point_write_binary( - &keypair->grp, &keypair->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, key_size, - key_buf, key_buf_size); - } - - mbedtls_pk_free(&key); - return result < 0 ? -EINVAL : 0; -} - -int convert_pem_certificate_or_csr_to_der(FAR uint8_t *der_buf, - size_t der_buf_size, - FAR size_t *der_content_size, - FAR char *pem_buf, - size_t pem_buf_size) -{ - int result; - - { - mbedtls_x509_crt crt; - mbedtls_x509_crt_init(&crt); - result = - mbedtls_x509_crt_parse(&crt, (FAR uint8_t *)pem_buf, pem_buf_size); - if ((result == 0) && (der_buf_size < crt.raw.len)) - { - result = -EINVAL; - } - - if (result == 0) - { - memcpy(der_buf, crt.raw.p, crt.raw.len); - *der_content_size = crt.raw.len; - } - - mbedtls_x509_crt_free(&crt); - } - - /* if bad input data then try parsing CSR */ - - if (result != 0) - { - mbedtls_x509_csr csr; - mbedtls_x509_csr_init(&csr); - result = - mbedtls_x509_csr_parse(&csr, (FAR uint8_t *)pem_buf, pem_buf_size); - if ((result == 0) && (der_buf_size < csr.raw.len)) - { - result = -EINVAL; - } - - if (result == 0) - { - memcpy(der_buf, csr.raw.p, csr.raw.len); - *der_content_size = csr.raw.len; - } - - mbedtls_x509_csr_free(&csr); - } - - return result; -} - -int convert_der_certificate_or_csr_to_pem(FAR char *pem_buf, - size_t pem_buf_size, - FAR size_t *pem_content_size, - FAR uint8_t *der_buf, - size_t der_buf_size) -{ - int result = convert_der_certificate_to_pem( - pem_buf, pem_buf_size, pem_content_size, der_buf, der_buf_size); - - if (result != 0) - { - result = convert_der_csr_to_pem(pem_buf, pem_buf_size, - pem_content_size, - der_buf, der_buf_size); - } - - return result; -} - -int sign_csr(int se05x_fd, uint32_t private_key_id, FAR char *crt_pem_buf, - size_t crt_pem_buf_size, FAR char *csr_pem_buf, - size_t csr_pem_buf_content_size) -{ - mbedtls_x509_csr csr; - mbedtls_x509_csr_init(&csr); - int result = mbedtls_x509_csr_parse(&csr, (FAR uint8_t *)csr_pem_buf, - csr_pem_buf_content_size); - - mbedtls_x509write_cert crt; - mbedtls_x509write_crt_init(&crt); - char subject_name[200]; - if (result == 0) - { - mbedtls_x509write_crt_set_version(&crt, MBEDTLS_X509_CRT_VERSION_3); - result = mbedtls_x509_dn_gets(subject_name, sizeof(subject_name), - &csr.subject); - } - - mbedtls_pk_context private_key; - mbedtls_pk_init(&private_key); - if (result >= 0) - { - mbedtls_x509write_crt_set_subject_key(&crt, &csr.pk); - result = mbedtls_pk_setup( - &private_key, - mbedtls_pk_info_from_type((mbedtls_pk_type_t)MBEDTLS_PK_ECDSA)); - } - - if (result == 0) - { - mbedtls_x509write_crt_set_issuer_key(&crt, &private_key); - result = mbedtls_x509write_crt_set_subject_name(&crt, subject_name); - } - - if (result == 0) - { - result = - mbedtls_x509write_crt_set_issuer_name(&crt, "CN=CA,O=NXP,C=NL"); - } - - mbedtls_mpi serial; - mbedtls_mpi_init(&serial); - if (result == 0) - { - mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256); - result = mbedtls_mpi_read_string(&serial, 10, "1"); - } - - if (result == 0) - { - result = mbedtls_x509write_crt_set_serial(&crt, &serial); - } - - if (result == 0) - { - time_t rawtime; - struct tm tm_info; - char from_datetime[20]; - char to_datetime[20]; - time(&rawtime); - strftime(from_datetime, sizeof(from_datetime), "%Y%m%d%H%M%S", - gmtime_r(&rawtime, &tm_info)); - rawtime += SECONDS_IN_DAY; - strftime(to_datetime, sizeof(to_datetime), "%Y%m%d%H%M%S", - gmtime_r(&rawtime, &tm_info)); - result = mbedtls_x509write_crt_set_validity(&crt, from_datetime, - to_datetime); - } - - if (result == 0) - { - result = mbedtls_x509write_crt_der_se05x( - &crt, (FAR uint8_t *)crt_pem_buf, crt_pem_buf_size, se05x_fd, - private_key_id); - } - - if (result >= 0) - { - size_t olen; - result = mbedtls_pem_write_buffer( - certificate_header, certificate_footer, - (FAR uint8_t *)(crt_pem_buf + crt_pem_buf_size - result), result, - (FAR uint8_t *)crt_pem_buf, crt_pem_buf_size, &olen); - } - - mbedtls_mpi_free(&serial); - mbedtls_pk_free(&private_key); - mbedtls_x509write_crt_free(&crt); - mbedtls_x509_csr_free(&csr); - return result; -} diff --git a/crypto/controlse/x509_utils.h b/crypto/controlse/x509_utils.h deleted file mode 100644 index 872136271..000000000 --- a/crypto/controlse/x509_utils.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** - * apps/crypto/controlse/x509_utils.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/* Copyright 2023 NXP */ - -#ifndef __INCLUDE_APPS_CRYPTO_CONTROLSE_X509_UTILS_H_ -#define __INCLUDE_APPS_CRYPTO_CONTROLSE_X509_UTILS_H_ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -int convert_public_key_raw_to_pem(FAR char *pem_buf, size_t pem_buf_size, - FAR uint8_t *key_buf, size_t key_buf_size); -int convert_public_key_pem_to_raw(FAR uint8_t *key_buf, size_t key_buf_size, - FAR size_t *key_size, char *pem_buf); -int convert_pem_certificate_or_csr_to_der(FAR uint8_t *der_buf, - size_t der_buf_size, - FAR size_t *der_content_size, - FAR char *pem_buf, - size_t pem_buf_size); -int convert_der_certificate_or_csr_to_pem(FAR char *pem_buf, - size_t pem_buf_size, - FAR size_t *pem_content_size, - FAR uint8_t *der_buf, - size_t der_buf_size); -int sign_csr(int se05x_fd, uint32_t private_key_id, FAR char *crt_pem_buf, - size_t crt_pem_buf_size, FAR char *csr_pem_buf, - size_t csr_pem_buf_content_size); - -#endif /* __INCLUDE_APPS_CRYPTO_CONTROLSE_X509_UTILS_H_ */ diff --git a/include/crypto/controlse/ccertificate.hxx b/include/crypto/controlse/ccertificate.hxx new file mode 100644 index 000000000..72bc45ac7 --- /dev/null +++ b/include/crypto/controlse/ccertificate.hxx @@ -0,0 +1,122 @@ +//*************************************************************************** +// apps/include/crypto/controlse/ccertificate.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//*************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element_object.hxx" +#include + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +namespace Controlse +{ +class ISecureElement; +class CPublicKey; +class CSerialNumber; + +class CCertificate : public ISecureElementObject +{ +public: + CCertificate(const ISecureElement &se, uint32_t keystore_id); + CCertificate(const uint8_t *crt_der_or_pem, size_t crt_size); + CCertificate(const ISecureElement &se, const uint8_t *csr_der_or_pem, + size_t csr_size, uint32_t keystore_id); + + // from_datetime and to_datetime need to have format: YYYYMMDDHHMMSSZ + CCertificate(const ISecureElement &se, const uint8_t *csr_der_or_pem, + size_t csr_size, uint32_t keystore_id, + const char *from_datetime, const char *to_datetime); + CCertificate(const CCertificate &) = delete; + CCertificate(CCertificate &&) = default; + ~CCertificate(); + + CCertificate &operator=(const CCertificate &other) = delete; + + bool IsLoaded() const; + bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const; + bool LoadFromSecureElement(const ISecureElement &se, uint32_t keystore_id); + bool LoadFromDerOrPem(const uint8_t *crt_der_or_pem, size_t crt_size); + bool LoadFromCsrDerOrPem(const ISecureElement &se, + const uint8_t *csr_der_or_pem, size_t csr_size, + uint32_t keystore_id, const char *from_datetime, + const char *to_datetime); + + bool VerifyAgainst(const ISecureElement &se, + uint32_t verify_against_id) const; + + // Test time range is valid + // returns 0 if valid + // -1 when expired + // 1 when not yet valid + int TestValidTimerange(time_t now) const; + + // Get public key from certificate + // returns pointer to public key when successful otherwise NULL + // note: must be deleted by caller when not NULL + CPublicKey *GetPublicKey() const; + + // Get oid from certificate if available + // oid must be one of MBEDTLS_OID_AT* from mbedtls/oid.h + // + // returns zero terminated text string when successful otherwise NULL + // note: must be deleted by caller when not NULL + char *GetOid(const char *oid) const; + + // Get serial number from from certificate + // returns pointer to CSerialNumber when successful otherwise NULL + // note: must be deleted by caller when not NULL + CSerialNumber *GetSerialNumber() const; + + size_t GetNumberOfSubjectAlternativeNames() const; + + // Get SAN from from certificate + // returns pointer to array when successful otherwise NULL + // note: must be deleted by caller when not NULL + char *GetSubjectAlternativeName(int item) const; + + // Get certificate in DER format + // returns size of the der array otherwise 0 + // note: der must be deleted by caller when not NULL + size_t GetDer(uint8_t **der) const; + + // Get certificate in PEM format + // returns pointer to pem string when successful otherwise NULL + // note: must be deleted by caller when not NULL + char *GetPem() const; + + bool ContainsSan(const char *name, size_t size) const; + + static constexpr char TAG_ID_SIZE = 18; + +private: + bool is_loaded = false; + + mbedtls_x509_crt crt; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/ccsr.hxx b/include/crypto/controlse/ccsr.hxx new file mode 100644 index 000000000..672866050 --- /dev/null +++ b/include/crypto/controlse/ccsr.hxx @@ -0,0 +1,92 @@ +//*************************************************************************** +// apps/include/crypto/controlse/ccsr.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element_object.hxx" +#include "mbedtls/x509_csr.h" + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CCsr : public ISecureElementObject +{ +public: + class CsrBuilder; + class CsrBuilder + { + public: + CsrBuilder(ISecureElement &se, const char *subject, uint32_t key_slot_id); + CsrBuilder(const CsrBuilder &) = delete; + CsrBuilder(CsrBuilder &&) = default; + + CsrBuilder &operator=(const CsrBuilder &other) = delete; + + CsrBuilder *AddExtension(const char *oid, size_t oid_size, + const uint8_t *value, size_t value_size); + + // result: pointer to dynamically allocated Csr (to be deleted) or nullptr + // if error + CCsr *Build(); + + private: + mbedtls_x509write_csr csr_w; + mbedtls_pk_context key; + bool ready; + }; + + CCsr(const ISecureElement &se, uint32_t keystore_id); + CCsr(const uint8_t *der_or_pem, size_t size); + CCsr(const CCsr &) = delete; + CCsr(CCsr &&) = default; + ~CCsr(); + + CCsr &operator=(const CCsr &other) = delete; + + bool IsLoaded() const; + bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const; + bool LoadFromSecureElement(const ISecureElement &se, uint32_t keystore_id); + + // Get CSR in DER format + // returns size of the der array otherwise 0 + // note: der must be deleted by caller when not NULL + size_t GetDer(uint8_t **der) const; + + // Get certificate in PEM format + // returns pointer to pem string when successful otherwise NULL + // note: must be deleted by caller when not NULL + char *GetPem() const; + +private: + mbedtls_x509_csr csr; + bool is_loaded = false; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/chex_util.hxx b/include/crypto/controlse/chex_util.hxx new file mode 100644 index 000000000..446518148 --- /dev/null +++ b/include/crypto/controlse/chex_util.hxx @@ -0,0 +1,62 @@ +//*************************************************************************** +// apps/include/crypto/controlse/chex_util.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CHexUtil +{ +public: + static size_t GetByteArraySizeFromHexString(const char *hex_buffer); + static size_t GetByteArraySizeFromHexStringSize(size_t hex_buffer_size); + static size_t GetHexStringSizeFromByteArraySize(size_t byte_array_size); + + // result contains allocated pointer to byte array (delete[] afterwards) if + // successfull otherwise nullptr + static uint8_t *ConvertHexStringToByteArray(const char *hex_buffer); + + // result contains allocated pointer to byte array (delete[] afterwards) if + // successfull otherwise nullptr + static uint8_t *ConvertHexStringToByteArray(const char *hex_buffer, + size_t hex_buffer_size); + + // result contains allocated pointer to hex string (delete[] afterwards) if + // successfull otherwise nullptr + static char *ByteArrayToHexString(const uint8_t bytearray[], size_t size); + +private: + static constexpr size_t AMOUNT_OF_HEXDIGITS_PER_BYTE = 2; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/cpublic_key.hxx b/include/crypto/controlse/cpublic_key.hxx new file mode 100644 index 000000000..eed61ca15 --- /dev/null +++ b/include/crypto/controlse/cpublic_key.hxx @@ -0,0 +1,82 @@ +//*************************************************************************** +// apps/include/crypto/controlse/cpublic_key.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element_object.hxx" +#include + +struct mbedtls_x509_crt; + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class ISecureElement; + +class CPublicKey : public ISecureElementObject +{ +public: + CPublicKey(const ISecureElement &se, uint32_t keystore_id); + CPublicKey(const uint8_t *buffer, size_t buffer_size); + CPublicKey(const char *pem); + CPublicKey(const CPublicKey &p1); + ~CPublicKey(); + + CPublicKey &operator=(const CPublicKey &other); + + bool IsLoaded() const; + bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const; + bool LoadFromSecureElement(const ISecureElement &se, uint32_t keystore_id); + bool operator==(const CPublicKey &a) const; + bool operator!=(const CPublicKey &a) const; + + size_t GetRawSize() const; + void GetRaw(uint8_t *raw_buffer) const; + + // Get public key in PEM format + // returns pointer to pem string when successful otherwise NULL + // note: must be deleted by caller when not NULL + char *GetPem() const; + +private: + void Unload(); + static int convert_public_key_raw_to_pem(char *pem_buf, size_t pem_buf_size, + const uint8_t *key_buf, + size_t key_buf_size); + static int convert_public_key_pem_to_raw(uint8_t *key_buf, + size_t key_buf_size, + size_t *key_size, + const char *pem_buf); + + uint8_t *m_key = nullptr; + size_t m_size = 0; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/csan_builder.hxx b/include/crypto/controlse/csan_builder.hxx new file mode 100644 index 000000000..c992e94c0 --- /dev/null +++ b/include/crypto/controlse/csan_builder.hxx @@ -0,0 +1,69 @@ +//*************************************************************************** +// apps/include/crypto/controlse/csan_builder.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CSanBuilder; +class CSanBuilder +{ +public: + CSanBuilder() = default; + CSanBuilder(const CSanBuilder &) = delete; + CSanBuilder(CSanBuilder &&) = default; + ~CSanBuilder(); + + CSanBuilder &operator=(const CSanBuilder &other) = delete; + + CSanBuilder *AddSan(uint8_t type, const char *value, size_t value_size); + + // result: pointer to dynamically allocated san (to be deleted with delete[]) + // or error when size == 0 + size_t Build(uint8_t **san); + + uint32_t GetNumberOfSan(); + +private: + struct List + { + char *p; + size_t size; + uint8_t type; + List *next; + }; + size_t total_size = 0; + List *entry = nullptr; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/csecure_element.hxx b/include/crypto/controlse/csecure_element.hxx new file mode 100644 index 000000000..ac79bad10 --- /dev/null +++ b/include/crypto/controlse/csecure_element.hxx @@ -0,0 +1,73 @@ +//*************************************************************************** +// apps/include/crypto/controlse/csecure_element.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element.hxx" + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CCertificate; +class CertificateCatalog; +class CPublicKey; + +class CSecureElement : public ISecureElement +{ +public: + explicit CSecureElement(const char *se05x_device); + explicit CSecureElement(int fd); + CSecureElement(const CSecureElement &) = delete; + CSecureElement(CSecureElement &&) = default; + ~CSecureElement(); + + CSecureElement &operator=(const CSecureElement &other) = delete; + + bool IsReady() const; + bool GenerateKey(struct se05x_generate_keypair_s &args) const; + bool SetKey(struct se05x_key_transmission_s &args) const; + bool GetKey(struct se05x_key_transmission_s &args) const; + bool DeleteKey(uint32_t id) const; + bool SetData(struct se05x_key_transmission_s &args) const; + bool GetData(struct se05x_key_transmission_s &args) const; + bool CreateSignature(struct se05x_signature_s &args) const; + bool Verify(struct se05x_signature_s &args) const; + bool DeriveSymmetricalKey(struct se05x_derive_key_s &args) const; + bool GetUid(struct se05x_uid_s &args) const; + bool GetInfo(struct se05x_info_s &args) const; + + CCertificate *GetCertificate(uint32_t keystore_id); + CPublicKey *GetPublicKey(uint32_t keystore_id); + +private: + const int se05x_fd; + const bool close_device_at_destructor; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/cserial_number.hxx b/include/crypto/controlse/cserial_number.hxx new file mode 100644 index 000000000..d8dde8df8 --- /dev/null +++ b/include/crypto/controlse/cserial_number.hxx @@ -0,0 +1,62 @@ +//*************************************************************************** +// apps/include/crypto/controlse/cserial_number.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element_object.hxx" +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CSerialNumber : ISecureElementObject +{ +public: + static constexpr size_t SERIAL_NUMBER_SIZE = 20; + CSerialNumber(const ISecureElement &se, uint32_t keystore_id); + CSerialNumber(uint8_t const *serial_number_byte_array); + + bool operator==(CSerialNumber &a) const; + bool operator!=(CSerialNumber &a) const; + bool operator<(const CSerialNumber &a) const; + + bool IsLoaded() const; + bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const; + bool LoadFromSecureElement(const ISecureElement &se, uint32_t keystore_id); + + bool + GetSerialNumber(uint8_t serial_number_destination[SERIAL_NUMBER_SIZE]) const; + +private: + bool is_loaded = false; + uint8_t serial_number[SERIAL_NUMBER_SIZE]; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/cstring.hxx b/include/crypto/controlse/cstring.hxx new file mode 100644 index 000000000..4e744f9d4 --- /dev/null +++ b/include/crypto/controlse/cstring.hxx @@ -0,0 +1,64 @@ +//*************************************************************************** +// apps/include/crypto/controlse/cstring.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include "crypto/controlse/isecure_element_object.hxx" +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class CString : public ISecureElementObject +{ +public: + CString(const ISecureElement &se, uint32_t keystore_id); + CString(char *string, size_t size); + CString(const CString &p1); + ~CString(); + + CString &operator=(const CString &other); + bool operator==(CString &a) const; + bool operator!=(CString &a) const; + + // return value is string otherwise nullptr + // NOTE: need to delete[] return value + char *c_str(void) const; + + bool IsLoaded() const; + bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const; + bool LoadFromSecureElement(const ISecureElement &se, uint32_t keystore_id); + +private: + size_t m_size = 0; + char *m_string = nullptr; +}; +} // namespace Controlse diff --git a/include/crypto/controlse/isecure_element.hxx b/include/crypto/controlse/isecure_element.hxx new file mode 100644 index 000000000..ad559f96e --- /dev/null +++ b/include/crypto/controlse/isecure_element.hxx @@ -0,0 +1,71 @@ +//*************************************************************************** +// apps/include/crypto/controlse/isecure_element.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#pragma once + +#include "crypto/controlse/isecure_element_object.hxx" +#include +#include + +struct se05x_key_transmission_s; +struct se05x_signature_s; +struct se05x_uid_s; +struct se05x_info_s; +struct se05x_generate_keypair_s; +struct se05x_derive_key_s; + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class ISecureElement +{ +public: + virtual ~ISecureElement() = default; + + virtual bool IsReady() const = 0; + virtual bool GenerateKey(struct se05x_generate_keypair_s &args) const = 0; + virtual bool SetKey(struct se05x_key_transmission_s &args) const = 0; + virtual bool GetKey(struct se05x_key_transmission_s &args) const = 0; + virtual bool DeleteKey(uint32_t id) const = 0; + virtual bool SetData(struct se05x_key_transmission_s &args) const = 0; + virtual bool GetData(struct se05x_key_transmission_s &args) const = 0; + virtual bool CreateSignature(struct se05x_signature_s &args) const = 0; + virtual bool Verify(struct se05x_signature_s &args) const = 0; + virtual bool DeriveSymmetricalKey(struct se05x_derive_key_s &args) const = 0; + virtual bool GetUid(struct se05x_uid_s &args) const = 0; + virtual bool GetInfo(struct se05x_info_s &args) const = 0; + + virtual bool Set(uint32_t keystore_id, + const ISecureElementObject &object) const + { + return object.StoreOnSecureElement(*this, keystore_id); + } +}; +} // namespace Controlse diff --git a/include/crypto/controlse/isecure_element_object.hxx b/include/crypto/controlse/isecure_element_object.hxx new file mode 100644 index 000000000..ecff59015 --- /dev/null +++ b/include/crypto/controlse/isecure_element_object.hxx @@ -0,0 +1,51 @@ +//*************************************************************************** +// apps/include/crypto/controlse/isecure_element_object.hxx +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. The +// ASF licenses this file to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//************************************************************************** + +// Copyright 2024 NXP + +#pragma once + +//*************************************************************************** +// Included Files +//*************************************************************************** + +#include + +namespace Controlse +{ + +//*************************************************************************** +// Class definitions +//*************************************************************************** + +class ISecureElement; + +class ISecureElementObject +{ +public: + virtual ~ISecureElementObject() = default; + virtual bool IsLoaded() const = 0; + virtual bool StoreOnSecureElement(const ISecureElement &se, + uint32_t keystore_id) const = 0; + virtual bool LoadFromSecureElement(const ISecureElement &se, + uint32_t keystore_id) + = 0; +}; +} // namespace Controlse