Software APIs
ecdsa_p256_verify_functest.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/lib/crypto/drivers/entropy.h"
6 #include "sw/device/lib/crypto/drivers/otbn.h"
7 #include "sw/device/lib/crypto/impl/ecc/p256.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
12 
13 // The autogen rule that creates this header creates it in a directory named
14 // after the rule, then manipulates the include path in the
15 // cc_compilation_context to include that directory, so the compiler will find
16 // the version of this file matching the Bazel rule under test.
17 #include "ecdsa_p256_verify_testvectors.h"
18 
19 status_t ecdsa_p256_verify_test(
20  const ecdsa_p256_verify_test_vector_t *testvec) {
21  // Hash message.
22  otcrypto_const_byte_buf_t msg_buf = {
23  .data = testvec->msg,
24  .len = testvec->msg_len,
25  };
26  uint32_t digest_buf[kSha256DigestWords];
27  otcrypto_hash_digest_t digest = {
28  .mode = kOtcryptoHashModeSha256,
29  .data = digest_buf,
30  .len = kSha256DigestWords,
31  };
32  TRY(otcrypto_hash(msg_buf, digest));
33 
34  // Attempt to verify signature.
35  TRY(p256_ecdsa_verify_start(&testvec->signature, digest.data,
36  &testvec->public_key));
37  hardened_bool_t result;
38  TRY(p256_ecdsa_verify_finalize(&testvec->signature, &result));
39 
40  if (testvec->valid && result != kHardenedBoolTrue) {
41  LOG_ERROR("Valid signature failed verification.");
42  return OTCRYPTO_RECOV_ERR;
43  } else if (!testvec->valid && result != kHardenedBoolFalse) {
44  LOG_ERROR("Invalid signature passed verification.");
45  return OTCRYPTO_RECOV_ERR;
46  }
47 
48  return OTCRYPTO_OK;
49 }
50 
51 OTTF_DEFINE_TEST_CONFIG();
52 
53 bool test_main(void) {
54  // Stays true only if all tests pass.
55  bool result = true;
56 
57  CHECK_STATUS_OK(entropy_complex_init());
58 
59  // The definition of `RULE_NAME` comes from the autogen Bazel rule.
60  LOG_INFO("Starting ecdsa_p256_verify_test:%s", RULE_NAME);
61  for (uint32_t i = 0; i < kEcdsaP256VerifyNumTests; i++) {
62  LOG_INFO("Starting ecdsa_p256_verify_test on test vector %d of %d...",
63  i + 1, kEcdsaP256VerifyNumTests);
64  // Run test and print out result.
65  ecdsa_p256_verify_test_vector_t testvec = ecdsa_p256_verify_tests[i];
66  status_t err = ecdsa_p256_verify_test(&testvec);
67  if (status_ok(err)) {
68  LOG_INFO("Finished ecdsa_p256_verify_test on test vector %d : ok", i + 1);
69  } else {
70  LOG_ERROR("Finished ecdsa_p256_verify_test on test vector %d : error %r",
71  i + 1, err);
72  // For help with debugging, print the OTBN error bits, instruction
73  // count, and test vector notes.
74  LOG_INFO("OTBN error bits: 0x%08x", otbn_err_bits_get());
75  LOG_INFO("OTBN instruction count: 0x%08x", otbn_instruction_count_get());
76  LOG_INFO("Test notes: %s", testvec.comment);
77  result = false;
78  }
79  }
80  LOG_INFO("Finished ecdsa_p256_verify_test:%s", RULE_NAME);
81 
82  return result;
83 }