6 #include "sw/device/lib/base/status.h"
7 #include "sw/device/lib/testing/test_framework/check.h"
9 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
10 #include "sw/device/lib/ujson/ujson.h"
11 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
12 #include "sw/device/silicon_creator/lib/otbn_boot_services.h"
13 #include "sw/device/silicon_creator/lib/sigverify/ecdsa_p256_key.h"
14 #include "sw/device/silicon_creator/lib/sigverify/ecdsa_p256_verify.h"
15 #include "sw/device/tests/crypto/cryptotest/json/ecdsa_commands.h"
18 #include "sw/device/tests/crypto/cryptotest/json/commands.h"
19 #include "sw/device/tests/crypto/cryptotest/json/ecdsa_commands.h"
23 OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice,
25 .console.test_may_clobber =
false, );
27 bool ecdsa_p256_params_set(cryptotest_ecdsa_coordinate_t uj_qx,
28 cryptotest_ecdsa_coordinate_t uj_qy,
29 cryptotest_ecdsa_signature_t uj_signature,
32 if (uj_qx.coordinate_len > kEcdsaP256SignatureComponentBytes) {
34 "Coordinate value qx too large for P256 (have = %d bytes, max = %d "
36 uj_qx.coordinate_len, kEcdsaP256SignatureComponentBytes);
39 if (uj_qy.coordinate_len > kEcdsaP256SignatureComponentBytes) {
41 "Coordinate value qy too large for P256 (have = %d bytes, max = %d "
43 uj_qy.coordinate_len, kEcdsaP256SignatureComponentBytes);
46 memset(public_key->
x, 0, kEcdsaP256SignatureComponentBytes);
47 memcpy(public_key->
x, uj_qx.coordinate, uj_qx.coordinate_len);
48 memset(public_key->
y, 0, kEcdsaP256SignatureComponentBytes);
49 memcpy(public_key->
y, uj_qy.coordinate, uj_qy.coordinate_len);
51 if (uj_signature.r_len > kEcdsaP256SignatureComponentBytes) {
53 "Signature r value too large for P256 (have = %d bytes, max = %d "
55 uj_signature.r_len, kEcdsaP256SignatureComponentBytes);
58 if (uj_signature.s_len > kEcdsaP256SignatureComponentBytes) {
60 "Signature s value too large for P256 (have = %d bytes, max = %d "
62 uj_signature.s_len, kEcdsaP256SignatureComponentBytes);
65 memset(signature_p256->r, 0, kEcdsaP256SignatureComponentBytes);
66 memcpy(signature_p256->r, uj_signature.r, uj_signature.r_len);
67 memset(signature_p256->s, 0, kEcdsaP256SignatureComponentBytes);
68 memcpy(signature_p256->s, uj_signature.s, uj_signature.s_len);
76 uint32_t flash_exec = 0;
78 sigverify_ecdsa_p256_verify(signature, public_key, digest, &flash_exec);
81 if (result == kErrorOk && flash_exec == kSigverifyEcdsaSuccess) {
85 cryptotest_ecdsa_verify_output_t uj_output;
86 switch (verification_result) {
88 uj_output = kCryptotestEcdsaVerifyOutputFailure;
91 uj_output = kCryptotestEcdsaVerifyOutputSuccess;
94 LOG_ERROR(
"Unexpected result value from otcrypto_ecdsa_verify: %d",
98 RESP_OK(ujson_serialize_cryptotest_ecdsa_verify_output_t, uj, &uj_output);
104 cryptotest_ecdsa_operation_t uj_op;
105 cryptotest_ecdsa_hash_alg_t uj_hash_alg;
106 cryptotest_ecdsa_curve_t uj_curve;
107 cryptotest_ecdsa_message_t uj_message;
108 cryptotest_ecdsa_signature_t uj_signature;
109 cryptotest_ecdsa_coordinate_t uj_qx;
110 cryptotest_ecdsa_coordinate_t uj_qy;
111 cryptotest_ecdsa_private_key_t uj_private_key;
114 TRY(ujson_deserialize_cryptotest_ecdsa_operation_t(uj, &uj_op));
115 TRY(ujson_deserialize_cryptotest_ecdsa_hash_alg_t(uj, &uj_hash_alg));
116 TRY(ujson_deserialize_cryptotest_ecdsa_curve_t(uj, &uj_curve));
117 TRY(ujson_deserialize_cryptotest_ecdsa_message_t(uj, &uj_message));
118 TRY(ujson_deserialize_cryptotest_ecdsa_signature_t(uj, &uj_signature));
119 TRY(ujson_deserialize_cryptotest_ecdsa_coordinate_t(uj, &uj_qx));
120 TRY(ujson_deserialize_cryptotest_ecdsa_coordinate_t(uj, &uj_qy));
121 TRY(ujson_deserialize_cryptotest_ecdsa_private_key_t(uj, &uj_private_key));
126 case kCryptotestEcdsaCurveP256:
127 if (!ecdsa_p256_params_set(uj_qx, uj_qy, uj_signature, &public_key,
129 return INVALID_ARGUMENT();
133 LOG_ERROR(
"Unsupported ECC curve: %d", uj_curve);
134 return INVALID_ARGUMENT();
137 switch (uj_hash_alg) {
138 case kCryptotestEcdsaHashAlgSha256:
141 LOG_ERROR(
"Unsupported ECDSA hash mode: %d", uj_hash_alg);
142 return INVALID_ARGUMENT();
146 memset(digest_be.digest, 0, kHmacDigestNumWords *
sizeof(uint32_t));
147 memcpy(digest_be.digest, uj_message.input, uj_message.input_len);
150 for (
size_t i = 0; launder32(i) < kHmacDigestNumWords; i++) {
152 __builtin_bswap32(digest_be.digest[kHmacDigestNumWords - 1 - i]);
156 case kCryptotestEcdsaOperationVerify: {
157 return sigverify_p256_to_status(uj, &signature_p256, &public_key,
161 LOG_ERROR(
"Usupported ECDSA operation: %d", uj_op);
162 return INVALID_ARGUMENT();
169 cryptotest_cmd_t cmd;
170 TRY(ujson_deserialize_cryptotest_cmd_t(uj, &cmd));
172 case kCryptotestCommandEcdsa:
173 RESP_ERR(uj, sigverify_ecdsa_process_command(uj));
176 LOG_ERROR(
"Unsupported command: %d", cmd);
177 RESP_ERR(uj, INVALID_ARGUMENT());
185 CHECK(otbn_boot_app_load() == kErrorOk);
187 ujson_t uj = ujson_ottf_console();
188 return status_ok(process_cmd(&uj));