From aab621df68682a90c9b562f146b5cfec7e4583d7 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Thu, 3 Sep 2020 12:56:32 +0900 Subject: [PATCH 01/16] Fix errors in public api headers Change-Id: Icd6bdf804d3df8c0e3dae5aab7b878dde5589c5f Signed-off-by: Dongsun Lee --- api/yaca/yaca_key.h | 2 +- api/yaca/yaca_types.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/api/yaca/yaca_key.h b/api/yaca/yaca_key.h index 8abf4d1..e0bf47a 100644 --- a/api/yaca/yaca_key.h +++ b/api/yaca/yaca_key.h @@ -222,7 +222,7 @@ int yaca_key_generate(yaca_key_type_e key_type, size_t key_bit_len, yaca_key_h * * based on pre-generated parameters. * @remarks This function does not support RSA keys, as it's not possible * to extract parameters from them. - * @remarks The @a key should be released using yaca_key_destroy(). + * @remarks The @a prv_key should be released using yaca_key_destroy(). * @param[in] params Pre-generated parameters * @param[out] prv_key Newly generated private key * @return #YACA_ERROR_NONE on success, diff --git a/api/yaca/yaca_types.h b/api/yaca/yaca_types.h index ec32158..8973422 100644 --- a/api/yaca/yaca_types.h +++ b/api/yaca/yaca_types.h @@ -283,12 +283,14 @@ typedef enum { * @brief Definition for the value indicating generator equal 2 for DH parameters. * To be or'ed with safe prime length in bits. Prime length is recommended * to be 2048 bits or higher. + * @since_tizen 3.0 */ #define YACA_KEY_LENGTH_DH_GENERATOR_2 (YACA_KEYLEN_COMPONENT_TYPE_DH | YACA_KEYLEN_COMPONENT_DH_GEN_2) /** * @brief Definition for the value indicating generator equal 5 for DH parameters. * To be or'ed with safe prime length in bits. Prime length is recommended * to be 2048 bits or higher. + * @since_tizen 3.0 */ #define YACA_KEY_LENGTH_DH_GENERATOR_5 (YACA_KEYLEN_COMPONENT_TYPE_DH | YACA_KEYLEN_COMPONENT_DH_GEN_5) -- 2.7.4 From 1a6ed356c15132b9affacd8fb5bb08fdbcfd898f Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 2 Sep 2020 13:37:14 +0200 Subject: [PATCH 02/16] Automate code coverage measurement To gather unit tests coverage report: - use COVERAGE build_type, - instal yaca-coverage rpm, - run yaca-coverage.sh script. Change-Id: Ia3dd921d12e86cf0541252d9b1d224ce52a2d428 --- CMakeLists.txt | 4 ++++ packaging/yaca.spec | 47 +++++++++++++++++++++++------------------------ tests/CMakeLists.txt | 24 ++++++++++++++++++++++++ tests/yaca-coverage.sh.in | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 tests/yaca-coverage.sh.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f74a5..8629504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,10 @@ IF(NOT DEFINED EXAMPLES_DIR) SET(EXAMPLES_DIR "${SHARE_INSTALL_PREFIX}/${PROJECT_NAME}/examples") ENDIF(NOT DEFINED EXAMPLES_DIR) +IF(NOT DEFINED COVERAGE_DIR) + SET(COVERAGE_DIR "${SHARE_INSTALL_PREFIX}/${PROJECT_NAME}-coverage") +ENDIF(NOT DEFINED COVERAGE_DIR) + CONFIGURE_FILE(packaging/yaca.manifest.in yaca.manifest @ONLY) ADD_SUBDIRECTORY(${SRC_FOLDER}) diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 22adaec..86d02ad 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -34,30 +34,23 @@ The package provides Yet Another Crypto API. %prep %setup -q +%global coverage_dir %{_datadir}/yaca-coverage + %build -%cmake . -DCMAKE_BUILD_TYPE=%{build_type} +%cmake . \ + -DCMAKE_BUILD_TYPE=%{build_type} \ + -DCOVERAGE_DIR=%{coverage_dir} make -k %{?jobs:-j%jobs} -%if %{build_type} == "COVERAGE" -mkdir -p gcov-obj -find . \( -name '*.gcno' ! -name 'tc_*' \) -exec cp '{}' gcov-obj ';' -%endif - %install %make_install %py3_compile %{buildroot}/%{python3_sitearch} -%if "%{build_type}" == "COVERAGE" -mkdir -p %{buildroot}%{_datadir}/gcov/obj -install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj -%endif - - %clean rm -rf %{buildroot} -## Devel Package ############################################################### +## Devel Package ############################################################## %package devel Summary: Yet Another Crypto API development files Group: Security/Other @@ -71,7 +64,7 @@ The package provides Yet Another Crypto API development files. %{_includedir}/yaca %{_libdir}/pkgconfig/yaca.pc -## Examples Package ############################################################ +## Examples Package ########################################################### %package examples Summary: Yet Another Crypto API example files Group: Security/Other @@ -84,7 +77,7 @@ The package provides Yet Another Crypto API example files. %{_bindir}/yaca-example* %{_datadir}/%{name}/examples -## Tests Package ############################################################ +## Tests Package ############################################################## %package tests Summary: Yet Another Crypto API tests Group: Security/Other @@ -108,14 +101,20 @@ The package provides Yet Another Crypto API bindings for Python3. %files -n python3-yaca %{python3_sitearch}/%{name} -## gcov Package ############################################################ +## Coverage Package ########################################################### %if "%{build_type}" == "COVERAGE" -%package gcov -Summary: yaca gcov for measuring test coverage -Group: Secureity/Testing -%description gcov -New yaca gcov objects - -%files gcov -%{_datadir}/gcov/obj/* +%package coverage +Summary: Yet Another Crypto API code coverage data +Group: Security/Other +Requires: yaca-tests = %{version}-%{release} +Requires: yaca-debugsource = %{version}-%{release} +Requires: lcov +Requires: gcc + +%description coverage +Yet Another Crypto API code coverage data + +%files coverage +%{_bindir}/yaca-coverage.sh +%coverage_dir %endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8e81541..efcbd0e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,30 @@ # SET(TESTS_NAME yaca-unit-tests) + +IF (CMAKE_BUILD_TYPE MATCHES "COVERAGE") + + # coverage data + SET(COVERAGE_BUILD_DIR + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TESTS_NAME}.dir/ + ) + + # install gcno files + INSTALL( + DIRECTORY ${COVERAGE_BUILD_DIR}/ + DESTINATION ${COVERAGE_DIR} + FILES_MATCHING PATTERN "*.gcno" + ) + + # install code coverage automation script + CONFIGURE_FILE(yaca-coverage.sh.in yaca-coverage.sh @ONLY) + INSTALL( + PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/yaca-coverage.sh + DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + +ENDIF (CMAKE_BUILD_TYPE MATCHES "COVERAGE") + FILE(GLOB YACA_SOURCES ${SRC_FOLDER}/*.c) SET(TESTS_SOURCES common.cpp diff --git a/tests/yaca-coverage.sh.in b/tests/yaca-coverage.sh.in new file mode 100644 index 0000000..6cd4584 --- /dev/null +++ b/tests/yaca-coverage.sh.in @@ -0,0 +1,39 @@ +#!/bin/bash + +set -exuo pipefail + +REPORT="@PROJECT_NAME@-coverage.info" +STDERR="@PROJECT_NAME@-coverage.stderr" +HTML_DIR="@PROJECT_NAME@-coverage" + +SRCS_DIR="/usr/src/debug/@PROJECT_NAME@-@VERSION@" + +# create dir for the report +mkdir $HTML_DIR + +# remove old gcda files +find / -iname "*.gcda" -exec rm {} \; + +# launch unit tests +yaca-unit-tests + +# copy source files +cp -rp $SRCS_DIR/* "@CMAKE_BINARY_DIR@" + +# copy gcda files +cp -r "@COVERAGE_BUILD_DIR@"/* "@COVERAGE_DIR@" + +# prepare report +rm -f $STDERR +lcov --no-external -c -d "@COVERAGE_DIR@" -b "@CMAKE_BINARY_DIR@" -o $REPORT 2>$STDERR +lcov -r $REPORT "@CMAKE_BINARY_DIR@/tests/*" -o $REPORT + +# check warnings +if [ -s $STDERR ] +then + echo "Warnings detected (see $STDERR). Aborting." + exit 1 +fi + +# html +genhtml $REPORT --output-directory $HTML_DIR/ -- 2.7.4 From 02f6dd11f549fb6ddb03a9b8036a8a7d76be4f80 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 10 Nov 2020 14:28:57 +0100 Subject: [PATCH 03/16] Fix typo in python Change-Id: Ia15e71dbd32e62ad74eca315dd321eb5a4f23410 --- python/yaca/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 python/yaca/__init__.py diff --git a/python/yaca/__init__.py b/python/yaca/__init__.py old mode 100644 new mode 100755 index 3efd0bd..2002f08 --- a/python/yaca/__init__.py +++ b/python/yaca/__init__.py @@ -188,8 +188,8 @@ class DIGEST_ALGORITHM(_enum.Enum): class ENCRYPT_ALGORITHM(_enum.Enum): AES = 0 UNSAFE_DES = 1 - UNSAFE_TRIPPLE_DES_2TDEA = 2 - TRIPPLE_DES_3TDEA = 3 + UNSAFE_TRIPLE_DES_2TDEA = 2 + TRIPLE_DES_3TDEA = 3 UNSAFE_RC2 = 4 UNSAFE_RC4 = 5 CAST5 = 6 -- 2.7.4 From 9459272ec1d0bc653eee10da54da6c8c76dd5b4c Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 13 Nov 2020 15:36:38 +0100 Subject: [PATCH 04/16] Add a cmake option to not build tests Change-Id: Ifb5e887c2086df3e7e53920334e14d409ca98198 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8629504..365bd0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,9 @@ CONFIGURE_FILE(packaging/yaca.manifest.in yaca.manifest @ONLY) ADD_SUBDIRECTORY(${SRC_FOLDER}) ADD_SUBDIRECTORY(${EXAMPLES_FOLDER}) -ADD_SUBDIRECTORY(${TESTS_FOLDER}) +IF(NOT WITHOUT_TESTS) + ADD_SUBDIRECTORY(${TESTS_FOLDER}) +ENDIF(NOT WITHOUT_TESTS) IF(NOT WITHOUT_PYTHON) ADD_SUBDIRECTORY(${PYTHON_FOLDER}) ENDIF(NOT WITHOUT_PYTHON) -- 2.7.4 From 105cd12fc5291c7d6b5f062ce7f0c57e46650ffe Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Fri, 13 Nov 2020 15:36:58 +0100 Subject: [PATCH 05/16] Add a static library Change-Id: Ic8ff0e863787bbb49dbdf59a05258e1f4bc79e70 --- src/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 57c4488..7cf4872 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,6 +43,9 @@ ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${HEADERS}) SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${_LIB_SOVERSION_} VERSION ${_LIB_VERSION_}) +ADD_LIBRARY(${PROJECT_NAME}-static STATIC ${SRCS} ${HEADERS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME}-static PROPERTIES + OUTPUT_NAME ${PROJECT_NAME}) ## Link libraries ############################################################## PKG_CHECK_MODULES(YACA_DEPS REQUIRED openssl1.1 capi-base-common) @@ -65,6 +68,9 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +INSTALL(TARGETS ${PROJECT_NAME}-static + DESTINATION ${LIB_INSTALL_DIR} + COMPONENT DevelopmentLibraries) INSTALL(FILES ${HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/yaca) -- 2.7.4 From 32604b251b3b4e5e562867b780ff68c712b1dced Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 26 Nov 2020 12:18:10 +0100 Subject: [PATCH 06/16] Add colour log formatter Change-Id: I2f5febb66b26107e092c72cfadccf6a91ab8a976 --- tests/CMakeLists.txt | 1 + tests/colour_log_formatter.cpp | 355 +++++++++++++++++++++++++++++++++++++++++ tests/colour_log_formatter.h | 78 +++++++++ tests/common.cpp | 2 + 4 files changed, 436 insertions(+) create mode 100644 tests/colour_log_formatter.cpp create mode 100644 tests/colour_log_formatter.h diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index efcbd0e..5bb357a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -48,6 +48,7 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "COVERAGE") FILE(GLOB YACA_SOURCES ${SRC_FOLDER}/*.c) SET(TESTS_SOURCES common.cpp + colour_log_formatter.cpp test_debug.cpp test_crypto.cpp test_key.cpp diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp new file mode 100644 index 0000000..5033e2f --- /dev/null +++ b/tests/colour_log_formatter.cpp @@ -0,0 +1,355 @@ +/* + * (C) Copyright Gennadiy Rozental 2005-2008. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/test for the library home page. + */ +/* + * @file colour_log_formatter.cpp + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version + * @brief + */ +// Boost.Test +#include "colour_log_formatter.h" +#include +#if BOOST_VERSION >= 105900 +#include +#else +#include +#endif +#include +#include +#include + +// Boost +#include + +// STL +#include +#include + +const char* GREEN_BEGIN = "\033[0;32m"; +const char* RED_BEGIN = "\033[0;31m"; +const char* CYAN_BEGIN = "\033[0;36m"; +const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char* COLOR_END = "\033[m"; + +// ************************************************************************** // +// ************** colour_log_formatter ************** // +// ************************************************************************** // + +using namespace boost::unit_test; +namespace Yaca { + +namespace { + +const_string +test_unit_type_name(const test_unit &tu) +{ +#if BOOST_VERSION >= 105900 + return const_string(tu.p_type_name); +#else + return tu.p_type_name.get(); +#endif +} + +const_string +test_unit_name(const test_unit &tu) +{ +#if BOOST_VERSION >= 105900 + return const_string(tu.p_name); +#else + return tu.p_name.get(); +#endif +} + +const_string +test_phase_identifier() +{ + return test_unit_name(framework::current_test_case()); +} + +const_string +get_basename(const const_string &file_name) +{ + return basename(file_name.begin()); +} + +std::string +get_basename(const std::string &file_name) +{ + return basename(file_name.c_str()); +} + +bool +test_unit_type_name_contains(const test_unit &tu, const std::string &substr) +{ + return test_unit_type_name(tu).find(const_string(substr)) == 0; +} + +} // local namespace + +//____________________________________________________________________________// + +void +colour_log_formatter::log_start( + std::ostream &output, + counter_t test_cases_amount) +{ + if (test_cases_amount > 0) + output << "Running " << test_cases_amount << " test " + << (test_cases_amount > 1 ? "cases" : "case") << "...\n"; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_finish(std::ostream &ostr) +{ + ostr.flush(); +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_build_info(std::ostream &output, bool log_build_info) +{ + if (log_build_info) + output << "Platform: " << BOOST_PLATFORM << '\n' + << "Compiler: " << BOOST_COMPILER << '\n' + << "STL : " << BOOST_STDLIB << '\n'; + output << "Boost : " << BOOST_VERSION / 100000 << '.' + << BOOST_VERSION / 100 % 1000 << '.' + << BOOST_VERSION % 100 << std::endl; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::test_unit_start( + std::ostream &output, + test_unit const &tu) +{ + if (test_unit_type_name_contains(tu, "suite")) { + output << "Starting test "; + } else { + output << "Running test "; + } + output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) + << "\"" << std::endl; + +} + +//____________________________________________________________________________// + +void +colour_log_formatter::test_unit_finish( + std::ostream &output, + test_unit const &tu, + unsigned long elapsed) +{ + if (test_unit_type_name_contains(tu, "suite")) { + output << "Finished test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << + std::endl; + return; + } + + std::string color = GREEN_BEGIN; + std::string status = "OK"; + + if (m_isTestCaseFailed) { + color = RED_BEGIN; + status = "FAIL"; + } + + output << "\t" << "[ " << color << status << COLOR_END << + " ]"; + + + output << ", " << CYAN_BEGIN << "time: "; + + if (elapsed > 0) { + if (elapsed % 1000 == 0) + output << elapsed / 1000 << "ms"; + else + output << elapsed << "mks"; + } else { + output << "N/A"; + } + + output << COLOR_END << std::endl; + m_isTestCaseFailed = false; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::test_unit_skipped( + std::ostream &output, + test_unit const &tu) +{ + output << "Test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << + "is skipped" << std::endl; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_exception( + std::ostream &output, + log_checkpoint_data const &checkpoint_data, + boost::execution_exception const &ex) +{ + boost::execution_exception::location const &loc = ex.where(); + output << '\t' << BOLD_YELLOW_BEGIN << get_basename( + loc.m_file_name) + << '(' << loc.m_line_num << "), "; + + output << "fatal error in \"" + << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function) << + "\": "; + + output << COLOR_END << ex.what(); + + if (!checkpoint_data.m_file_name.is_empty()) { + output << '\n'; + output << "\tlast checkpoint : " << get_basename(checkpoint_data.m_file_name) + << '(' << checkpoint_data.m_line_num << ")"; + + if (!checkpoint_data.m_message.empty()) + output << ": " << checkpoint_data.m_message; + } + + output << std::endl; + m_isTestCaseFailed = true; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_start( + std::ostream &output, + log_entry_data const &entry_data, + log_entry_types let) +{ + switch (let) { + case BOOST_UTL_ET_INFO: + output << '\t' << entry_data.m_file_name << '(' << entry_data.m_line_num << + "), "; + output << "info: "; + break; + + case BOOST_UTL_ET_MESSAGE: + break; + + case BOOST_UTL_ET_WARNING: + output << '\t' << get_basename(entry_data.m_file_name) << '(' << + entry_data.m_line_num << "), "; + output << "warning in \"" << test_phase_identifier() << "\": "; + break; + + case BOOST_UTL_ET_ERROR: + output << '\t' << BOLD_YELLOW_BEGIN << get_basename( + entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << "error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + + case BOOST_UTL_ET_FATAL_ERROR: + output << '\t' << BOLD_YELLOW_BEGIN << get_basename( + entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << " fatal error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + } + + output << COLOR_END; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_value( + std::ostream &output, + const_string value) +{ + output << value; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_value( + std::ostream &output, + lazy_ostream const &value) +{ + output << value; +} + +//____________________________________________________________________________// + +void +colour_log_formatter::log_entry_finish( + std::ostream &output) +{ + output << std::endl; +} + +//____________________________________________________________________________// + +#if BOOST_VERSION >= 106501 +void +colour_log_formatter::log_exception_start( + std::ostream& os, + boost::unit_test::log_checkpoint_data const& lcd, + boost::execution_exception const& ex) +{ + log_exception(os, lcd, ex); +} + +void +colour_log_formatter::log_exception_finish(std::ostream& os) +{ + (void)os; +} + +void +colour_log_formatter::entry_context_start( + std::ostream& os, + boost::unit_test::log_level l) +{ + (void)os; + (void)l; +} + +void +colour_log_formatter::log_entry_context( + std::ostream& os, + boost::unit_test::log_level l, + boost::unit_test::const_string value) +{ + (void)os; + (void)l; + (void)value; +} + +void +colour_log_formatter::entry_context_finish( + std::ostream& os, + boost::unit_test::log_level l) +{ + (void)os; + (void)l; +} +#endif + +//____________________________________________________________________________// + +} // namespace Yaca + +//____________________________________________________________________________// diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h new file mode 100644 index 0000000..c971263 --- /dev/null +++ b/tests/colour_log_formatter.h @@ -0,0 +1,78 @@ +/* + * (C) Copyright Gennadiy Rozental 2005-2008. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/test for the library home page. + */ +/* + * @file colour_log_formatter.h + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version + * @brief + */ +#pragma once +#include + +namespace Yaca { +class colour_log_formatter : public boost::unit_test::unit_test_log_formatter { +public: + // Formatter interface + colour_log_formatter() : m_isTestCaseFailed(false) {} + void log_start( + std::ostream &, + boost::unit_test::counter_t test_cases_amount); + void log_finish(std::ostream &); + void log_build_info(std::ostream &output, bool log_build_info = true); + + void test_unit_start( + std::ostream &, + boost::unit_test::test_unit const &tu); + void test_unit_finish( + std::ostream &, + boost::unit_test::test_unit const &tu, + unsigned long elapsed); + void test_unit_skipped( + std::ostream &, + boost::unit_test::test_unit const &tu); + + void log_exception( + std::ostream &, + boost::unit_test::log_checkpoint_data const &, + boost::execution_exception const &ex); + + void log_entry_start( + std::ostream &, + boost::unit_test::log_entry_data const &, + log_entry_types let); + void log_entry_value( + std::ostream &, + boost::unit_test::const_string value); + void log_entry_value( + std::ostream &, + boost::unit_test::lazy_ostream const &value); + void log_entry_finish(std::ostream &); + +#if BOOST_VERSION >= 106501 + void log_exception_start( + std::ostream& os, + boost::unit_test::log_checkpoint_data const& lcd, + boost::execution_exception const& ex); + void log_exception_finish(std::ostream& os); + void entry_context_start( + std::ostream& os, + boost::unit_test::log_level l); + void log_entry_context( + std::ostream& os, + boost::unit_test::log_level l, + boost::unit_test::const_string value); + void entry_context_finish( + std::ostream& os, + boost::unit_test::log_level l); +#endif + +private: + bool m_isTestCaseFailed; +}; +} // namespace Yaca diff --git a/tests/common.cpp b/tests/common.cpp index e7b5db3..04c2779 100644 --- a/tests/common.cpp +++ b/tests/common.cpp @@ -36,6 +36,7 @@ #include "../src/debug.h" #include "common.h" +#include "colour_log_formatter.h" namespace { @@ -84,6 +85,7 @@ struct TestConfig { boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_test_units); boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); + boost::unit_test::unit_test_log.set_formatter(new Yaca::colour_log_formatter); } ~TestConfig() { -- 2.7.4 From d8a2c64d6f1f6c586abdea37fb8790f6489f8a1e Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 30 Nov 2020 11:16:59 +0100 Subject: [PATCH 07/16] Categorize neutral tests as positive Change-Id: I5fdd9344850e781a6625539cde9a350b8c932713 --- tests/test_debug.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_debug.cpp b/tests/test_debug.cpp index 3786abd..8d366ab 100644 --- a/tests/test_debug.cpp +++ b/tests/test_debug.cpp @@ -73,7 +73,7 @@ struct CallbackCleanup BOOST_AUTO_TEST_SUITE(TESTS_DEBUG) -BOOST_AUTO_TEST_CASE(T001__neutral__translate_error) +BOOST_AUTO_TEST_CASE(T001__positive__translate_error) { struct error_args { yaca_error_e err; @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(T001__neutral__translate_error) } } -BOOST_FIXTURE_TEST_CASE(T002__neutral__debug_set_error_cb, CallbackCleanup) +BOOST_FIXTURE_TEST_CASE(T002__positive__debug_set_error_cb, CallbackCleanup) { ERROR_DUMP(YACA_ERROR_INTERNAL); BOOST_REQUIRE(error_cb_called == 0); @@ -114,7 +114,7 @@ BOOST_FIXTURE_TEST_CASE(T002__neutral__debug_set_error_cb, CallbackCleanup) BOOST_REQUIRE(error_cb_called == 2); } -BOOST_FIXTURE_TEST_CASE(T003__neutral__error_dump, CallbackCleanup) +BOOST_FIXTURE_TEST_CASE(T003__positive__error_dump, CallbackCleanup) { yaca_debug_set_error_cb(&debug_error_cb); @@ -146,7 +146,7 @@ BOOST_FIXTURE_TEST_CASE(T003__neutral__error_dump, CallbackCleanup) BOOST_REQUIRE(ellipsis == ELLIPSIS); } -BOOST_FIXTURE_TEST_CASE(T004__neutral__error_handle, CallbackCleanup) +BOOST_FIXTURE_TEST_CASE(T004__positive__error_handle, CallbackCleanup) { struct error_args { long err1; -- 2.7.4 From 997a1147b5b53e591a60c93c1f73917a5474c945 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 1 Dec 2020 11:38:19 +0100 Subject: [PATCH 08/16] Fix colour log formatter compatibility with boost 1.65 Change-Id: I855eed7f331163e0edc3dee9644e7c673b063377 --- tests/colour_log_formatter.cpp | 13 ++++++++----- tests/colour_log_formatter.h | 6 +++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index 5033e2f..bd1e323 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -115,12 +115,15 @@ colour_log_formatter::log_finish(std::ostream &ostr) //____________________________________________________________________________// void -colour_log_formatter::log_build_info(std::ostream &output, bool log_build_info) +#if BOOST_VERSION >= 107000 +colour_log_formatter::log_build_info(std::ostream &output, bool) +#else +colour_log_formatter::log_build_info(std::ostream &output) +#endif { - if (log_build_info) - output << "Platform: " << BOOST_PLATFORM << '\n' - << "Compiler: " << BOOST_COMPILER << '\n' - << "STL : " << BOOST_STDLIB << '\n'; + output << "Platform: " << BOOST_PLATFORM << '\n' + << "Compiler: " << BOOST_COMPILER << '\n' + << "STL : " << BOOST_STDLIB << '\n'; output << "Boost : " << BOOST_VERSION / 100000 << '.' << BOOST_VERSION / 100 % 1000 << '.' << BOOST_VERSION % 100 << std::endl; diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index c971263..10c4b76 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -24,7 +24,11 @@ public: std::ostream &, boost::unit_test::counter_t test_cases_amount); void log_finish(std::ostream &); - void log_build_info(std::ostream &output, bool log_build_info = true); +#if BOOST_VERSION >= 107000 + void log_build_info(std::ostream &, bool); +#else + void log_build_info(std::ostream &); +#endif void test_unit_start( std::ostream &, -- 2.7.4 From bbd1d8e575c8f1df9397b2f87588363d2a60bddb Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 1 Dec 2020 17:52:09 +0100 Subject: [PATCH 09/16] Fix style, coding rules and overall esthetics of log formatter code Change-Id: I96da85bbe6b24f37a79d76365a69707afd430752 --- tests/colour_log_formatter.cpp | 178 +++++++++++++++-------------------------- tests/colour_log_formatter.h | 38 +++++---- 2 files changed, 84 insertions(+), 132 deletions(-) diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index bd1e323..81ffd06 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -12,6 +12,7 @@ * @version * @brief */ + // Boost.Test #include "colour_log_formatter.h" #include @@ -37,17 +38,14 @@ const char* CYAN_BEGIN = "\033[0;36m"; const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; const char* COLOR_END = "\033[m"; -// ************************************************************************** // -// ************** colour_log_formatter ************** // -// ************************************************************************** // - using namespace boost::unit_test; + + namespace Yaca { namespace { -const_string -test_unit_type_name(const test_unit &tu) +const_string test_unit_type_name(const test_unit &tu) { #if BOOST_VERSION >= 105900 return const_string(tu.p_type_name); @@ -56,8 +54,7 @@ test_unit_type_name(const test_unit &tu) #endif } -const_string -test_unit_name(const test_unit &tu) +const_string test_unit_name(const test_unit &tu) { #if BOOST_VERSION >= 105900 return const_string(tu.p_name); @@ -66,73 +63,59 @@ test_unit_name(const test_unit &tu) #endif } -const_string -test_phase_identifier() +const_string test_phase_identifier() { return test_unit_name(framework::current_test_case()); } -const_string -get_basename(const const_string &file_name) +const_string get_basename(const const_string &file_name) { return basename(file_name.begin()); } -std::string -get_basename(const std::string &file_name) +std::string get_basename(const std::string &file_name) { return basename(file_name.c_str()); } -bool -test_unit_type_name_contains(const test_unit &tu, const std::string &substr) +bool test_unit_type_name_contains(const test_unit &tu, const std::string &substr) { return test_unit_type_name(tu).find(const_string(substr)) == 0; } } // local namespace -//____________________________________________________________________________// -void -colour_log_formatter::log_start( +void colour_log_formatter::log_start( std::ostream &output, counter_t test_cases_amount) { - if (test_cases_amount > 0) - output << "Running " << test_cases_amount << " test " - << (test_cases_amount > 1 ? "cases" : "case") << "...\n"; + if (test_cases_amount > 0) { + output << "Running " << test_cases_amount << " test " + << (test_cases_amount > 1 ? "cases" : "case") << "...\n"; + } } -//____________________________________________________________________________// - -void -colour_log_formatter::log_finish(std::ostream &ostr) +void colour_log_formatter::log_finish(std::ostream &ostr) { ostr.flush(); } -//____________________________________________________________________________// - -void #if BOOST_VERSION >= 107000 -colour_log_formatter::log_build_info(std::ostream &output, bool) +void colour_log_formatter::log_build_info(std::ostream &output, bool) #else -colour_log_formatter::log_build_info(std::ostream &output) +void colour_log_formatter::log_build_info(std::ostream &output) #endif { - output << "Platform: " << BOOST_PLATFORM << '\n' - << "Compiler: " << BOOST_COMPILER << '\n' - << "STL : " << BOOST_STDLIB << '\n'; - output << "Boost : " << BOOST_VERSION / 100000 << '.' - << BOOST_VERSION / 100 % 1000 << '.' - << BOOST_VERSION % 100 << std::endl; + output << "Platform: " << BOOST_PLATFORM << '\n' + << "Compiler: " << BOOST_COMPILER << '\n' + << "STL : " << BOOST_STDLIB << '\n'; + output << "Boost : " << BOOST_VERSION / 100000 << '.' + << BOOST_VERSION / 100 % 1000 << '.' + << BOOST_VERSION % 100 << '\n'; } -//____________________________________________________________________________// - -void -colour_log_formatter::test_unit_start( +void colour_log_formatter::test_unit_start( std::ostream &output, test_unit const &tu) { @@ -141,22 +124,17 @@ colour_log_formatter::test_unit_start( } else { output << "Running test "; } - output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) - << "\"" << std::endl; - + output << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"\n"; } -//____________________________________________________________________________// - -void -colour_log_formatter::test_unit_finish( +void colour_log_formatter::test_unit_finish( std::ostream &output, test_unit const &tu, unsigned long elapsed) { if (test_unit_type_name_contains(tu, "suite")) { - output << "Finished test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << - std::endl; + output << "Finished test " << test_unit_type_name(tu) + << " \"" << test_unit_name(tu) << "\"\n"; return; } @@ -168,52 +146,44 @@ colour_log_formatter::test_unit_finish( status = "FAIL"; } - output << "\t" << "[ " << color << status << COLOR_END << - " ]"; - - - output << ", " << CYAN_BEGIN << "time: "; + output << "\t" << "[ " << color << status << COLOR_END << " ], " + << ", " << CYAN_BEGIN << "time: "; if (elapsed > 0) { - if (elapsed % 1000 == 0) + if (elapsed % 1000 == 0) { output << elapsed / 1000 << "ms"; - else + } else { output << elapsed << "mks"; + } } else { output << "N/A"; } - output << COLOR_END << std::endl; + output << COLOR_END << '\n'; m_isTestCaseFailed = false; } -//____________________________________________________________________________// - -void -colour_log_formatter::test_unit_skipped( +void colour_log_formatter::test_unit_skipped( std::ostream &output, test_unit const &tu) { - output << "Test " << test_unit_type_name(tu) << " \"" << test_unit_name(tu) << "\"" << - "is skipped" << std::endl; + output << "Test " << test_unit_type_name(tu) + << " \"" << test_unit_name(tu) << "\" is skipped\n"; } -//____________________________________________________________________________// - -void -colour_log_formatter::log_exception( +void colour_log_formatter::log_exception( std::ostream &output, log_checkpoint_data const &checkpoint_data, boost::execution_exception const &ex) { boost::execution_exception::location const &loc = ex.where(); - output << '\t' << BOLD_YELLOW_BEGIN << get_basename( - loc.m_file_name) + output << '\t' << BOLD_YELLOW_BEGIN + << get_basename(loc.m_file_name) << '(' << loc.m_line_num << "), "; output << "fatal error in \"" - << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function) << - "\": "; + << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function) + << "\": "; output << COLOR_END << ex.what(); @@ -222,26 +192,24 @@ colour_log_formatter::log_exception( output << "\tlast checkpoint : " << get_basename(checkpoint_data.m_file_name) << '(' << checkpoint_data.m_line_num << ")"; - if (!checkpoint_data.m_message.empty()) + if (!checkpoint_data.m_message.empty()) { output << ": " << checkpoint_data.m_message; + } } - output << std::endl; + output << '\n'; m_isTestCaseFailed = true; } -//____________________________________________________________________________// - -void -colour_log_formatter::log_entry_start( +void colour_log_formatter::log_entry_start( std::ostream &output, log_entry_data const &entry_data, log_entry_types let) { switch (let) { case BOOST_UTL_ET_INFO: - output << '\t' << entry_data.m_file_name << '(' << entry_data.m_line_num << - "), "; + output << '\t' << entry_data.m_file_name + << '(' << entry_data.m_line_num << "), "; output << "info: "; break; @@ -249,22 +217,22 @@ colour_log_formatter::log_entry_start( break; case BOOST_UTL_ET_WARNING: - output << '\t' << get_basename(entry_data.m_file_name) << '(' << - entry_data.m_line_num << "), "; + output << '\t' << get_basename(entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; output << "warning in \"" << test_phase_identifier() << "\": "; break; case BOOST_UTL_ET_ERROR: - output << '\t' << BOLD_YELLOW_BEGIN << get_basename( - entry_data.m_file_name) + output << '\t' << BOLD_YELLOW_BEGIN + << get_basename(entry_data.m_file_name) << '(' << entry_data.m_line_num << "), "; output << "error in \"" << test_phase_identifier() << "\": "; m_isTestCaseFailed = true; break; case BOOST_UTL_ET_FATAL_ERROR: - output << '\t' << BOLD_YELLOW_BEGIN << get_basename( - entry_data.m_file_name) + output << '\t' << BOLD_YELLOW_BEGIN + << get_basename(entry_data.m_file_name) << '(' << entry_data.m_line_num << "), "; output << " fatal error in \"" << test_phase_identifier() << "\": "; m_isTestCaseFailed = true; @@ -274,40 +242,28 @@ colour_log_formatter::log_entry_start( output << COLOR_END; } -//____________________________________________________________________________// - -void -colour_log_formatter::log_entry_value( +void colour_log_formatter::log_entry_value( std::ostream &output, const_string value) { output << value; } -//____________________________________________________________________________// - -void -colour_log_formatter::log_entry_value( +void colour_log_formatter::log_entry_value( std::ostream &output, lazy_ostream const &value) { output << value; } -//____________________________________________________________________________// - -void -colour_log_formatter::log_entry_finish( +void colour_log_formatter::log_entry_finish( std::ostream &output) { - output << std::endl; + output << '\n'; } -//____________________________________________________________________________// - #if BOOST_VERSION >= 106501 -void -colour_log_formatter::log_exception_start( +void colour_log_formatter::log_exception_start( std::ostream& os, boost::unit_test::log_checkpoint_data const& lcd, boost::execution_exception const& ex) @@ -315,14 +271,12 @@ colour_log_formatter::log_exception_start( log_exception(os, lcd, ex); } -void -colour_log_formatter::log_exception_finish(std::ostream& os) +void colour_log_formatter::log_exception_finish(std::ostream& os) { (void)os; } -void -colour_log_formatter::entry_context_start( +void colour_log_formatter::entry_context_start( std::ostream& os, boost::unit_test::log_level l) { @@ -330,8 +284,7 @@ colour_log_formatter::entry_context_start( (void)l; } -void -colour_log_formatter::log_entry_context( +void colour_log_formatter::log_entry_context( std::ostream& os, boost::unit_test::log_level l, boost::unit_test::const_string value) @@ -341,8 +294,7 @@ colour_log_formatter::log_entry_context( (void)value; } -void -colour_log_formatter::entry_context_finish( +void colour_log_formatter::entry_context_finish( std::ostream& os, boost::unit_test::log_level l) { @@ -351,8 +303,4 @@ colour_log_formatter::entry_context_finish( } #endif -//____________________________________________________________________________// - } // namespace Yaca - -//____________________________________________________________________________// diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index 10c4b76..8760a74 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -12,66 +12,69 @@ * @version * @brief */ + #pragma once #include + namespace Yaca { + class colour_log_formatter : public boost::unit_test::unit_test_log_formatter { public: // Formatter interface colour_log_formatter() : m_isTestCaseFailed(false) {} - void log_start( + void log_start( std::ostream &, boost::unit_test::counter_t test_cases_amount); - void log_finish(std::ostream &); + void log_finish(std::ostream &); #if BOOST_VERSION >= 107000 - void log_build_info(std::ostream &, bool); + void log_build_info(std::ostream &, bool); #else - void log_build_info(std::ostream &); + void log_build_info(std::ostream &); #endif - void test_unit_start( + void test_unit_start( std::ostream &, boost::unit_test::test_unit const &tu); - void test_unit_finish( + void test_unit_finish( std::ostream &, boost::unit_test::test_unit const &tu, unsigned long elapsed); - void test_unit_skipped( + void test_unit_skipped( std::ostream &, boost::unit_test::test_unit const &tu); - void log_exception( + void log_exception( std::ostream &, boost::unit_test::log_checkpoint_data const &, boost::execution_exception const &ex); - void log_entry_start( + void log_entry_start( std::ostream &, boost::unit_test::log_entry_data const &, log_entry_types let); - void log_entry_value( + void log_entry_value( std::ostream &, boost::unit_test::const_string value); - void log_entry_value( + void log_entry_value( std::ostream &, boost::unit_test::lazy_ostream const &value); - void log_entry_finish(std::ostream &); + void log_entry_finish(std::ostream &); #if BOOST_VERSION >= 106501 - void log_exception_start( + void log_exception_start( std::ostream& os, boost::unit_test::log_checkpoint_data const& lcd, boost::execution_exception const& ex); - void log_exception_finish(std::ostream& os); - void entry_context_start( + void log_exception_finish(std::ostream& os); + void entry_context_start( std::ostream& os, boost::unit_test::log_level l); - void log_entry_context( + void log_entry_context( std::ostream& os, boost::unit_test::log_level l, boost::unit_test::const_string value); - void entry_context_finish( + void entry_context_finish( std::ostream& os, boost::unit_test::log_level l); #endif @@ -79,4 +82,5 @@ public: private: bool m_isTestCaseFailed; }; + } // namespace Yaca -- 2.7.4 From 3492dc19d22e2b83149a6fd36c34d9f03bb20941 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Wed, 2 Dec 2020 14:55:23 +0100 Subject: [PATCH 10/16] Fix wrong key decryption test The test T604 fails from time to time at test_encrypt.cpp:738. The reason is that the wrong key used for decryption can generate a properly padded buffer with quite high probability (more than 1/256). Fix by adding a length check in above case. Also remove an outdated comment related to invalid decryption. Change-Id: I22f7c837dc30c605dadd5c7ba8fa6b025f3396e0 --- tests/test_encrypt.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/test_encrypt.cpp b/tests/test_encrypt.cpp index 92565a6..810c837 100644 --- a/tests/test_encrypt.cpp +++ b/tests/test_encrypt.cpp @@ -735,7 +735,16 @@ BOOST_FIXTURE_TEST_CASE(T604__negative__encrypt_decrypt, InitDebugFixture) decrypted_len = written; ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); - BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + if (ret != YACA_ERROR_INVALID_PARAMETER) { + /* + * There's a quite high (over 1/256) chance that the decryption with key2 will create + * a correctly padded buffer (e.g. last byte equal to 0x01). In such case we expect that + * the length of the decrypted buffer will not match the original one. + */ + + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(decrypted_len + written != INPUT_DATA_SIZE); + } yaca_context_destroy(ctx); ctx = YACA_CONTEXT_NULL; @@ -1776,9 +1785,6 @@ BOOST_FIXTURE_TEST_CASE(T610__negative__encrypt_decrypt_ccm, InitDebugFixture) ret = yaca_context_set_property(ctx, YACA_PROPERTY_CCM_AAD, aad, aad_len); BOOST_REQUIRE(ret == YACA_ERROR_NONE); - /* In case of AES/CBC wrong key returned INVALID_PASS - * Why this inconsistency? - */ ret = yaca_decrypt_update(ctx, encrypted, encrypted_len, decrypted, &written); BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); -- 2.7.4 From b1dd8931e77800033925255f9bcfccd8ff8f18a7 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Mon, 4 Jan 2021 11:31:18 +0100 Subject: [PATCH 11/16] Fix all accidentally valid padding cases in tests Another occasionally failing test has been observed. The reason was again a correctly padded buffer generated during decryption with invalid parameters. Statistically, this may happen in more than 1 per 256 cases and is an expected behavior when different key, iv, bcm or ciphertext is used during decryption. Hopefully all remaining cases related to accidentally valid padding have been fixed by adding a length check if padding was ok. Hepler function added. Verify by running T303 and T604 in a loop. while true; do yaca-unit-tests -t / 2>&1 | grep fatal; done Change-Id: I90c0d1322745de6341a8df13c83f9a34f6694fbe --- tests/common.cpp | 10 +++++++++- tests/common.h | 8 +++++++- tests/test_encrypt.cpp | 17 ++++------------- tests/test_simple.cpp | 6 +++--- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tests/common.cpp b/tests/common.cpp index 04c2779..f358fcb 100644 --- a/tests/common.cpp +++ b/tests/common.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -205,3 +205,11 @@ void call_update_loop(yaca_context_h ctx, const char *input, size_t input_len, part = left; } } + +void decrypt_check(int ret, size_t actual_len, size_t expected_len) +{ + if (ret != YACA_ERROR_INVALID_PARAMETER) { + BOOST_REQUIRE(ret == YACA_ERROR_NONE); + BOOST_REQUIRE(actual_len != expected_len); + } +} diff --git a/tests/common.h b/tests/common.h index eafeb79..45f9f8e 100644 --- a/tests/common.h +++ b/tests/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -136,5 +136,11 @@ void call_mock_test(func F) } } +/* + * There's a quite high (over 1/256) chance that the decryption with wrong key, bcm, iv or + * ciphertext will create a correctly padded buffer (e.g. last byte equal to 0x01). In such case we + * expect that the length of the decrypted buffer will not match the original one. + */ +void decrypt_check(int ret, size_t actual_len, size_t expected_len); #endif /* COMMON_H */ diff --git a/tests/test_encrypt.cpp b/tests/test_encrypt.cpp index 810c837..726f4cf 100644 --- a/tests/test_encrypt.cpp +++ b/tests/test_encrypt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -710,7 +710,7 @@ BOOST_FIXTURE_TEST_CASE(T604__negative__encrypt_decrypt, InitDebugFixture) decrypted_len = written; ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); - BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + decrypt_check(ret, decrypted_len + written, INPUT_DATA_SIZE); yaca_context_destroy(ctx); ctx = YACA_CONTEXT_NULL; @@ -735,16 +735,7 @@ BOOST_FIXTURE_TEST_CASE(T604__negative__encrypt_decrypt, InitDebugFixture) decrypted_len = written; ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); - if (ret != YACA_ERROR_INVALID_PARAMETER) { - /* - * There's a quite high (over 1/256) chance that the decryption with key2 will create - * a correctly padded buffer (e.g. last byte equal to 0x01). In such case we expect that - * the length of the decrypted buffer will not match the original one. - */ - - BOOST_REQUIRE(ret == YACA_ERROR_NONE); - BOOST_REQUIRE(decrypted_len + written != INPUT_DATA_SIZE); - } + decrypt_check(ret, decrypted_len + written, INPUT_DATA_SIZE); yaca_context_destroy(ctx); ctx = YACA_CONTEXT_NULL; @@ -772,7 +763,7 @@ BOOST_FIXTURE_TEST_CASE(T604__negative__encrypt_decrypt, InitDebugFixture) decrypted_len = written; ret = yaca_decrypt_finalize(ctx, decrypted + decrypted_len, &written); - BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + decrypt_check(ret, decrypted_len + written, INPUT_DATA_SIZE); yaca_context_destroy(ctx); ctx = YACA_CONTEXT_NULL; diff --git a/tests/test_simple.cpp b/tests/test_simple.cpp index 6c64788..e218cbf 100644 --- a/tests/test_simple.cpp +++ b/tests/test_simple.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -251,7 +251,7 @@ BOOST_FIXTURE_TEST_CASE(T303__negative__simple_encrypt_decrypt, InitDebugFixture ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym2, iv, encrypted, encrypted_len, &decrypted, &decrypted_len); - BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + decrypt_check(ret, decrypted_len, INPUT_DATA_SIZE); ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv2, encrypted, encrypted_len, @@ -273,7 +273,7 @@ BOOST_FIXTURE_TEST_CASE(T303__negative__simple_encrypt_decrypt, InitDebugFixture ret = yaca_simple_decrypt(YACA_ENCRYPT_AES, YACA_BCM_CBC, sym, iv, encrypted, encrypted_len, &decrypted, &decrypted_len); - BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + decrypt_check(ret, decrypted_len, INPUT_DATA_SIZE); yaca_key_destroy(sym); yaca_key_destroy(sym2); -- 2.7.4 From fc58b66cb5f85c6ca708e40d0e64665d10510eb6 Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Tue, 12 Jan 2021 11:00:31 +0900 Subject: [PATCH 12/16] Fix spec file for python 3.9.1 upgrade Change-Id: Iceabbee8e355233b1784307cccbac576573e64cd Signed-off-by: Dongsun Lee --- packaging/yaca.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 86d02ad..038d98a 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -45,7 +45,7 @@ make -k %{?jobs:-j%jobs} %install %make_install -%py3_compile %{buildroot}/%{python3_sitearch} +%py3_compile %{buildroot}/%{python3_sitelib} %clean rm -rf %{buildroot} @@ -99,7 +99,7 @@ Requires: yaca = %{version}-%{release} The package provides Yet Another Crypto API bindings for Python3. %files -n python3-yaca -%{python3_sitearch}/%{name} +%{python3_sitelib}/%{name} ## Coverage Package ########################################################### %if "%{build_type}" == "COVERAGE" -- 2.7.4 From e3b6ccff6850a91262dc2f1f54796f46f623d9c7 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Mon, 11 Jan 2021 07:05:08 +0100 Subject: [PATCH 13/16] Fix build with updated RPM tool Pre-4.14 RPM tools used to compile the spec file properly when this syntax: (1) %if %{build_type} was used in Requires section and this syntax: (2) %if "%{build_type}" was used in %files/%packages section. In RPM 4.14 version, this doesn't compile. Similarly, removing the "" in (2) doesn't work in pre-4.14 RPM, just like adding "" in (1). This patch changes combination of syntax in these %if statements that can be succesfully compiled under both: pre-4.14 and 4.14 RPM in Tizen. Change-Id: If8bf4410623a8fc693dda169fea467283c6f4cfc --- packaging/yaca.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/yaca.spec b/packaging/yaca.spec index 038d98a..08a88c2 100644 --- a/packaging/yaca.spec +++ b/packaging/yaca.spec @@ -1,4 +1,4 @@ -%{!?build_type:%define build_type "RELEASE"} +%{!?build_type:%define build_type RELEASE} Name: yaca Version: 0.0.6 @@ -12,7 +12,7 @@ BuildRequires: python3 >= 3.4 BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(openssl1.1) BuildRequires: boost-devel -%if %{build_type} == "COVERAGE" +%if "%build_type" == "COVERAGE" BuildRequires: lcov %endif Requires(post): /sbin/ldconfig @@ -102,7 +102,7 @@ The package provides Yet Another Crypto API bindings for Python3. %{python3_sitelib}/%{name} ## Coverage Package ########################################################### -%if "%{build_type}" == "COVERAGE" +%if "%build_type" == "COVERAGE" %package coverage Summary: Yet Another Crypto API code coverage data Group: Security/Other -- 2.7.4 From 08df91a8483c26e108132b945a0988909b330737 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Thu, 24 Dec 2020 15:17:28 +0100 Subject: [PATCH 14/16] Additional OpenSSL error codes that should be handled gracefully Change-Id: I13e4457cecfc5faf6d5d9f65394ab72ac671cec7 --- src/debug.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/debug.c b/src/debug.c index 486180e..e7a8056 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Krzysztof Jackiewicz * @@ -127,9 +127,13 @@ int error_handle(const char *file, int line, const char *function) /* known errors */ switch (err) { + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): + case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS): case ERR_PACK(ERR_LIB_PEM, PEM_F_GET_NAME, PEM_R_NO_START_LINE): case ERR_PACK(ERR_LIB_PEM, PEM_F_GET_HEADER_AND_DATA, PEM_R_BAD_END_LINE): -- 2.7.4 From cd7ffdd544595753d85d6ba2128a2832f45491e4 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Wed, 3 Mar 2021 14:53:20 +0100 Subject: [PATCH 15/16] Fix coverage generation in rpm 4.14.1 Debug source package directories now have different names. Change-Id: I73062559cf76dbecbcfaedb549e507ba9d56cc69 --- tests/yaca-coverage.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/yaca-coverage.sh.in b/tests/yaca-coverage.sh.in index 6cd4584..dc8e254 100644 --- a/tests/yaca-coverage.sh.in +++ b/tests/yaca-coverage.sh.in @@ -18,7 +18,7 @@ find / -iname "*.gcda" -exec rm {} \; yaca-unit-tests # copy source files -cp -rp $SRCS_DIR/* "@CMAKE_BINARY_DIR@" +cp -rp $SRCS_DIR*/* "@CMAKE_BINARY_DIR@" # copy gcda files cp -r "@COVERAGE_BUILD_DIR@"/* "@COVERAGE_DIR@" -- 2.7.4 From 60292b16152fcab14d082e9a383c65ce6f0c39cf Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 12 Mar 2021 19:26:53 +0100 Subject: [PATCH 16/16] Fix segfault found by fuzzer. Unsigned int(input_len) is casted to int(flen), this can lead to using negative value, unfortunately openssl doesn't check it. According to openssl documentation, input_len is limited by RSA key size, let's validate it in yaca to avoid segfault. Change-Id: I8e821b94794f1b5d7231df16c591fe88c12c84e2 --- src/rsa.c | 5 ++++- tests/test_rsa.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/rsa.c b/src/rsa.c index cbd951b..054db73 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Krzysztof Jackiewicz * @@ -94,6 +94,9 @@ static int encrypt_decrypt(yaca_padding_e padding, max_len = ret; + if (input_len > max_len) + return YACA_ERROR_INVALID_PARAMETER; + ret = yaca_zalloc(max_len, (void**)&loutput); if (ret != YACA_ERROR_NONE) return ret; diff --git a/tests/test_rsa.cpp b/tests/test_rsa.cpp index 0f9e095..105c77c 100644 --- a/tests/test_rsa.cpp +++ b/tests/test_rsa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Lukasz Pawelczyk * @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -452,6 +453,11 @@ BOOST_FIXTURE_TEST_CASE(T404__negative__public_encrypt, InitDebugFixture) BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, + INPUT_DATA, UINT_MAX, + &encrypted, &encrypted_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + + ret = yaca_rsa_public_encrypt(YACA_PADDING_NONE, key_pub, INPUT_DATA, input_len, NULL, &encrypted_len); BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); @@ -466,6 +472,11 @@ BOOST_FIXTURE_TEST_CASE(T404__negative__public_encrypt, InitDebugFixture) &encrypted_pkcs1, &encrypted_pkcs1_len); BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1, key_pub, + INPUT_DATA, UINT_MAX, + &encrypted_pkcs1, &encrypted_pkcs1_len); + BOOST_REQUIRE(ret == YACA_ERROR_INVALID_PARAMETER); + ret = yaca_rsa_public_encrypt(YACA_PADDING_PKCS1_OAEP, key_pub, INPUT_DATA, input_len_pkcs1_oaep + 1, &encrypted_pkcs1_oaep, &encrypted_pkcs1_oaep_len); -- 2.7.4