From 8a82137f44302a6a689bfc0b4d851f1ff451073b Mon Sep 17 00:00:00 2001 From: Jakub Wlostowski Date: Wed, 22 Jan 2025 11:19:39 +0100 Subject: [PATCH] Add security certs backend implementation Change-Id: If3358833301beebac1625be28de12d7e3c4aff5c --- CMakeLists.txt | 36 +++ LICENSE | 203 ++++++++++++++ packaging/hal-backend-security-certs.manifest | 5 + packaging/hal-backend-security-certs.spec | 39 +++ src/backend/CMakeLists.txt | 129 +++++++++ src/backend/bin2c.c | 84 ++++++ src/backend/hal_backend_security_certs.cpp | 253 ++++++++++++++++++ src/backend/hal_backend_security_certs.h | 46 ++++ .../hal_backend_security_certs_api.cpp | 180 +++++++++++++ src/shared/log.cpp | 58 ++++ src/shared/log.h | 70 +++++ 11 files changed, 1103 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 packaging/hal-backend-security-certs.manifest create mode 100644 packaging/hal-backend-security-certs.spec create mode 100644 src/backend/CMakeLists.txt create mode 100644 src/backend/bin2c.c create mode 100644 src/backend/hal_backend_security_certs.cpp create mode 100644 src/backend/hal_backend_security_certs.h create mode 100644 src/backend/hal_backend_security_certs_api.cpp create mode 100644 src/shared/log.cpp create mode 100644 src/shared/log.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..90f38f1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed 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. +# + +PROJECT(hal-backend-security-certs LANGUAGES C CXX) +CMAKE_MINIMUM_REQUIRED(VERSION 3.0) + +INCLUDE(GNUInstallDirs) +INCLUDE(CheckLibraryExists) + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "RELEASE") +ENDIF(NOT CMAKE_BUILD_TYPE) + +SET(CMAKE_C_FLAGS_DEBUG "-std=c11 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_CXX_FLAGS_DEBUG "-std=c++17 -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_RELEASE "-std=c11 -O2 -DNDEBUG") +SET(CMAKE_CXX_FLAGS_RELEASE "-std=c++17 -O2 -DNDEBUG") + +ADD_DEFINITIONS("-Werror -Wall -Wextra -Wno-deprecated-declarations") + +SET(CMAKE_POSITION_INDEPENDENT_CODE "True") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") + +ADD_SUBDIRECTORY(src/backend) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9f8d261 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/packaging/hal-backend-security-certs.manifest b/packaging/hal-backend-security-certs.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/hal-backend-security-certs.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/hal-backend-security-certs.spec b/packaging/hal-backend-security-certs.spec new file mode 100644 index 0000000..3581674 --- /dev/null +++ b/packaging/hal-backend-security-certs.spec @@ -0,0 +1,39 @@ +Name: hal-backend-security-certs +Summary: Security Certs (based on the OpenSSL) backend library +Version: 1.0.0 +Release: 0 +Group: Security/Development +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1001: hal-backend-security-certs.manifest +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(openssl3) +BuildRequires: pkgconfig(hal-rootstrap) +BuildRequires: openssl3 +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +# Disable hal-rootstrap-checker in order to use dlog and openssl3 +%define disable_hal_rootstrap_checker 1 + +%description +Security Certs (based on the OpenSSL) backend library + +%prep +%setup -q +cp -a %{SOURCE1001} . + +%build +cmake ./ -DHAL_LIB_DIR=%{_hal_libdir} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:Release} +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%files +%manifest hal-backend-security-certs.manifest +%license LICENSE +%{_hal_libdir}/lib%{name}.so* diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt new file mode 100644 index 0000000..5c26685 --- /dev/null +++ b/src/backend/CMakeLists.txt @@ -0,0 +1,129 @@ +# Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed 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. +# + +PROJECT(hal-backend-security-certs LANGUAGES C CXX) +SET(PROJECT_VERSION "1.0.0") + +SET(_LIB_VERSION_ "${PROJECT_VERSION}") +SET(_LIB_SOVERSION_ "0") + +FIND_PROGRAM(OPENSSL_TOOL openssl REQUIRED) +FIND_PACKAGE(PkgConfig REQUIRED) + +ADD_EXECUTABLE(bin2c bin2c.c) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key + COMMAND ${OPENSSL_TOOL} genrsa -out ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key 1024) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key + COMMAND ${OPENSSL_TOOL} genrsa -out ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key 1024) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem + COMMAND ${OPENSSL_TOOL} req -x509 -new -nodes -key ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key + -sha256 -days 1024 -out ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem + -subj "/C=PL/ST=Test1/L=Test2/O=Test3/CN=Test4" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.csr + COMMAND ${OPENSSL_TOOL} req -new -sha256 -key ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key + -out ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.csr + -subj "/C=PL/ST=Test10/L=Test20/O=Test30/CN=Test40" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.pem + COMMAND ${OPENSSL_TOOL} x509 -req -in ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.csr + -CA ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem -CAkey ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key -CAcreateserial + -days 1024 -sha256 -out ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.pem + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.csr ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chainRSA.pem + COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.pem ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem > ${CMAKE_CURRENT_BINARY_DIR}/chainRSA.pem + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rootRSA.pem ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.pem) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key + COMMAND ${OPENSSL_TOOL} ecparam -name secp521r1 -genkey -noout -out ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key + COMMAND ${OPENSSL_TOOL} ecparam -name secp521r1 -genkey -noout -out ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem + COMMAND ${OPENSSL_TOOL} req -x509 -new -nodes -key ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key + -sha256 -days 1024 -out ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem + -subj "/C=PL/ST=Test1/L=Test2/O=Test3/CN=Test4" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.csr + COMMAND ${OPENSSL_TOOL} req -new -sha256 -key ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key + -out ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.csr + -subj "/C=PL/ST=Test10/L=Test20/O=Test30/CN=Test40" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.pem + COMMAND ${OPENSSL_TOOL} x509 -req -in ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.csr + -CA ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem -CAkey ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key -CAcreateserial + -days 1024 -sha256 -out ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.pem + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.csr ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chainECDSA.pem + COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.pem ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem > ${CMAKE_CURRENT_BINARY_DIR}/chainECDSA.pem + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.pem) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_key.c + COMMAND $ ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_key.c device_rsa_key + DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/deviceRSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_cert.c + COMMAND $ ${CMAKE_CURRENT_BINARY_DIR}/chainRSA.pem ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_cert.c device_rsa_cert + DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/chainRSA.pem) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_key.c + COMMAND $ ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_key.c device_ecdsa_key + DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/deviceECDSA.key) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_cert.c + COMMAND $ ${CMAKE_CURRENT_BINARY_DIR}/chainECDSA.pem ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_cert.c device_ecdsa_cert + DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/chainECDSA.pem) + +PKG_CHECK_MODULES(SECURITY_CERTS_DEPS REQUIRED + dlog + hal-rootstrap + openssl3) + +INCLUDE_DIRECTORIES(SYSTEM ${SECURITY_CERTS_DEPS_INCLUDE_DIRS}) +LINK_DIRECTORIES(${SECURITY_CERTS_DEPS_LIBRARY_DIRS}) + +INCLUDE_DIRECTORIES(../shared) + +ADD_LIBRARY(${PROJECT_NAME} + SHARED + hal_backend_security_certs_api.cpp + hal_backend_security_certs.cpp + ../shared/log.cpp + ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_key.c + ${CMAKE_CURRENT_BINARY_DIR}/device_ecdsa_cert.c + ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_key.c + ${CMAKE_CURRENT_BINARY_DIR}/device_rsa_cert.c) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SECURITY_CERTS_DEPS_LIBRARIES}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} + PROPERTIES + VERSION ${_LIB_VERSION_} + SOVERSION ${_LIB_SOVERSION_} + VISIBILITY_INLINES_HIDDEN TRUE + C_VISIBILITY_PRESET hidden + CXX_VISIBILITY_PRESET hidden) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${HAL_LIB_DIR} COMPONENT RuntimeLibraries) diff --git a/src/backend/bin2c.c b/src/backend/bin2c.c new file mode 100644 index 0000000..d99764a --- /dev/null +++ b/src/backend/bin2c.c @@ -0,0 +1,84 @@ +/****************************************************************** + * + * Copyright 2017 - 2018 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ + +#include +#include + +int main(int argc, char** argv) +{ + int ret = 0; + size_t size; + char *buffer = NULL; + + if(argc != 4) + return -1; + + FILE *infile = fopen(argv[1], "rb"); + FILE *outfile = fopen(argv[2], "wb"); + if(!infile || !outfile) { + perror("fopen() failed"); + ret = -1; + goto exit; + } + + if(fseek(infile, 0L, SEEK_END) < 0) { + perror("fseek() failed"); + ret = -1; + goto exit; + } + if((size = ftell(infile)) <= 0) { + perror("ftell() failed"); + ret = -1; + goto exit; + } + if(fseek(infile, 0L, SEEK_SET) < 0) { + perror("fseek() failed"); + ret = -1; + goto exit; + } + + buffer = (char *)malloc(size); + if(!buffer) { + perror("malloc() failed"); + ret = -1; + goto exit; + } + + if(fread(buffer, 1, size, infile) <= 0) { + perror("fread() failed"); + ret = -1; + goto exit; + } + + fprintf(outfile, "#include \nsize_t %s_size = %zd;\nunsigned char %s[]= {\n", + argv[3], size, argv[3]); + + for(size_t i = 0 ; i < size ; ++i) { + if(!(i % 64)) { + fprintf(outfile, "\n"); + } + fprintf(outfile, "0x%02X,", (unsigned char)buffer[i]); + } + fprintf(outfile, "0\n};\n"); + +exit: + if(infile) fclose(infile); + if(outfile) fclose(outfile); + free(buffer); + return ret; +} diff --git a/src/backend/hal_backend_security_certs.cpp b/src/backend/hal_backend_security_certs.cpp new file mode 100644 index 0000000..8007e1f --- /dev/null +++ b/src/backend/hal_backend_security_certs.cpp @@ -0,0 +1,253 @@ +/****************************************************************** + * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include "hal_backend_security_certs.h" +#include "log.h" + +extern "C" { + extern size_t device_rsa_key_size; + extern char device_rsa_key[]; + extern size_t device_rsa_cert_size; + extern char device_rsa_cert[]; + extern size_t device_ecdsa_key_size; + extern char device_ecdsa_key[]; + extern size_t device_ecdsa_cert_size; + extern char device_ecdsa_cert[]; +} + +EVP_PKEY* get_rsa_pkey() +{ + EVP_PKEY* pkey = NULL; + BIO* bio = NULL; + + if (!(bio = BIO_new_mem_buf(device_rsa_key, device_rsa_key_size))) { + LOGE("Can't parse private RSA key"); + return pkey; + } + + if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL))) { + LOGE("Can't parse private RSA key"); + } + + BIO_free(bio); + return pkey; +} + +EVP_PKEY* get_ecdsa_pkey() +{ + EVP_PKEY* pkey = NULL; + EC_KEY* eckey = NULL; + BIO* bio = NULL; + + if (!(bio = BIO_new_mem_buf(device_ecdsa_key, device_ecdsa_key_size))) { + LOGE("Can't parse private ECDSA key"); + return pkey; + } + + eckey = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL); + BIO_free(bio); + if (!eckey) { + LOGE("Can't parse private ECDSA key"); + return pkey; + } + + if (!(pkey = EVP_PKEY_new())) { + LOGE("Can't allocate EVP_PKEY"); + EC_KEY_free(eckey); + return pkey; + } + + if (1 != EVP_PKEY_assign_EC_KEY(pkey, eckey)) { + LOGE("Can't assign EC key to PKEY"); + EC_KEY_free(eckey); + EVP_PKEY_free(pkey); + pkey = NULL; + } + + return pkey; +} + +const EVP_MD* to_openssl_md_type(hal_security_certs_digest_type_e digest_type) +{ + switch (digest_type) { + case HAL_SECURITY_CERTS_DIGEST_TYPE_NONE: + return EVP_md_null(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_MD2: + return EVP_md2(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_MD4: + return EVP_md4(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_MD5: + return EVP_md5(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_SHA1: + return EVP_sha1(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_SHA224: + return EVP_sha224(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_SHA256: + return EVP_sha256(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_SHA384: + return EVP_sha384(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_SHA512: + return EVP_sha512(); + case HAL_SECURITY_CERTS_DIGEST_TYPE_RIPEMD160: + return EVP_ripemd160(); + default: + return nullptr; + } +} + +hal_backend_security_certs::hal_backend_security_certs(hal_security_certs_data_s key_type) +{ + if (key_type.length == 0 || strncmp(key_type.buffer, "RSA", key_type.length) == 0) { + fKey = HAL_SECURITY_CERTS_KEY_TYPE_RSA; + } else if (strncmp(key_type.buffer, "ECDSA", key_type.length) == 0) { + fKey = HAL_SECURITY_CERTS_KEY_TYPE_ECDSA; + } else { + LOGE("Unsupported key type"); + throw std::invalid_argument("Unsupported key type"); + } +} + +hal_backend_security_certs::~hal_backend_security_certs() +{ +} + +int hal_backend_security_certs::request_certificate_chain(hal_security_certs_data_s* cert_chain) +{ + if (fKey == HAL_SECURITY_CERTS_KEY_TYPE_RSA) { + cert_chain->buffer = (char*)malloc(device_rsa_cert_size); + if (cert_chain->buffer == nullptr) { + LOGE("Failed to allocate memory for cert_chain"); + return -ENOMEM; + } + + cert_chain->length = device_rsa_cert_size; + memcpy(cert_chain->buffer, device_rsa_cert, cert_chain->length); + } else { + cert_chain->buffer = (char*)malloc(device_ecdsa_cert_size); + if (cert_chain->buffer == nullptr) { + LOGE("Failed to allocate memory for cert_chain"); + return -ENOMEM; + } + + cert_chain->length = device_ecdsa_cert_size; + memcpy(cert_chain->buffer, device_ecdsa_cert, cert_chain->length); + } + + return 0; +} + +int hal_backend_security_certs::sign_data(hal_security_certs_digest_type_e digest_type, + hal_security_certs_data_s message, + hal_security_certs_data_s* signature) +{ + EVP_PKEY* pkey = NULL; + size_t sig_len = 0; + + if (fKey == HAL_SECURITY_CERTS_KEY_TYPE_RSA) { + pkey = get_rsa_pkey(); + } else { + pkey = get_ecdsa_pkey(); + } + + if (!pkey) { + LOGE("Can't load private key"); + return -EINVAL; + } + + typedef std::unique_ptr CtxPtr; + CtxPtr ctx(EVP_PKEY_CTX_new(pkey, NULL), EVP_PKEY_CTX_free); + EVP_PKEY_free(pkey); + if (!ctx.get()) { + LOGE("Can't create pkey context"); + return -EINVAL; + } + + if (1 != EVP_PKEY_sign_init(ctx.get())) { + LOGE("Can't initialise sign operation"); + return -EINVAL; + } + + if (fKey == HAL_SECURITY_CERTS_KEY_TYPE_RSA) { + if(1 != EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING)) { + LOGE("Can't set padding"); + return -EINVAL; + } + } + + if (1 != EVP_PKEY_CTX_set_signature_md(ctx.get(), to_openssl_md_type(digest_type))) { + LOGE("Can't set signature digest"); + return -EINVAL; + } + + if (1 != EVP_PKEY_sign(ctx.get(), NULL, &sig_len, + (const unsigned char*)message.buffer, message.length)) { + LOGE("Can't get signature length"); + return -EINVAL; + } + + signature->buffer = (char*)malloc(sig_len + 1); + if (signature->buffer == nullptr) { + LOGE("Failed to allocate memory for signature"); + return -ENOMEM; + } + signature->length = sig_len; + memset(signature->buffer, 0, signature->length); + + if (1 != EVP_PKEY_sign(ctx.get(), (unsigned char*) &signature->buffer[0], &sig_len, + (const unsigned char*)message.buffer, message.length)) { + free(signature->buffer); + signature->buffer = NULL; + return -EINVAL; + } + + return 0; +} + +int hal_backend_security_certs::get_key_type(hal_security_certs_crypto_key_type_e* key_type) +{ + *key_type = fKey; + return 0; +} + +int hal_backend_security_certs::get_key_length(unsigned int* key_length) +{ + *key_length = 0; + EVP_PKEY* pkey = NULL; + + if (fKey == HAL_SECURITY_CERTS_KEY_TYPE_RSA) { + pkey = get_rsa_pkey(); + } else { + pkey = get_ecdsa_pkey(); + } + + if (!pkey) { + LOGE("Can't load private key"); + return -EINVAL; + } + + *key_length = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); + return 0; +} diff --git a/src/backend/hal_backend_security_certs.h b/src/backend/hal_backend_security_certs.h new file mode 100644 index 0000000..549c250 --- /dev/null +++ b/src/backend/hal_backend_security_certs.h @@ -0,0 +1,46 @@ +/****************************************************************** + * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ + +#ifndef BACKEND_HAL_BACKEND_SECURITY_CERTS_H_ +#define BACKEND_HAL_BACKEND_SECURITY_CERTS_H_ + +#include + +#include +#include +#include + +class hal_backend_security_certs { +public: + hal_backend_security_certs(hal_security_certs_data_s key_type); + ~hal_backend_security_certs(); + + int request_certificate_chain(hal_security_certs_data_s* cert_chain); + + int sign_data(hal_security_certs_digest_type_e digest_type, + hal_security_certs_data_s message, + hal_security_certs_data_s* signature); + + int get_key_type(hal_security_certs_crypto_key_type_e* key_type); + + int get_key_length(unsigned int* key_length); + +private: + hal_security_certs_crypto_key_type_e fKey; +}; + +#endif /* BACKEND_HAL_BACKEND_SECURITY_CERTS_H_ */ diff --git a/src/backend/hal_backend_security_certs_api.cpp b/src/backend/hal_backend_security_certs_api.cpp new file mode 100644 index 0000000..434a20a --- /dev/null +++ b/src/backend/hal_backend_security_certs_api.cpp @@ -0,0 +1,180 @@ +/****************************************************************** + * Copyright 2019 - 2020 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ + +#include + +#include "hal_backend_security_certs.h" +#include "log.h" + +#define EXPORT __attribute__ ((visibility("default"))) + +int security_certs_create_key_context(hal_security_certs_context_s* context, + hal_security_certs_data_s key_type) +{ + LOGD("Create backend context"); + try { + context->ctx = new hal_backend_security_certs(key_type); + if (!context->ctx) + return -EINVAL; + } catch (std::invalid_argument&) { + LOGE("Unsupported key type"); + return -ENODATA; + } catch (std::bad_alloc&) { + LOGE("Out of memory when creating backend context"); + return -ENOMEM; + } + + return 0; +} + +int security_certs_free_key_context(hal_security_certs_context_s* context) +{ + LOGD("Delete backend context"); + try { + delete static_cast(context->ctx); + context->ctx = nullptr; + } catch (std::exception& ex) { + LOGE("Caught exception when trying to free backend context: ", ex.what()); + return -EINVAL; + } + + return 0; +} + +int security_certs_request_certificate_chain(hal_security_certs_context_s* context, + hal_security_certs_data_s* cert_chain) +{ + return context->ctx ? static_cast(context->ctx) + ->request_certificate_chain(cert_chain) : -EINVAL; +} + +int security_certs_sign_crypto_data(hal_security_certs_context_s* context, + hal_security_certs_digest_type_e digest_type, + hal_security_certs_data_s message, + hal_security_certs_data_s* signature) +{ + return context->ctx ? static_cast(context->ctx) + ->sign_data(digest_type, message, signature) : -EINVAL; +} + +int security_certs_get_key_type(hal_security_certs_context_s* context, + hal_security_certs_crypto_key_type_e* key_type) +{ + return context->ctx ? static_cast(context->ctx) + ->get_key_type(key_type) : -EINVAL; +} + +int security_certs_get_key_bit_length(hal_security_certs_context_s* context, + unsigned int* key_length) +{ + return context->ctx ? static_cast(context->ctx) + ->get_key_length(key_length) : -EINVAL; +} + +int security_certs_ext_call_api(hal_security_certs_data_s method_name, + hal_security_certs_data_s input_data, + hal_security_certs_data_s* output_data) +{ + if (strncmp(method_name.buffer, "square-int-method", method_name.length) == 0) { + // method expects one int 'x' and returns one int as 'x*x' + int x = *((int*) input_data.buffer); + x = x * x; + output_data->buffer = (char*)malloc(sizeof(int)); + if (output_data->buffer == nullptr) { + LOGE("Failed to allocate memory for output_data"); + return -ENOMEM; + } + memcpy(output_data->buffer, &x, sizeof(int)); + output_data->length = sizeof(int); + return 0; + } + if (strncmp(method_name.buffer, "method-with-a-privilege-not-granted", method_name.length) == 0) { + // no-op, implemented just formally + output_data->buffer = NULL; + output_data->length = 0; + return 0; + } + // no other methods + return -EINVAL; +} + +std::string sysadminPrivilege = "http://tizen.org/privilege/internal/sysadmin"; + +int security_certs_ext_get_api_privilege(hal_security_certs_data_s method_name, + hal_security_certs_data_s* privilege) +{ + if (strncmp(method_name.buffer, "method-with-a-privilege-not-granted", method_name.length) == 0) { + // this privilege is not granted to any label like User System::Privileged etc. + // so API test binary will NOT have it when executed from shell + privilege->buffer = (char*)malloc(sysadminPrivilege.size() + 1); + if (privilege->buffer == nullptr) { + LOGE("Failed to allocate memory for privilege"); + return -ENOMEM; + } + + privilege->length = sysadminPrivilege.size(); + memcpy(privilege->buffer, sysadminPrivilege.c_str(), privilege->length); + return 0; + } + if (strncmp(method_name.buffer, "square-int-method", method_name.length) == 0) { + // no privileges here as an example for security certs API that does not require any privilege check + privilege->buffer = NULL; + privilege->length = 0; + return 0; + } + // no other methods + return -EINVAL; +} + +static int security_certs_backend_init(void **data) +{ + hal_backend_security_certs_funcs *security_certs_funcs; + + if (!data) { + return -EINVAL; + } + + security_certs_funcs = *(hal_backend_security_certs_funcs **)data; + if (!security_certs_funcs) + return -EINVAL; + + security_certs_funcs->create_key_context = security_certs_create_key_context; + security_certs_funcs->free_key_context = security_certs_free_key_context; + security_certs_funcs->request_certificate_chain = security_certs_request_certificate_chain; + security_certs_funcs->sign_crypto_data = security_certs_sign_crypto_data; + security_certs_funcs->get_key_type = security_certs_get_key_type; + security_certs_funcs->get_key_bit_length = security_certs_get_key_bit_length; + security_certs_funcs->ext_call_api = security_certs_ext_call_api; + security_certs_funcs->ext_get_api_privilege = security_certs_ext_get_api_privilege; + + return 0; +} + +static int security_certs_backend_exit(void *data) +{ + (void)data; + return 0; +} + +hal_backend EXPORT hal_backend_security_certs_data = { + .name = "backend_security_certs", + .vendor = "Samsung", + .init = security_certs_backend_init, + .exit = security_certs_backend_exit, + .major_version = 1, + .minor_version = 0, +}; diff --git a/src/shared/log.cpp b/src/shared/log.cpp new file mode 100644 index 0000000..e697c55 --- /dev/null +++ b/src/shared/log.cpp @@ -0,0 +1,58 @@ +/****************************************************************** + * + * Copyright 2020 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ + +#include +#include + +#ifdef NDEBUG +int __log_level = LOG_ERR; +#else +int __log_level = LOG_DEBUG; +#endif + +#define SECURITY_CERTS_LOG_TAG "SECURITY_CERTS_BACKEND" + +void security_certs_print(int priority, char const *fmt, ...) +{ + log_priority dlog_prio; + + switch (priority) { + case LOG_EMERG: + dlog_prio = DLOG_FATAL; + break; + case LOG_ERR: + dlog_prio = DLOG_ERROR; + break; + case LOG_WARNING: + dlog_prio = DLOG_WARN; + break; + case LOG_INFO: + dlog_prio = DLOG_INFO; + break; + case LOG_DEBUG: + dlog_prio = DLOG_DEBUG; + break; + default: + dlog_prio = DLOG_DEFAULT; + } + + va_list ap; + va_start(ap, fmt); + (void) vprint_system_log(dlog_prio, SECURITY_CERTS_LOG_TAG, fmt, ap); + va_end(ap); +} diff --git a/src/shared/log.h b/src/shared/log.h new file mode 100644 index 0000000..c2280cd --- /dev/null +++ b/src/shared/log.h @@ -0,0 +1,70 @@ +/****************************************************************** + * + * Copyright 2020 Samsung Electronics All Rights Reserved. + * + * Licensed 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. + * + ******************************************************************/ +#ifndef SHARED_LOG_H_ +#define SHARED_LOG_H_ + +#include +#include +#include + +#define UNUSED __attribute__((unused)) + +extern int __log_level; +extern void security_certs_print(int priority, char const *fmt, ...); + +namespace { + template + void UNUSED __LOG_FUN(int level, const std::stringstream &format, Args&&... args) { + security_certs_print(level, format.str().c_str(), std::forward(args)...); + } + + template <> + void UNUSED __LOG_FUN(int level, const std::stringstream &format) { + security_certs_print(level, "%s", format.str().c_str()); + } + + template + void UNUSED __LOG_FUN(int level, const char *format, Args&&... args) { + security_certs_print(level, format, std::forward(args)...); + } + + template <> + void UNUSED __LOG_FUN(int level, const char *format) { + security_certs_print(level, "%s", format); + } + +} // namespace anonymous + +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define __LOG(LEVEL, FORMAT, ...) \ + do { \ + if (LEVEL <= __log_level) { \ + std::stringstream __LOG_FORMAT; \ + __LOG_FORMAT << __FILENAME__ << ": " << __func__ << "(" << __LINE__ << ") > " << FORMAT; \ + __LOG_FUN(LEVEL, __LOG_FORMAT, ##__VA_ARGS__); \ + } \ + } while (0) + +#define LOGM(...) __LOG(LOG_EMERG, __VA_ARGS__) /* system is unusable */ +#define LOGE(...) __LOG(LOG_ERR, __VA_ARGS__) /* error conditions */ +#define LOGW(...) __LOG(LOG_WARNING, __VA_ARGS__) /* warning conditions */ +#define LOGI(...) __LOG(LOG_INFO, __VA_ARGS__) /* informational */ +#define LOGD(...) __LOG(LOG_DEBUG, __VA_ARGS__) /* debug-level messages */ + +#endif /* SHARED_LOG_H_ */ -- 2.34.1