blob: 606d1e5be4fb12f89a88d99ecbd1b7cdedd2f609 [file] [log] [blame]
// 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