controlse: add accesslib for the se05x secure element
This commit is contained in:
parent
fe12ad9444
commit
cecc2e762b
45
crypto/controlse/CMakeLists.txt
Normal file
45
crypto/controlse/CMakeLists.txt
Normal file
@ -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()
|
@ -18,8 +18,9 @@ config CRYPTO_CONTROLSE
|
|||||||
select MBEDTLS_X509_CSR_WRITE_C
|
select MBEDTLS_X509_CSR_WRITE_C
|
||||||
select MBEDTLS_X509_CRT_WRITE_C
|
select MBEDTLS_X509_CRT_WRITE_C
|
||||||
---help---
|
---help---
|
||||||
Enable the controlse utility. This program is used control the
|
Enable the controlse library and utility. It provides an
|
||||||
secure element device
|
access library to the secure element device. The utility can
|
||||||
|
control the secure element device from the nuttx shell
|
||||||
|
|
||||||
if CRYPTO_CONTROLSE
|
if CRYPTO_CONTROLSE
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
# Copyright 2023, 2024 NXP
|
||||||
|
|
||||||
include $(APPDIR)/Make.defs
|
include $(APPDIR)/Make.defs
|
||||||
|
|
||||||
# controlse built-in application info
|
# controlse built-in application info
|
||||||
@ -28,7 +30,8 @@ STACKSIZE = $(CONFIG_CRYPTO_CONTROLSE_STACKSIZE)
|
|||||||
|
|
||||||
# controlse main source
|
# controlse main source
|
||||||
|
|
||||||
MAINSRC = controlse_main.c
|
MAINSRC = controlse_main.cxx
|
||||||
CSRCS = x509_utils.c mbedtls_extension.c
|
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
|
include $(APPDIR)/Application.mk
|
||||||
|
532
crypto/controlse/ccertificate.cxx
Normal file
532
crypto/controlse/ccertificate.cxx
Normal file
@ -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 <mbedtls/oid.h>
|
||||||
|
#include <mbedtls/pem.h>
|
||||||
|
#include <mbedtls/sha256.h>
|
||||||
|
#include <mbedtls/x509_crt.h>
|
||||||
|
#include <mbedtls/x509_csr.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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<mbedtls_ecp_keypair *>(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
|
212
crypto/controlse/ccsr.cxx
Normal file
212
crypto/controlse/ccsr.cxx
Normal file
@ -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 <cstring>
|
||||||
|
#include <mbedtls/pem.h>
|
||||||
|
|
||||||
|
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
|
100
crypto/controlse/chex_util.cxx
Normal file
100
crypto/controlse/chex_util.cxx
Normal file
@ -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 <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
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
|
188
crypto/controlse/cmbedtls_se05x_extension.hxx
Normal file
188
crypto/controlse/cmbedtls_se05x_extension.hxx
Normal file
@ -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 <cerrno>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
#include <mbedtls/pk.h>
|
||||||
|
#include <mbedtls/x509_csr.h>
|
||||||
|
#include <nuttx/crypto/se05x.h>
|
||||||
|
|
||||||
|
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<mbedtls_ecp_keypair *>(ctx);
|
||||||
|
auto se05x_ctx = reinterpret_cast<mbedtls_se05x_ctx *>(key->d.p);
|
||||||
|
|
||||||
|
struct se05x_signature_s args
|
||||||
|
= { se05x_ctx->private_key_slot_id,
|
||||||
|
SE05X_ALGORITHM_SHA256,
|
||||||
|
{ const_cast<uint8_t *>(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<mbedtls_mpi_uint *>(se05x_ctx);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mbedtls_pk_free_se05x(mbedtls_pk_context &key)
|
||||||
|
{
|
||||||
|
auto key_ctx = reinterpret_cast<mbedtls_ecp_keypair *>(key.pk_ctx);
|
||||||
|
if (key_ctx)
|
||||||
|
{
|
||||||
|
auto se05x_ctx = reinterpret_cast<mbedtls_se05x_ctx *>(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
|
@ -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 <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
|
||||||
#include <mbedtls/sha256.h>
|
|
||||||
#include <mbedtls/x509_crt.h>
|
|
||||||
#include <mbedtls/x509_csr.h>
|
|
||||||
#include <nuttx/config.h>
|
|
||||||
#include <nuttx/crypto/se05x.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_COLORATION
|
|
||||||
#include <nuttx/arch.h>
|
|
||||||
#include <nuttx/sched.h>
|
|
||||||
#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] <secure element device>\n", prg);
|
|
||||||
fprintf(f, "Options:\n");
|
|
||||||
fprintf(f, " -r <id> (read item from keystore at <id>)\n");
|
|
||||||
fprintf(f, " -w <id> (set item in keystore at <id>)\n");
|
|
||||||
fprintf(f, " -g <id> (generate keypair at <id>)\n");
|
|
||||||
fprintf(f, " -d <id> (delete key at <id>)\n");
|
|
||||||
fprintf(f, " -s <id> (create signature for data\n");
|
|
||||||
fprintf(f, " with key at <id>)\n");
|
|
||||||
fprintf(f, " -S <id> (Sign CSR with key at <id>)\n");
|
|
||||||
fprintf(f, " -v <id> (verify signature for data\n");
|
|
||||||
fprintf(f, " with key at <id>)\n");
|
|
||||||
fprintf(f, " -V <id> (verify CRT with key at <id>\n");
|
|
||||||
fprintf(f, " -a <id> (derive symm key\n");
|
|
||||||
fprintf(f, " from public key <id>\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 <id> (select private key\n");
|
|
||||||
fprintf(f, " use with -a)\n");
|
|
||||||
fprintf(f, " -n <file> (Read input from file)\n");
|
|
||||||
fprintf(f, " -N <file> (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;
|
|
||||||
}
|
|
711
crypto/controlse/controlse_main.cxx
Normal file
711
crypto/controlse/controlse_main.cxx
Normal file
@ -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 <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_STACK_COLORATION
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/sched.h>
|
||||||
|
#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] <secure element device>\n", prg);
|
||||||
|
fprintf(f, "Options:\n");
|
||||||
|
fprintf(f, " -r <id> (read item from keystore at <id>)\n");
|
||||||
|
fprintf(f, " -w <id> (set item in keystore at <id>)\n");
|
||||||
|
fprintf(f, " -g <id> (generate keypair at <id>)\n");
|
||||||
|
fprintf(f, " -d <id> (delete key at <id>)\n");
|
||||||
|
fprintf(f, " -s <id> (create signature for data\n");
|
||||||
|
fprintf(f, " with key at <id>)\n");
|
||||||
|
fprintf(f, " -S <id> (Sign CSR with key at <id>)\n");
|
||||||
|
fprintf(f, " -v <id> (verify signature for data\n");
|
||||||
|
fprintf(f, " with key at <id>)\n");
|
||||||
|
fprintf(f, " -V <id> (verify CRT with key at <id>\n");
|
||||||
|
fprintf(f, " -a <id> (derive symm key\n");
|
||||||
|
fprintf(f, " from public key <id>\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 <id> (select private key\n");
|
||||||
|
fprintf(f, " use with -a)\n");
|
||||||
|
fprintf(f, " -n <file> (Read input from file)\n");
|
||||||
|
fprintf(f, " -N <file> (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<uint8_t *>(data), data_size);
|
||||||
|
if (object)
|
||||||
|
{
|
||||||
|
if (!object->IsLoaded())
|
||||||
|
{
|
||||||
|
delete object;
|
||||||
|
object = new Controlse::CCsr(
|
||||||
|
reinterpret_cast<uint8_t *>(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<uint8_t *>(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<uint8_t *>(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;
|
||||||
|
}
|
243
crypto/controlse/cpublic_key.cxx
Normal file
243
crypto/controlse/cpublic_key.cxx
Normal file
@ -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 <errno.h>
|
||||||
|
#include <mbedtls/pk.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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
|
124
crypto/controlse/csan_builder.cxx
Normal file
124
crypto/controlse/csan_builder.cxx
Normal file
@ -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 <cstring>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
189
crypto/controlse/csecure_element.cxx
Normal file
189
crypto/controlse/csecure_element.cxx
Normal file
@ -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 <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <nuttx/crypto/se05x.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
94
crypto/controlse/cserial_number.cxx
Normal file
94
crypto/controlse/cserial_number.cxx
Normal file
@ -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 <string.h>
|
||||||
|
|
||||||
|
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
|
141
crypto/controlse/cstring.cxx
Normal file
141
crypto/controlse/cstring.cxx
Normal file
@ -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 <cstring>
|
||||||
|
|
||||||
|
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<uint8_t *>(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
|
@ -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 <mbedtls/asn1write.h>
|
|
||||||
#include <mbedtls/error.h>
|
|
||||||
#include <mbedtls/oid.h>
|
|
||||||
#include <mbedtls/x509_crt.h>
|
|
||||||
#include <nuttx/crypto/se05x.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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);
|
|
||||||
}
|
|
@ -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 <mbedtls/x509_crt.h>
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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_ */
|
|
@ -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 <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#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 <time.h>
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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;
|
|
||||||
}
|
|
@ -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 <stdint.h>
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* 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_ */
|
|
122
include/crypto/controlse/ccertificate.hxx
Normal file
122
include/crypto/controlse/ccertificate.hxx
Normal file
@ -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 <mbedtls/x509_crt.h>
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
// 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
|
92
include/crypto/controlse/ccsr.hxx
Normal file
92
include/crypto/controlse/ccsr.hxx
Normal file
@ -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
|
62
include/crypto/controlse/chex_util.hxx
Normal file
62
include/crypto/controlse/chex_util.hxx
Normal file
@ -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 <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
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
|
82
include/crypto/controlse/cpublic_key.hxx
Normal file
82
include/crypto/controlse/cpublic_key.hxx
Normal file
@ -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 <stddef.h>
|
||||||
|
|
||||||
|
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
|
69
include/crypto/controlse/csan_builder.hxx
Normal file
69
include/crypto/controlse/csan_builder.hxx
Normal file
@ -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 <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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
|
73
include/crypto/controlse/csecure_element.hxx
Normal file
73
include/crypto/controlse/csecure_element.hxx
Normal file
@ -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
|
62
include/crypto/controlse/cserial_number.hxx
Normal file
62
include/crypto/controlse/cserial_number.hxx
Normal file
@ -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 <stddef.h>
|
||||||
|
|
||||||
|
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
|
64
include/crypto/controlse/cstring.hxx
Normal file
64
include/crypto/controlse/cstring.hxx
Normal file
@ -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 <stddef.h>
|
||||||
|
|
||||||
|
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
|
71
include/crypto/controlse/isecure_element.hxx
Normal file
71
include/crypto/controlse/isecure_element.hxx
Normal file
@ -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 <nuttx/crypto/se05x.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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
|
51
include/crypto/controlse/isecure_element_object.hxx
Normal file
51
include/crypto/controlse/isecure_element_object.hxx
Normal file
@ -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 <stdint.h>
|
||||||
|
|
||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user