5 #include "sw/device/silicon_creator/lib/sigverify/spx_verify.h"
9 #include "sw/device/silicon_creator/lib/drivers/otp.h"
10 #include "sw/device/silicon_creator/lib/sigverify/sphincsplus/verify.h"
12 #include "otp_ctrl_regs.h"
17 uint32_t sigverify_spx_verify_enabled(lifecycle_state_t lc_state) {
18 switch (launder32(lc_state)) {
23 return kSigverifySpxDisabledOtp;
26 return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_SIGVERIFY_SPX_EN_OFFSET);
29 return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_SIGVERIFY_SPX_EN_OFFSET);
32 return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_SIGVERIFY_SPX_EN_OFFSET);
35 return otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_SIGVERIFY_SPX_EN_OFFSET);
58 static const uint32_t kSpxVerifyShares[kSigverifySpxRootNumWords] = {
73 static const uint8_t kSpxVerifyPureDomainSep[] = {
87 static const uint8_t kSpxVerifyPrehashDomainSep[] = {
88 0x01, 0x00, 0x06, 0x09, 0x60, 0x86, 0x48,
89 0x01, 0x65, 0x03, 0x04, 0x02, 0x01};
91 rom_error_t sigverify_spx_verify(
93 const sigverify_spx_config_id_t config, lifecycle_state_t lc_state,
94 const void *msg_prefix_1,
size_t msg_prefix_1_len,
const void *msg_prefix_2,
95 size_t msg_prefix_2_len,
const void *msg,
size_t msg_len,
97 uint32_t spx_en = launder32(sigverify_spx_verify_enabled(lc_state));
98 rom_error_t error = kErrorSigverifyBadSpxSignature;
99 if (launder32(spx_en) != kSigverifySpxDisabledOtp) {
101 spx_public_key_root(key->data, expected_root.
data);
103 if (launder32(config) == kSigverifySpxConfigIdSha2128sPrehash) {
105 HARDENED_RETURN_IF_ERROR(
106 spx_verify(signature->
data, kSpxVerifyPrehashDomainSep,
107 sizeof(kSpxVerifyPrehashDomainSep),
110 (
unsigned char *)digest->digest,
sizeof(digest->digest),
111 key->data, actual_root.
data));
112 }
else if (launder32(config) == kSigverifySpxConfigIdSha2128s) {
114 HARDENED_RETURN_IF_ERROR(
115 spx_verify(signature->
data, kSpxVerifyPureDomainSep,
116 sizeof(kSpxVerifyPureDomainSep), msg_prefix_1,
117 msg_prefix_1_len, msg_prefix_2, msg_prefix_2_len, msg,
118 msg_len, key->data, actual_root.
data));
121 return kErrorSigverifyBadSpxConfig;
125 for (; launder32(i) < kSigverifySpxRootNumWords; ++i) {
126 actual_root.
data[i] ^= expected_root.
data[i] ^ kSpxVerifyShares[i];
129 uint32_t flash_exec_spx = 0;
131 for (--i; launder32(i) < kSigverifySpxRootNumWords; --i) {
134 diff |= actual_root.
data[i] ^ kSpxVerifyShares[i];
136 diff |= ~(diff >> 31) + 1;
138 flash_exec_spx ^= actual_root.
data[i];
140 flash_exec_spx |= diff;
143 error = sigverify_spx_success_to_ok(flash_exec_spx);
144 *flash_exec ^= flash_exec_spx;
147 *flash_exec ^= spx_en;
148 uint32_t otp_val = sigverify_spx_verify_enabled(lc_state);
151 error = sigverify_spx_success_to_ok(otp_val);
153 if (error != kErrorOk) {
154 return kErrorSigverifyBadSpxSignature;
160 extern uint32_t sigverify_spx_success_to_ok(uint32_t v);