Skip to content

Commit

Permalink
[cryptotest] add device-side firmware handler for SPHINCS+ tests
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Torok <[email protected]>
  • Loading branch information
RyanTorok authored and Ryan Torok committed Mar 15, 2024
1 parent 5914d57 commit 6790fa0
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
21 changes: 21 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ cc_library(
],
)

cc_library(
name = "sphincsplus",
srcs = ["sphincsplus.c"],
hdrs = ["sphincsplus.h"],
deps = [
"//sw/device/lib/base:memory",
"//sw/device/lib/base:status",
"//sw/device/lib/crypto/impl:integrity",
"//sw/device/lib/crypto/impl:keyblob",
"//sw/device/lib/crypto/include:datatypes",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/lib/ujson",
"//sw/device/silicon_creator/lib/sigverify/sphincsplus:verify",
"//sw/device/tests/crypto/cryptotest/json:sphincsplus_commands",
],
)

cc_library(
name = "aes_sca",
srcs = ["aes_sca.c"],
Expand Down Expand Up @@ -251,6 +269,7 @@ opentitan_binary(
":kmac_sca",
":prng_sca",
":sha3_sca",
":sphincsplus",
":trigger_sca",
"//sw/device/lib/base:status",
"//sw/device/lib/crypto/drivers:entropy",
Expand Down Expand Up @@ -290,6 +309,7 @@ opentitan_test(
":kmac_sca",
":prng_sca",
":sha3_sca",
":sphincsplus",
":trigger_sca",
"//sw/device/lib/base:status",
"//sw/device/lib/crypto/drivers:entropy",
Expand All @@ -305,5 +325,6 @@ opentitan_test(
"//sw/device/tests/crypto/cryptotest/json:hash_commands",
"//sw/device/tests/crypto/cryptotest/json:hmac_commands",
"//sw/device/tests/crypto/cryptotest/json:ibex_fi_commands",
"//sw/device/tests/crypto/cryptotest/json:sphincsplus_commands",
],
)
5 changes: 5 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "sw/device/tests/crypto/cryptotest/json/kmac_sca_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/prng_sca_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/sha3_sca_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/sphincsplus_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/trigger_sca_commands.h"

// Include handlers
Expand All @@ -37,6 +38,7 @@
#include "kmac_sca.h"
#include "prng_sca.h"
#include "sha3_sca.h"
#include "sphincsplus.h"
#include "trigger_sca.h"

OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
Expand Down Expand Up @@ -64,6 +66,9 @@ status_t process_cmd(ujson_t *uj) {
case kCryptotestCommandHmac:
RESP_ERR(uj, handle_hmac(uj));
break;
case kCryptotestCommandSphincsPlus:
RESP_ERR(uj, handle_sphincsplus(uj));
break;
case kCryptotestCommandAesSca:
RESP_ERR(uj, handle_aes_sca(uj));
break;
Expand Down
100 changes: 100 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/sphincsplus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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/base/memory.h"
#include "sw/device/lib/base/status.h"
#include "sw/device/lib/crypto/impl/integrity.h"
#include "sw/device/lib/crypto/impl/keyblob.h"
#include "sw/device/lib/crypto/include/datatypes.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/ujson_ottf.h"
#include "sw/device/lib/ujson/ujson.h"
#include "sw/device/silicon_creator/lib/sigverify/sphincsplus/verify.h"
#include "sw/device/tests/crypto/cryptotest/json/sphincsplus_commands.h"

status_t handle_sphincsplus_verify(ujson_t *uj) {
// Declare SPHINCS+ parameter ujson deserializer types
cryptotest_sphincsplus_hash_alg_t uj_hash_alg;
cryptotest_sphincsplus_public_key_t uj_public_key;
cryptotest_sphincsplus_message_t uj_message;
cryptotest_sphincsplus_signature_t uj_signature;

// Deserialize ujson byte stream into SPHINCS+ parameters
TRY(ujson_deserialize_cryptotest_sphincsplus_hash_alg_t(uj, &uj_hash_alg));
TRY(ujson_deserialize_cryptotest_sphincsplus_public_key_t(uj,
&uj_public_key));
TRY(ujson_deserialize_cryptotest_sphincsplus_message_t(uj, &uj_message));
TRY(ujson_deserialize_cryptotest_sphincsplus_signature_t(uj, &uj_signature));

if (uj_public_key.public_len != kSpxVerifyPkBytes) {
LOG_ERROR("Incorrect public key length: (expected = %d, got = %d)",
kSpxVerifyPkBytes, uj_public_key.public_len);
return INVALID_ARGUMENT();
}
if (uj_signature.signature_len != kSpxVerifySigBytes) {
LOG_ERROR("Incorrect signature length: (expected = %d, got = %d)",
kSpxVerifySigBytes, uj_signature.signature_len);
return INVALID_ARGUMENT();
}

switch (uj_hash_alg) {
case kCryptotestSphincsPlusHashAlgSha256:
LOG_ERROR("SPHINCS+ SHA-256 is not supported yet.");
return INVALID_ARGUMENT();
break;
case kCryptotestSphincsPlusHashAlgShake256:
break;
default:
LOG_ERROR("Unrecognized SPHINCS+ hash mode: %d", uj_hash_alg);
return INVALID_ARGUMENT();
}
uint32_t exp_root[kSpxVerifyRootNumWords];
spx_public_key_root((uint32_t *)uj_public_key.public, exp_root);
uint32_t act_root[kSpxVerifyRootNumWords];
rom_error_t error =
spx_verify((uint32_t *)uj_signature.signature, NULL, 0, NULL, 0,
(uint8_t *)uj_message.message, uj_message.message_len,
(uint32_t *)uj_public_key.public, act_root);
cryptotest_sphincsplus_verify_output_t uj_output;
switch (error) {
case kErrorOk:
uj_output = kCryptotestSphincsPlusVerifyOutputSuccess;
for (size_t i = 0; i < kSpxVerifyRootNumWords; i++) {
if (exp_root[i] != act_root[i]) {
uj_output = kCryptotestSphincsPlusVerifyOutputFailure;
break;
}
}
RESP_OK(ujson_serialize_cryptotest_sphincsplus_verify_output_t, uj,
&uj_output);
break;
case kErrorSigverifyBadSpxSignature:
OT_FALLTHROUGH_INTENDED;
case kErrorSigverifyBadSpxKey:
uj_output = kCryptotestSphincsPlusVerifyOutputFailure;
// Respond "failure" if the IUT reports an invalid argument
RESP_OK(ujson_serialize_cryptotest_sphincsplus_verify_output_t, uj,
&uj_output);
break;
default:
LOG_ERROR(
"Unexpected error value returned from spx_verify: "
"0x%x",
error);
return INTERNAL();
}
return OK_STATUS(0);
}

status_t handle_sphincsplus(ujson_t *uj) {
cryptotest_sphincsplus_operation_t uj_op;
TRY(ujson_deserialize_cryptotest_sphincsplus_operation_t(uj, &uj_op));
switch (uj_op) {
case kCryptotestSphincsPlusOperationVerify:
return handle_sphincsplus_verify(uj);
default:
LOG_ERROR("Unsupported SPHINCS+ operation: %d", uj_op);
return INVALID_ARGUMENT();
}
}
13 changes: 13 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/sphincsplus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_SPHINCSPLUS_H_
#define OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_SPHINCSPLUS_H_

#include "sw/device/lib/base/status.h"
#include "sw/device/lib/ujson/ujson.h"

status_t handle_sphincsplus(ujson_t *uj);

#endif // OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_SPHINCSPLUS_H_

0 comments on commit 6790fa0

Please sign in to comment.