Software APIs
sigverify_keys.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/rom_ext/sigverify_keys.h"
6 
7 #include <assert.h>
8 #include <stddef.h>
9 
11 #include "sw/device/silicon_creator/lib/drivers/rnd.h"
12 
13 /**
14  * Determines whether a key is valid.
15  *
16  * Only key_types with known enumerated values are valid.
17  *
18  * @param key_type Type of the key.
19  * @return The result of the operation.
20  */
22 static rom_error_t key_is_valid(sigverify_key_type_t key_type) {
23  switch (launder32(key_type)) {
24  case kSigverifyKeyTypeFirmwareTest:
25  HARDENED_CHECK_EQ(key_type, kSigverifyKeyTypeFirmwareTest);
26  return kErrorOk;
27  case kSigverifyKeyTypeFirmwareProd:
28  HARDENED_CHECK_EQ(key_type, kSigverifyKeyTypeFirmwareProd);
29  return kErrorOk;
30  case kSigverifyKeyTypeFirmwareDev:
31  HARDENED_CHECK_EQ(key_type, kSigverifyKeyTypeFirmwareDev);
32  return kErrorOk;
33  default:
34  HARDENED_TRAP();
36  }
37 }
38 
39 rom_error_t sigverify_rsa_key_get(uint32_t key_id,
40  const sigverify_rsa_key_t **key) {
41  size_t cand_key_index = UINT32_MAX;
42  // Random start index that is less than `kSigverifyRsaKeysCnt`.
43  size_t i = ((uint64_t)rnd_uint32() * (uint64_t)kSigverifyRsaKeysCnt) >> 32;
44  size_t iter_cnt = 0;
45  for (; launder32(iter_cnt) < kSigverifyRsaKeysCnt; ++iter_cnt) {
46  const sigverify_rom_ext_key_t *k = &kSigverifyRsaKeys[i];
47  size_t k_id = sigverify_rsa_key_id_get(&k->key.n);
48  if (launder32(k_id) == key_id) {
49  HARDENED_CHECK_EQ(k_id, key_id);
50  cand_key_index = i;
51  }
52  i += kSigverifyRsaKeysStep;
53  if (launder32(i) >= kSigverifyRsaKeysCnt) {
54  i -= kSigverifyRsaKeysCnt;
55  }
56  HARDENED_CHECK_LT(i, kSigverifyRsaKeysCnt);
57  }
58  HARDENED_CHECK_EQ(iter_cnt, kSigverifyRsaKeysCnt);
59 
60  if (launder32(cand_key_index) < kSigverifyRsaKeysCnt) {
61  HARDENED_CHECK_LT(cand_key_index, kSigverifyRsaKeysCnt);
62  rom_error_t error =
63  key_is_valid(kSigverifyRsaKeys[cand_key_index].key_type);
64  HARDENED_CHECK_EQ(error, kErrorOk);
65  *key = &kSigverifyRsaKeys[cand_key_index].key;
66  return error;
67  }
68 
69  return kErrorSigverifyBadKey;
70 }