Software APIs
ecdsa_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 
6 #include "sw/device/lib/base/status.h"
8 #include "sw/device/lib/testing/entropy_testutils.h"
9 #include "sw/device/lib/testing/hexstr.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
12 #include "sw/device/silicon_creator/lib/ownership/ecdsa.h"
13 #include "sw/device/silicon_creator/lib/ownership/keys/fake/no_owner_recovery_ecdsa_p256.h"
14 
15 // From: http://www.abrahamlincolnonline.org/lincoln/speeches/gettysburg.htm
16 static const char kGettysburgPrelude[] =
17  "Four score and seven years ago our fathers brought forth on this "
18  "continent, a new nation, conceived in Liberty, and dedicated to the "
19  "proposition that all men are created equal.";
20 
21 // clang-format off
22 /*
23  * This signature was generated by signing the sha256sum of the prelude to
24  * Lincoln's Gettysburg Address with the fake "no owner recovery key".
25  *
26  $ echo -n "Four score and seven years ago our fathers brought forth on this\
27  continent, a new nation, conceived in Liberty, and dedicated to the\
28  proposition that all men are created equal." | sha256sum -
29 
30  1e6fd4030f9034cd775708a396c324ed420ec587eb3dd433e29f6ac08b8cc7ba -
31 
32  $ opentitantool ecdsa sign \
33  sw/device/silicon_creator/rom_ext/keys/fake/ownership_no_owner_recovery_ecdsa_p256.der \
34  0x1e6fd4030f9034cd775708a396c324ed420ec587eb3dd433e29f6ac08b8cc7ba
35 
36 {
37  digest: "bac78c8bc06a9fe233d43deb87c50e42ed24c396a3085777cd34900f03d46f1e",
38  signature: "cda24f37d4979cea1446c495af344af83d2047d13191b41003431a182bf2b74c365b08b78c57e3c3c11960fbc4a53fb63f61aecba3ddbda00059aebd08ad8f2c"
39 }
40 
41  *
42  * The `digest` and `signature` string were copied verbatim into this test.
43  */
44 // This is the little-endian representation of the Gettysburg SHA256 digest.
45 static const char kGettysburgDigest[] =
46  "bac78c8bc06a9fe233d43deb87c50e42ed24c396a3085777cd34900f03d46f1e";
47 
48 static const char kGettysburgSignature[] =
49  "cda24f37d4979cea1446c495af344af83d2047d13191b41003431a182bf2b74c"
50  "365b08b78c57e3c3c11960fbc4a53fb63f61aecba3ddbda00059aebd08ad8f2c";
51 // clang-format on
52 
53 static const owner_key_t kNoOwnerRecoveryKey = NO_OWNER_RECOVERY_ECDSA_P256;
54 
55 void __assert_func(const char *file, int line, const char *func,
56  const char *expr) {
57  LOG_ERROR("%s:%d: %s %s", file, line, func, expr);
58  abort();
59 }
60 
61 static status_t initialize(void) {
62  TRY(ecdsa_init());
63  return OK_STATUS();
64 }
65 
66 // Tests that we can verify an ECDSA signature given the digest.
67 status_t ecdsa_verify_digest_test(void) {
68  hmac_digest_t digest;
69  TRY(hexstr_decode(&digest, sizeof(digest), kGettysburgDigest));
70  owner_signature_t signature;
71  TRY(hexstr_decode(&signature.ecdsa, sizeof(signature.ecdsa),
72  kGettysburgSignature));
73  hardened_bool_t result = ecdsa_verify_digest(&kNoOwnerRecoveryKey.ecdsa,
74  &signature.ecdsa, &digest);
75  TRY_CHECK(result == kHardenedBoolTrue);
76  return OK_STATUS();
77 }
78 
79 // Tests that we can verify an ECDSA signature of a message.
80 // The message is first sha256-hashed to a digest and then verified.
81 status_t ecdsa_verify_message_test(void) {
82  owner_signature_t signature;
83  TRY(hexstr_decode(&signature.ecdsa, sizeof(signature.ecdsa),
84  kGettysburgSignature));
85  hardened_bool_t result =
86  ecdsa_verify_message(&kNoOwnerRecoveryKey.ecdsa, &signature.ecdsa,
87  kGettysburgPrelude, sizeof(kGettysburgPrelude) - 1);
88  TRY_CHECK(result == kHardenedBoolTrue);
89  return OK_STATUS();
90 }
91 
92 OTTF_DEFINE_TEST_CONFIG();
93 
94 bool test_main(void) {
95  CHECK_STATUS_OK(entropy_testutils_auto_mode_init());
96  status_t result = initialize();
97  EXECUTE_TEST(result, ecdsa_verify_digest_test);
98  EXECUTE_TEST(result, ecdsa_verify_message_test);
99  return status_ok(result);
100 }