提交 d527b885 编写于 作者: Q qiaozzzh

deviceauth代码整改

Signed-off-by: Nqiaozzzh <qiaozhang@huawei.com>
上级 4ecb7b3b
# Copyright (C) 2021 Huawei Device Co., Ltd.
# 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.
import("//test/xts/acts/security_lite/deviceauth_basic_deps/deviceauth.gni")
import("//test/xts/tools/lite/build/suite_lite.gni")
hctest_suite("ActsSecurityHichainBasicDeps") {
suite_name = "acts"
sources = [ "test.c" ]
sources += DEVICEAUTH_BASIC_DEPS_SOURCE
include_dirs = [
"//commonlibrary/c_utils/base/include",
"//commonlibrary/utils_lite/include",
"//test/xts/tools/lite/hctest/include",
"//third_party/unity/src",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr",
]
include_dirs += DEVICEAUTH_BASIC_DEPS_INC
deps = []
cflags = [ "-Werror" ]
ldflags = [
"-lstdc++",
"-lm",
"-lpthread",
]
defines = [
"MKDIR_IMPLEMENTED=0",
"STAT_IMPLEMENTED=0",
"ACCESS_IMPLEMENTED=0",
"F_API_IMPLEMENTED=0",
"FLASH_START_ADDRESS_HICHAIN=0",
"UTILS_FILE_IMPLEMENTED=1",
"TEST_PTHREAD_CREATE_DETACHED=0",
"TEST_HC_FILE_OPEN_SERIES=1",
]
defines += DEVICEAUTH_BASIC_DEPS_ALGORITHM_DEFINES
if (defined(ohos_lite)) {
include_dirs += [
"//base/security/device_auth/deps_adapter/os_adapter/interfaces/liteos",
]
if (ohos_kernel_type == "liteos_m") {
# liteos m
include_dirs +=
[ "//base/startup/init/interfaces/innerkits/include/syspara" ]
deps += [ "//base/startup/init/interfaces/innerkits:libbegetutil" ]
if (board_name == "rtl8720") {
cflags +=
[ "-isystem${ohos_root_path}/kernel/liteos_m/kal/posix/include" ]
defines -= [
"FLASH_START_ADDRESS_HICHAIN=0",
"TEST_HC_FILE_OPEN_SERIES=1",
"TEST_HKDF_WITH_KEY_ALIAS_TRUE=1",
"TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE=1",
"TEST_HASH_TO_POINT=1",
"TEST_GENERATE_KEY_PAIR_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET=1",
"TEST_GENERATE_KEY_PAIR=1",
"TEST_EXPORT_PUBLIC_KEY=1",
"TEST_ALGORITHM_SIGN=1",
"TEST_ALGORITHM_VERIFY=1",
"TEST_IMPORT_PUBLIC_KEY=1",
"TEST_CHECK_KEY_EXIST=1",
"TEST_DELETE_KEY=1",
"TEST_AES_GCM_ENCRYPT=1",
"TEST_AES_GCM_DECRYPT=1",
]
defines += [
"FLASH_START_ADDRESS_HICHAIN=0x1F6000",
"TEST_HC_FILE_OPEN_SERIES=0",
"TEST_HKDF_WITH_KEY_ALIAS_TRUE=0",
"TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE=0",
"TEST_HASH_TO_POINT=0",
"TEST_GENERATE_KEY_PAIR_WITH_STORAGE=0",
"TEST_AGREE_SHARED_SECRET_WITH_STORAGE=0",
"TEST_AGREE_SHARED_SECRET=0",
"TEST_GENERATE_KEY_PAIR=0",
"TEST_EXPORT_PUBLIC_KEY=0",
"TEST_ALGORITHM_SIGN=0",
"TEST_ALGORITHM_VERIFY=0",
"TEST_IMPORT_PUBLIC_KEY=0",
"TEST_CHECK_KEY_EXIST=0",
"TEST_DELETE_KEY=0",
"TEST_AES_GCM_ENCRYPT=0",
"TEST_AES_GCM_DECRYPT=0",
]
defines += [ "DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY=1" ]
}
if (board_name == "hispark_pegasus") {
# 3861
defines -= [
"TEST_HKDF_WITH_KEY_ALIAS_TRUE=1",
"TEST_HASH_TO_POINT=1",
"TEST_GENERATE_KEY_PAIR_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET=1",
"TEST_GENERATE_KEY_PAIR=1",
"TEST_EXPORT_PUBLIC_KEY=1",
"TEST_ALGORITHM_SIGN=1",
"TEST_ALGORITHM_VERIFY=1",
"TEST_IMPORT_PUBLIC_KEY=1",
]
defines += [
"TEST_HKDF_WITH_KEY_ALIAS_TRUE=0",
"TEST_HASH_TO_POINT=0",
"TEST_GENERATE_KEY_PAIR_WITH_STORAGE=0",
"TEST_AGREE_SHARED_SECRET_WITH_STORAGE=0",
"TEST_AGREE_SHARED_SECRET=0",
"TEST_GENERATE_KEY_PAIR=0",
"TEST_EXPORT_PUBLIC_KEY=0",
"TEST_ALGORITHM_SIGN=0",
"TEST_ALGORITHM_VERIFY=0",
"TEST_IMPORT_PUBLIC_KEY=0",
]
}
} else {
#liteos a or L1 linux
include_dirs +=
[ "//base/startup/init/interfaces/innerkits/include/syspara" ]
deps += [ "//base/startup/init/interfaces/innerkits:libbegetutil" ]
}
} else {
# linux
include_dirs += [
"//base/startup/init/interfaces/innerkits/include/syspara",
"//base/security/device_auth/deps_adapter/os_adapter/interfaces/linux",
]
deps += [ "//base/startup/init/interfaces/innerkits:libbegetutil" ]
}
}
## wifiiot_hispark_pegasus
1. compile command:
``` bash
cd test/xts/tools/lite
./build.sh product=wifiiot xts=acts target=//test/xts/acts/security_lite/deviceauth_basic_deps:ActsSecurityHichainBasicDeps
```
{
"description": "Config for $module test cases",
"environment": [
{
"type": "device",
"label": "wifiiot"
}
],
"kits": [
{
"type": "DeployKit",
"timeout": "20000",
"burn_file": "$subsystem/$module.bin"
}
],
"driver": {
"type": "CTestLite"
}
}
\ No newline at end of file
# Copyright (C) 2021 Huawei Device Co., Ltd.
# 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.
DEVICEAUTH_BASIC_DEPS_DIR =
"//test/xts/acts/security_lite/deviceauth_basic_deps"
DEVICEAUTH_BASIC_DEPS_SOURCE = [
"${DEVICEAUTH_BASIC_DEPS_DIR}/print_log.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/test_timer.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_file_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_mutex_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_file_f_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_thread_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_dev_info_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_condition_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_file_utils_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_file_iot_flash_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_time_test.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_file_common.c",
"${DEVICEAUTH_BASIC_DEPS_DIR}/hc_alg_test.c",
]
DEVICEAUTH_BASIC_DEPS_INC = [
"//base/iothardware/peripheral/interfaces/inner_api",
"//commonlibrary/utils_lite/include", # utils_file.h ohos_types.h
# alg test
"//base/security/device_auth/deps_adapter/key_management_adapter/interfaces",
"//base/security/device_auth/deps_adapter/os_adapter/interfaces",
"//base/security/device_auth/common_lib/interfaces",
"//base/security/device_auth/interfaces/innerkits",
]
DEVICEAUTH_BASIC_DEPS_ALGORITHM_DEFINES = [
"TEST_HKDF_WITH_KEY_ALIAS_TRUE=1",
"TEST_IMPORT_SYMMETRIC_KEY=1",
"TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE=1",
"TEST_HASH_TO_POINT=1",
"TEST_GENERATE_KEY_PAIR_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET_WITH_STORAGE=1",
"TEST_AGREE_SHARED_SECRET=1",
"TEST_BIG_NUM_EXP_MOD=1",
"TEST_EXPORT_IMPORT_SIGN_VERIFY_ED25519=1",
"TEST_EXPORT_IMPORT_SIGN_VERIFY_P256=1",
"TEST_BIG_NUM_COMPARE=1",
"TEST_GENERATE_KEY_PAIR=1",
"TEST_EXPORT_PUBLIC_KEY=1",
"TEST_ALGORITHM_SIGN=1",
"TEST_ALGORITHM_VERIFY=1",
"TEST_IMPORT_PUBLIC_KEY=1",
"TEST_CHECK_DL_PUBLIC_KEY=1",
"TEST_CHECK_KEY_EXIST=1",
"TEST_DELETE_KEY=1",
"TEST_AES_GCM_ENCRYPT=1",
"TEST_AES_GCM_DECRYPT=1",
]
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_alg_test.h"
#include <alg_loader.h>
#include <device_auth.h>
#include <hal_error.h>
#include <hctest.h>
#include <stdlib.h>
#include <string_util.h>
#include <unistd.h>
#include "hc_alg_test_case.h"
#include "print_log.h"
#include "test_timer.h"
#define LOG_ERROR_IF_POINTER_NULL(pointer) LOGE("Pointer %s is %s", #pointer, ((pointer) == NULL ? "NULL" : "not NULL"))
#ifdef __cplusplus
extern "C" {
#endif
static uint32_t CountZero(const uint8_t *buffer, uint32_t length)
{
uint32_t zeroCount = 0;
for (uint32_t i = 0; i < length; ++i) {
if (buffer[i] == 0) {
++zeroCount;
}
}
return zeroCount;
}
static void FillRandom(uint8_t *msg, uint32_t setZeroLength, uint32_t randomLength)
{
if (randomLength < 1) {
return;
}
int res;
res = memset_s(msg, setZeroLength, 0, setZeroLength);
TEST_ASSERT_EQUAL(EOK, res);
msg[0] = rand() % (UINT8_MAX - 1) + 1;
for (uint32_t i = 1; i < randomLength; ++i) {
msg[i] = rand() % UINT8_MAX;
}
enum {
// ignore rand correctness if the random length is equal or less than 3
RANDOM_CONSECUTIVE_ZERO_LENGTH_LIMIT = 3,
};
if (randomLength <= RANDOM_CONSECUTIVE_ZERO_LENGTH_LIMIT + 1) {
return;
}
TEST_ASSERT_NOT_EQUAL(randomLength - 1, CountZero(msg + 1, randomLength - 1));
}
// Note: sha256 and sha256Compare will be set to all zero
static void TestSha256Inner(
const AlgLoader *loader, Uint8Buff *msg, Uint8Buff *sha256, Uint8Buff *sha256Compare)
{
int res;
res = memset_s(sha256->val, SHA256_LEN, 0, SHA256_LEN);
TEST_ASSERT_EQUAL(EOK, res);
res = memset_s(sha256Compare->val, SHA256_LEN, 0, SHA256_LEN);
TEST_ASSERT_EQUAL(EOK, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->sha256(msg, sha256));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TEST_ASSERT_EQUAL((uint32_t)SHA256_LEN, sha256->length);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->sha256(msg, sha256Compare));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TEST_ASSERT_EQUAL((uint32_t)SHA256_LEN, sha256Compare->length);
uint32_t zeroCount = CountZero(sha256->val, sha256->length);
TEST_ASSERT_NOT_EQUAL_MESSAGE((uint32_t)SHA256_LEN, zeroCount, "invalid all zero sha256");
TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(sha256->val, sha256Compare->val, SHA256_LEN,
"different sha256 against the same message");
}
static void TestSha256(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->sha256);
if (loader->sha256 == NULL) {
LOGE("sha256 pointer is NULL! will not test!");
return;
}
Uint8Buff msg = { (uint8_t *)malloc(SHA256_MSG_MAX_SIZE), SHA256_MSG_MAX_SIZE };
TEST_ASSERT_NOT_NULL(msg.val);
Uint8Buff sha256 = { (uint8_t *)malloc(SHA256_LEN), SHA256_LEN };
TEST_ASSERT_NOT_NULL(sha256.val);
Uint8Buff sha256Compare = { (uint8_t *)malloc(SHA256_LEN), SHA256_LEN };
TEST_ASSERT_NOT_NULL(sha256Compare.val);
for (int i = 1; i <= SHA256_TEST_MIN_LIMIT; ++i) {
msg.length = i;
LOGI("test sha256 with msg length %d", msg.length);
FillRandom(msg.val, SHA256_MSG_MAX_SIZE, msg.length);
TestSha256Inner(loader, &msg, &sha256, &sha256Compare);
}
msg.length = SHA256_MSG_MAX_SIZE;
LOGI("test sha256 with max msg length %d", msg.length);
FillRandom(msg.val, SHA256_MSG_MAX_SIZE, msg.length);
TestSha256Inner(loader, &msg, &sha256, &sha256Compare);
for (int i = 0; i < SHA256_TEST_TIMES; ++i) {
msg.length = rand() % SHA256_MSG_MAX_SIZE + 1;
LOGI("test sha256 with random msg length %d", msg.length);
FillRandom(msg.val, SHA256_MSG_MAX_SIZE, msg.length);
TestSha256Inner(loader, &msg, &sha256, &sha256Compare);
}
msg.val = (uint8_t *)(SHA256_EXAMPLE_MESSAGE);
msg.length = strlen(SHA256_EXAMPLE_MESSAGE);
TestSha256Inner(loader, &msg, &sha256, &sha256Compare);
TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(sha256.val, SHA256_EXAMPLE_RESULT, SHA256_LEN,
"incorrect sha256 result");
PrintBuffer(SHA256_EXAMPLE_MESSAGE, sha256.val, sha256.length);
free(msg.val);
free(sha256.val);
free(sha256Compare.val);
}
static void TestGenerateRandomInner(const AlgLoader *loader, Uint8Buff *random)
{
uint32_t randomLength = random->length;
int res;
res = memset_s(random->val, GEN_RANDOM_MAX_SIZE, 0, GEN_RANDOM_MAX_SIZE);
TEST_ASSERT_EQUAL(EOK, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->generateRandom(random));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TEST_ASSERT_EQUAL(randomLength, random->length);
uint32_t zeroCount = CountZero(random->val, random->length);
TEST_ASSERT_NOT_EQUAL_MESSAGE(random->length, zeroCount, "random all zero");
}
static void TestGenerateRandomNoPeriodicRepetition(const AlgLoader *loader,
Uint8Buff *previous,
Uint8Buff *current)
{
int res;
res = memset_s(previous->val, GEN_RANDOM_TEST_REPEAT_SIZE, 0, GEN_RANDOM_TEST_REPEAT_SIZE);
TEST_ASSERT_EQUAL(EOK, res);
for (int i = 0; i < GEN_RANDOM_TEST_REPEAT_TIMES; ++i) {
res = memset_s(current->val, GEN_RANDOM_TEST_REPEAT_SIZE, 0, GEN_RANDOM_TEST_REPEAT_SIZE);
TEST_ASSERT_EQUAL(EOK, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->generateRandom(current));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TEST_ASSERT_EQUAL(GEN_RANDOM_TEST_REPEAT_SIZE, current->length);
int equalCount = 0;
for (int j = 0; j < GEN_RANDOM_TEST_REPEAT_SIZE; ++j) {
if (previous->val[j] == current->val[j]) {
++equalCount;
}
}
TEST_ASSERT_NOT_EQUAL_MESSAGE(GEN_RANDOM_TEST_REPEAT_SIZE, equalCount,
"random is the same as previous generated");
res = memcpy_s(previous->val, GEN_RANDOM_TEST_REPEAT_SIZE, current->val, GEN_RANDOM_TEST_REPEAT_SIZE);
TEST_ASSERT_EQUAL(EOK, res);
}
}
static void TestGenerateRandom(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->generateRandom);
if (loader->generateRandom == NULL) {
LOGE("generateRandom pointer is NULL! will not test!");
return;
}
Uint8Buff random = { (uint8_t *)malloc(GEN_RANDOM_MAX_SIZE), GEN_RANDOM_MAX_SIZE };
TEST_ASSERT_NOT_NULL(random.val);
for (int i = 1; i <= GEN_RANDOM_MIN_LIMIT; ++i) {
random.length = i;
LOGI("test generate random with length %d", random.length);
TestGenerateRandomInner(loader, &random);
}
random.length = GEN_RANDOM_MAX_SIZE;
LOGI("test generate random with max length %d", random.length);
TestGenerateRandomInner(loader, &random);
for (int i = 0; i < GEN_RANDOM_TEST_TIMES; ++i) {
random.length = rand() % GEN_RANDOM_MAX_SIZE + 1;
LOGI("test generate random with random length %d", random.length);
TestGenerateRandomInner(loader, &random);
}
// test whether the random number is repeated
Uint8Buff previousUint8Buff = { (uint8_t *)malloc(GEN_RANDOM_TEST_REPEAT_SIZE), GEN_RANDOM_TEST_REPEAT_SIZE };
TEST_ASSERT_NOT_NULL(previousUint8Buff.val);
Uint8Buff currentUint8Buff = { (uint8_t *)malloc(GEN_RANDOM_TEST_REPEAT_SIZE), GEN_RANDOM_TEST_REPEAT_SIZE };
TEST_ASSERT_NOT_NULL(currentUint8Buff.val);
TestGenerateRandomNoPeriodicRepetition(loader, &previousUint8Buff, &currentUint8Buff);
free(currentUint8Buff.val);
free(previousUint8Buff.val);
free(random.val);
}
// key will not be modified
// message will be malloced if message->val is NULL
// hmac will be clear with zero
static void TestComputeHmacInner(
const AlgLoader *loader, const Uint8Buff *key, Uint8Buff *msg, Uint8Buff *hmac, bool isAlias)
{
int32_t res;
bool allocMemory = false;
if (msg->val == NULL) {
msg->val = (uint8_t *)malloc(msg->length);
TEST_ASSERT_NOT_NULL(msg->val);
allocMemory = true;
res = memset_s(msg->val, msg->length, 0, msg->length);
TEST_ASSERT_EQUAL(EOK, res);
FillRandom(msg->val, msg->length, msg->length);
}
res = memset_s(hmac->val, hmac->length, 0, hmac->length);
TEST_ASSERT_EQUAL(EOK, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->computeHmac(key, msg, hmac, isAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
uint32_t zeroCount = CountZero(hmac->val, hmac->length);
TEST_ASSERT_NOT_EQUAL_MESSAGE(hmac->length, zeroCount, "invalid all zero hmac");
if (allocMemory && msg->val != NULL) {
free(msg->val);
msg->val = NULL;
}
}
static void TestComputeHmacWithIsAliasTrue(const AlgLoader *loader,
Uint8Buff *msg, Uint8Buff *hmacKeyBuff, Uint8Buff *outHmacBuff)
#if TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE
{
TEST_ASSERT_NOT_NULL(loader->importSymmetricKey);
if (!loader->importSymmetricKey) {
LOGE("importSymmetricKey is NULL, can not test computeHmac with isAlias true");
return;
}
LOGI("test hmac for isAlias true");
msg->val = (uint8_t *)NULL;
msg->length = TEST_HMAC_ISALIAS_TRUE_MSG_LENGTH;
FillRandom(hmacKeyBuff->val, hmacKeyBuff->length, hmacKeyBuff->length);
// write key with specified alias first, then do the test
const ExtraInfo info = {
.authId = *hmacKeyBuff,
.userType = DEVICE_TYPE_ACCESSORY,
.pairType = PAIR_TYPE_BIND,
};
int res = loader->importSymmetricKey(hmacKeyBuff, hmacKeyBuff, KEY_PURPOSE_MAC, &info);
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TestComputeHmacInner(loader, hmacKeyBuff, msg, outHmacBuff, true);
// delete key after the test
if (loader->deleteKey) {
LOGD("test deleteKey");
res = loader->deleteKey(hmacKeyBuff);
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
}
}
#else // TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE
{
LOGE("no TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE, do not test computeHmac with isAlias true");
#if (defined(DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY) && DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY)
(void)(loader);
#else // DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY
TEST_ASSERT_NULL(loader->importSymmetricKey);
#endif // DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY
(void)(msg);
(void)(hmacKeyBuff);
(void)(outHmacBuff);
}
#endif // TEST_COMPUTEHMAC_WITH_ISALIAS_TRUE
static void TestComputeHmac(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->computeHmac);
if (loader->computeHmac == NULL) {
LOGE("computeHmac pointer is NULL! will not test!");
return;
}
Uint8Buff hmacKeyBuff = { (uint8_t *)malloc(TEST_HMAC_KEY_LEN), TEST_HMAC_KEY_LEN };
TEST_ASSERT_NOT_NULL(hmacKeyBuff.val);
Uint8Buff msg = { (uint8_t *)NULL, 0 };
uint8_t *outHmac = (uint8_t *)malloc(HMAC_LEN);
TEST_ASSERT_NOT_NULL(outHmac);
Uint8Buff outHmacBuff = { (uint8_t *)outHmac, HMAC_LEN };
TestComputeHmacWithIsAliasTrue(loader, &msg, &hmacKeyBuff, &outHmacBuff);
LOGI("test hmac for isAlias false");
for (uint32_t i = 0; i < ARRAY_SIZE(TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_ARRAY); ++i) {
msg.val = (uint8_t *)NULL;
msg.length = TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_ARRAY[i];
LOGI("test hmac for msg length %d", msg.length);
FillRandom(hmacKeyBuff.val, hmacKeyBuff.length, hmacKeyBuff.length);
TestComputeHmacInner(loader, &hmacKeyBuff, &msg, &outHmacBuff, false);
}
free(hmacKeyBuff.val);
hmacKeyBuff.val = (uint8_t *)NULL;
LOGI("test the correctness of hmac");
hmacKeyBuff.val = (uint8_t *)(HMAC_EXAMPLE_KEY),
hmacKeyBuff.length = sizeof(HMAC_EXAMPLE_KEY);
msg.val = (uint8_t *)(HMAC_EXAMPLE_MESSAGE),
msg.length = strlen(HMAC_EXAMPLE_MESSAGE);
TestComputeHmacInner(loader, &hmacKeyBuff, &msg, &outHmacBuff, false);
TEST_ASSERT_EQUAL(sizeof(HMAC_EXAMPLE_RESULT), outHmacBuff.length);
TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(HMAC_EXAMPLE_RESULT, outHmacBuff.val, sizeof(HMAC_EXAMPLE_RESULT),
"incorrect hmac result");
PrintBuffer("hmac", outHmacBuff.val, outHmacBuff.length);
free(outHmac);
outHmac = NULL;
outHmacBuff.val = (uint8_t *)NULL;
}
struct HkdfArgument {
Uint8Buff baseKey;
Uint8Buff salt;
Uint8Buff keyInfo;
Uint8Buff outHkdf;
bool isAlias;
};
// baseKey, salt will be malloced and fill random if NULL
// keyInfo, isAlias will not be modified
// outHkdf will be clear with zero
static void TestComputeHkdfInner(
const AlgLoader *loader, struct HkdfArgument *arg)
{
bool baseAlloced = false, saltAlloced = false;
if (arg->baseKey.val == NULL) {
arg->baseKey.val = (uint8_t *)malloc(arg->baseKey.length);
TEST_ASSERT_NOT_NULL(arg->baseKey.val);
baseAlloced = true;
FillRandom(arg->baseKey.val, arg->baseKey.length, arg->baseKey.length);
}
if (arg->salt.val == NULL) {
arg->salt.val = (uint8_t *)malloc(arg->salt.length);
TEST_ASSERT_NOT_NULL(arg->salt.val);
saltAlloced = true;
FillRandom(arg->salt.val, arg->salt.length, arg->salt.length);
}
int32_t res;
res = memset_s(arg->outHkdf.val, arg->outHkdf.length, 0, arg->outHkdf.length);
TEST_ASSERT_EQUAL(EOK, res);
RUN_AND_PRINT_ELAPSED_TIME(
res,
loader->computeHkdf(
&arg->baseKey, &arg->salt, &arg->keyInfo, &arg->outHkdf, arg->isAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
if (saltAlloced && arg->salt.val != NULL) {
free(arg->salt.val);
arg->salt.val = (uint8_t *)NULL;
}
if (baseAlloced && arg->baseKey.val != NULL) {
free(arg->baseKey.val);
arg->baseKey.val = (uint8_t *)NULL;
}
uint32_t zeroCount = CountZero(arg->outHkdf.val, arg->outHkdf.length);
TEST_ASSERT_NOT_EQUAL_MESSAGE(arg->outHkdf.length, zeroCount, "invalid all zero hkdf result");
}
#if TEST_HKDF_WITH_KEY_ALIAS_TRUE // {
static void TestComputeHkdfWithKeyAliasTrueFirstAndSecondStep(
const AlgLoader *loader,
Uint8Buff *privKeyPairAlias,
Uint8Buff *pubKeyPairAlias,
ExtraInfo *extraInfo,
Uint8Buff *sharedKeyAlias)
{
LOGI("First, generate two pairs of public-private key pairs");
TEST_ASSERT_EQUAL(HAL_SUCCESS,
loader->generateKeyPairWithStorage(privKeyPairAlias,
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH, ED25519, extraInfo));
TEST_ASSERT_EQUAL(HAL_SUCCESS,
loader->generateKeyPairWithStorage(pubKeyPairAlias,
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH, ED25519, extraInfo));
LOGI("Second, agree shared key with privateKey and publicKey");
KeyBuff privKeyBuff = { privKeyPairAlias->val, privKeyPairAlias->length, true };
KeyBuff pubKeyBuff = { pubKeyPairAlias->val, pubKeyPairAlias->length, true };
TEST_ASSERT_EQUAL(HAL_SUCCESS,
loader->agreeSharedSecretWithStorage(&privKeyBuff, &pubKeyBuff, ED25519,
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_SHARED_KEY_LENGTH, sharedKeyAlias));
}
static void TestComputeHkdfWithKeyAliasTrueThirdStep(
const AlgLoader *loader,
struct HkdfArgument *argument,
Uint8Buff *sharedKeyAlias)
{
LOGI("Third, compute hkdf with shared key");
argument->baseKey = *sharedKeyAlias;
argument->salt.val = (uint8_t *)NULL;
argument->salt.length = HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_SALT_LEN;
argument->keyInfo.val = (uint8_t *)(TMP_AUTH_KEY_FACTOR);
argument->keyInfo.length = strlen(TMP_AUTH_KEY_FACTOR);
argument->outHkdf.val = (uint8_t *)malloc(HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_OUTKEY_LEN);
TEST_ASSERT_NOT_NULL(argument->outHkdf.val);
argument->outHkdf.length = HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_OUTKEY_LEN;
argument->isAlias = true;
TestComputeHkdfInner(loader, argument);
free(argument->outHkdf.val);
argument->outHkdf.val = (uint8_t *)NULL;
}
static void TestComputeHkdfWithKeyAliasTrue(
const AlgLoader *loader,
struct HkdfArgument *argument)
{
LOGI("pake psk derive secret keyAlias true");
TEST_ASSERT_NOT_NULL(loader->generateKeyPairWithStorage);
TEST_ASSERT_NOT_NULL(loader->agreeSharedSecretWithStorage);
if (!loader->generateKeyPairWithStorage || !loader->agreeSharedSecretWithStorage) {
LOGE("generateKeyPairWithStorage or agreeSharedSecretWithStorage pointer is NULL! "
"can not test hkdf with alias true!");
return;
}
Uint8Buff privKeyPairAlias = { (uint8_t *)malloc(TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH),
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH };
Uint8Buff pubKeyPairAlias = { (uint8_t *)malloc(TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH),
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH };
ExtraInfo extraInfo = { { (uint8_t *)malloc(TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_AUTH_ID_LENGTH),
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_AUTH_ID_LENGTH },
DEVICE_TYPE_ACCESSORY, PAIR_TYPE_BIND };
TEST_ASSERT_NOT_NULL(privKeyPairAlias.val);
TEST_ASSERT_NOT_NULL(pubKeyPairAlias.val);
TEST_ASSERT_NOT_NULL(extraInfo.authId.val);
FillRandom(privKeyPairAlias.val, privKeyPairAlias.length, privKeyPairAlias.length);
FillRandom(pubKeyPairAlias.val, pubKeyPairAlias.length, pubKeyPairAlias.length);
FillRandom(extraInfo.authId.val, extraInfo.authId.length, extraInfo.authId.length);
Uint8Buff sharedKeyAlias = { (uint8_t *)malloc(HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_BASEKEY_LEN),
HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_BASEKEY_LEN };
TEST_ASSERT_NOT_NULL(sharedKeyAlias.val);
FillRandom(sharedKeyAlias.val, sharedKeyAlias.length, sharedKeyAlias.length);
TestComputeHkdfWithKeyAliasTrueFirstAndSecondStep(
loader, &privKeyPairAlias, &pubKeyPairAlias, &extraInfo, &sharedKeyAlias);
TestComputeHkdfWithKeyAliasTrueThirdStep(
loader, argument, &sharedKeyAlias);
if (loader->deleteKey) {
LOGD("test deleteKey");
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&privKeyPairAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&pubKeyPairAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&sharedKeyAlias));
}
LOGD("At last, free all memories allocated");
free(privKeyPairAlias.val);
privKeyPairAlias.val = (uint8_t *)NULL;
free(pubKeyPairAlias.val);
pubKeyPairAlias.val = (uint8_t *)NULL;
free(extraInfo.authId.val);
extraInfo.authId.val = (uint8_t *)NULL;
free(sharedKeyAlias.val);
sharedKeyAlias.val = (uint8_t *)NULL;
}
#else // TEST_HKDF_WITH_KEY_ALIAS_TRUE // } {
static void TestComputeHkdfWithKeyAliasTrue(
const AlgLoader *loader,
struct HkdfArgument *argument)
{
LOGE("no TEST_HKDF_WITH_KEY_ALIAS_TRUE, do not test hkdf with key alias true");
TEST_ASSERT_TRUE(loader->generateKeyPairWithStorage == NULL || loader->agreeSharedSecretWithStorage == NULL);
LOG_ERROR_IF_POINTER_NULL(loader->generateKeyPairWithStorage);
LOG_ERROR_IF_POINTER_NULL(loader->agreeSharedSecretWithStorage);
(void)(argument);
}
#endif // TEST_HKDF_WITH_KEY_ALIAS_TRUE // }
static void TestComputeHkdfCorrectness(
const AlgLoader *loader,
struct HkdfArgument *argument)
{
LOGI("test the correctness of hkdf");
argument->baseKey.val = (uint8_t *)(HKDF_EXAMPLE_MESSAGE);
argument->baseKey.length = strlen(HKDF_EXAMPLE_MESSAGE);
argument->salt.val = (uint8_t *)(HKDF_EXAMPLE_SALT);
argument->salt.length = sizeof(HKDF_EXAMPLE_SALT);
argument->keyInfo.val = (uint8_t *)(HKDF_EXAMPLE_INFO);
argument->keyInfo.length = strlen(HKDF_EXAMPLE_INFO);
argument->outHkdf.val = (uint8_t *)malloc(sizeof(HKDF_EXAMPLE_RESULT_KEY));
TEST_ASSERT_NOT_NULL(argument->outHkdf.val);
argument->outHkdf.length = sizeof(HKDF_EXAMPLE_RESULT_KEY);
argument->isAlias = false;
TestComputeHkdfInner(loader, argument);
TEST_ASSERT_EQUAL(sizeof(HKDF_EXAMPLE_RESULT_KEY), argument->outHkdf.length);
TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(HKDF_EXAMPLE_RESULT_KEY, argument->outHkdf.val,
sizeof(HKDF_EXAMPLE_RESULT_KEY), "incorrect hkdf result");
PrintBuffer("hkdf result", argument->outHkdf.val, argument->outHkdf.length);
free(argument->outHkdf.val);
argument->outHkdf.val = (uint8_t *)NULL;
}
static void TestComputeHkdf(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->computeHkdf);
if (loader->computeHkdf == NULL) {
LOGE("computeHkdf pointer is NULL! will not test!");
return;
}
struct HkdfArgument argument;
int res;
res = memset_s(&argument, sizeof(argument), 0, sizeof(argument));
TEST_ASSERT_EQUAL(EOK, res);
for (uint32_t i = 0; i < ARRAY_SIZE(g_hkdfTestCase); ++i) {
LOGI("test case for: \"%s\"", g_hkdfTestCase[i].caseName);
LOGI("test case for: baseKeyLength = %d, saltLength = %d, keyInfo = \"%s\", outKeyLength = %d",
g_hkdfTestCase[i].baseKeyLength, g_hkdfTestCase[i].saltLength,
g_hkdfTestCase[i].keyInfo, g_hkdfTestCase[i].outKeyLength);
argument.baseKey.val = (uint8_t *)NULL;
argument.baseKey.length = g_hkdfTestCase[i].baseKeyLength;
argument.salt.val = (uint8_t *)NULL;
argument.salt.length = g_hkdfTestCase[i].saltLength;
argument.keyInfo.val = (uint8_t *)(g_hkdfTestCase[i].keyInfo);
argument.keyInfo.length = strlen(g_hkdfTestCase[i].keyInfo);
argument.outHkdf.val = (uint8_t *)malloc(g_hkdfTestCase[i].outKeyLength);
TEST_ASSERT_NOT_NULL(argument.outHkdf.val);
argument.outHkdf.length = g_hkdfTestCase[i].outKeyLength;
argument.isAlias = false;
TestComputeHkdfInner(loader, &argument);
free(argument.outHkdf.val);
argument.outHkdf.val = (uint8_t *)NULL;
}
TestComputeHkdfWithKeyAliasTrue(loader, &argument);
TestComputeHkdfCorrectness(loader, &argument);
}
#if TEST_IMPORT_SYMMETRIC_KEY // {
enum {
WAIT_FOR_WATCH_DOG = 1,
};
static void TestImportSymmetricKey(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->importSymmetricKey);
if (loader->importSymmetricKey == NULL) {
LOGE("importSymmetricKey pointer is NULL! will not test!");
return;
}
int res;
const uint32_t authIdLenArray[] = { TEST_IMPORT_SYMMETRIC_KEY_AUTH_ID_LENGTH_32,
TEST_IMPORT_SYMMETRIC_KEY_AUTH_ID_LENGTH_64 };
for (uint32_t i = 0; i < ARRAY_SIZE(authIdLenArray); ++i) {
for (
uint32_t j = IMPORT_SYMMETRIC_KEY_KEYALIAS_LEN_MIN;
j <= IMPORT_SYMMETRIC_KEY_KEYALIAS_LEN_MAX;
++j) {
LOGD("auth id length = %u, msg length = %u", authIdLenArray[i], j);
Uint8Buff keyAlias = { (uint8_t *)malloc(j), j };
Uint8Buff authToken = { (uint8_t *)malloc(IMPORT_SYMMETRIC_KEY_AUTHTOKEN_LEN),
IMPORT_SYMMETRIC_KEY_AUTHTOKEN_LEN };
ExtraInfo extraInfo = { { (uint8_t *)malloc(authIdLenArray[i]), authIdLenArray[i] },
DEVICE_TYPE_ACCESSORY, PAIR_TYPE_BIND };
TEST_ASSERT_NOT_NULL(keyAlias.val);
TEST_ASSERT_NOT_NULL(authToken.val);
TEST_ASSERT_NOT_NULL(extraInfo.authId.val);
FillRandom(keyAlias.val, keyAlias.length, keyAlias.length);
FillRandom(authToken.val, authToken.length, authToken.length);
FillRandom(extraInfo.authId.val, extraInfo.authId.length, extraInfo.authId.length);
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->importSymmetricKey(&keyAlias, &authToken, KEY_PURPOSE_MAC, &extraInfo));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
if (loader->checkKeyExist) {
LOGD("test checkKeyExist");
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkKeyExist(&keyAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
}
if (loader->deleteKey) {
LOGD("test delete");
RUN_AND_PRINT_ELAPSED_TIME(res, loader->deleteKey(&keyAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
}
free(keyAlias.val);
keyAlias.val = (uint8_t *)NULL;
free(authToken.val);
authToken.val = (uint8_t *)NULL;
free(extraInfo.authId.val);
extraInfo.authId.val = (uint8_t *)NULL;
}
LOGI("sleep for %d seconds, waiting for watch dog", WAIT_FOR_WATCH_DOG);
sleep(WAIT_FOR_WATCH_DOG);
}
}
#else // TEST_IMPORT_SYMMETRIC_KEY // } {
static void TestImportSymmetricKey(const AlgLoader *loader)
{
LOGE("no TEST_IMPORT_SYMMETRIC_KEY, do not test importSymmetricKey");
TEST_ASSERT_NULL(loader->importSymmetricKey);
}
#endif // TEST_IMPORT_SYMMETRIC_KEY // }
static void TestCheckKeyExist(const AlgLoader *loader)
#if TEST_CHECK_KEY_EXIST
{
TEST_ASSERT_NOT_NULL(loader->checkKeyExist);
if (loader->checkKeyExist == NULL) {
LOGE("checkKeyExist pointer is NULL! will not test!");
return;
}
const char bufferKeyAlias[] = "A non-existent key";
Uint8Buff keyAlias = {
.val = (uint8_t *)bufferKeyAlias,
.length = strlen(bufferKeyAlias),
};
int32_t res;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkKeyExist(&keyAlias));
TEST_ASSERT_NOT_EQUAL(HAL_SUCCESS, res);
}
#else // TEST_CHECK_KEY_EXIST
{
LOGE("no TEST_CHECK_KEY_EXIST, do not test checkKeyExist");
TEST_ASSERT_NULL(loader->checkKeyExist);
}
#endif // TEST_CHECK_KEY_EXIST
static void TestDeleteKey(const AlgLoader *loader)
#if TEST_DELETE_KEY
{
TEST_ASSERT_NOT_NULL(loader->deleteKey);
if (loader->deleteKey == NULL) {
LOGE("deleteKey pointer is NULL! will not test!");
return;
}
const char bufferKeyAlias[] = "A non-existent key";
Uint8Buff keyAlias = {
.val = (uint8_t *)bufferKeyAlias,
.length = strlen(bufferKeyAlias),
};
int32_t res;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->deleteKey(&keyAlias));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
}
#else // TEST_DELETE_KEY
{
LOGE("no TEST_DELETE_KEY, do not test deleteKey");
TEST_ASSERT_NULL(loader->deleteKey);
}
#endif // TEST_DELETE_KEY
static void TestAesGcmEncrypt(const AlgLoader *loader)
#if TEST_AES_GCM_ENCRYPT
{
LOGI("begin to test the AES-GCM algorithm encryption");
TEST_ASSERT_NOT_NULL(loader->aesGcmEncrypt);
if (loader->aesGcmEncrypt == NULL) {
LOGE("aesGcmEncrypt pointer is NULL! will not test!");
return;
}
const Uint8Buff key = { (uint8_t *)AES_GCM_TEST_KEY, AES_GCM_KEY_LEN };
const Uint8Buff plainBuffer = { (uint8_t *)PLAIN_CASE, PLAIN_LEN };
uint8_t *nonce = (uint8_t *)malloc(NONCE_SIZE);
TEST_ASSERT_NOT_NULL(nonce);
TEST_ASSERT_EQUAL(EOK, memset_s(nonce, NONCE_SIZE, 0, NONCE_SIZE));
GcmParam gcmParams;
gcmParams.aad = (uint8_t *)EXCHANGE_AAD;
gcmParams.aadLen = (uint32_t)strlen(EXCHANGE_AAD);
gcmParams.nonce = nonce;
gcmParams.nonceLen = NONCE_SIZE;
uint8_t *cipher = (uint8_t *)malloc(CIPHER_LEN);
TEST_ASSERT_NOT_NULL(cipher);
TEST_ASSERT_EQUAL(EOK, memset_s(cipher, CIPHER_LEN, 0, CIPHER_LEN));
Uint8Buff cipherBuffer = { cipher, CIPHER_LEN };
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->aesGcmEncrypt(&key, &plainBuffer, &gcmParams, false, &cipherBuffer));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
PrintBuffer("AES-GCM cipher", cipher, CIPHER_LEN);
TEST_ASSERT_EQUAL_HEX8_ARRAY(AES_GCM_CIPHER_CASE, cipher, CIPHER_LEN);
free(nonce);
free(cipher);
}
#else // TEST_AES_GCM_ENCRYPT
{
LOGE("no TEST_AES_GCM_ENCRYPT, do not test aesGcmEncrypt");
TEST_ASSERT_NULL(loader->aesGcmEncrypt);
}
#endif // TEST_AES_GCM_ENCRYPT
static void TestAesGcmDecrypt(const AlgLoader *loader)
#if TEST_AES_GCM_DECRYPT
{
LOGI("begin to test the AES-GCM algorithm decryption");
TEST_ASSERT_NOT_NULL(loader->aesGcmDecrypt);
if (loader->aesGcmDecrypt == NULL) {
LOGE("aesGcmDecrypt pointer is NULL! will not test!");
return;
}
const Uint8Buff key = { (uint8_t *)AES_GCM_TEST_KEY, AES_GCM_KEY_LEN };
const Uint8Buff cipherBuffer = { (uint8_t *)AES_GCM_CIPHER_CASE, CIPHER_LEN };
uint8_t *nonce = (uint8_t *)malloc(NONCE_SIZE);
TEST_ASSERT_NOT_NULL(nonce);
TEST_ASSERT_EQUAL(EOK, memset_s(nonce, NONCE_SIZE, 0, NONCE_SIZE));
GcmParam gcmParams;
gcmParams.aad = (uint8_t *)EXCHANGE_AAD;
gcmParams.aadLen = (uint32_t)strlen(EXCHANGE_AAD);
gcmParams.nonce = nonce;
gcmParams.nonceLen = NONCE_SIZE;
uint8_t *plain = (uint8_t *)malloc(PLAIN_LEN);
TEST_ASSERT_NOT_NULL(plain);
TEST_ASSERT_EQUAL(EOK, memset_s(plain, PLAIN_LEN, 0, PLAIN_LEN));
Uint8Buff plainBuffer = { plain, PLAIN_LEN };
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->aesGcmDecrypt(&key, &cipherBuffer, &gcmParams, false, &plainBuffer));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
PrintBuffer("AES-GCM plain", plain, PLAIN_LEN);
TEST_ASSERT_EQUAL_HEX8_ARRAY(PLAIN_CASE, plain, PLAIN_LEN);
free(nonce);
free(plain);
}
#else // TEST_AES_GCM_DECRYPT
{
LOGE("no TEST_AES_GCM_DECRYPT, do not test aesGcmDecrypt");
TEST_ASSERT_NULL(loader->aesGcmDecrypt);
}
#endif // TEST_AES_GCM_DECRYPT
static void TestHashToPoint(const AlgLoader *loader)
#if TEST_HASH_TO_POINT
{
TEST_ASSERT_NOT_NULL(loader->hashToPoint);
if (loader->hashToPoint == NULL) {
LOGE("hashToPoint pointer is NULL! will not test!");
return;
}
const Uint8Buff hash = { (uint8_t *)HASH_TO_POINT_CASE, SHA256_LEN };
uint8_t *point = (uint8_t *)malloc(SHA256_LEN);
TEST_ASSERT_NOT_NULL(point);
TEST_ASSERT_EQUAL(EOK, memset_s(point, SHA256_LEN, 0, SHA256_LEN));
Uint8Buff pointBuffer = { point, SHA256_LEN };
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->hashToPoint(&hash, X25519, &pointBuffer));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
PrintBuffer("hashToPoint", point, SHA256_LEN);
TEST_ASSERT_EQUAL_HEX8_ARRAY(HASH_TO_POINT_RESULT, point, PLAIN_LEN);
free(point);
}
#else // TEST_HASH_TO_POINT
{
LOGE("no TEST_HASH_TO_POINT, do not test loader->hashToPoint!");
TEST_ASSERT_NULL(loader->hashToPoint);
}
#endif // TEST_HASH_TO_POINT
#if TEST_AGREE_SHARED_SECRET_WITH_STORAGE
static void VerifyAgreeSharedSecretWithStorage(const AlgLoader *loader, const Uint8Buff *key1, const Uint8Buff *key2)
{
const Uint8Buff keyInfo = { (uint8_t *)HKDF_EXAMPLE_INFO, strlen(HKDF_EXAMPLE_INFO) };
const Uint8Buff salt = { (uint8_t *)HKDF_EXAMPLE_SALT, sizeof(HKDF_EXAMPLE_SALT) };
Uint8Buff outHkdf1 = { (uint8_t *)malloc(ED25519_KEY_BYTE_LEN), ED25519_KEY_BYTE_LEN };
Uint8Buff outHkdf2 = { (uint8_t *)malloc(ED25519_KEY_BYTE_LEN), ED25519_KEY_BYTE_LEN };
TEST_ASSERT_NOT_NULL(outHkdf1.val);
TEST_ASSERT_NOT_NULL(outHkdf2.val);
TEST_ASSERT_EQUAL(EOK, memset_s(outHkdf1.val, ED25519_KEY_BYTE_LEN, 0, ED25519_KEY_BYTE_LEN));
TEST_ASSERT_EQUAL(EOK, memset_s(outHkdf2.val, ED25519_KEY_BYTE_LEN, 0, ED25519_KEY_BYTE_LEN));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->computeHkdf(key1, &salt, &keyInfo, &outHkdf1, true));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->computeHkdf(key2, &salt, &keyInfo, &outHkdf2, true));
TEST_ASSERT_EQUAL_HEX8_ARRAY(outHkdf1.val, outHkdf2.val, ED25519_KEY_BYTE_LEN);
free(outHkdf1.val);
free(outHkdf2.val);
}
static int32_t GenerateKeyPairWithStorage(const AlgLoader *loader, const Uint8Buff *keyAlias)
{
const ExtraInfo extraInfo = {
.authId = {
.val = (uint8_t *)malloc(TEST_GENERATE_KEY_PAIR_WITH_STORAGE_AUTH_ID_LENGTH),
.length = TEST_GENERATE_KEY_PAIR_WITH_STORAGE_AUTH_ID_LENGTH,
},
.userType = DEVICE_TYPE_ACCESSORY,
.pairType = PAIR_TYPE_BIND,
};
TEST_ASSERT_NOT_NULL(extraInfo.authId.val);
TEST_ASSERT_EQUAL(EOK, memset_s(extraInfo.authId.val, extraInfo.authId.length, 0, extraInfo.authId.length));
int32_t ret = loader->generateKeyPairWithStorage(keyAlias, ED25519_KEY_BYTE_LEN, ED25519, &extraInfo);
free(extraInfo.authId.val);
return ret;
}
static void TestAgreeSharedSecretWithStorage(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->agreeSharedSecretWithStorage);
TEST_ASSERT_NOT_NULL(loader->computeHkdf);
TEST_ASSERT_NOT_NULL(loader->generateKeyPairWithStorage);
if (!loader->agreeSharedSecretWithStorage || !loader->computeHkdf
|| !loader->generateKeyPairWithStorage) {
LOGE("one of required function pointer is NULL! will not test!");
return;
}
Uint8Buff keyAliasA = { (uint8_t *)KEY_PAIR_ALIAS_1, strlen(KEY_PAIR_ALIAS_1) };
Uint8Buff keyAliasB = { (uint8_t *)KEY_PAIR_ALIAS_2, strlen(KEY_PAIR_ALIAS_2) };
int ret;
ret = GenerateKeyPairWithStorage(loader, &keyAliasA);
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
ret = GenerateKeyPairWithStorage(loader, &keyAliasB);
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
if (ret != HAL_SUCCESS) {
LOGE("GenerateKeyPair failed! will not test!");
return;
}
KeyBuff keyA = { keyAliasA.val, keyAliasA.length, true };
KeyBuff keyB = { keyAliasB.val, keyAliasB.length, true };
Uint8Buff sharedKeyAlias1 = { (uint8_t *)SHARED_KEY_ALIAS_1, strlen(SHARED_KEY_ALIAS_1) };
Uint8Buff sharedKeyAlias2 = { (uint8_t *)SHARED_KEY_ALIAS_2, strlen(SHARED_KEY_ALIAS_1) };
Algorithm alg = ED25519;
const uint32_t keyLength = ED25519_KEY_BYTE_LEN;
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->agreeSharedSecretWithStorage(&keyA,
&keyB, alg, keyLength, &sharedKeyAlias1));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->agreeSharedSecretWithStorage(&keyB,
&keyA, alg, keyLength, &sharedKeyAlias2));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
VerifyAgreeSharedSecretWithStorage(loader, &sharedKeyAlias1, &sharedKeyAlias2);
if (loader->deleteKey) {
LOGD("test deleteKey");
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&sharedKeyAlias1));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&sharedKeyAlias2));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&keyAliasA));
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&keyAliasB));
}
}
#else // TEST_AGREE_SHARED_SECRET_WITH_STORAGE
static void TestAgreeSharedSecretWithStorage(const AlgLoader *loader)
{
LOGE("no TEST_AGREE_SHARED_SECRET_WITH_STORAGE, do not test loader->agreeSharedSecretWithStorage!");
TEST_ASSERT_TRUE(loader->agreeSharedSecretWithStorage == NULL ||
loader->computeHkdf == NULL ||
loader->generateKeyPairWithStorage == NULL);
LOG_ERROR_IF_POINTER_NULL(loader->agreeSharedSecretWithStorage);
LOG_ERROR_IF_POINTER_NULL(loader->computeHkdf);
LOG_ERROR_IF_POINTER_NULL(loader->generateKeyPairWithStorage);
}
#endif // TEST_AGREE_SHARED_SECRET_WITH_STORAGE
static void TestAgreeSharedSecret(const AlgLoader *loader)
#if TEST_AGREE_SHARED_SECRET
{
TEST_ASSERT_NOT_NULL(loader->agreeSharedSecret);
if (!loader->agreeSharedSecret) {
LOGE("agreeSharedSecret pointer is NULL! will not test!");
return;
}
Algorithm alg = X25519;
const uint32_t keyLength = X25519_KEY_BYTE_LEN;
KeyBuff privateKeyA = { (uint8_t *)X25519_PRIVATE_KEY_A, keyLength, false };
KeyBuff publicKeyA = { (uint8_t *)X25519_PUBLIC_KEY_A, keyLength, false };
KeyBuff privateKeyB = { (uint8_t *)X25519_PRIVATE_KEY_B, keyLength, false };
KeyBuff publicKeyB = { (uint8_t *)X25519_PUBLIC_KEY_B, keyLength, false };
Uint8Buff sharedKey1 = { (uint8_t *)malloc(keyLength), keyLength };
Uint8Buff sharedKey2 = { (uint8_t *)malloc(keyLength), keyLength };
TEST_ASSERT_NOT_NULL(sharedKey1.val);
TEST_ASSERT_NOT_NULL(sharedKey2.val);
TEST_ASSERT_EQUAL(EOK, memset_s(sharedKey1.val, keyLength, 0, keyLength));
TEST_ASSERT_EQUAL(EOK, memset_s(sharedKey2.val, keyLength, 0, keyLength));
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->agreeSharedSecret(&privateKeyA, &publicKeyB, alg, &sharedKey1));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->agreeSharedSecret(&privateKeyB, &publicKeyA, alg, &sharedKey2));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
PrintBuffer("shared key 1", sharedKey1.val, keyLength);
PrintBuffer("shared key 2", sharedKey2.val, keyLength);
TEST_ASSERT_EQUAL_HEX8_ARRAY(sharedKey1.val, sharedKey2.val, ED25519_KEY_BYTE_LEN);
free(sharedKey1.val);
free(sharedKey2.val);
}
#else // TEST_AGREE_SHARED_SECRET
{
LOGE("no TEST_AGREE_SHARED_SECRET, do not test loader->agreeSharedSecret");
TEST_ASSERT_NULL(loader->agreeSharedSecret);
}
#endif // TEST_AGREE_SHARED_SECRET
static void TestGenerateKeyPairWithStorage(const AlgLoader *loader)
#if TEST_GENERATE_KEY_PAIR_WITH_STORAGE
{
TEST_ASSERT_NOT_NULL(loader->generateKeyPairWithStorage);
if (!loader->generateKeyPairWithStorage) {
LOGE("generateKeyPairWithStorage pointer is NULL! will not test!");
return;
}
Uint8Buff keyAlias = { (uint8_t *)KEY_PAIR_ALIAS_1, strlen(KEY_PAIR_ALIAS_1) };
const ExtraInfo extraInfo = {
.authId = {
.val = (uint8_t *)malloc(TEST_GENERATE_KEY_PAIR_WITH_STORAGE_AUTH_ID_LENGTH),
.length = TEST_GENERATE_KEY_PAIR_WITH_STORAGE_AUTH_ID_LENGTH,
},
.userType = DEVICE_TYPE_ACCESSORY,
.pairType = PAIR_TYPE_BIND,
};
TEST_ASSERT_NOT_NULL(extraInfo.authId.val);
TEST_ASSERT_EQUAL(EOK, memset_s(extraInfo.authId.val, extraInfo.authId.length, 0, extraInfo.authId.length));
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret,
loader->generateKeyPairWithStorage(&keyAlias, ED25519_KEY_BYTE_LEN, ED25519, &extraInfo));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
if (loader->checkKeyExist) {
LOGD("test checkKeyExist");
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->checkKeyExist(&keyAlias));
}
if (loader->deleteKey) {
LOGD("test deleteKey");
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&keyAlias));
}
free(extraInfo.authId.val);
}
#else // TEST_GENERATE_KEY_PAIR_WITH_STORAGE
{
LOGE("no TEST_GENERATE_KEY_PAIR_WITH_STORAGE, do not test loader->generateKeyPairWithStorage!");
TEST_ASSERT_NULL(loader->generateKeyPairWithStorage);
}
#endif // TEST_GENERATE_KEY_PAIR_WITH_STORAGE
static void TestBigNumExpMod(const AlgLoader *loader)
#if TEST_BIG_NUM_EXP_MOD
{
TEST_ASSERT_NOT_NULL(loader->bigNumExpMod);
if (loader->bigNumExpMod == NULL) {
LOGE("bigNumExpMod pointer is NULL! will not test!");
return;
}
for (uint32_t i = 0; i < ARRAY_SIZE(BIG_NUM_TEST_CASES); ++i) {
uint32_t baseLength = BIG_NUM_TEST_CASES[i].baseLength;
uint32_t expLength = BIG_NUM_TEST_CASES[i].expLength;
uint32_t primeLength = strlen(BIG_NUM_TEST_CASES[i].prime) >> 1;
const Uint8Buff base = { (uint8_t *)BIG_NUM_TEST_CASES[i].base, baseLength };
const Uint8Buff exp = { (uint8_t *)BIG_NUM_TEST_CASES[i].exp, expLength };
Uint8Buff modResult = { (uint8_t *)malloc(primeLength), primeLength };
TEST_ASSERT_NOT_NULL(modResult.val);
TEST_ASSERT_EQUAL(EOK, memset_s(modResult.val, primeLength, 0, primeLength));
int ret;
LOGI("test the big num case: base = %u, exp = %u, prime = %u", baseLength, expLength, primeLength);
RUN_AND_PRINT_ELAPSED_TIME(ret, loader->bigNumExpMod(&base, &exp, BIG_NUM_TEST_CASES[i].prime, &modResult));
TEST_ASSERT_EQUAL(HAL_SUCCESS, ret);
TEST_ASSERT_EQUAL_HEX8_ARRAY(BIG_NUM_TEST_CASES[i].result, modResult.val, primeLength);
PrintBuffer("mod result", modResult.val, modResult.length);
free(modResult.val);
}
}
#else // TEST_BIG_NUM_EXP_MOD
{
LOGE("no TEST_BIG_NUM_EXP_MOD, do not test loader->bigNumExpMod!");
TEST_ASSERT_NULL(loader->bigNumExpMod);
}
#endif // TEST_BIG_NUM_EXP_MOD
static void TestGenerateKeyPair(const AlgLoader *loader)
#if TEST_GENERATE_KEY_PAIR
{
TEST_ASSERT_NOT_NULL(loader->generateKeyPair);
LOGE("nobody use generateKeyPair, do not test");
}
#else // TEST_GENERATE_KEY_PAIR
{
TEST_ASSERT_NULL(loader->generateKeyPair);
LOGE("no TEST_GENERATE_KEY_PAIR, do not test generateKeyPair");
}
#endif // TEST_GENERATE_KEY_PAIR
#if (TEST_EXPORT_PUBLIC_KEY || TEST_IMPORT_PUBLIC_KEY || TEST_ALGORITHM_SIGN || TEST_ALGORITHM_VERIFY)
struct TestExportImportSignVerifyParam {
ExtraInfo extInfo;
Uint8Buff keyAlias;
Uint8Buff outPubKey;
Uint8Buff anotherKeyAlias;
Uint8Buff messages[ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES)];
Uint8Buff signatures[ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES)];
Uint8Buff anotherOutPk;
};
static void TestExportImportSignVerifyPrepareResources(struct TestExportImportSignVerifyParam *param)
{
param->extInfo.authId.length = TEST_EX_IM_SN_VF_EXTRA_INFO_AUTH_ID_LENGTH;
param->extInfo.authId.val = (uint8_t *)malloc(param->extInfo.authId.length);
param->extInfo.userType = DEVICE_TYPE_ACCESSORY;
param->extInfo.pairType = PAIR_TYPE_BIND;
TEST_ASSERT_NOT_NULL(param->extInfo.authId.val);
FillRandom(param->extInfo.authId.val, param->extInfo.authId.length, param->extInfo.authId.length);
param->keyAlias.length = TEST_EX_IM_SN_VF_KEY_ALIAS_LENGTH;
param->keyAlias.val = (uint8_t *)malloc(param->keyAlias.length);
TEST_ASSERT_NOT_NULL(param->keyAlias.val);
FillRandom(param->keyAlias.val, param->keyAlias.length, param->keyAlias.length);
param->outPubKey.length = TEST_EX_IM_SN_VF_OUT_PUB_KEY_LENGTH;
param->outPubKey.val = (uint8_t *)malloc(param->outPubKey.length);
TEST_ASSERT_NOT_NULL(param->outPubKey.val);
TEST_ASSERT_EQUAL(EOK, memset_s(param->outPubKey.val, param->outPubKey.length, 0, param->outPubKey.length));
param->anotherKeyAlias.length = TEST_EX_IM_SN_VF_KEY_ALIAS_LENGTH;
param->anotherKeyAlias.val = (uint8_t *)malloc(param->anotherKeyAlias.length);
TEST_ASSERT_NOT_NULL(param->anotherKeyAlias.val);
do {
FillRandom(param->anotherKeyAlias.val, param->anotherKeyAlias.length, param->anotherKeyAlias.length);
} while (memcmp(param->keyAlias.val, param->anotherKeyAlias.val, TEST_EX_IM_SN_VF_KEY_ALIAS_LENGTH) == 0);
for (uint32_t i = 0; i < ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES); ++i) {
param->messages[i].length = TEST_SIGN_MSG_LENGTHES[i];
param->messages[i].val = (uint8_t *)malloc(param->messages[i].length);
TEST_ASSERT_NOT_NULL(param->messages[i].val);
FillRandom(param->messages[i].val, param->messages[i].length, param->messages[i].length);
param->signatures[i].length = TEST_SIGN_SIGNATURE_LENGTH;
param->signatures[i].val = (uint8_t *)malloc(param->signatures[i].length);
TEST_ASSERT_NOT_NULL(param->signatures[i].val);
TEST_ASSERT_EQUAL(EOK,
memset_s(param->signatures[i].val, param->signatures[i].length, 0, param->signatures[i].length));
}
param->anotherOutPk.length = TEST_EX_IM_SN_VF_OUT_PUB_KEY_LENGTH;
param->anotherOutPk.val = (uint8_t *)malloc(param->anotherOutPk.length);
TEST_ASSERT_NOT_NULL(param->anotherOutPk.val);
TEST_ASSERT_EQUAL(EOK,
memset_s(param->anotherOutPk.val, param->anotherOutPk.length, 0, param->anotherOutPk.length));
}
static void TestExportImportSignVerifyInnerVerfiyNormalAndAbnormalCases(
const AlgLoader *loader, const Algorithm alg, struct TestExportImportSignVerifyParam *param)
{
int res;
for (uint32_t i = 0; i < ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES); ++i) {
// test normal case
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->verify(&param->anotherOutPk, &param->messages[i], alg, &param->signatures[i], false));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
// test tamper message
uint8_t originMsg = param->messages[i].val[0];
param->messages[i].val[0] = ((originMsg == UINT8_MAX) ? 0 : (originMsg + 1));
TEST_ASSERT_NOT_EQUAL(originMsg, param->messages[i].val[0]);
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->verify(&param->anotherOutPk, &param->messages[i], alg, &param->signatures[i], false));
TEST_ASSERT_NOT_EQUAL(HAL_SUCCESS, res);
param->messages[i].val[0] = originMsg;
// test normal case
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->verify(&param->anotherOutPk, &param->messages[i], alg, &param->signatures[i], false));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
// test tamper signature
uint8_t originSig = param->signatures[i].val[0];
param->signatures[i].val[0] = ((originSig == UINT8_MAX) ? 0 : (originSig + 1));
TEST_ASSERT_NOT_EQUAL(originSig, param->signatures[i].val[0]);
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->verify(&param->anotherOutPk, &param->messages[i], alg, &param->signatures[i], false));
TEST_ASSERT_NOT_EQUAL(HAL_SUCCESS, res);
param->signatures[i].val[0] = originSig;
// test normal case
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->verify(&param->anotherOutPk, &param->messages[i], alg, &param->signatures[i], false));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
}
}
static void TestExportImportSignVerifyInner(
const AlgLoader *loader, const Algorithm alg, struct TestExportImportSignVerifyParam *param)
{
int res;
// 1. generate one public private key pair
TEST_ASSERT_EQUAL(HAL_SUCCESS,
loader->generateKeyPairWithStorage(&param->keyAlias, TEST_EX_IM_SN_VF_KEY_LENGTH, alg, &param->extInfo));
// 2. export the public key which is generated in the first step
RUN_AND_PRINT_ELAPSED_TIME(res, loader->exportPublicKey(&param->keyAlias, &param->outPubKey));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
// 3. import the public key which is exported in the second step with a different name
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->importPublicKey(&param->anotherKeyAlias, &param->outPubKey, alg, &param->extInfo));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
// 4. sign with the public key which is generated in the first step
for (uint32_t i = 0; i < ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES); ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res,
loader->sign(&param->keyAlias, &param->messages[i], alg, &param->signatures[i], true));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TEST_ASSERT_GREATER_THAN(0u, param->signatures[i].length);
TEST_ASSERT_LESS_OR_EQUAL(TEST_SIGN_SIGNATURE_LENGTH, param->signatures[i].length);
TEST_ASSERT_NOT_EQUAL(param->signatures[i].length,
CountZero(param->signatures[i].val, param->signatures[i].length));
}
// 5. export the public key which is imported in the third step
RUN_AND_PRINT_ELAPSED_TIME(res, loader->exportPublicKey(&param->anotherKeyAlias, &param->anotherOutPk));
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
// 6. verify the signature that is signed in the fourth step with the public key that is imported in the fifth step
TestExportImportSignVerifyInnerVerfiyNormalAndAbnormalCases(loader, alg, param);
// 7. compare the public keys which are exported in the second and fifth step
PrintBuffer("exported public key", param->outPubKey.val, param->outPubKey.length);
TEST_ASSERT_GREATER_THAN(0u, param->outPubKey.length);
TEST_ASSERT_LESS_OR_EQUAL(TEST_EX_IM_SN_VF_OUT_PUB_KEY_LENGTH, param->outPubKey.length);
TEST_ASSERT_NOT_EQUAL(param->outPubKey.length, CountZero(param->outPubKey.val, param->outPubKey.length));
TEST_ASSERT_EQUAL_MESSAGE(param->outPubKey.length, param->anotherOutPk.length,
TEST_EXPORT_DIFFERENT_ERROR_MESSAGE);
TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(param->outPubKey.val, param->anotherOutPk.val, param->outPubKey.length,
TEST_EXPORT_DIFFERENT_ERROR_MESSAGE);
if (loader->deleteKey) {
LOGD("test deleteKey");
// 8. delete the key pair which is generated in the first step
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&param->keyAlias));
// 9. delete the public key which is imported in the third step
TEST_ASSERT_EQUAL(HAL_SUCCESS, loader->deleteKey(&param->anotherKeyAlias));
}
}
static void TestExportImportSignVerifyReleaseResources(struct TestExportImportSignVerifyParam *param)
{
free(param->extInfo.authId.val);
param->extInfo.authId.val = NULL;
free(param->keyAlias.val);
param->keyAlias.val = NULL;
free(param->outPubKey.val);
param->outPubKey.val = NULL;
free(param->anotherKeyAlias.val);
param->anotherKeyAlias.val = NULL;
for (uint32_t i = 0; i < ARRAY_SIZE(TEST_SIGN_MSG_LENGTHES); ++i) {
free(param->messages[i].val);
param->messages[i].val = NULL;
free(param->signatures[i].val);
param->signatures[i].val = NULL;
}
free(param->anotherOutPk.val);
param->anotherOutPk.val = NULL;
}
static void TestExportImportSignVerify(const AlgLoader *loader, const Algorithm alg)
{
TEST_ASSERT_NOT_NULL(loader->generateKeyPairWithStorage);
// only two test cases for exportPublicKey, P256 and ED25519, outKey length is 32
TEST_ASSERT_NOT_NULL(loader->exportPublicKey);
TEST_ASSERT_NOT_NULL(loader->importPublicKey);
// sign message length varies from min 1 to max 1024
TEST_ASSERT_NOT_NULL(loader->sign);
TEST_ASSERT_NOT_NULL(loader->verify);
TEST_ASSERT_TRUE((alg == ED25519) || (alg == P256));
if (((alg != ED25519) && (alg != P256)) || !loader->generateKeyPairWithStorage ||
!loader->exportPublicKey || !loader->importPublicKey || !loader->sign || !loader->verify) {
LOGE("one of requested pointer is NULL or alg is invalid, can not test!");
return;
}
struct TestExportImportSignVerifyParam param;
TestExportImportSignVerifyPrepareResources(&param);
TestExportImportSignVerifyInner(loader, alg, &param);
TestExportImportSignVerifyReleaseResources(&param);
}
static void TestExportImportSignVerifyP256AndEd25519(const AlgLoader *loader)
{
#if TEST_EXPORT_IMPORT_SIGN_VERIFY_ED25519
LOGI("test export import sign verify ED25519");
TestExportImportSignVerify(loader, ED25519);
#else // TEST_EXPORT_IMPORT_SIGN_VERIFY_ED25519
LOGE("no TEST_EXPORT_IMPORT_SIGN_VERIFY_ED25519, do not test ED25519");
#endif // TEST_EXPORT_IMPORT_SIGN_VERIFY_ED25519
#if TEST_EXPORT_IMPORT_SIGN_VERIFY_P256
LOGI("test export import sign verify P256");
TestExportImportSignVerify(loader, P256);
#else // TEST_EXPORT_IMPORT_SIGN_VERIFY_P256
LOGE("no TEST_EXPORT_IMPORT_SIGN_VERIFY_P256, do not test P256");
#endif // TEST_EXPORT_IMPORT_SIGN_VERIFY_P256
}
#endif // (TEST_EXPORT_PUBLIC_KEY || TEST_IMPORT_PUBLIC_KEY || TEST_ALGORITHM_SIGN || TEST_ALGORITHM_VERIFY)
static void TestExportPublicKey(const AlgLoader *loader)
#if TEST_EXPORT_PUBLIC_KEY
{
TEST_ASSERT_NOT_NULL(loader->exportPublicKey);
if (!loader->exportPublicKey) {
LOGE("exportPublicKey pointer is NULL, can not test!");
return;
}
TestExportImportSignVerifyP256AndEd25519(loader);
}
#else // TEST_EXPORT_PUBLIC_KEY
{
TEST_ASSERT_NULL(loader->exportPublicKey);
LOGE("no TEST_EXPORT_PUBLIC_KEY, do not test exportPublicKey");
}
#endif // TEST_EXPORT_PUBLIC_KEY
static void TestSign(const AlgLoader *loader)
#if TEST_ALGORITHM_SIGN
{
TEST_ASSERT_NOT_NULL(loader->sign);
if (!loader->sign) {
LOGE("sign pointer is NULL, can not test!");
return;
}
TestExportImportSignVerifyP256AndEd25519(loader);
}
#else // TEST_ALGORITHM_SIGN
{
TEST_ASSERT_NULL(loader->sign);
LOGE("no TEST_ALGORITHM_SIGN, do not test sign");
}
#endif // TEST_ALGORITHM_SIGN
static void TestVerify(const AlgLoader *loader)
#if TEST_ALGORITHM_VERIFY
{
TEST_ASSERT_NOT_NULL(loader->verify);
if (!loader->verify) {
LOGE("verify pointer is NULL, can not test!");
return;
}
TestExportImportSignVerifyP256AndEd25519(loader);
}
#else // TEST_ALGORITHM_VERIFY
{
TEST_ASSERT_NULL(loader->verify);
LOGE("no TEST_ALGORITHM_VERIFY, do not test verify");
}
#endif // TEST_ALGORITHM_VERIFY
static void TestImportPublicKey(const AlgLoader *loader)
#if TEST_IMPORT_PUBLIC_KEY
{
TEST_ASSERT_NOT_NULL(loader->importPublicKey);
if (!loader->importPublicKey) {
LOGE("importPublicKey pointer is NULL, can not test!");
return;
}
TestExportImportSignVerifyP256AndEd25519(loader);
}
#else // TEST_IMPORT_PUBLIC_KEY
{
TEST_ASSERT_NULL(loader->importPublicKey);
LOGE("no TEST_IMPORT_PUBLIC_KEY, do not test importPublicKey");
}
#endif // TEST_IMPORT_PUBLIC_KEY
#if TEST_CHECK_DL_PUBLIC_KEY // {
static void TestCheckDlPublicKeyInner(const AlgLoader *loader,
Uint8Buff *key, const char *primeHex)
{
bool res;
int randIndex;
// 1. all zero
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(false, res);
// 2. value is 1
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
key->val[key->length - 1] = TEST_CHECK_DL_VALUE_ONE;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(false, res);
// 3. value is 2
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
key->val[key->length - 1] = TEST_CHECK_DL_VALUE_TWO;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(true, res);
// 4. value is between 2 and primeHex - 2
// first, init value with 2
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
key->val[key->length - 1] = TEST_CHECK_DL_VALUE_TWO;
// then add 1 on rand byte
randIndex = rand() % key->length;
key->val[randIndex] += TEST_CHECK_DL_VALUE_ONE;
PrintBuffer("rand key", key->val, key->length);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(true, res);
// first, init value with primeHex - 2
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
TEST_ASSERT_EQUAL(HAL_SUCCESS, HexStringToByte(primeHex, key->val, key->length));
TEST_ASSERT_GREATER_OR_EQUAL(TEST_CHECK_DL_VALUE_TWO, key->val[key->length - 1]);
key->val[key->length - 1] -= TEST_CHECK_DL_VALUE_TWO;
// then sub 1 on rand byte
do {
randIndex = rand() % key->length;
} while (key->val[randIndex] < TEST_CHECK_DL_VALUE_ONE);
key->val[randIndex] -= TEST_CHECK_DL_VALUE_ONE;
PrintBuffer("rand key", key->val, key->length);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(true, res);
// 5. value is primeHex - 2
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
TEST_ASSERT_EQUAL(HAL_SUCCESS, HexStringToByte(primeHex, key->val, key->length));
TEST_ASSERT_GREATER_OR_EQUAL(TEST_CHECK_DL_VALUE_TWO, key->val[key->length - 1]);
key->val[key->length - 1] -= TEST_CHECK_DL_VALUE_TWO;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(true, res);
// 6. value is primeHex - 1
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
TEST_ASSERT_EQUAL(HAL_SUCCESS, HexStringToByte(primeHex, key->val, key->length));
TEST_ASSERT_GREATER_OR_EQUAL(TEST_CHECK_DL_VALUE_ONE, key->val[key->length - 1]);
key->val[key->length - 1] -= TEST_CHECK_DL_VALUE_ONE;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(false, res);
// 7. value is primeHex
TEST_ASSERT_EQUAL(EOK, memset_s(key->val, key->length, 0, key->length));
TEST_ASSERT_EQUAL(HAL_SUCCESS, HexStringToByte(primeHex, key->val, key->length));
RUN_AND_PRINT_ELAPSED_TIME(res, loader->checkDlPublicKey(key, primeHex));
TEST_ASSERT_EQUAL(false, res);
}
static void TestCheckDlPublicKey(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->checkDlPublicKey);
if (!loader->checkDlPublicKey) {
LOGE("checkDlPublicKey pointer is NULL, can not test!");
return;
}
Uint8Buff key;
key.length = PAKE_DL_PRIME_LEN_256;
key.val = (uint8_t *)malloc(key.length);
TEST_ASSERT_NOT_NULL(key.val);
TestCheckDlPublicKeyInner(loader, &key, LARGE_PRIME_NUM_HEX_256);
free(key.val);
key.length = PAKE_DL_PRIME_LEN_384;
key.val = (uint8_t *)malloc(key.length);
TEST_ASSERT_NOT_NULL(key.val);
TestCheckDlPublicKeyInner(loader, &key, LARGE_PRIME_NUM_HEX_384);
free(key.val);
}
#else // TEST_CHECK_DL_PUBLIC_KEY // } {
static void TestCheckDlPublicKey(const AlgLoader *loader)
{
TEST_ASSERT_NULL(loader->checkDlPublicKey);
LOGE("no TEST_CHECK_DL_PUBLIC_KEY, do not test checkDlPublicKey");
}
#endif // TEST_CHECK_DL_PUBLIC_KEY // }
static void TestCheckEcPublicKey(const AlgLoader *loader)
{
TEST_ASSERT_NULL(loader->checkEcPublicKey);
LOGE("loader->checkEcPublicKey is NULL, and nobody use it, do not test!");
}
#if TEST_BIG_NUM_COMPARE // {
static void TestBigNumCompareInnerMinMax(const AlgLoader *loader,
Uint8Buff *x, Uint8Buff *y)
{
// 0. 0xFFFFFF > 0x000000
int res;
TEST_ASSERT_EQUAL(EOK, memset_s(x->val, x->length, UINT8_MAX, x->length));
TEST_ASSERT_EQUAL(EOK, memset_s(y->val, y->length, 0, y->length));
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(-1, res);
}
static void TestBigNumCompareInnerFull(const AlgLoader *loader,
Uint8Buff *x, Uint8Buff *y)
{
int previous, res;
// 1. 0x123456 > 0x123455
TEST_ASSERT_EQUAL(EOK, memcpy_s(x->val, x->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val, y->val, TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL);
previous = y->val[y->length - 1];
y->val[y->length - 1] -= 1;
TEST_ASSERT_LESS_THAN(previous, y->val[y->length - 1]);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(-1, res);
// 2. 0x123456 = 0x123456
TEST_ASSERT_EQUAL(EOK, memcpy_s(x->val, x->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val, y->val, TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(0, res);
// 3. 0x123456 < 0x123457
TEST_ASSERT_EQUAL(EOK, memcpy_s(x->val, x->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val, y->val, TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL);
previous = y->val[y->length - 1];
y->val[y->length - 1] += 1;
TEST_ASSERT_GREATER_THAN(previous, y->val[y->length - 1]);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(-1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(1, res);
}
static void TestBigNumCompareInnerHalf(const AlgLoader *loader,
Uint8Buff *x, Uint8Buff *y)
{
int previous, res;
// 4. 0x003456 > 0x3455
TEST_ASSERT_EQUAL(EOK,
memset_s(x->val, x->length, 0, TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF));
TEST_ASSERT_EQUAL(EOK, memcpy_s(
x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, x->length - TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, y->val,
TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF);
previous = y->val[y->length - 1];
y->val[y->length - 1] -= 1;
TEST_ASSERT_LESS_THAN(previous, y->val[y->length - 1]);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(-1, res);
// 5. 0x003456 = 0x3456
TEST_ASSERT_EQUAL(EOK,
memset_s(x->val, x->length, 0, TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF));
TEST_ASSERT_EQUAL(EOK, memcpy_s(
x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, x->length - TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, y->val,
TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(0, res);
// 6. 0x003456 < 0x3457
TEST_ASSERT_EQUAL(EOK,
memset_s(x->val, x->length, 0, TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF));
TEST_ASSERT_EQUAL(EOK, memcpy_s(
x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, x->length - TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, y->val,
TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF);
previous = y->val[y->length - 1];
y->val[y->length - 1] += 1;
TEST_ASSERT_GREATER_THAN(previous, y->val[y->length - 1]);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(-1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(1, res);
}
static void TestBigNumCompareInnerCompareFullAgainstHalf(const AlgLoader *loader,
Uint8Buff *x, Uint8Buff *y)
{
int res;
// 7. 0x123456 > 0x3456
TEST_ASSERT_EQUAL(EOK, memcpy_s(
x->val, x->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(
x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, x->length - TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL(EOK, memcpy_s(y->val, y->length,
TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF, sizeof(TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF)));
TEST_ASSERT_EQUAL_HEX8_ARRAY(x->val + TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF, y->val,
TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(x, y));
TEST_ASSERT_EQUAL(1, res);
RUN_AND_PRINT_ELAPSED_TIME(res, loader->bigNumCompare(y, x));
TEST_ASSERT_EQUAL(-1, res);
}
static void TestBigNumCompare(const AlgLoader *loader)
{
TEST_ASSERT_NOT_NULL(loader->bigNumCompare);
if (!loader->bigNumCompare) {
LOGE("bigNumCompare pointer is NULL, can not test!");
return;
}
Uint8Buff x = { (uint8_t *)malloc(TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL), TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL };
TEST_ASSERT_NOT_NULL(x.val);
Uint8Buff y = { (uint8_t *)malloc(TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL), TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL };
TEST_ASSERT_NOT_NULL(y.val);
TestBigNumCompareInnerMinMax(loader, &x, &y);
TestBigNumCompareInnerFull(loader, &x, &y);
free(y.val);
y.length = TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF;
y.val = (uint8_t *)malloc(y.length);
TEST_ASSERT_NOT_NULL(y.val);
TestBigNumCompareInnerHalf(loader, &x, &y);
TestBigNumCompareInnerCompareFullAgainstHalf(loader, &x, &y);
free(x.val);
free(y.val);
}
#else // TEST_BIG_NUM_COMPARE // } {
static void TestBigNumCompare(const AlgLoader *loader)
{
TEST_ASSERT_NULL(loader->bigNumCompare);
LOGE("no TEST_BIG_NUM_COMPARE, do not test loader->bigNumCompare");
}
#endif // TEST_BIG_NUM_COMPARE // {
void TestHcAlg(void)
{
const AlgLoader *loader = GetLoaderInstance();
TEST_ASSERT_NOT_NULL(loader);
if (loader == NULL) {
LOGE("alg loader instance is NULL");
return;
}
int32_t res;
RUN_AND_PRINT_ELAPSED_TIME(res, loader->initAlg());
TEST_ASSERT_EQUAL(HAL_SUCCESS, res);
TestSha256(loader);
TestGenerateRandom(loader);
TestComputeHmac(loader);
TestComputeHkdf(loader);
#if (defined(DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY) && DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY)
(void)(TestImportSymmetricKey);
#else // DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY
TestImportSymmetricKey(loader);
#endif // DO_NOT_TEST_DEPRECATED_IMPORT_SYMMETRIC_KEY
TestCheckKeyExist(loader);
TestDeleteKey(loader);
TestAesGcmEncrypt(loader);
TestAesGcmDecrypt(loader);
TestHashToPoint(loader);
TestGenerateKeyPairWithStorage(loader);
TestAgreeSharedSecretWithStorage(loader);
TestAgreeSharedSecret(loader);
TestBigNumExpMod(loader);
TestGenerateKeyPair(loader);
TestExportPublicKey(loader);
TestSign(loader);
TestVerify(loader);
TestImportPublicKey(loader);
TestCheckDlPublicKey(loader);
TestCheckEcPublicKey(loader);
TestBigNumCompare(loader);
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_ALG_TEST_H
#define HC_ALG_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcAlg(void);
#ifdef __cplusplus
}
#endif
#endif // HC_ALG_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_ALG_TEST_CASE_H
#define HC_ALG_TEST_CASE_H
#include <ohos_types.h> // ARRAY_SIZE
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define KEY_PAIR_ALIAS_1 "test: key pair 1"
#define KEY_PAIR_ALIAS_2 "test: key pair 2"
#define SHARED_KEY_ALIAS_1 "test: shared key 1"
#define SHARED_KEY_ALIAS_2 "test: shared key 2"
#define EXCHANGE_AAD "hichain_iso_exchange"
enum {
NONCE_SIZE = 12,
AES_GCM_KEY_LEN = 128 / 8,
TAG_LEN = 16,
CIPHER_LEN = 32,
PLAIN_LEN = 16,
X25519_KEY_BYTE_LEN = 32,
ED25519_KEY_BYTE_LEN = 32,
};
typedef struct {
uint32_t baseLength;
uint32_t expLength;
const char *prime;
const uint8_t *base;
const uint8_t *exp;
const uint8_t *result;
} BigNumTestCase;
static const uint8_t AES_GCM_TEST_KEY[AES_GCM_KEY_LEN] = {
0xc7, 0x4f, 0x98, 0x27, 0x09, 0xcf, 0xbe, 0x04,
0x03, 0x81, 0xbc, 0x4a, 0x45, 0xed, 0xe9, 0xcb
};
static const uint8_t AES_GCM_CIPHER_CASE[CIPHER_LEN] = {
0xf0, 0x1f, 0x08, 0xb2, 0xb1, 0x79, 0xc9, 0x65,
0xc6, 0x45, 0x0c, 0xc9, 0xb9, 0xb6, 0x07, 0xc0,
0x27, 0x0c, 0x8d, 0xa0, 0x33, 0x6a, 0x5b, 0xa9,
0x0f, 0x1a, 0x01, 0xde, 0x43, 0xda, 0x79, 0x7f
};
static const uint8_t PLAIN_CASE[] = "This is the case";
static const uint8_t HASH_TO_POINT_CASE[] = {
0x75, 0x6d, 0xee, 0x8b, 0xa1, 0xce, 0xce, 0xa3,
0x1e, 0x68, 0x02, 0xe8, 0xe4, 0xbe, 0xe0, 0x9e,
0x3b, 0x01, 0xfa, 0xe0, 0x34, 0x77, 0x65, 0x2c,
0xf0, 0x2F, 0x33, 0x7a, 0x54, 0x6b, 0xd9, 0xdd
};
static const uint8_t HASH_TO_POINT_RESULT[] = {
0xd4, 0xa8, 0x7e, 0xa6, 0xd7, 0x07, 0xb0, 0xea,
0xef, 0x28, 0xd8, 0x98, 0x89, 0xcc, 0xa0, 0xd8,
0x65, 0x4d, 0x8e, 0xdd, 0x4b, 0x16, 0x7a, 0x0d,
0xde, 0x4f, 0xf2, 0x99, 0xd3, 0x4c, 0xb4, 0x45
};
static const uint8_t X25519_PRIVATE_KEY_A[X25519_KEY_BYTE_LEN] = {
0x6c, 0xe7, 0xf5, 0x5c, 0x2d, 0xc8, 0x89, 0x6b,
0xfc, 0x64, 0xe8, 0xc4, 0x58, 0xfe, 0xbe, 0x13,
0x45, 0x01, 0xa4, 0x7a, 0xa1, 0x60, 0xcd, 0x4c,
0xaa, 0x7b, 0x19, 0x10, 0x23, 0x33, 0xa1, 0x32
};
static const uint8_t X25519_PUBLIC_KEY_A[X25519_KEY_BYTE_LEN] = {
0x10, 0x65, 0x4b, 0x65, 0xf9, 0x40, 0x10, 0x20,
0x4b, 0x2f, 0xff, 0xc6, 0xaf, 0xb3, 0xa8, 0x86,
0x69, 0xda, 0x32, 0xf4, 0xa7, 0x00, 0x37, 0x82,
0x7e, 0xd3, 0x39, 0xd1, 0x02, 0x2b, 0x23, 0x5d
};
static const uint8_t X25519_PRIVATE_KEY_B[X25519_KEY_BYTE_LEN] = {
0xc3, 0xb2, 0xc7, 0xc3, 0x1c, 0x7e, 0xad, 0x20,
0x5f, 0x00, 0xdf, 0x1a, 0xe0, 0xe6, 0x9e, 0x6c,
0xf8, 0xac, 0x2f, 0xd5, 0xea, 0xa5, 0xb6, 0xe7,
0x75, 0x46, 0xcb, 0x85, 0xbc, 0x0e, 0x68, 0xb6
};
static const uint8_t X25519_PUBLIC_KEY_B[X25519_KEY_BYTE_LEN] = {
0xd7, 0x7b, 0xa7, 0x19, 0x8b, 0x3e, 0x54, 0x4c,
0xc3, 0x45, 0xb9, 0x61, 0xa0, 0x9c, 0x23, 0xfc,
0xeb, 0x1f, 0x9c, 0x30, 0x0f, 0x3c, 0xcd, 0x17,
0x7d, 0xdc, 0x50, 0x0f, 0x40, 0x03, 0x90, 0x2e
};
static const char PRIME_HEX_384[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"
"9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
"3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33"
"A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864"
"D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2"
"08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
static const char PRIME_HEX_256[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"
"9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
"3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
static const uint8_t BASE_HEX_32[] = {
0x42, 0x6B, 0x93, 0xAA, 0x93, 0x27, 0xD7, 0x43, 0x8A, 0x92, 0x67, 0x77, 0x77, 0x23, 0x51, 0xAA,
0xD5, 0xCF, 0xA3, 0xDB, 0x53, 0x0B, 0x81, 0x77, 0x85, 0x85, 0xCC, 0x83, 0x50, 0x41, 0x38, 0xE3
};
static const uint8_t BASE_HEX_256[] = {
0xDA, 0xC2, 0xE1, 0x78, 0x68, 0xD7, 0x3E, 0x0E, 0xB2, 0x1A, 0x33, 0xA9, 0x1F, 0x0C, 0xD2, 0x44,
0x75, 0xEC, 0xDC, 0xF3, 0x47, 0x7B, 0xEF, 0x7D, 0x22, 0x01, 0x94, 0x34, 0x01, 0x8F, 0x9A, 0x57,
0xC1, 0x04, 0xFE, 0x09, 0x9C, 0xB1, 0x50, 0xF5, 0xDD, 0x09, 0x08, 0x3E, 0x08, 0x9E, 0xD3, 0x13,
0x62, 0x91, 0xC7, 0x72, 0x9B, 0x1F, 0x1F, 0x6A, 0x0A, 0x26, 0xD6, 0xF7, 0xEE, 0xFC, 0x3C, 0x35,
0x90, 0x94, 0xF0, 0x7B, 0xEF, 0x59, 0xE3, 0xF2, 0x0D, 0x2B, 0x47, 0xAB, 0x8D, 0xB2, 0xA4, 0xFD,
0x0D, 0x68, 0x9E, 0xA4, 0xCF, 0xE2, 0x7D, 0x19, 0x74, 0x91, 0x7D, 0x18, 0xFB, 0x81, 0x89, 0xC4,
0xCA, 0x49, 0x31, 0xC3, 0xFB, 0xE5, 0x6C, 0x43, 0x9A, 0x5B, 0x56, 0xF1, 0xBB, 0xE7, 0xF0, 0x76,
0x66, 0x3E, 0x06, 0x4B, 0x53, 0x01, 0x38, 0x28, 0xA6, 0xB6, 0x27, 0x50, 0xAB, 0x00, 0x20, 0x54,
0x84, 0x6F, 0x08, 0xCB, 0x13, 0xC3, 0x5D, 0x24, 0x27, 0x02, 0x5C, 0x0F, 0x90, 0xA5, 0xA0, 0x1E,
0xDC, 0xF9, 0xE5, 0x2F, 0xCB, 0x53, 0xBC, 0xD9, 0x10, 0x52, 0xF6, 0x45, 0x73, 0x21, 0x7B, 0x53,
0x12, 0xBD, 0xF3, 0x05, 0xDA, 0xE2, 0x1B, 0x65, 0x70, 0x62, 0x74, 0x68, 0xCB, 0x1C, 0xEE, 0xFD,
0xF9, 0xFC, 0x83, 0x95, 0x7C, 0xB5, 0xCF, 0xCE, 0x83, 0x7B, 0xBA, 0x4D, 0xEC, 0xA9, 0xDF, 0x6D,
0xF1, 0x85, 0x59, 0x14, 0xB7, 0x94, 0x46, 0x57, 0x44, 0x10, 0x4E, 0x6E, 0xC5, 0x68, 0xDA, 0x82,
0x92, 0x5A, 0xDB, 0x89, 0x5D, 0x3B, 0x5E, 0xB3, 0x24, 0xB4, 0x55, 0x4A, 0xE9, 0x41, 0xCB, 0xC6,
0xE3, 0xFE, 0xC3, 0xAD, 0x2F, 0xB3, 0xA6, 0x0F, 0x7D, 0x4C, 0xA5, 0xED, 0x95, 0x70, 0x97, 0x12,
0x54, 0xAB, 0x58, 0x0E, 0xE5, 0xF6, 0x8B, 0x37, 0x0B, 0x7C, 0x06, 0x54, 0x89, 0xDD, 0x8A, 0xA9
};
static const uint8_t EXP_HEX_1[] = { 0xE9 };
static const uint8_t EXP_HEX_28[] = {
0x8F, 0x6F, 0xC2, 0xC0, 0x64, 0x37, 0x1E, 0x98, 0x71, 0xC9, 0xF5, 0x5E, 0x45, 0x5F, 0x46, 0x61,
0x1B, 0x4D, 0x7D, 0x23, 0x21, 0x01, 0x1C, 0x56, 0xE2, 0x77, 0x14, 0x64
};
static const uint8_t EXP_HEX_32[] = {
0xA9, 0xC9, 0x9A, 0x5B, 0xB5, 0x9F, 0xC6, 0x9E, 0xE3, 0xF7, 0x4B, 0xFC, 0xDC, 0xF4, 0x26, 0x20,
0xBE, 0xAF, 0x03, 0x17, 0xEC, 0x56, 0x2C, 0xB5, 0x46, 0x13, 0x33, 0xD6, 0x97, 0x6A, 0x33, 0x7C
};
static const uint8_t BASE_HEX_384[] = {
0x37, 0xBE, 0xDE, 0x74, 0x1B, 0x5D, 0x7D, 0x58, 0x86, 0x55, 0xD3, 0xCB, 0x52, 0x2A, 0x6C, 0x11,
0xB5, 0x97, 0x68, 0x26, 0x21, 0x68, 0x62, 0x51, 0x6E, 0xFA, 0x0B, 0x44, 0x04, 0x18, 0x92, 0xD9,
0x11, 0xB0, 0x33, 0x58, 0x46, 0xCD, 0x8B, 0x8E, 0x46, 0x24, 0x25, 0xFE, 0x58, 0xD9, 0x9D, 0xC4,
0x1B, 0xA2, 0x17, 0x5D, 0xA5, 0x76, 0xA9, 0x81, 0x93, 0x49, 0x1A, 0xB8, 0x2D, 0x29, 0xDA, 0xE5,
0x29, 0x5F, 0xE3, 0x85, 0x09, 0xE4, 0xC6, 0xF2, 0x73, 0x65, 0x40, 0xBA, 0x93, 0xAA, 0x08, 0x43,
0xB8, 0x07, 0xF7, 0x01, 0xA5, 0xFB, 0x1E, 0x85, 0xBB, 0x14, 0x3C, 0x2B, 0xA8, 0x4D, 0xD8, 0x3C,
0xA3, 0x19, 0x16, 0x86, 0x55, 0xE2, 0xFC, 0xC0, 0xA0, 0xA0, 0x69, 0x07, 0x6A, 0x04, 0xBA, 0x76,
0xC4, 0x60, 0xFE, 0xCB, 0xA8, 0x50, 0x26, 0x40, 0xAB, 0x86, 0x90, 0xBA, 0x23, 0xDC, 0x06, 0xA3,
0xFE, 0xE2, 0x21, 0x2C, 0xB8, 0x3B, 0xF8, 0x02, 0xFB, 0x1E, 0x2A, 0xBA, 0xA7, 0x60, 0x5D, 0x12,
0xE6, 0xE7, 0xC1, 0xA3, 0x14, 0x53, 0x42, 0x50, 0x52, 0x10, 0x20, 0xC2, 0x7C, 0x9B, 0xE6, 0xE7,
0xD0, 0x3B, 0x31, 0x2D, 0x4B, 0xFA, 0x70, 0x3B, 0x32, 0x19, 0x32, 0x71, 0x34, 0xFE, 0x12, 0x0D,
0xE4, 0x03, 0x1D, 0x95, 0xAD, 0xBC, 0xEB, 0x86, 0xE2, 0x72, 0xBE, 0x22, 0xCC, 0x7A, 0xEF, 0x4B,
0xEA, 0x2A, 0xD7, 0x61, 0x54, 0x66, 0xC2, 0x51, 0x70, 0x84, 0xC2, 0x93, 0x92, 0x74, 0xE7, 0x91,
0xFC, 0xF1, 0x1C, 0x7F, 0x3F, 0x47, 0xF7, 0x4D, 0x74, 0xDF, 0xD7, 0xD3, 0x93, 0x06, 0x80, 0xBA,
0x9B, 0xCE, 0xC4, 0x52, 0x64, 0xF6, 0x83, 0x96, 0x00, 0x3D, 0xE4, 0x6F, 0xF5, 0xDD, 0xA8, 0xC5,
0xFC, 0x24, 0xBC, 0x4C, 0x86, 0x1C, 0x97, 0xEA, 0x6B, 0xA7, 0x66, 0x86, 0x83, 0xC6, 0x31, 0xAA,
0x6A, 0x89, 0x9C, 0x51, 0x4C, 0x0A, 0xFB, 0x15, 0x2A, 0x67, 0x23, 0x0A, 0xA7, 0x1E, 0x7E, 0xEA,
0x62, 0x13, 0x6E, 0x32, 0xA6, 0x3A, 0xE7, 0x39, 0x37, 0x3F, 0xBB, 0x1F, 0x59, 0x0C, 0x54, 0x70,
0xCE, 0xE8, 0x16, 0xC9, 0xE4, 0x2D, 0xC3, 0xB8, 0xEB, 0xB1, 0x4E, 0x3B, 0x00, 0xFA, 0xD0, 0xFD,
0xB1, 0x44, 0x86, 0x84, 0x5F, 0xBA, 0x1D, 0xA4, 0x10, 0xC8, 0x7D, 0xAC, 0x90, 0xC4, 0xD2, 0xF4,
0x52, 0xDD, 0x68, 0xC4, 0x9D, 0xEE, 0x10, 0x6E, 0xE3, 0xD5, 0x1B, 0xBD, 0xF7, 0xFD, 0xBE, 0x7A,
0xF6, 0xEA, 0x2F, 0x22, 0xEA, 0x8F, 0x41, 0xCB, 0x88, 0x94, 0x0A, 0x63, 0x3C, 0xF2, 0x4B, 0xDF,
0x97, 0x74, 0xA6, 0x41, 0x55, 0xAE, 0xC9, 0x4B, 0xC7, 0xA6, 0x9D, 0xA1, 0xCD, 0xC8, 0x8F, 0x74,
0x08, 0x15, 0x00, 0x7B, 0x1D, 0x2B, 0xDB, 0xAD, 0xC9, 0x9E, 0x9E, 0xAD, 0x5D, 0x6A, 0x5F, 0xEB
};
static const uint8_t BIG_NUM_TEST_CASE_1_RESULT[] = {
0x84, 0x24, 0x3B, 0x5B, 0x99, 0x29, 0x54, 0xCD, 0xD8, 0x7E, 0x38, 0xE3, 0x80, 0xAA, 0x7D, 0xC7,
0x30, 0xD4, 0xCA, 0xE7, 0x8B, 0x3F, 0xAE, 0x0D, 0xAE, 0xCD, 0x71, 0x27, 0x4D, 0xE7, 0x52, 0x96,
0x77, 0x08, 0x88, 0x09, 0xC9, 0x4A, 0xD3, 0x09, 0x55, 0xC1, 0xB5, 0x78, 0x98, 0x2E, 0x42, 0x2D,
0x28, 0xEB, 0xCE, 0x2E, 0x56, 0xA5, 0x15, 0x1A, 0xB4, 0x13, 0xFA, 0x3A, 0xB9, 0xB3, 0xE8, 0x5C,
0x79, 0xDE, 0x06, 0xAE, 0xBA, 0x58, 0x5F, 0x71, 0x56, 0xCA, 0x51, 0xCF, 0x00, 0x42, 0x6D, 0xD9,
0x8E, 0x07, 0x5D, 0xA0, 0x71, 0xE4, 0x86, 0x56, 0x7B, 0x05, 0x27, 0x70, 0x7E, 0xEC, 0x81, 0x58,
0xD3, 0xBE, 0x3A, 0x27, 0x3F, 0x22, 0x15, 0xAB, 0x7B, 0x4E, 0xC5, 0x09, 0xEF, 0x02, 0x6F, 0xE7,
0x00, 0x40, 0x71, 0x70, 0xC1, 0x44, 0xC7, 0xED, 0xFE, 0xC6, 0x86, 0x10, 0x12, 0xF2, 0x1B, 0x51,
0x40, 0x02, 0x2F, 0xA1, 0x90, 0xE7, 0x07, 0xC7, 0xFE, 0x52, 0x57, 0xD6, 0xB3, 0x6E, 0xB6, 0xF3,
0x3F, 0xC9, 0x25, 0xCC, 0x86, 0xBC, 0xEC, 0x18, 0x34, 0x4A, 0x4F, 0xF6, 0xE5, 0x01, 0x42, 0xD7,
0x7E, 0xE4, 0x54, 0xAF, 0xE4, 0xA3, 0x26, 0x6C, 0x01, 0x0C, 0x64, 0xAD, 0x1C, 0xE0, 0x41, 0xAE,
0x4B, 0x40, 0xB0, 0xE7, 0x67, 0x08, 0x16, 0xE5, 0x54, 0x05, 0x55, 0x9E, 0x20, 0x3F, 0x54, 0x91,
0xCF, 0x2F, 0x1F, 0xE7, 0xE3, 0xF2, 0x4A, 0xF1, 0x58, 0x3F, 0xFE, 0x55, 0x56, 0x9A, 0x3C, 0xFB,
0x63, 0x32, 0xF6, 0x64, 0x55, 0x5C, 0x6C, 0xAA, 0x79, 0xE0, 0x4F, 0x47, 0x36, 0x32, 0xDB, 0x2A,
0x3F, 0xA1, 0x70, 0xAD, 0x72, 0x93, 0xFB, 0xD2, 0xF9, 0xE5, 0x0F, 0xDC, 0x85, 0x2C, 0xB9, 0x32,
0x4E, 0x9B, 0x31, 0x8C, 0x8C, 0xFB, 0x21, 0xCF, 0xC3, 0x76, 0x22, 0x04, 0xF9, 0xCD, 0x7F, 0xE0
};
static const uint8_t BIG_NUM_TEST_CASE_2_RESULT[] = {
0x1A, 0xA5, 0x23, 0xA4, 0x6B, 0x19, 0x79, 0xF0, 0xD0, 0x62, 0x8E, 0xE7, 0xC4, 0x5C, 0x41, 0x54,
0x54, 0xF8, 0xB6, 0xC2, 0xA7, 0xF6, 0x80, 0x69, 0xB3, 0xE2, 0x3E, 0x0E, 0xBD, 0x73, 0xB3, 0xBC,
0x3D, 0xB6, 0x18, 0xE1, 0xDC, 0x07, 0x2C, 0xDA, 0x37, 0xA8, 0x55, 0xA0, 0xE6, 0x19, 0x2C, 0x12,
0xD0, 0x80, 0x36, 0x73, 0x14, 0xBA, 0x59, 0x97, 0xDC, 0x88, 0x83, 0x75, 0x65, 0x62, 0x4D, 0xA7,
0x74, 0x6A, 0x0F, 0xCB, 0x3E, 0x0F, 0x63, 0xF3, 0x4D, 0xFD, 0xD0, 0x99, 0xE4, 0xA7, 0xF4, 0xBB,
0x10, 0xE9, 0xF1, 0x57, 0x4B, 0xB5, 0xC4, 0x0A, 0x79, 0x5B, 0xFB, 0x9C, 0xF2, 0x01, 0x52, 0x9A,
0x00, 0xBE, 0x59, 0xD2, 0xE8, 0xE4, 0xB4, 0x46, 0xD5, 0xF4, 0xE0, 0xC1, 0x99, 0xDC, 0xE8, 0x88,
0x62, 0x34, 0x52, 0xE8, 0x61, 0xAC, 0xA1, 0x47, 0x05, 0xE7, 0x01, 0x2B, 0x92, 0x0B, 0xD2, 0x43,
0x9D, 0x57, 0xC3, 0x18, 0x18, 0x2D, 0x6F, 0xA6, 0xB8, 0x01, 0xC5, 0x2C, 0xD3, 0x9D, 0x5E, 0x1B,
0x54, 0x9C, 0x61, 0x32, 0x5C, 0x7D, 0xA4, 0xE4, 0x65, 0xA6, 0x7E, 0xB9, 0xD2, 0x39, 0x65, 0xB6,
0x8D, 0xB1, 0xC1, 0xFE, 0xB3, 0x67, 0x9B, 0x31, 0xD3, 0x45, 0xCD, 0xA5, 0x94, 0x3F, 0x7C, 0x4D,
0x75, 0x57, 0x36, 0x9A, 0x78, 0x23, 0x32, 0xE6, 0xD4, 0xFA, 0xA3, 0x15, 0x47, 0x53, 0x58, 0x08,
0xAE, 0xF0, 0xC2, 0x0A, 0x5E, 0x47, 0x9A, 0x83, 0x7D, 0x7E, 0x40, 0xA3, 0xDA, 0xA7, 0xE3, 0x19,
0x9A, 0xFE, 0x81, 0x3F, 0x87, 0xF9, 0x40, 0xA5, 0x96, 0xF3, 0x1E, 0x3D, 0xAF, 0xEC, 0x1F, 0x63,
0xAA, 0x89, 0xF5, 0x03, 0xD4, 0xD4, 0x3C, 0x47, 0xEA, 0x01, 0xA2, 0xFB, 0x58, 0x4A, 0x40, 0x86,
0x68, 0xE7, 0x30, 0x87, 0x43, 0xD8, 0xEE, 0xFF, 0x02, 0x01, 0x0B, 0xE7, 0xC7, 0xEF, 0x6F, 0x69
};
static const uint8_t BIG_NUM_TEST_CASE_3_RESULT[] = {
0x6C, 0x16, 0x45, 0x3E, 0x1F, 0xEB, 0x63, 0xDE, 0x06, 0x95, 0x62, 0xC7, 0x45, 0x89, 0xDA, 0xBB,
0xE4, 0x5B, 0x61, 0x2D, 0x80, 0x46, 0xFE, 0x5F, 0x48, 0x2C, 0xFC, 0x6A, 0x8F, 0xAC, 0x62, 0xB0,
0x36, 0x85, 0xD1, 0xB5, 0x0F, 0xE9, 0xAD, 0x6C, 0x2B, 0x57, 0x84, 0xB4, 0x12, 0x31, 0xF9, 0xA0,
0xF8, 0xB3, 0x27, 0xE9, 0xFD, 0x86, 0xE4, 0x29, 0x96, 0x31, 0x98, 0x80, 0x86, 0x31, 0xFE, 0x0F,
0xC5, 0xD0, 0x68, 0xC1, 0xA9, 0x88, 0x79, 0xD5, 0x28, 0xAA, 0x8C, 0x68, 0x19, 0x3D, 0xC4, 0x9D,
0xDC, 0x0E, 0xC4, 0x01, 0xEB, 0x8C, 0x12, 0xBA, 0x09, 0x56, 0x91, 0x30, 0x02, 0xC4, 0x8B, 0x88,
0xD5, 0x73, 0xA8, 0xB5, 0x36, 0x2D, 0x95, 0x63, 0x10, 0x26, 0xE3, 0x21, 0x52, 0x75, 0x99, 0xA1,
0xA6, 0x34, 0xA0, 0xA6, 0x9A, 0x65, 0x06, 0xA3, 0x03, 0x5C, 0x20, 0xB4, 0xE5, 0x34, 0xEF, 0x40,
0x03, 0xFE, 0x15, 0xB7, 0xBA, 0xF4, 0x0F, 0x30, 0x00, 0x15, 0xB2, 0x05, 0x17, 0x41, 0xE9, 0xD7,
0x26, 0xB8, 0x9B, 0x78, 0xAC, 0xE7, 0xF8, 0xC5, 0xA5, 0xCB, 0x08, 0x65, 0x12, 0x89, 0x00, 0x48,
0xE9, 0x70, 0x02, 0xFE, 0xDB, 0xE2, 0x2E, 0x6B, 0x16, 0x89, 0xD4, 0x71, 0x52, 0x9D, 0x2B, 0xE5,
0x6D, 0x01, 0x33, 0x53, 0xFD, 0x2A, 0x36, 0xD7, 0x27, 0x94, 0xC1, 0x42, 0x2D, 0x4D, 0x32, 0x46,
0x07, 0x04, 0x64, 0x16, 0xA2, 0x75, 0x50, 0x77, 0x1A, 0x5B, 0x4A, 0x43, 0x1A, 0x64, 0x78, 0x69,
0x63, 0xB6, 0x8E, 0xB3, 0x02, 0x44, 0x7A, 0xDC, 0xAC, 0x68, 0xF5, 0x8C, 0xE4, 0x8E, 0x94, 0xC9,
0xAE, 0x4A, 0x5C, 0x01, 0x04, 0xFF, 0xBB, 0x87, 0xD7, 0x4C, 0x62, 0xF6, 0x8F, 0x9F, 0xD7, 0x27,
0x99, 0xEF, 0x96, 0xAB, 0xB9, 0x9B, 0xB3, 0x6E, 0x92, 0xDB, 0x55, 0xFB, 0x46, 0x1C, 0x3B, 0x1F,
0xC2, 0xF9, 0xCC, 0x12, 0x23, 0x0F, 0x0D, 0xD7, 0xCE, 0x22, 0xFD, 0x99, 0xF4, 0x00, 0xED, 0xD0,
0xC4, 0xA6, 0xE1, 0xAA, 0x8B, 0x22, 0x80, 0x7F, 0x56, 0xF1, 0x10, 0x55, 0xAF, 0x9F, 0x5A, 0xC7,
0xA2, 0xCD, 0x48, 0xAA, 0x6D, 0x5E, 0x37, 0x8F, 0xA1, 0xC4, 0xA0, 0x3B, 0x78, 0xC8, 0xB6, 0xFD,
0x0A, 0x7E, 0xE1, 0x61, 0x63, 0xFC, 0x33, 0x6B, 0x50, 0xEB, 0xE7, 0x13, 0x6A, 0x84, 0xF7, 0x33,
0xB4, 0x38, 0x49, 0xF0, 0x31, 0x0A, 0x05, 0x7C, 0x10, 0xDF, 0xF6, 0x4B, 0x4F, 0x1F, 0x79, 0x96,
0xF1, 0x37, 0x7D, 0x80, 0x3B, 0xF1, 0x73, 0xB4, 0x4E, 0x62, 0x7D, 0x86, 0x7B, 0x43, 0x51, 0x06,
0x0B, 0xA0, 0xDC, 0xA7, 0xD5, 0x3D, 0xF2, 0xD7, 0xD3, 0x3C, 0x57, 0x9B, 0x64, 0xB1, 0xDE, 0x69,
0x90, 0x43, 0xEE, 0xD1, 0xC6, 0xAE, 0xDD, 0x67, 0x02, 0xDF, 0xA1, 0x84, 0x7B, 0x5D, 0xB3, 0xD8
};
static const uint8_t BIG_NUM_TEST_CASE_4_RESULT[] = {
0x31, 0xEA, 0x6E, 0x6B, 0x8C, 0xE0, 0x0F, 0x62, 0xA0, 0xDD, 0xE1, 0x3E, 0xAD, 0xB1, 0xA5, 0xA2,
0xC8, 0xDE, 0x3D, 0x61, 0x9D, 0x37, 0xE1, 0x66, 0xF7, 0xF5, 0xCC, 0x11, 0x17, 0xFD, 0x2A, 0xA2,
0x00, 0x36, 0xFC, 0x72, 0x74, 0x19, 0xC1, 0xA2, 0x0C, 0x35, 0x05, 0x34, 0xB0, 0x64, 0xBE, 0x7E,
0xD0, 0x96, 0xBF, 0xCA, 0x48, 0x92, 0xA9, 0x0B, 0x4A, 0x8C, 0x56, 0x3F, 0xE6, 0xDA, 0xFC, 0xE6,
0x66, 0xD4, 0xF8, 0x23, 0x3D, 0x6F, 0xC6, 0xC3, 0x21, 0x27, 0x10, 0x2A, 0x65, 0xE3, 0x15, 0x57,
0xC9, 0xE4, 0x35, 0xE4, 0xC1, 0x4D, 0x1C, 0x4D, 0x89, 0xF6, 0xF6, 0x67, 0x66, 0x6F, 0x79, 0x77,
0x64, 0xCA, 0x32, 0x52, 0x2A, 0xBC, 0xAE, 0xD3, 0xB4, 0x58, 0x9F, 0x47, 0xA5, 0x68, 0x94, 0x34,
0x97, 0x19, 0x9F, 0x48, 0x33, 0x4C, 0x2D, 0x94, 0xD3, 0xC0, 0xBD, 0x66, 0x07, 0x4A, 0xE0, 0x4E,
0x18, 0x08, 0xDE, 0x82, 0x1A, 0x26, 0xE7, 0x3F, 0x4E, 0x2F, 0x4D, 0x8B, 0x1B, 0x8F, 0x23, 0x81,
0x51, 0xCA, 0xDC, 0x9B, 0x6F, 0xCB, 0x49, 0x9B, 0x2E, 0x0C, 0x24, 0x8B, 0x08, 0x9E, 0xFF, 0x1C,
0xEA, 0x40, 0x59, 0xB3, 0xDD, 0xC6, 0x29, 0x1F, 0xBA, 0xA4, 0x2D, 0x9B, 0x5C, 0x78, 0x9F, 0x84,
0xC6, 0x3B, 0xFB, 0xCB, 0xA0, 0x9E, 0x07, 0xB9, 0x0D, 0x6A, 0x88, 0x91, 0x0C, 0x67, 0xFC, 0x1E,
0xAF, 0xA2, 0x54, 0x95, 0x7B, 0x50, 0xBD, 0x7D, 0x40, 0x3D, 0x3A, 0x58, 0x13, 0x14, 0x3C, 0x5C,
0xEE, 0xF6, 0x95, 0x9C, 0x0E, 0x65, 0xA7, 0x4F, 0x67, 0x91, 0xA0, 0xE8, 0xB7, 0xC0, 0xE8, 0xD7,
0x3E, 0x06, 0x35, 0xB6, 0x82, 0x65, 0x28, 0xA7, 0x29, 0xDA, 0xA6, 0xC1, 0xBD, 0xBA, 0x72, 0x41,
0xBE, 0x77, 0x4F, 0x30, 0xEB, 0x8E, 0xB1, 0x29, 0x71, 0x44, 0x6B, 0x3A, 0xD8, 0xEA, 0x87, 0x1A,
0x29, 0x41, 0xA4, 0x2B, 0x59, 0x41, 0x13, 0x4A, 0xC8, 0x60, 0xA1, 0x61, 0x13, 0x30, 0xA6, 0x4B,
0x4F, 0x6A, 0x7C, 0x82, 0xF3, 0x78, 0x20, 0x20, 0x52, 0x5B, 0xED, 0xD5, 0xF8, 0xBF, 0x03, 0x15,
0xD8, 0xBB, 0x71, 0x62, 0x88, 0x73, 0xEB, 0xFC, 0x32, 0x4E, 0x20, 0x17, 0xEA, 0xD6, 0xBA, 0xDF,
0x55, 0x26, 0x6C, 0x19, 0x7F, 0x7F, 0x62, 0x83, 0x43, 0x6C, 0xA9, 0xBD, 0x12, 0x2F, 0x6B, 0x8E,
0x55, 0x18, 0x84, 0xD6, 0x0E, 0x11, 0xA2, 0x78, 0x05, 0xD2, 0x4F, 0xEA, 0xB3, 0x61, 0x47, 0x9C,
0xB2, 0xCF, 0x5C, 0xE1, 0xFF, 0xC8, 0x54, 0x56, 0x93, 0x2F, 0x71, 0xE0, 0xF5, 0x85, 0xC8, 0x98,
0x0C, 0x0E, 0x02, 0x4A, 0x1C, 0xDB, 0xB6, 0x3F, 0x78, 0x4C, 0x4F, 0x1E, 0x54, 0xF9, 0x48, 0x2C,
0xB1, 0x6E, 0x4D, 0xD6, 0x25, 0xB3, 0x91, 0x5C, 0x2B, 0x9F, 0x3A, 0xFD, 0xEB, 0x75, 0x44, 0x17
};
static const BigNumTestCase BIG_NUM_TEST_CASES[] = {
// case 1:
{
.baseLength = ARRAY_SIZE(BASE_HEX_32),
.expLength = ARRAY_SIZE(EXP_HEX_1),
.prime = PRIME_HEX_256,
.base = BASE_HEX_32,
.exp = EXP_HEX_1,
.result = BIG_NUM_TEST_CASE_1_RESULT
},
// case 2:
{
.baseLength = ARRAY_SIZE(BASE_HEX_256),
.expLength = ARRAY_SIZE(EXP_HEX_28),
.prime = PRIME_HEX_256,
.base = BASE_HEX_256,
.exp = EXP_HEX_28,
.result = BIG_NUM_TEST_CASE_2_RESULT
},
// case 3:
{
.baseLength = ARRAY_SIZE(BASE_HEX_32),
.expLength = ARRAY_SIZE(EXP_HEX_1),
.prime = PRIME_HEX_384,
.base = BASE_HEX_32,
.exp = EXP_HEX_1,
.result = BIG_NUM_TEST_CASE_3_RESULT
},
// case 4:
{
.baseLength = ARRAY_SIZE(BASE_HEX_384),
.expLength = ARRAY_SIZE(EXP_HEX_32),
.prime = PRIME_HEX_384,
.base = BASE_HEX_384,
.exp = EXP_HEX_32,
.result = BIG_NUM_TEST_CASE_4_RESULT
}
};
enum {
SHA256_MSG_MAX_SIZE = 1024,
SHA256_TEST_TIMES = 100,
SHA256_TEST_MIN_LIMIT = 64, // test msg length form 1 to 64
GEN_RANDOM_MAX_SIZE = 1024,
GEN_RANDOM_TEST_TIMES = 100,
GEN_RANDOM_MIN_LIMIT = 64, // test generate random from 1 to 64
GEN_RANDOM_TEST_REPEAT_SIZE = 32,
GEN_RANDOM_TEST_REPEAT_TIMES = 100,
TEST_HMAC_KEY_LEN = 32, // equal to PSK_LEN PAKE_HMAC_KEY_LEN SHA256_LEN HC_SHA256_LEN
TEST_HMAC_ISALIAS_TRUE_MSG_LENGTH = 32, // msg length when isAlias is true ISO_KEY_ALIAS_LEN
HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN = 32,
HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN = 32,
#define GENERATE_RETURN_KEY_STR "hichain_return_key"
HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN = 16,
HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN = 16,
#define HICHAIN_RETURN_KEY "hichain_return_key"
HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_BASEKEY_LEN = 64,
HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_SALT_LEN = 32,
#define TMP_AUTH_KEY_FACTOR "hichain_tmp_auth_enc_key"
HKDF_PAKE_PSK_DERIVE_SECRET_ALIAS_OUTKEY_LEN = 32,
HKDF_ISO_PSK_DERIVE_SESSIONKEY_BASEKEY_LEN = 32,
HKDF_ISO_PSK_DERIVE_SESSIONKEY_SALT_LEN = 32,
#define GENERATE_SESSION_KEY_STR "hichain_iso_session_key"
HKDF_ISO_PSK_DERIVE_SESSIONKEY_OUTKEY_LEN = 32,
HKDF_NEW_PAKE_PSK_DERIVE_SECRET_BASEKEY_LEN = 32 * 2, // PAKE_PSK_LEN * BYTE_TO_HEX_OPER_LENGTH
HKDF_NEW_PAKE_PSK_DERIVE_SECRET_SALT_LEN = 16,
#define HICHAIN_SPEKE_BASE_INFO "hichain_speke_base_info"
HKDF_NEW_PAKE_PSK_DERIVE_SECRET_OUTKEY_LEN = 32,
HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_BASEKEY_LEN = SHA256_LEN,
HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_SALT_LEN = 16,
#define HICHAIN_SPEKE_SESSIONKEY_INFO "hichain_speke_sessionkey_info"
HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_OUTKEY_LEN = 32,
HKDF_PAKE_PSK_DERIVE_SECRET_BASEKEY_LEN = 32 * 2, // PAKE_PSK_LEN * BYTE_TO_HEX_OPER_LENGTH
HKDF_PAKE_PSK_DERIVE_SECRET_SALT_LEN = 16,
HKDF_PAKE_PSK_DERIVE_SECRET_OUTKEY_LEN = 32,
HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_SALT_LEN = 16,
HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_OUTKEY_LEN = 48,
IMPORT_SYMMETRIC_KEY_KEYALIAS_LEN_MAX = 32,
IMPORT_SYMMETRIC_KEY_KEYALIAS_LEN_MIN = 1,
IMPORT_SYMMETRIC_KEY_AUTHTOKEN_LEN = 32,
};
enum {
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_4 = 4,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_32 = 32,
// the meaning of 16 * 2 + 256 * 2 is
// length of randSelf + length of randPeer + length of authIdPeer + length of authIdSelf
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_RAND_AUTH_ID_SELF_PEER = 16 * 2 + 256 * 2,
// MAC FF:FF:FF:FF:FF:FF
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_MAC = 16 * 2 + 6 * 2,
// UDID FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_UDID = 16 * 2 + 16 * 2,
// IMEI 999999999999999
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_IMEI = 16 * 2 + 15 * 2,
};
static const uint32_t TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_ARRAY[] = {
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_4,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_32,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_RAND_AUTH_ID_SELF_PEER,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_MAC,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_UDID,
TEST_HMAC_ISALIAS_FALSE_MSG_LENGTH_IMEI,
};
static const char SHA256_EXAMPLE_MESSAGE[] = "hichain-sha256-example";
static const uint8_t SHA256_EXAMPLE_RESULT[SHA256_LEN] = {
0x53, 0x0a, 0x91, 0x67, 0xab, 0x1f, 0xf0, 0x18,
0xfa, 0x1b, 0x8e, 0xb1, 0x03, 0xcf, 0x1c, 0x8a,
0x1b, 0x7b, 0x05, 0x0d, 0xfb, 0x2d, 0xe0, 0x60,
0x19, 0x64, 0x50, 0x76, 0x69, 0xd6, 0xc5, 0x79,
};
static const char HMAC_EXAMPLE_MESSAGE[] = "hichain hmac message example";
static const uint8_t HMAC_EXAMPLE_KEY[TEST_HMAC_KEY_LEN] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
};
static const uint8_t HMAC_EXAMPLE_RESULT[HMAC_LEN] = {
0x99, 0xbe, 0xaf, 0x20, 0x84, 0xeb, 0xae, 0x5d,
0xc4, 0x1d, 0x62, 0x19, 0xcb, 0x52, 0xe1, 0x43,
0xa1, 0xf3, 0x74, 0xf8, 0x33, 0x61, 0xe0, 0x82,
0x61, 0xfe, 0x19, 0x09, 0x1f, 0xac, 0x9d, 0xb9,
};
// Hashing type: SHA-256
static const char HKDF_EXAMPLE_MESSAGE[] = "hello hichain";
static const uint8_t HKDF_EXAMPLE_SALT[] = {
0x01, 0x23, 0x45, 0x67, 0x89,
};
static const char HKDF_EXAMPLE_INFO[] = "hichain hkdf info";
static const uint8_t HKDF_EXAMPLE_RESULT_KEY[] = {
0x4e, 0xc8, 0xf7, 0x6a, 0x03, 0xe9, 0x18, 0xbf,
0xaa, 0xaa, 0x22, 0xc1, 0xd7, 0x7e, 0x0a, 0xa8,
};
static const char hkdfCaseNameIsoSessionKeyDeriveReturnKey[] =
"iso sessionkey derive returnkey";
static const char hkdfCaseNamePakeSessionKeyDeriveReturnKey[] =
"pake sessionkey derive returnkey";
static const char hkdfCaseNameIsoPskDeriveSessionKey[] =
"iso psk derive sessionkey";
static const char hkdfCaseNameNewPakePskDeriveSecret[] =
"new pake psk derive secret";
static const char hkdfCaseNameNewPakeSharedSecretDeriveSessionKey[] =
"new pake sharedSecret derive sessionkey";
static const char hkdfCaseNamePakePskDeriveSecretIsAliasFalse[] =
"pake psk derive secret isAlias false";
static const char hkdfCaseNamePakeSharedSecretDeriveUnionKey[] =
"pake sharedSecret derive unionkey";
enum {
HKDF_OUT_KEY_LENGTH_RANGE_16 = 16,
HKDF_OUT_KEY_LENGTH_RANGE_32 = 32,
HKDF_OUT_KEY_LENGTH_RANGE_64 = 64,
HKDF_OUT_KEY_LENGTH_RANGE_128 = 128,
HKDF_OUT_KEY_LENGTH_RANGE_256 = 256,
HKDF_OUT_KEY_LENGTH_RANGE_512 = 512,
HKDF_OUT_KEY_LENGTH_RANGE_1024 = 1024,
HKDF_CASE_PAKE_SHARED_SECRET_DERIVE_UNION_KEY_BASE_KEY_LENGTH_ED25519 = 32,
HKDF_CASE_PAKE_SHARED_SECRET_DERIVE_UNION_KEY_BASE_KEY_LENGTH_P256 = 64,
};
static const struct HkdfTestCase {
const char *caseName;
uint32_t baseKeyLength;
uint32_t saltLength;
const char *keyInfo;
uint32_t outKeyLength;
} g_hkdfTestCase[] = {
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_16,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_32,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_64,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_128,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_256,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_512,
},
{
.caseName = hkdfCaseNameIsoSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = GENERATE_RETURN_KEY_STR,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_1024,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_16,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_32,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_64,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_128,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_256,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_512,
},
{
.caseName = hkdfCaseNamePakeSessionKeyDeriveReturnKey,
.baseKeyLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_BASEKEY_LEN,
.saltLength = HKDF_PAKE_SESSIONKEY_DERIVE_RETURNKEY_SALT_LEN,
.keyInfo = HICHAIN_RETURN_KEY,
.outKeyLength = HKDF_OUT_KEY_LENGTH_RANGE_1024,
},
{
.caseName = hkdfCaseNameIsoPskDeriveSessionKey,
.baseKeyLength = HKDF_ISO_PSK_DERIVE_SESSIONKEY_BASEKEY_LEN,
.saltLength = HKDF_ISO_PSK_DERIVE_SESSIONKEY_SALT_LEN,
.keyInfo = GENERATE_SESSION_KEY_STR,
.outKeyLength = HKDF_ISO_PSK_DERIVE_SESSIONKEY_OUTKEY_LEN,
},
{
.caseName = hkdfCaseNameNewPakePskDeriveSecret,
.baseKeyLength = HKDF_NEW_PAKE_PSK_DERIVE_SECRET_BASEKEY_LEN,
.saltLength = HKDF_NEW_PAKE_PSK_DERIVE_SECRET_SALT_LEN,
.keyInfo = HICHAIN_SPEKE_BASE_INFO,
.outKeyLength = HKDF_NEW_PAKE_PSK_DERIVE_SECRET_OUTKEY_LEN,
},
{
.caseName = hkdfCaseNameNewPakeSharedSecretDeriveSessionKey,
.baseKeyLength = HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_BASEKEY_LEN,
.saltLength = HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_SALT_LEN,
.keyInfo = HICHAIN_SPEKE_SESSIONKEY_INFO,
.outKeyLength = HKDF_NEW_PAKE_SHAREDSECRET_DERIVE_SESSIONKEY_OUTKEY_LEN,
},
{
.caseName = hkdfCaseNamePakePskDeriveSecretIsAliasFalse,
.baseKeyLength = HKDF_PAKE_PSK_DERIVE_SECRET_BASEKEY_LEN,
.saltLength = HKDF_PAKE_PSK_DERIVE_SECRET_SALT_LEN,
.keyInfo = HICHAIN_SPEKE_BASE_INFO,
.outKeyLength = HKDF_PAKE_PSK_DERIVE_SECRET_OUTKEY_LEN,
},
{
.caseName = hkdfCaseNamePakeSharedSecretDeriveUnionKey,
.baseKeyLength = HKDF_CASE_PAKE_SHARED_SECRET_DERIVE_UNION_KEY_BASE_KEY_LENGTH_ED25519,
.saltLength = HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_SALT_LEN,
.keyInfo = HICHAIN_SPEKE_SESSIONKEY_INFO,
.outKeyLength = HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_OUTKEY_LEN,
},
{
.caseName = hkdfCaseNamePakeSharedSecretDeriveUnionKey,
.baseKeyLength = HKDF_CASE_PAKE_SHARED_SECRET_DERIVE_UNION_KEY_BASE_KEY_LENGTH_P256,
.saltLength = HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_SALT_LEN,
.keyInfo = HICHAIN_SPEKE_SESSIONKEY_INFO,
.outKeyLength = HKDF_PAKE_SHAREDSECRET_DERIVE_UNIONKEY_OUTKEY_LEN,
},
};
enum {
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_KEY_PAIR_KEY_ALIAS_LENGTH = 32,
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_SHARED_KEY_LENGTH = 32,
TEST_COMPUTE_HKDF_WITH_KEY_ALIAS_TRUE_AUTH_ID_LENGTH = 32,
};
enum {
TEST_IMPORT_SYMMETRIC_KEY_AUTH_ID_LENGTH_32 = 32,
TEST_IMPORT_SYMMETRIC_KEY_AUTH_ID_LENGTH_64 = 64,
};
enum {
TEST_GENERATE_KEY_PAIR_WITH_STORAGE_AUTH_ID_LENGTH = 32,
};
// TestExportImportSignVerify
enum {
TEST_EX_IM_SN_VF_EXTRA_INFO_AUTH_ID_LENGTH = 32,
TEST_EX_IM_SN_VF_KEY_ALIAS_LENGTH = 64,
TEST_EX_IM_SN_VF_KEY_LENGTH = 32,
TEST_EX_IM_SN_VF_OUT_PUB_KEY_LENGTH = 32,
TEST_SIGN_MESSAGE_LENGTH_1 = 1,
TEST_SIGN_MESSAGE_LENGTH_2 = 2,
TEST_SIGN_MESSAGE_LENGTH_4 = 4,
TEST_SIGN_MESSAGE_LENGTH_8 = 8,
TEST_SIGN_MESSAGE_LENGTH_16 = 16,
TEST_SIGN_MESSAGE_LENGTH_32 = 32,
TEST_SIGN_MESSAGE_LENGTH_64 = 64,
TEST_SIGN_MESSAGE_LENGTH_128 = 128,
TEST_SIGN_MESSAGE_LENGTH_256 = 256,
TEST_SIGN_MESSAGE_LENGTH_512 = 512,
TEST_SIGN_MESSAGE_LENGTH_1024 = 1024,
TEST_SIGN_SIGNATURE_LENGTH = 64,
};
static const uint32_t TEST_SIGN_MSG_LENGTHES[] = {
TEST_SIGN_MESSAGE_LENGTH_1,
TEST_SIGN_MESSAGE_LENGTH_2,
TEST_SIGN_MESSAGE_LENGTH_4,
TEST_SIGN_MESSAGE_LENGTH_8,
TEST_SIGN_MESSAGE_LENGTH_16,
TEST_SIGN_MESSAGE_LENGTH_32,
TEST_SIGN_MESSAGE_LENGTH_64,
TEST_SIGN_MESSAGE_LENGTH_128,
TEST_SIGN_MESSAGE_LENGTH_256,
TEST_SIGN_MESSAGE_LENGTH_512,
TEST_SIGN_MESSAGE_LENGTH_1024,
};
static const char TEST_EXPORT_DIFFERENT_ERROR_MESSAGE[] = "two different public keys are exported";
// g_largePrimeNumberHex384 and g_largePrimeNumberHex256 are from
// base/security/device_auth/services/protocol/src/pake_protocol/pake_protocol_dl_common/pake_protocol_dl_common.c
static const char LARGE_PRIME_NUM_HEX_384[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"
"9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
"3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33"
"A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864"
"D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2"
"08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
static const char LARGE_PRIME_NUM_HEX_256[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"
"020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"
"4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"
"9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
"3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
enum {
PAKE_DL_PRIME_LEN_256 = 256,
PAKE_DL_PRIME_LEN_384 = 384,
};
enum {
TEST_CHECK_DL_VALUE_ONE = 1,
TEST_CHECK_DL_VALUE_TWO = 2,
};
enum {
TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL = 32,
TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF = TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL / 2, // 16
};
static const uint8_t TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_FULL[TEST_BIG_NUM_COMPARE_NUM_LENGTH_FULL] = {
/* */ /* */
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89,
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89,
};
static const uint8_t TEST_BIG_NUM_COMPARE_NUM_EXAMPLE_HALF[TEST_BIG_NUM_COMPARE_NUM_LENGTH_HALF] = {
/* */ /* */
0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89,
};
#ifdef __cplusplus
}
#endif
#endif // HC_ALG_TEST_CASE_H
\ No newline at end of file
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_condition_test.h"
#include <hctest.h>
#include <parameter.h>
#include <pthread.h>
#include <securec.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
pthread_cond_t *cond;
pthread_mutex_t *mutex;
sem_t *sem;
int32_t semState;
int32_t condState;
} ThreadTestArgs;
#define REQUIRED_SEM_DEFAULT_COUNT 20
#define REQUIRED_SEM_COUNT 20
#define REQUIRED_ATTR_DEFAULT_COUNT 20
#define REQUIRED_ATTR_COUNT 20
/* sem_wait thread test */
static void *ThreadSemWait(void *args)
{
LOGI("into ThreadSemWait");
int res;
ThreadTestArgs *semArgs = (ThreadTestArgs *)args;
TEST_ASSERT_NOT_NULL(semArgs->sem);
TEST_ASSERT_NOT_EQUAL(0, semArgs->semState);
RUN_AND_PRINT_ELAPSED_TIME(res, sem_wait((sem_t *)semArgs->sem));
// after sem_post
LOGI("sem_wait result = %d", res);
TEST_ASSERT_EQUAL(0, res);
semArgs->semState = 0;
return args;
}
/* sem_post thread test */
static void *ThreadSemPost(void *args)
{
LOGI("into ThreadSemPost");
int res;
ThreadTestArgs *semArgs = (ThreadTestArgs *)args;
TEST_ASSERT_NOT_NULL(semArgs->sem);
RUN_AND_PRINT_ELAPSED_TIME(res, sem_post((sem_t *)semArgs->sem));
LOGI("sem_post result = %d", res);
TEST_ASSERT_EQUAL(0, res);
return args;
}
/* pthread_cond_wait thread test */
static void *ThreadCondWait(void *args)
{
LOGI("into ThreadCondWait");
int res;
ThreadTestArgs *condArgs = (ThreadTestArgs *)args;
TEST_ASSERT_NOT_NULL(condArgs->cond);
TEST_ASSERT_NOT_NULL(condArgs->mutex);
TEST_ASSERT_NOT_EQUAL(0, condArgs->condState);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_wait(condArgs->cond, condArgs->mutex));
// after pthread_cond_signal
LOGI("pthread_cond_wait result = %d", res);
TEST_ASSERT_EQUAL(0, res);
condArgs->condState = 0;
return args;
}
/* pthread_cond_signal thread test */
static void *ThreadCondSignal(void *args)
{
LOGI("into ThreadCondSignal");
int res;
ThreadTestArgs *testArgs = (ThreadTestArgs *)args;
TEST_ASSERT_NOT_NULL(testArgs->cond);
TEST_ASSERT_NOT_NULL(testArgs->mutex);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_signal(testArgs->cond));
LOGI("pthread_cond_signal result = %d", res);
return args;
}
/* sem_init and sem_destroy test */
static void TestSemInit(int count)
{
int res;
sem_t sem[count];
res = memset_s(sem, sizeof(sem), 0, sizeof(sem));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem[i], 0, 0));
LOGI("sem_init result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_destroy(&sem[i]));
LOGI("sem_destroy result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
}
/* sem_wait test */
static void TestSemWait(int count)
{
int res;
pthread_attr_t attr;
pthread_t threads[count];
res = memset_s(threads, sizeof(threads), 0, sizeof(threads));
TEST_ASSERT_EQUAL(0, res);
sem_t sem = {0};
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&attr));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem, 0, 0));
LOGI("sem_init result = %d", res);
ThreadTestArgs args = {
.sem = &sem,
.semState = -1,
};
TEST_ASSERT_EQUAL(0, res);
/* create phread to wait */
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, ThreadSemWait, &args));
LOGI("create sem_wait thread result = %d", res);
int sleepSeconds = rand() % (WAIT_IN_SEM_SECONDS_MAX - WAIT_IN_SEM_SECONDS_MIN) + WAIT_IN_SEM_SECONDS_MIN;
sleep(sleepSeconds);
/* sleep seconds then create thread to post */
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, ThreadSemPost, &args));
LOGI("create sem_post thread result = %d", res);
TEST_ASSERT_EQUAL(0, res);
sleep(sleepSeconds);
TEST_ASSERT_EQUAL(0, args.semState);
}
}
/* sem_post test */
static void TestSemPost(int count)
{
int res;
sem_t sem[count];
res = memset_s(sem, sizeof(sem), 0, sizeof(sem));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_init(&sem[i], 0, 0));
LOGI("sem_init int TestSemPost result = %d", res);
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, sem_post(&sem[i]));
LOGI("sem_post result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_post(&sem[i]));
LOGI("sem_post result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, sem_destroy(&sem[i]));
LOGI("sem_destroy in TestSemPost result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
}
/* pthread_condattr_init and pthread_condattr_destroy test */
static void TestAttrConInit(int count)
{
int res;
pthread_condattr_t attr[count];
res = memset_s(attr, sizeof(attr), 0, sizeof(attr));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr[i]));
LOGI("pthread_condattr_init result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_destroy(&attr[i]));
LOGI("pthread_condattr_destroy result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
}
/* pthread_cond_init and pthread_cond_destroy test */
static void TestConInit(int count)
{
int res;
pthread_condattr_t attr = {0};
pthread_cond_t cond[count];
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr));
LOGI("pthread_condattr_init in TestConInit result = %d", res);
TEST_ASSERT_EQUAL(0, res);
res = memset_s(cond, sizeof(cond), 0, sizeof(cond));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond[i], &attr));
LOGI("pthread_cond_init result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_destroy(&cond[i]));
LOGI("pthread_cond_destroy result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
}
/* pthread_cond_wait and pthread_cond_signal test */
static void TestConWait(int count)
{
int res;
pthread_attr_t pthreadAttr;
pthread_condattr_t attr = {0};
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_t threads[count];
res = memset_s(&mutex, sizeof(mutex), 0, sizeof(mutex));
TEST_ASSERT_EQUAL(0, res);
res = memset_s(threads, sizeof(threads), 0, sizeof(threads));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&pthreadAttr));
TEST_ASSERT_EQUAL(0, res);
// init attr and cond and mutex
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_condattr_init(&attr));
LOGI("pthread_condattr_init in TestConWait result = %d", res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond, &attr));
LOGI("pthread_cond_init in TestConWait result = %d", res);
for (int i = 0; i < count; ++i) {
ThreadTestArgs args = {
.cond = &cond,
.mutex = &mutex,
.condState = -1,
};
/* create phread to wait */
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &pthreadAttr, ThreadCondWait, &args));
LOGI("create pthread_cond_wait thread result = %d", res);
TEST_ASSERT_EQUAL(0, res);
int sleepSeconds = rand() % (WAIT_IN_SEM_SECONDS_MAX - WAIT_IN_SEM_SECONDS_MIN) + WAIT_IN_SEM_SECONDS_MIN;
sleep(sleepSeconds);
/* sleep seconds then create thread to send signal */
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &pthreadAttr, ThreadCondSignal, &args));
LOGI("create pthread_cond_signal thread result = %d", res);
TEST_ASSERT_EQUAL(0, res);
sleep(sleepSeconds);
TEST_ASSERT_EQUAL(0, args.condState);
}
}
/* pthread_cond_signal test */
static void TestConSignal(int count)
{
int res;
pthread_condattr_t attr = {0};
pthread_cond_t cond;
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_init(&cond, &attr));
LOGI("pthread_cond_init in TestConWait result = %d", res);
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_cond_signal(&cond));
LOGI("pthread_cond_signal result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
}
/* test semaphore with sem series */
void TestHcSemCondition(void)
{
TestSemInit(REQUIRED_SEM_DEFAULT_COUNT);
TestSemPost(REQUIRED_SEM_DEFAULT_COUNT);
TestSemWait(REQUIRED_SEM_DEFAULT_COUNT);
}
/* test semaphore with phread cond */
void TestHcPthreadCondition(void)
{
TestConWait(REQUIRED_ATTR_DEFAULT_COUNT);
TestAttrConInit(REQUIRED_ATTR_DEFAULT_COUNT);
TestConInit(REQUIRED_ATTR_DEFAULT_COUNT);
TestConSignal(REQUIRED_ATTR_DEFAULT_COUNT);
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_CONDITION_TEST_H
#define HC_CONDITION_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcSemCondition(void);
void TestHcPthreadCondition(void);
#ifdef __cplusplus
}
#endif
enum {
WAIT_IN_SEM_SECONDS_MIN = 1,
WAIT_IN_SEM_SECONDS_MAX = 2,
};
#endif // HC_CONDITION_TEST_H
\ No newline at end of file
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_dev_info_test.h"
#include <hctest.h>
#include <parameter.h>
#include <pthread.h>
#include <securec.h>
#include <stdlib.h>
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_INPUT_UDID_LEN 200
enum {
INPUT_UDID_LEN = 65,
TEST_UDID_TIMES = 20,
};
static void TestGetDevUdid(char *udid, int len)
{
int res;
int zeroCount = 0;
res = memset_s(udid, MAX_INPUT_UDID_LEN, 0, MAX_INPUT_UDID_LEN);
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, GetDevUdid(udid, len));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < len; ++i) {
if (udid[i] == 0) {
++zeroCount;
}
}
TEST_ASSERT_NOT_EQUAL_MESSAGE(len, zeroCount, "invalid all zero udid");
}
void TestHcGetUdid(void)
{
int res;
char udid[MAX_INPUT_UDID_LEN] = {0};
int udidLen;
LOGI("check rand size udid");
for (int i = 0; i < TEST_UDID_TIMES; ++i) {
udidLen = rand() % (MAX_INPUT_UDID_LEN - INPUT_UDID_LEN) + INPUT_UDID_LEN;
LOGI("rand udidLen = %d", udidLen);
res = memset_s(udid, sizeof(udid), 0, sizeof(udid));
TEST_ASSERT_EQUAL(0, res);
TestGetDevUdid(udid, udidLen);
LOGI("udid = \"%s\"", udid);
}
LOGI("check min size udid");
res = memset_s(udid, sizeof(udid), 0, sizeof(udid));
TEST_ASSERT_EQUAL(0, res);
TestGetDevUdid(udid, INPUT_UDID_LEN);
LOGI("udid = \"%s\"", udid);
LOGI("check max size udid");
res = memset_s(udid, sizeof(udid), 0, sizeof(udid));
TEST_ASSERT_EQUAL(0, res);
TestGetDevUdid(udid, MAX_INPUT_UDID_LEN);
LOGI("udid = \"%s\"", udid);
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_DEV_INFO_TEST_H
#define HC_DEV_INFO_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcGetUdid(void);
#ifdef __cplusplus
}
#endif
#endif // HC_DEV_INFO_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_file_common.h"
#include <hctest.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
char *GenerateTestingText(int size)
{
TEST_ASSERT_LESS_OR_EQUAL(TEN_KILOBYTE, size);
char *text = (char *)malloc(size + 1);
if (text == NULL) {
return NULL;
}
for (int i = 0; i < size; i++) {
text[i] = rand() % (ASCII_END - ASCII_START) + ASCII_START;
}
text[size] = 0;
return text;
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_FILE_COMMON_H
#define HC_FILE_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#define TEST_FILE_NAME "test"
#define TEST_FILE_DIR "/testDir"
#define DEFAULT_FILE_PERMISSION 0644
#define ASCII_START 32
#define ASCII_END 126
#define ONE_BYTE 1
#define HALF_KILOBYTE 512
#define ONE_KILOBYTE 1024
#define TEN_KILOBYTE 10240
#define TEST_FILE_SIZE_LIST_LEN 4
static const int testFileSizeList[TEST_FILE_SIZE_LIST_LEN] = {
ONE_BYTE,
HALF_KILOBYTE,
ONE_KILOBYTE,
TEN_KILOBYTE
};
char *GenerateTestingText(int size);
#ifdef __cplusplus
}
#endif
#endif // HC_FILE_COMMON_H
\ No newline at end of file
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_file_f_test.h"
#include <errno.h>
#include <fcntl.h>
#include <hctest.h>
#include <securec.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include "hc_file_common.h"
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#if F_API_IMPLEMENTED
static void ReadFile(char *buffer, FILE *file, int size)
{
int total = 0;
while (total < size) {
int readCount = fread(buffer + total, 1, size - total, file);
TEST_ASSERT_GREATER_OR_EQUAL(0, readCount);
TEST_ASSERT_LESS_OR_EQUAL(size - total, readCount);
total += readCount;
if (readCount <= 0) {
break;
}
}
}
static void WriteFile(const char *buffer, FILE *file, int size)
{
int total = 0;
while (total < size) {
int writeCount = fwrite(buffer + total, 1, size - total, file);
TEST_ASSERT_GREATER_OR_EQUAL(0, writeCount);
TEST_ASSERT_LESS_OR_EQUAL(size - total, writeCount);
total += writeCount;
if (writeCount <= 0) {
break;
}
}
}
static void TestHcFileFopenAndFclose(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to open file: %s", fileName);
FILE *file;
RUN_AND_PRINT_ELAPSED_TIME(file, fopen(fileName, "w+"));
TEST_ASSERT_NOT_NULL(file);
int ret;
LOGI("begin to close file: %s", fileName);
RUN_AND_PRINT_ELAPSED_TIME(ret, fclose(file));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileFreadAndFwrite(void)
{
const char *fileName = TEST_FILE_NAME;
for (int i = 0; i < TEST_FILE_SIZE_LIST_LEN; i++) {
FILE *file = fopen(fileName, "w+");
TEST_ASSERT_NOT_NULL(file);
int size = testFileSizeList[i];
LOGI("begin to write file [%s] for size: %d", fileName, size);
char *writeBuffer = GenerateTestingText(size);
TEST_ASSERT_NOT_NULL(writeBuffer);
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(WriteFile(writeBuffer, file, size));
TEST_ASSERT_EQUAL(0, fseek(file, 0, SEEK_END));
const int fileSize = ftell(file);
TEST_ASSERT_EQUAL(size, fileSize);
TEST_ASSERT_EQUAL(0, fseek(file, 0, SEEK_SET));
LOGI("begin to read file [%s] for size: %d", fileName, fileSize);
TEST_ASSERT_LESS_OR_EQUAL(TEN_KILOBYTE, fileSize);
char *readBuffer = (char *)malloc(fileSize + 1);
TEST_ASSERT_NOT_NULL(readBuffer);
TEST_ASSERT_EQUAL(0, memset_s(readBuffer, fileSize + 1, 0, fileSize + 1));
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(ReadFile(readBuffer, file, fileSize));
TEST_ASSERT_EQUAL_STRING(writeBuffer, readBuffer);
free(readBuffer);
free(writeBuffer);
TEST_ASSERT_EQUAL(0, fclose(file));
sleep(1);
}
}
static void TestHcFileFseekAndFtell(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to count file size");
FILE *file = fopen(fileName, "rb");
TEST_ASSERT_NOT_NULL(file);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, fseek(file, 0, SEEK_END));
TEST_ASSERT_EQUAL(0, ret);
int size;
RUN_AND_PRINT_ELAPSED_TIME(size, ftell(file));
TEST_ASSERT_EQUAL(TEN_KILOBYTE, size);
TEST_ASSERT_EQUAL(0, fseek(file, 0, SEEK_SET));
LOGI("the file size is: %d", size);
TEST_ASSERT_EQUAL(0, fclose(file));
RUN_AND_PRINT_ELAPSED_TIME(ret, unlink(fileName));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileMkdir(void)
{
#if MKDIR_IMPLEMENTED
const char *dir = TEST_FILE_DIR;
LOGI("begin to make directory: %s", dir);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, mkdir(dir, DEFAULT_FILE_PERMISSION));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(-1, mkdir(dir, DEFAULT_FILE_PERMISSION));
TEST_ASSERT_EQUAL(0, rmdir(dir));
#endif
}
static void TestHcFileStat(void)
{
#if STAT_IMPLEMENTED
const char *fileName = TEST_FILE_NAME;
LOGI("begin to check [%s] state", fileName);
FILE *file = fopen(fileName, "w+");
TEST_ASSERT_NOT_NULL(file);
TEST_ASSERT_EQUAL(0, fclose(file));
struct stat fileStat;
int ret;
ret = memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
TEST_ASSERT_EQUAL(0, ret);
RUN_AND_PRINT_ELAPSED_TIME(ret, stat(fileName, &fileStat));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(0, unlink(fileName));
ret = memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(-1, stat(fileName, &fileStat));
TEST_ASSERT_EQUAL(ENOENT, errno);
#endif
}
static void TestHcFileRemove(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to remove file: %s", fileName);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, unlink(fileName));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileAccess(void)
{
#if ACCESS_IMPLEMENTED
const char *fileName = TEST_FILE_NAME;
LOGI("begin to check access of [%s]", fileName);
FILE *file = fopen(fileName, "w+");
TEST_ASSERT_NOT_NULL(file);
TEST_ASSERT_EQUAL(0, fclose(file));
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, access(fileName, F_OK));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(0, unlink(fileName));
TEST_ASSERT_EQUAL(-1, access(fileName, F_OK));
#endif
}
void TestHcFileFApi(void)
{
LOGI("test opening and closing file");
TestHcFileFopenAndFclose();
LOGI("test removing file");
TestHcFileRemove();
LOGI("test reading and writing file");
TestHcFileFreadAndFwrite();
LOGI("test counting file size");
TestHcFileFseekAndFtell();
LOGI("test making directory");
TestHcFileMkdir();
LOGI("test getting file state");
TestHcFileStat();
LOGI("test accessing a file");
TestHcFileAccess();
}
#else // F_API_IMPLEMENTED
void TestHcFileFApi(void)
{
LOGE("no F_API_IMPLEMENTED, do not test fopen series!");
}
#endif // F_API_IMPLEMENTED
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_FILE_F_TEST_H
#define HC_FILE_F_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcFileFApi(void);
#ifdef __cplusplus
}
#endif
#endif // HC_FILE_F_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_file_iot_flash_test.h"
#include <hctest.h>
#include <iot_errno.h>
#include <iot_flash.h>
#include <securec.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#if FLASH_START_ADDRESS_HICHAIN
#define FLASH_SIZE_4_K 4096
#define TOTAL_STORAGE_SIZE FLASH_SIZE_4_K // 4K Bytes
#define GROUP_OFFSET_ADDR 0x0100 // sizeof(struct FlashHeader)
#define TCIS_OFFSET_ADDR 0x0BC0
#define KEY_OFFSET_ADDR 0x0DC0
#define PART2_OFFSET_ADDR 0x0EC0
#define PART3_OFFSET_ADDR 0x0F00
#define SALT_OFFSET_ADDR 0x0F40
#define MK_OFFSET_ADDR 0x0F80
#define MAGIC_NUM 0x07DECADE
#define DEFAULT_VERSION 0x01
typedef enum FileIdEnumT {
FILE_ID_GROUP = 0,
FILE_ID_TCIS_DATA,
FILE_ID_KEYCONTENT,
FILE_ID_PART2,
FILE_ID_PART3,
FILE_ID_SALT,
FILE_ID_MK,
FILE_ID_LAST,
} FileIdEnum;
static uint32_t g_startAddr = FLASH_START_ADDRESS_HICHAIN;
static const struct FlashHeader {
struct VersionHeader {
uint64_t magic;
uint16_t version;
uint8_t reserved[54]; // 54: Reserved bytes for expansion
} versionHeader;
struct FileHeader {
uint32_t start;
uint32_t size;
uint32_t end;
} fileHeaders[FILE_ID_LAST];
uint8_t reserved[108]; // 108: Reserved bytes for expansion
} g_flashHeader = {
.versionHeader = {
.magic = MAGIC_NUM,
.version = DEFAULT_VERSION,
},
.fileHeaders[FILE_ID_GROUP] = {
.start = GROUP_OFFSET_ADDR,
.size = TCIS_OFFSET_ADDR - GROUP_OFFSET_ADDR,
.end = TCIS_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_TCIS_DATA] = {
.start = TCIS_OFFSET_ADDR,
.size = KEY_OFFSET_ADDR - TCIS_OFFSET_ADDR,
.end = KEY_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_KEYCONTENT] = {
.start = KEY_OFFSET_ADDR,
.size = PART2_OFFSET_ADDR - KEY_OFFSET_ADDR,
.end = PART2_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_PART2] = {
.start = PART2_OFFSET_ADDR,
.size = PART3_OFFSET_ADDR - PART2_OFFSET_ADDR,
.end = PART3_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_PART3] = {
.start = PART3_OFFSET_ADDR,
.size = SALT_OFFSET_ADDR - PART3_OFFSET_ADDR,
.end = SALT_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_SALT] = {
.start = SALT_OFFSET_ADDR,
.size = MK_OFFSET_ADDR - SALT_OFFSET_ADDR,
.end = MK_OFFSET_ADDR,
},
.fileHeaders[FILE_ID_MK] = {
.start = MK_OFFSET_ADDR,
.size = TOTAL_STORAGE_SIZE - MK_OFFSET_ADDR,
.end = TOTAL_STORAGE_SIZE,
},
};
enum {
RANDOM_READ_TIMES = 20,
};
static void ReadFlash(uint32_t offset, uint8_t *buffer, uint32_t size)
{
int res;
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashInit());
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashRead(g_startAddr + offset, size, buffer));
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashDeinit());
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
}
static void WriteFlash(uint32_t offset, const uint8_t *buffer, uint32_t size)
{
int res;
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashInit());
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
LOGI("begin write, g_startAddr + offset = %lu, size = %lu, buffer = %p",
(unsigned long)(g_startAddr + offset), (unsigned long)(size), buffer);
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashWrite(g_startAddr + offset, size, buffer, true));
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
RUN_AND_PRINT_ELAPSED_TIME(res, IoTFlashDeinit());
TEST_ASSERT_EQUAL(IOT_SUCCESS, res);
}
static void TestIotFlashWrite(const uint8_t *totalDataContent, uint32_t sz)
{
LOGI("begin to test writing flash");
WriteFlash(0, totalDataContent, sz);
LOGI("test writing flash done");
}
static void TestIotFlashReadWholeBlock(
uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
{
int res = memset_s(totalData, sz, 0, sz);
TEST_ASSERT_EQUAL(EOK, res);
LOGI("begin to test read whole flash");
ReadFlash(0, totalData, sz);
LOGI("test reading whole flash done");
TEST_ASSERT_EQUAL(sz, contentSz);
TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent, sz);
}
static void TestIotFlashReadFlashHeader(
struct FlashHeader *flashHeader, const struct FlashHeader *flashHeaderCompare)
{
int res = memset_s(flashHeader, sizeof(*flashHeader), 0, sizeof(*flashHeader));
TEST_ASSERT_EQUAL(EOK, res);
LOGI("begin reading header");
ReadFlash(0, (uint8_t *)flashHeader, sizeof(struct FlashHeader));
LOGI("end reading header");
TEST_ASSERT_EQUAL_HEX8_ARRAY((const uint8_t *)flashHeader, (const uint8_t *)flashHeaderCompare,
sizeof(struct FlashHeader));
}
static void TestIotFlashReadSmallFiles(
uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
{
LOGI("begin reading small files");
TEST_ASSERT_EQUAL((uint32_t)(TOTAL_STORAGE_SIZE), contentSz);
int res;
for (int i = 0; i < FILE_ID_LAST; ++i) {
LOGI("test flash file %d/%d", i, FILE_ID_LAST);
res = memset_s(totalData, sz, 0, sz);
TEST_ASSERT_EQUAL(EOK, res);
LOGI("test read from %lu, size %lu", (unsigned long)(g_flashHeader.fileHeaders[i].start),
(unsigned long)(g_flashHeader.fileHeaders[i].size));
ReadFlash(g_flashHeader.fileHeaders[i].start, totalData, g_flashHeader.fileHeaders[i].size);
TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + g_flashHeader.fileHeaders[i].start,
g_flashHeader.fileHeaders[i].size);
}
LOGI("end reading small files");
}
static void TestIotFlashReadRandom(uint8_t *totalData, uint32_t sz, const uint8_t *totalDataContent, uint32_t contentSz)
{
LOGI("begin reading random bytes");
TEST_ASSERT_EQUAL((uint32_t)(TOTAL_STORAGE_SIZE), contentSz);
int res;
for (int i = 0; i < RANDOM_READ_TIMES; ++i) {
uint32_t startAddr = rand() % TOTAL_STORAGE_SIZE;
uint32_t size = rand() % (TOTAL_STORAGE_SIZE - startAddr);
LOGI("test random read flash %d/%d, startAddr = %lu, size = %lu", i,
RANDOM_READ_TIMES, (unsigned long)(startAddr), (unsigned long)(size));
res = memset_s(totalData, sz, 0, sz);
TEST_ASSERT_EQUAL(EOK, res);
ReadFlash(startAddr, totalData, size);
TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + startAddr, size);
}
LOGI("end reading random bytes");
LOGI("begin reading small bytes");
for (int i = 0; i < RANDOM_READ_TIMES; ++i) {
uint32_t size = i + 1;
uint32_t startAddr = rand() % (TOTAL_STORAGE_SIZE - size);
LOGI("test random read flash %d/%d, startAddr = %lu, size = %lu", i,
RANDOM_READ_TIMES, (unsigned long)(startAddr), (unsigned long)(size));
res = memset_s(totalData, sz, 0, sz);
TEST_ASSERT_EQUAL(EOK, res);
ReadFlash(startAddr, totalData, size);
TEST_ASSERT_EQUAL_HEX8_ARRAY(totalData, totalDataContent + startAddr, size);
}
LOGI("end reading small bytes");
}
void TestHcFileIotFlash(void)
{
uint8_t *totalData = (uint8_t *)malloc(TOTAL_STORAGE_SIZE);
TEST_ASSERT_NOT_NULL(totalData);
uint8_t *totalDataContent = (uint8_t *)malloc(TOTAL_STORAGE_SIZE);
TEST_ASSERT_NOT_NULL(totalDataContent);
LOGI("malloc memory succeed");
int res, zeroCount = 0;
struct FlashHeader flashHeader;
res = memset_s(&flashHeader, sizeof(flashHeader), 0, sizeof(flashHeader));
TEST_ASSERT_EQUAL(EOK, res);
for (uint32_t i = 0; i < TOTAL_STORAGE_SIZE; ++i) {
totalDataContent[i] = rand() % UINT8_MAX;
if (totalDataContent[i] == 0) {
++zeroCount;
}
}
TEST_ASSERT_NOT_EQUAL(TOTAL_STORAGE_SIZE, zeroCount);
TestIotFlashWrite(totalDataContent, TOTAL_STORAGE_SIZE);
TestIotFlashReadWholeBlock(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
TestIotFlashReadFlashHeader(&flashHeader, (struct FlashHeader *)totalDataContent);
TestIotFlashReadSmallFiles(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
TestIotFlashReadRandom(totalData, TOTAL_STORAGE_SIZE, totalDataContent, TOTAL_STORAGE_SIZE);
free(totalData);
free(totalDataContent);
}
#else // FLASH_START_ADDRESS_HICHAIN
void TestHcFileIotFlash(void)
{
LOGE("no FLASH_START_ADDRESS_HICHAIN, do not test iot flash");
}
#endif // FLASH_START_ADDRESS_HICHAIN
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_FILE_IOT_FLASH_TEST_H
#define HC_FILE_IOT_FLASH_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcFileIotFlash(void);
#ifdef __cplusplus
}
#endif
#endif // HC_FILE_IOT_FLASH_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_file_test.h"
#include <errno.h>
#include <fcntl.h>
#include <hctest.h>
#include <securec.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "hc_file_common.h"
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#if TEST_HC_FILE_OPEN_SERIES
static void ReadFile(char *buffer, int fd, int size)
{
int total = 0;
while (total < size) {
int readCount = read(fd, buffer + total, size - total);
TEST_ASSERT_GREATER_OR_EQUAL(0, readCount);
TEST_ASSERT_LESS_OR_EQUAL(size - total, readCount);
total += readCount;
if (readCount <= 0) {
break;
}
}
}
static void WriteFile(char *buffer, int fd, int size)
{
int total = 0;
while (total < size) {
int writeCount = write(fd, buffer + total, size - total);
TEST_ASSERT_GREATER_OR_EQUAL(0, writeCount);
TEST_ASSERT_LESS_OR_EQUAL(size - total, writeCount);
total += writeCount;
if (writeCount <= 0) {
break;
}
}
}
static void TestHcFileOpenAndClose(void)
{
const char *file = TEST_FILE_NAME;
LOGI("begin to open file: %s", file);
int fd;
RUN_AND_PRINT_ELAPSED_TIME(fd, open(file, O_RDWR | O_CREAT));
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
int ret;
LOGI("begin to close file: %s", file);
RUN_AND_PRINT_ELAPSED_TIME(ret, close(fd));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileReadAndWrite(void)
{
const char *file = TEST_FILE_NAME;
for (int i = 0; i < TEST_FILE_SIZE_LIST_LEN; i++) {
int fd = open(file, O_RDWR | O_CREAT);
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
int size = testFileSizeList[i];
LOGI("begin to write file [%s] for size: %d", file, size);
char *writeBuffer = GenerateTestingText(size);
TEST_ASSERT_NOT_NULL(writeBuffer);
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(WriteFile(writeBuffer, fd, size));
const int fileSize = lseek(fd, 0, SEEK_END);
TEST_ASSERT_EQUAL(size, fileSize);
TEST_ASSERT_EQUAL(0, lseek(fd, 0, SEEK_SET));
LOGI("begin to read file [%s] for size: %d", file, fileSize);
TEST_ASSERT_LESS_OR_EQUAL(TEN_KILOBYTE, fileSize);
char *readBuffer = (char *)malloc(fileSize + 1);
TEST_ASSERT_NOT_NULL(readBuffer);
TEST_ASSERT_EQUAL(0, memset_s(readBuffer, fileSize + 1, 0, fileSize + 1));
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(ReadFile(readBuffer, fd, fileSize));
TEST_ASSERT_EQUAL_STRING(writeBuffer, readBuffer);
free(readBuffer);
free(writeBuffer);
TEST_ASSERT_EQUAL(0, close(fd));
sleep(1);
}
}
static void TestHcFileSize(void)
{
const char *file = TEST_FILE_NAME;
LOGI("begin to count file size");
int fd = open(file, O_RDWR);
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
int size;
RUN_AND_PRINT_ELAPSED_TIME(size, lseek(fd, 0, SEEK_END));
TEST_ASSERT_EQUAL(TEN_KILOBYTE, size);
TEST_ASSERT_EQUAL(0, lseek(fd, 0, SEEK_SET));
LOGI("the file size is: %d", size);
TEST_ASSERT_EQUAL(0, close(fd));
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, unlink(file));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileMkdir(void)
{
#if MKDIR_IMPLEMENTED
const char *dir = TEST_FILE_DIR;
LOGI("begin to make directory: %s", dir);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, mkdir(dir, DEFAULT_FILE_PERMISSION));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(-1, mkdir(dir, DEFAULT_FILE_PERMISSION));
TEST_ASSERT_EQUAL(0, rmdir(dir));
#else
LOGE("no MKDIR_IMPLEMENTED, do not test mkdir() !");
#endif
}
static void TestHcFileStat(void)
{
#if STAT_IMPLEMENTED
const char *file = TEST_FILE_NAME;
LOGI("begin to check [%s] state", file);
TEST_ASSERT_GREATER_OR_EQUAL(0, open(file, O_RDWR | O_CREAT));
struct stat fileStat;
int ret;
ret = memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
TEST_ASSERT_EQUAL(0, ret);
RUN_AND_PRINT_ELAPSED_TIME(ret, stat(file, &fileStat));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(0, unlink(file));
ret = memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(-1, stat(file, &fileStat));
TEST_ASSERT_EQUAL(ENOENT, errno);
#else
LOGE("no STAT_IMPLEMENTED, do not test stat() !");
#endif
}
static void TestHcFileRemove(void)
{
const char *file = TEST_FILE_NAME;
LOGI("begin to remove file: %s", file);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, unlink(file));
TEST_ASSERT_EQUAL(0, ret);
}
void TestHcFile(void)
{
LOGI("test opening and closing file");
TestHcFileOpenAndClose();
LOGI("test removing file");
TestHcFileRemove();
LOGI("test reading and writing file");
TestHcFileReadAndWrite();
LOGI("test counting file size");
TestHcFileSize();
LOGI("test making directory");
TestHcFileMkdir();
LOGI("test getting file state");
TestHcFileStat();
}
#else // TEST_HC_FILE_OPEN_SERIES
void TestHcFile(void)
{
LOGE("no TEST_HC_FILE_OPEN_SERIES, do not test hc_file open series!");
}
#endif // TEST_HC_FILE_OPEN_SERIES
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_LINUX_FILE_TEST_H
#define HC_LINUX_FILE_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcFile(void);
#ifdef __cplusplus
}
#endif
#endif // HC_LINUX_FILE_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_file_utils_test.h"
#include <hctest.h>
#include <securec.h>
#include <stdlib.h>
#include <unistd.h>
#include "hc_file_common.h"
#include "print_log.h"
#include "test_timer.h"
#include "utils_file.h"
#ifdef __cplusplus
extern "C" {
#endif
#if UTILS_FILE_IMPLEMENTED
static void TestHcFileUtilsFileOpenAndUtilsFileClose(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to open file: %s", fileName);
int fd;
TEST_ASSERT_EQUAL(-1, UtilsFileOpen(fileName, O_RDONLY_FS, 0));
RUN_AND_PRINT_ELAPSED_TIME(fd, UtilsFileOpen(fileName, O_RDONLY_FS | O_CREAT_FS, 0));
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
int ret;
LOGI("begin to close file: %s", fileName);
RUN_AND_PRINT_ELAPSED_TIME(ret, UtilsFileClose(fd));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileUtilsFileReadAndFileWrite(void)
{
const char *fileName = TEST_FILE_NAME;
for (int i = 0; i < TEST_FILE_SIZE_LIST_LEN; i++) {
int fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS, 0);
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
unsigned int size = testFileSizeList[i];
LOGI("begin to write file [%s] for size: %d", fileName, size);
char *writeBuffer = GenerateTestingText(size);
TEST_ASSERT_NOT_NULL(writeBuffer);
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(UtilsFileWrite(fd, writeBuffer, size));
TEST_ASSERT_EQUAL(0, UtilsFileClose(fd));
fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS, 0);
TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
unsigned int fileSize;
TEST_ASSERT_EQUAL(0, UtilsFileStat(fileName, &fileSize));
TEST_ASSERT_EQUAL(size, fileSize);
LOGI("begin to read file [%s] for size: %d", fileName, fileSize);
char *readBuffer = (char *)malloc(fileSize + 1);
TEST_ASSERT_NOT_NULL(readBuffer);
TEST_ASSERT_EQUAL(0, memset_s(readBuffer, fileSize + 1, 0, fileSize + 1));
RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(UtilsFileRead(fd, readBuffer, fileSize));
TEST_ASSERT_EQUAL_STRING(writeBuffer, readBuffer);
free(readBuffer);
free(writeBuffer);
TEST_ASSERT_EQUAL(0, UtilsFileClose(fd));
sleep(1);
}
}
static void TestHcFileUtilsFileSize(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to count file size");
unsigned int size;
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, UtilsFileStat(fileName, &size));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(TEN_KILOBYTE, size);
LOGI("the file size is: %d", size);
RUN_AND_PRINT_ELAPSED_TIME(ret, UtilsFileDelete(fileName));
TEST_ASSERT_EQUAL(0, ret);
}
static void TestHcFileUtilsFileDelete(void)
{
const char *fileName = TEST_FILE_NAME;
LOGI("begin to remove file: %s", fileName);
int ret;
RUN_AND_PRINT_ELAPSED_TIME(ret, UtilsFileDelete(fileName));
TEST_ASSERT_EQUAL(0, ret);
}
void TestHcFileUtilsFile(void)
{
LOGI("test opening and closing file");
TestHcFileUtilsFileOpenAndUtilsFileClose();
LOGI("test removing file");
TestHcFileUtilsFileDelete();
LOGI("test reading and writing file");
TestHcFileUtilsFileReadAndFileWrite();
LOGI("test counting file size");
TestHcFileUtilsFileSize();
}
#else // UTILS_FILE_IMPLEMENTED
void TestHcFileUtilsFile(void)
{
LOGE("no UTILS_FILE_IMPLEMENTED, do not test utils file!");
}
#endif // UTILS_FILE_IMPLEMENTED
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_FILE_UTILS_TEST_H
#define HC_FILE_UTILS_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcFileUtilsFile(void);
#ifdef __cplusplus
}
#endif
#endif // HC_FILE_UTILS_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_mutex_test.h"
#include <hctest.h>
#include <pthread.h>
#include <securec.h>
#include <unistd.h>
#include "hc_thread_mutex_share.h"
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#define REQUIRED_MUTEX_COUNT 20
static void TestSpecifiedCount(int count)
{
pthread_mutex_t mutexes[REQUIRED_MUTEX_COUNT];
int res;
TEST_ASSERT_GREATER_THAN(0, count);
TEST_ASSERT_LESS_OR_EQUAL(REQUIRED_MUTEX_COUNT, count);
res = memset_s(mutexes, sizeof(mutexes), 0, sizeof(mutexes));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_init(&mutexes[i], NULL));
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_lock(&mutexes[i]));
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_unlock(&mutexes[i]));
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < count; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_destroy(&mutexes[i]));
TEST_ASSERT_EQUAL(0, res);
}
}
static void *MutexThreadRoutine(void *args)
{
pthread_mutex_t *mtx = (pthread_mutex_t *)args;
TEST_ASSERT_NOT_NULL(mtx);
unsigned long long timeConsumingResult;
int res;
int sleepSeconds = rand() % (WAIT_IN_MUTEX_SECONDS_MAX - WAIT_IN_MUTEX_SECONDS_MIN) + WAIT_IN_MUTEX_SECONDS_MIN;
LOGI("in thread begin phase 1 work");
RUN_AND_PRINT_ELAPSED_TIME(timeConsumingResult, TimeConsumingOperation());
LOGI("in thread begin wait for mutex");
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_lock(mtx));
TEST_ASSERT_EQUAL(0, res);
LOGI("in thread wait for mutex succeed");
LOGI("in thread begin wait for %d seconds", sleepSeconds);
sleep(sleepSeconds);
LOGI("in thread wait for %d seconds succeed", sleepSeconds);
LOGI("in thread begin phase 2 work");
RUN_AND_PRINT_ELAPSED_TIME(timeConsumingResult, TimeConsumingOperation());
LOGI("in thread begin release mutex");
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_unlock(mtx));
TEST_ASSERT_EQUAL(0, res);
LOGI("in thread release mutex successfully");
LOGI("in thread begin phase 3 work");
RUN_AND_PRINT_ELAPSED_TIME(timeConsumingResult, TimeConsumingOperation());
(void)(timeConsumingResult);
LOGI("in thread all work done");
return mtx;
}
static void TestMutexInThreads(void)
{
pthread_mutex_t mtx;
pthread_attr_t attr;
int res;
pthread_t threads[REQUIRED_THREAD_COUNT];
res = memset_s(&mtx, sizeof(mtx), 0, sizeof(mtx));
TEST_ASSERT_EQUAL(0, res);
res = memset_s(&attr, sizeof(attr), 0, sizeof(attr));
TEST_ASSERT_EQUAL(0, res);
res = memset_s(&threads, sizeof(threads), 0, sizeof(threads));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_mutex_init(&mtx, NULL));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&attr));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setstacksize(&attr, MAX_THREAD_STACK_SIZE));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < REQUIRED_THREAD_COUNT; ++i) {
LOGI("test threads %d/%d", i, REQUIRED_THREAD_COUNT);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, MutexThreadRoutine, &mtx));
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < REQUIRED_THREAD_COUNT; ++i) {
LOGI("test threads %d/%d", i, REQUIRED_THREAD_COUNT);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_join(threads[i], NULL));
LOGI("pthread_join result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_destroy(&attr));
TEST_ASSERT_EQUAL(0, res);
}
void TestHcMutex(void)
{
LOGI("test one mutex");
TestSpecifiedCount(1);
LOGI("test %d mutexes", REQUIRED_MUTEX_COUNT);
TestSpecifiedCount(REQUIRED_MUTEX_COUNT);
LOGI("test mutexes in threads");
TestMutexInThreads();
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_MUTEX_TEST_H
#define HC_MUTEX_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcMutex(void);
#ifdef __cplusplus
}
#endif
#endif // HC_MUTEX_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_THREAD_MUTEX_SHARE_H
#define HC_THREAD_MUTEX_SHARE_H
#define REQUIRED_THREAD_COUNT 5
#define MAX_THREAD_STACK_SIZE 4096
#define MIN_THREAD_STACK_SIZE 4096
enum {
WAIT_IN_MUTEX_SECONDS_MIN = 3,
WAIT_IN_MUTEX_SECONDS_MAX = 5,
};
#endif // HC_THREAD_MUTEX_SHARE_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_thread_test.h"
#include <hctest.h>
#include <pthread.h>
#include <securec.h>
#include <stdlib.h>
#include <unistd.h>
#include "hc_thread_mutex_share.h"
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#define REQUIRED_PTHREAD_ATTR_COUNT 20
#define TEST_STRING "hello"
typedef struct {
void *(*function)(void *);
size_t sz;
int i;
char *str;
} ThreadTestArgs;
static void *ThreadRountine(void *args)
{
TEST_ASSERT_NOT_NULL(args);
ThreadTestArgs *testArgs = (ThreadTestArgs *)args;
int sleepSeconds = rand() % (WAIT_IN_MUTEX_SECONDS_MAX - WAIT_IN_MUTEX_SECONDS_MIN) + WAIT_IN_MUTEX_SECONDS_MIN;
TEST_ASSERT_EQUAL((void *)ThreadRountine, (void *)testArgs->function);
TEST_ASSERT_EQUAL((size_t)MAX_THREAD_STACK_SIZE, testArgs->sz);
TEST_ASSERT_GREATER_OR_EQUAL(MIN_THREAD_STACK_SIZE, testArgs->i);
TEST_ASSERT_LESS_OR_EQUAL(MAX_THREAD_STACK_SIZE, testArgs->i);
TEST_ASSERT_EQUAL_STRING(TEST_STRING, testArgs->str);
LOGI("test thread begin wait for %d seconds", sleepSeconds);
sleep(sleepSeconds);
LOGI("test thread wait for %d seconds successfully", sleepSeconds);
LOGI("begin time consuming operation");
unsigned long long res;
RUN_AND_PRINT_ELAPSED_TIME(res, TimeConsumingOperation());
LOGI("end time consuming operation, res = %llu", res);
return args;
}
static int GetStackSize(void)
{
// use macro instead of enum to avoid error: division by zero [-Werror=div-by-zero]
#if (MAX_THREAD_STACK_SIZE == MIN_THREAD_STACK_SIZE)
return MIN_THREAD_STACK_SIZE;
#else
int stackSize = rand() % (MAX_THREAD_STACK_SIZE - MIN_THREAD_STACK_SIZE) + MIN_THREAD_STACK_SIZE;
LOGI("rand stack size = %d", stackSize);
return stackSize;
#endif
}
static void TestSpecifiedCount(int count, int detachState)
{
TEST_ASSERT_GREATER_THAN(0, count);
TEST_ASSERT_LESS_OR_EQUAL(REQUIRED_THREAD_COUNT, count);
TEST_ASSERT_TRUE_MESSAGE(detachState == PTHREAD_CREATE_JOINABLE || detachState == PTHREAD_CREATE_DETACHED,
"invalid detach state");
pthread_attr_t attr;
pthread_t threads[REQUIRED_THREAD_COUNT];
int res, stackSize;
static ThreadTestArgs args = {
.function = ThreadRountine,
.sz = MAX_THREAD_STACK_SIZE,
.i = -1,
.str = (char *)TEST_STRING,
};
res = memset_s(threads, sizeof(threads), 0, sizeof(threads));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&attr));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setdetachstate(&attr, detachState));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < count; ++i) {
LOGI("test thread %d/%d", i, count);
stackSize = GetStackSize();
LOGI("rand stack size = %d", stackSize);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setstacksize(&attr, stackSize));
TEST_ASSERT_EQUAL(0, res);
args.i = stackSize;
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_create(&threads[i], &attr, ThreadRountine, &args));
TEST_ASSERT_EQUAL(0, res);
}
if (detachState == PTHREAD_CREATE_JOINABLE) {
for (int i = 0; i < count; ++i) {
LOGI("test thread %d/%d", i, count);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_join(threads[i], NULL));
LOGI("pthread_join result = %d", res);
TEST_ASSERT_EQUAL(0, res);
}
} else {
LOGI("detachState is PTHREAD_CREATE_DETACHED, do not test pthread_join");
}
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_destroy(&attr));
TEST_ASSERT_EQUAL(0, res);
}
static void TestPthreadAttr(int detachState)
{
TEST_ASSERT_TRUE_MESSAGE(detachState == PTHREAD_CREATE_JOINABLE || detachState == PTHREAD_CREATE_DETACHED,
"invalid detach state");
int res, stackSize;
pthread_attr_t attr[REQUIRED_PTHREAD_ATTR_COUNT];
res = memset_s(attr, sizeof(attr), 0, sizeof(attr));
TEST_ASSERT_EQUAL(0, res);
for (int i = 0; i < REQUIRED_PTHREAD_ATTR_COUNT; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_init(&attr[i]));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setdetachstate(&attr[i], detachState));
TEST_ASSERT_EQUAL(0, res);
stackSize = GetStackSize();
LOGI("rand stack size = %d", stackSize);
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_setstacksize(&attr[i], stackSize));
TEST_ASSERT_EQUAL(0, res);
}
for (int i = 0; i < REQUIRED_PTHREAD_ATTR_COUNT; ++i) {
RUN_AND_PRINT_ELAPSED_TIME(res, pthread_attr_destroy(&attr[i]));
TEST_ASSERT_EQUAL(0, res);
}
}
static void TestState(int detachState)
{
TEST_ASSERT_TRUE_MESSAGE(detachState == PTHREAD_CREATE_JOINABLE || detachState == PTHREAD_CREATE_DETACHED,
"invalid detach state");
TestPthreadAttr(detachState);
LOGI("test one thread");
TestSpecifiedCount(1, detachState);
LOGI("test %d threads", REQUIRED_THREAD_COUNT);
TestSpecifiedCount(REQUIRED_THREAD_COUNT, detachState);
}
void TestHcThread(void)
{
#if TEST_PTHREAD_CREATE_DETACHED
LOGI("test state PTHREAD_CREATE_DETACHED");
TestState(PTHREAD_CREATE_DETACHED);
#else // TEST_PTHREAD_CREATE_DETACHED
LOGI("test state PTHREAD_CREATE_JOINABLE");
TestState(PTHREAD_CREATE_JOINABLE);
#endif // TEST_PTHREAD_CREATE_DETACHED
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_THREAD_TEST_H
#define HC_THREAD_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcThread(void);
#ifdef __cplusplus
}
#endif
#endif // HC_THREAD_TEST_H
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "hc_time_test.h"
// math.h must be included before hctest.h -> unity.h -> unity_internals.h
// otherwise isinf and isnan macro will be redefined
#include <math.h>
#include <hctest.h>
#include <securec.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include "print_log.h"
#include "test_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
SLEEP_SECONDS_MIN = 3,
SLEEP_SECONDS_MAX = 5,
TEST_TIMES = 5,
};
#define MILLISECONDS_DEVIATION 1.e2
static void TestTime(void)
{
struct timespec start, end;
int res, sleepSeconds = rand() % (SLEEP_SECONDS_MAX - SLEEP_SECONDS_MIN) + SLEEP_SECONDS_MIN;
res = memset_s(&start, sizeof(start), 0, sizeof(start));
TEST_ASSERT_EQUAL(0, res);
res = memset_s(&end, sizeof(end), 0, sizeof(end));
TEST_ASSERT_EQUAL(0, res);
LOGI("test correctness");
RUN_AND_PRINT_ELAPSED_TIME(res, clock_gettime(CLOCK_MONOTONIC, &start));
TEST_ASSERT_EQUAL(0, res);
LOGI("begin sleeping for %d seconds", sleepSeconds);
sleep(sleepSeconds);
RUN_AND_PRINT_ELAPSED_TIME(res, clock_gettime(CLOCK_MONOTONIC, &end));
TEST_ASSERT_EQUAL(0, res);
TEST_ASSERT_LESS_THAN(MILLISECONDS_DEVIATION, fabs(CalcTimeSpecDiff(start, end) - sleepSeconds * 1000.0f));
LOGI("test precision");
res = memset_s(&start, sizeof(start), 0, sizeof(start));
TEST_ASSERT_EQUAL(0, res);
res = memset_s(&end, sizeof(end), 0, sizeof(end));
TEST_ASSERT_EQUAL(0, res);
RUN_AND_PRINT_ELAPSED_TIME(res, clock_gettime(CLOCK_MONOTONIC, &start));
TEST_ASSERT_EQUAL(0, res);
LOGI("in testing precision");
RUN_AND_PRINT_ELAPSED_TIME(res, clock_gettime(CLOCK_MONOTONIC, &end));
TEST_ASSERT_EQUAL(0, res);
TEST_ASSERT_LESS_THAN(MILLISECONDS_DEVIATION, fabs(CalcTimeSpecDiff(start, end)));
}
static void TestPrintTime(void)
{
for (int i = 0; i < TEST_TIMES; ++i) {
struct timespec start;
int res, sleepSeconds;
res = memset_s(&start, sizeof(start), 0, sizeof(start));
TEST_ASSERT_EQUAL(0, res);
sleepSeconds = rand() % (SLEEP_SECONDS_MAX - SLEEP_SECONDS_MIN) + SLEEP_SECONDS_MIN;
res = clock_gettime(CLOCK_MONOTONIC, &start);
TEST_ASSERT_EQUAL(0, res);
double rawTime = (start.tv_nsec / 1000.0 / 1000.0 / 1000.0) + start.tv_sec;
time_t timeTime = (time_t)rawTime;
struct tm *pts = gmtime(&timeTime);
TEST_ASSERT_NOT_NULL(pts);
LOGI("time = %d-%d-%d %d:%d:%d, %d day of week, %d days in year, isdst = %d",
pts->tm_year,
pts->tm_mon + 1,
pts->tm_mday,
pts->tm_hour,
pts->tm_min,
pts->tm_sec,
pts->tm_wday + 1,
pts->tm_yday + 1,
pts->tm_isdst);
LOGI("begin sleeping for %d seconds", sleepSeconds);
sleep(sleepSeconds);
}
}
void TestHcTime(void)
{
for (int i = 0; i < TEST_TIMES; ++i) {
TestTime();
}
TestPrintTime();
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 HC_TIME_TEST_H
#define HC_TIME_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
void TestHcTime(void);
#ifdef __cplusplus
}
#endif
#endif // HC_TIME_TEST_H
\ No newline at end of file
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "print_log.h"
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LINE_BYTE_COUNT 16
#define FORMAT_PRINT_BUFFER LOGD
#define CHAR_ZERO '0'
#define CHAR_A 'A'
#define NUM_ZERO 0
#define NUM_ONE 1
#define NUM_TWO 2
#define NUM_THREE 3
#define NUM_FOUR 4
#define NUM_NINE 9
#define NUM_TEN 10
#define NUM_FIFTEEN 15
#define HALF_BYTE_MASK 0x0F
#define NUM_PRINTABLE_BEGIN 0x20
#define NUM_PRINTABLE_END 0x7E
#define BITS_PER_BYTE 8
#define BITS_PER_HEX 4
static char Int2char(uint8_t c)
{
// c >= NUM_ZERO comparison is always true due to limited range of data type
if (c <= NUM_NINE) {
return (char)(c + CHAR_ZERO);
} else if (c >= NUM_TEN && c <= NUM_FIFTEEN) {
return (char)(c - NUM_TEN + CHAR_A);
} else {
return 0;
}
}
static void PrintLine(const uint8_t *ptr, int32_t len, uint32_t offset)
{
int i;
char x1;
char x2;
char str[NUM_NINE + LINE_BYTE_COUNT * NUM_FOUR + NUM_ONE] = {0};
char *out = str + NUM_NINE;
uint32_t t;
for (i = 0; i < BITS_PER_BYTE; i++) {
t = offset << (i * BITS_PER_HEX);
t = t >> ((BITS_PER_BYTE - 1) * BITS_PER_HEX);
str[i] = Int2char(t);
}
str[BITS_PER_BYTE] = ' ';
for (i = 0; i < len; i++) {
uint8_t c = ptr[i];
x1 = Int2char(c >> NUM_FOUR);
x2 = Int2char(c & HALF_BYTE_MASK);
out[i * NUM_THREE] = x1;
out[i * NUM_THREE + NUM_ONE] = x2;
out[i * NUM_THREE + NUM_TWO] = ' ';
}
for (i = len; i < LINE_BYTE_COUNT; i++) {
out[i * NUM_THREE] = out[i * NUM_THREE + NUM_ONE] = out[i * NUM_THREE + NUM_TWO] = ' ';
}
for (i = 0; i < len; i++) {
if (ptr[i] >= NUM_PRINTABLE_BEGIN && ptr[i] <= NUM_PRINTABLE_END) {
out[LINE_BYTE_COUNT * NUM_THREE + i] = ptr[i];
} else {
out[LINE_BYTE_COUNT * NUM_THREE + i] = '.';
}
}
FORMAT_PRINT_BUFFER("%s", str);
}
void PrintBuffer(const char *tag, const uint8_t *ptr, int32_t len)
{
int i = 0;
const uint8_t *linePtr = ptr;
uint32_t offset = 0;
FORMAT_PRINT_BUFFER("PrintBuffer tag = %s, len = %d, 0x%x", tag, len, len);
while (i < len) {
int currentLineByteCount = (int)(len - i);
if (currentLineByteCount >= LINE_BYTE_COUNT) {
PrintLine(linePtr, LINE_BYTE_COUNT, offset);
i += LINE_BYTE_COUNT;
} else {
PrintLine(linePtr, currentLineByteCount, offset);
i += currentLineByteCount;
}
linePtr += LINE_BYTE_COUNT;
offset += LINE_BYTE_COUNT;
}
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 PRINT_LOG_H
#define PRINT_LOG_H
#include <stdint.h>
#include <stdio.h>
#define LOGI(fmt, ...) printf("[I][%s][%d]" fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define LOGD(fmt, ...) printf("[D][%s][%d]" fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define LOGE(fmt, ...) printf("[E][%s][%d]" fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
void PrintBuffer(const char *tag, const uint8_t *ptr, int32_t len);
#ifdef __cplusplus
}
#endif
#endif // PRINT_LOG_H
\ No newline at end of file
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 <hctest.h>
#include <ohos_types.h>
#include <securec.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "hc_alg_test.h"
#include "hc_condition_test.h"
#include "hc_dev_info_test.h"
#include "hc_file_f_test.h"
#include "hc_file_iot_flash_test.h"
#include "hc_file_test.h"
#include "hc_file_utils_test.h"
#include "hc_mutex_test.h"
#include "hc_thread_test.h"
#include "hc_time_test.h"
#include "print_log.h"
LITE_TEST_SUIT(security, deviceAuth, DeviceAuthBasicDepsTestSuite)
static BOOL DeviceAuthBasicDepsTestSuiteSetUp(void)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
(void)(srand(time(NULL)));
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
return TRUE;
}
static BOOL DeviceAuthBasicDepsTestSuiteTearDown(void)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
return TRUE;
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcMutex
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcMutex, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcMutex();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcThread
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcThread, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcThread();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcGetUdid
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcGetUdid, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcGetUdid();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcFile
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcFile, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcFile();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcFileFApi
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcFileFApi, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcFileFApi();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcFileUtilsFile
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcFileUtilsFile, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcFileUtilsFile();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseSemCondition
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseSemCondition, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcSemCondition();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCasePthreadCondition
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCasePthreadCondition, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcPthreadCondition();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcFileIotFlash
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcFileIotFlash, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcFileIotFlash();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcTime
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcTime, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcTime();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
/**
* @tc.name: DeviceAuthBasicDepsTestSuite.TestCaseHcAlg
* @tc.desc:
* @tc.type: FUNC
*/
LITE_TEST_CASE(DeviceAuthBasicDepsTestSuite, TestCaseHcAlg, Function | SmallTest | Level1)
{
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
TestHcAlg();
LOGI("++++++++++++++++++++++++++++++++++++++++\n");
}
RUN_TEST_SUITE(DeviceAuthBasicDepsTestSuite)
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 "test_timer.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
// 3861 platform limits that the running time cannot exceed 16 seconds.
// If the running time exceeds 16 seconds, crash occurs.
// The following comments are from at91SAM9_wdt.c in directory
// device/hisilicon/hispark_pegasus/sdk_liteos/third_party/u-boot-v2019.07/u-boot-v2019.07/drivers/watchdog
/*
* All counting occurs at SLOW_CLOCK / 128 = 256 Hz
*
* Since WDV is a 12-bit counter, the maximum period is
* 4096 / 256 = 16 seconds.
*/
enum {
MAX_FIBONACCI_OPTION = 0xFFFFFF,
MIN_FIBONACCI_OPTION = 0xFFFFF,
};
double CalcTimeSpecDiff(struct timespec before, struct timespec after)
{
double mseconds = (((double)after.tv_sec - (double)before.tv_sec) * 1000000.0f +
((double)after.tv_nsec - (double)before.tv_nsec) / 1000.0f) / 1000.0f;
return mseconds;
}
unsigned long long TimeConsumingOperation(void)
{
unsigned long long i, n, t1 = 0, t2 = 1, nextTerm = 0;
n = rand() % (MAX_FIBONACCI_OPTION - MIN_FIBONACCI_OPTION) + MIN_FIBONACCI_OPTION;
for (i = 1; i <= n; ++i) {
nextTerm = t1 + t2;
t1 = t2;
t2 = nextTerm;
}
return nextTerm;
}
#ifdef __cplusplus
}
#endif
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* 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 TEST_TIMER_H
#define TEST_TIMER_H
#include "print_log.h"
#include <hctest.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
double CalcTimeSpecDiff(struct timespec before, struct timespec after);
unsigned long long TimeConsumingOperation(void);
#ifdef __cplusplus
}
#endif
#define RUN_AND_PRINT_ELAPSED_TIME(out_result, operation) \
do { \
struct timespec __before, __after; \
int __beforeRes = clock_gettime(CLOCK_MONOTONIC, &__before); \
out_result = operation; \
int __afterRes = clock_gettime(CLOCK_MONOTONIC, &__after); \
TEST_ASSERT_TRUE(__beforeRes == 0 && __afterRes == 0); \
double __mseconds = CalcTimeSpecDiff(__before, __after); \
LOGI("operation %s took %f ms", #operation, __mseconds); \
} while (0)
#define RUN_AND_PRINT_ELAPSED_TIME_WITHOUT_RESULT(operation) \
do { \
struct timespec __before, __after; \
int __beforeRes = clock_gettime(CLOCK_MONOTONIC, &__before); \
(void)(operation); \
int __afterRes = clock_gettime(CLOCK_MONOTONIC, &__after); \
TEST_ASSERT_TRUE(__beforeRes == 0 && __afterRes == 0); \
double __mseconds = CalcTimeSpecDiff(__before, __after); \
LOGI("operation %s took %f ms", #operation, __mseconds); \
} while (0)
#endif // TEST_TIMER_H
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册