| // Copyright lowRISC contributors. | |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| // SPDX-License-Identifier: Apache-2.0 | |
| #include "sw/device/lib/crypto/impl/status.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| // NOTE: This test does not verify hardening measures; it only checks that the | |
| // "normal" contract of the functions is upheld. | |
| namespace status_unittest { | |
| namespace { | |
| TEST(Status, OkIsHardenedOk) { | |
| EXPECT_EQ(hardened_status_ok(OTCRYPTO_OK), kHardenedBoolTrue); | |
| } | |
| TEST(Status, OkIsNonHardenedOk) { EXPECT_EQ(status_ok(OTCRYPTO_OK), true); } | |
| TEST(Status, ErrorMacrosNotOk) { | |
| // Error macros should evaluate to non-OK statuses. | |
| EXPECT_EQ(status_ok(OTCRYPTO_BAD_ARGS), false); | |
| EXPECT_EQ(status_ok(OTCRYPTO_RECOV_ERR), false); | |
| EXPECT_EQ(status_ok(OTCRYPTO_FATAL_ERR), false); | |
| EXPECT_EQ(status_ok(OTCRYPTO_ASYNC_INCOMPLETE), false); | |
| } | |
| TEST(Status, ErrorMacrosNotHardenedOk) { | |
| // Error macros should evaluate to non-OK statuses. | |
| EXPECT_EQ(hardened_status_ok(OTCRYPTO_BAD_ARGS), kHardenedBoolFalse); | |
| EXPECT_EQ(hardened_status_ok(OTCRYPTO_RECOV_ERR), kHardenedBoolFalse); | |
| EXPECT_EQ(hardened_status_ok(OTCRYPTO_FATAL_ERR), kHardenedBoolFalse); | |
| EXPECT_EQ(hardened_status_ok(OTCRYPTO_ASYNC_INCOMPLETE), kHardenedBoolFalse); | |
| } | |
| TEST(Status, InterpretErrorMacros) { | |
| // Error macros should translate to the crypto status implied by their name. | |
| EXPECT_EQ(crypto_status_interpret(OTCRYPTO_OK), kCryptoStatusOK); | |
| EXPECT_EQ(crypto_status_interpret(OTCRYPTO_BAD_ARGS), kCryptoStatusBadArgs); | |
| EXPECT_EQ(crypto_status_interpret(OTCRYPTO_RECOV_ERR), | |
| kCryptoStatusInternalError); | |
| EXPECT_EQ(crypto_status_interpret(OTCRYPTO_FATAL_ERR), | |
| kCryptoStatusFatalError); | |
| EXPECT_EQ(crypto_status_interpret(OTCRYPTO_ASYNC_INCOMPLETE), | |
| kCryptoStatusAsyncIncomplete); | |
| } | |
| __attribute__((noinline)) crypto_status_t try_interpret(status_t status) { | |
| OTCRYPTO_TRY_INTERPRET(status); | |
| return kCryptoStatusOK; | |
| } | |
| TEST(Status, TryInterpretOk) { | |
| // Hardened OK should result in an OK status. | |
| EXPECT_EQ(try_interpret(OTCRYPTO_OK), kCryptoStatusOK); | |
| } | |
| TEST(Status, TryInterpretNonHardenedOk) { | |
| // Non-hardened OK should result in an error. | |
| EXPECT_EQ(try_interpret(OK_STATUS()), kCryptoStatusInternalError); | |
| } | |
| TEST(Status, TryInterpretErrors) { | |
| // Error macros should result in error statuses. | |
| EXPECT_EQ(try_interpret(OTCRYPTO_BAD_ARGS), kCryptoStatusBadArgs); | |
| EXPECT_EQ(try_interpret(OTCRYPTO_RECOV_ERR), kCryptoStatusInternalError); | |
| EXPECT_EQ(try_interpret(OTCRYPTO_FATAL_ERR), kCryptoStatusFatalError); | |
| EXPECT_EQ(try_interpret(OTCRYPTO_ASYNC_INCOMPLETE), | |
| kCryptoStatusAsyncIncomplete); | |
| } | |
| constexpr char kTestModId[3] = {'X', 'Y', 'Z'}; | |
| #define MODULE_ID MAKE_MODULE_ID(kTestModId[0], kTestModId[1], kTestModId[2]) | |
| TEST(Status, ExtractStatusFieldsBadArgs) { | |
| const char *code = NULL; | |
| char mod_id[3] = {0}; | |
| int32_t line = 0; | |
| const char expected_code[] = "InvalidArgument"; | |
| int32_t expected_line = __LINE__ + 1; | |
| EXPECT_EQ(status_extract(OTCRYPTO_BAD_ARGS, &code, &line, mod_id), true); | |
| // Check the fields to ensure that the format of cryptolib errors matches the | |
| // error format from the main status library. | |
| EXPECT_EQ(memcmp(code, expected_code, ARRAYSIZE(expected_code)), 0); | |
| EXPECT_THAT(mod_id, testing::ElementsAreArray(kTestModId)); | |
| EXPECT_EQ(line, expected_line); | |
| } | |
| TEST(Status, ExtractStatusFieldsRecovErr) { | |
| const char *code = NULL; | |
| char mod_id[3] = {0}; | |
| int32_t line = 0; | |
| const char expected_code[] = "Aborted"; | |
| int32_t expected_line = __LINE__ + 1; | |
| EXPECT_EQ(status_extract(OTCRYPTO_RECOV_ERR, &code, &line, mod_id), true); | |
| // Check the fields to ensure that the format of cryptolib errors matches the | |
| // error format from the main status library. | |
| EXPECT_EQ(memcmp(code, expected_code, ARRAYSIZE(expected_code)), 0); | |
| EXPECT_THAT(mod_id, testing::ElementsAreArray(kTestModId)); | |
| EXPECT_EQ(line, expected_line); | |
| } | |
| TEST(Status, ExtractStatusFieldsFatalErr) { | |
| const char *code = NULL; | |
| char mod_id[3] = {0}; | |
| int32_t line = 0; | |
| const char expected_code[] = "FailedPrecondition"; | |
| int32_t expected_line = __LINE__ + 1; | |
| EXPECT_EQ(status_extract(OTCRYPTO_FATAL_ERR, &code, &line, mod_id), true); | |
| // Check the fields to ensure that the format of cryptolib errors matches the | |
| // error format from the main status library. | |
| EXPECT_EQ(memcmp(code, expected_code, ARRAYSIZE(expected_code)), 0); | |
| EXPECT_THAT(mod_id, testing::ElementsAreArray(kTestModId)); | |
| EXPECT_EQ(line, expected_line); | |
| } | |
| TEST(Status, ExtractStatusFieldsAsyncIncomplete) { | |
| const char *code = NULL; | |
| char mod_id[3] = {0}; | |
| int32_t line = 0; | |
| const char expected_code[] = "Unavailable"; | |
| int32_t expected_line = __LINE__ + 1; | |
| EXPECT_EQ(status_extract(OTCRYPTO_ASYNC_INCOMPLETE, &code, &line, mod_id), | |
| true); | |
| // Check the fields to ensure that the format of cryptolib errors matches the | |
| // error format from the main status library. | |
| EXPECT_EQ(memcmp(code, expected_code, ARRAYSIZE(expected_code)), 0); | |
| EXPECT_THAT(mod_id, testing::ElementsAreArray(kTestModId)); | |
| EXPECT_EQ(line, expected_line); | |
| } | |
| } // namespace | |
| } // namespace status_unittest |