Software APIs
ecdsa.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/silicon_creator/lib/ownership/ecdsa.h"
6 
7 #include <stdbool.h>
8 
11 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
12 #if USE_OTBN == 1
13 #include "sw/device/silicon_creator/lib/otbn_boot_services.h"
14 #elif USE_CRYPTOC == 1
15 // TODO(cfrantz): Replace the CryptoC implementation with a native OpenTitan
16 // implementation.
17 #include "sw/vendor/cryptoc/include/cryptoc/p256.h"
18 #include "sw/vendor/cryptoc/include/cryptoc/p256_ecdsa.h"
19 
20 // This satisfies cryptoc's use of the assert macro.
21 OT_WEAK void __assert_func(const char *file, int line, const char *func,
22  const char *expr) {
23  while (true) {
24  HARDENED_TRAP();
25  }
26 }
27 #else
28 #error "No ECDSA implementation for lib/ownership."
29 #endif
30 
31 rom_error_t ecdsa_init(void) {
32 #if USE_OTBN == 1
33  return otbn_boot_app_load();
34 #elif USE_CRYPTOC == 1
35  return kErrorOk;
36 #endif
37 }
38 
39 hardened_bool_t ecdsa_verify_digest(const ecdsa_p256_public_key_t *pubkey,
40  const ecdsa_p256_signature_t *signature,
41  const hmac_digest_t *digest) {
42 #if USE_OTBN == 1
43  uint32_t rr[8];
44  rom_error_t error = otbn_boot_sigverify(pubkey, signature, digest, rr);
45  if (error != kErrorOk) {
46  return kHardenedBoolFalse;
47  }
48  return hardened_memeq(signature->r, rr, ARRAYSIZE(rr));
49 #elif USE_CRYPTOC == 1
50  const p256_int *x = (const p256_int *)&pubkey->data[0];
51  const p256_int *y = (const p256_int *)&pubkey->data[8];
52  const p256_int *r = (const p256_int *)&signature->data[0];
53  const p256_int *s = (const p256_int *)&signature->data[8];
54  const p256_int *message = (const p256_int *)&digest->digest;
55 
56  int ok = p256_ecdsa_verify(x, y, message, r, s);
58  return result;
59 #endif
60 }
61 
62 hardened_bool_t ecdsa_verify_message(const ecdsa_p256_public_key_t *pubkey,
63  const ecdsa_p256_signature_t *signature,
64  const void *message, size_t message_len) {
65  hmac_digest_t digest;
66  hmac_sha256(message, message_len, &digest);
67  return ecdsa_verify_digest(pubkey, signature, &digest);
68 }