Software APIs
spx_verify.h
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 #ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_SIGVERIFY_SPX_VERIFY_H_
6 #define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_SIGVERIFY_SPX_VERIFY_H_
7 
8 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
9 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
10 #include "sw/device/silicon_creator/lib/error.h"
11 #include "sw/device/silicon_creator/lib/sigverify/spx_key.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif // __cplusplus
16 
17 enum {
18  /**
19  * A non-trivial constant chosen such that `kSigverifySpxSuccess ^
20  * kSigverifyRsaSuccess = kSigverifyFlashExec`.
21  */
22  kSigverifySpxSuccess = 0x8d6c8c17,
23  /**
24  * A non-trivial constant equal to `kSigverifySpxSuccess`.
25  *
26  * SPHINCS+ signature verification is always disabled in TEST_UNLOCKED states.
27  * In other life cycle states, setting `CREATOR_SW_CFG_SIGVERIFY_SPX_EN` to
28  * this value disables SPHINCS+ signature verification and any other value
29  * enables it.
30  */
31  kSigverifySpxDisabledOtp = kSigverifySpxSuccess,
32 };
33 
34 /**
35  * Get whether SPHINCS+ signature verification is enabled in OTP.
36  *
37  * This function returns the value of the `CREATOR_SW_CFG_SIGVERIFY_SPX_EN` OTP
38  * item unless the lifecycle state of the device is `TEST_UNLOCKED`. For
39  * `TEST_UNLOCKED` this function always returns `kSigverifySpxDisabledOtp`.
40  *
41  * @param lc_state Life cycle state of the device.
42  * @return Result of the operation.
43  */
45 uint32_t sigverify_spx_verify_enabled(lifecycle_state_t lc_state);
46 
47 /**
48  * Verifies a SPHINCS+ signature.
49  *
50  * To accomodate both "pure" and "pre-hash" variants of SPHINCS+, this function
51  * takes both the raw message components and the precomputed SHA256 digest as
52  * parameters. If the OTP parameter `SIGVERIFY_SPX_PREHASH` is set, then the
53  * raw message is ignored and we sign the digest. If it is unset, we ignore the
54  * digest and sign the raw message.
55  *
56  * @param signature Signature to be verified.
57  * @param key Signer's SPHINCS+ public key.
58  * @param config Signer's SPHINCS+ key configuration.
59  * @param lc_state Life cycle state of the device.
60  * @param msg_prefix_1 Optional message prefix.
61  * @param msg_prefix_1_len Length of the first prefix.
62  * @param msg_prefix_2 Optional message prefix.
63  * @param msg_prefix_2_len Length of the second prefix.
64  * @param msg Start of the message.
65  * @param msg_len Length of the message.
66  * @param digest Precomputed SHA256 digest of the message.
67  * @param[out] flash_exec Value to write to the flash_ctrl EXEC register.
68  * @return Result of the operation.
69  */
71 rom_error_t sigverify_spx_verify(
72  const sigverify_spx_signature_t *signature, const sigverify_spx_key_t *key,
73  const sigverify_spx_config_id_t config, lifecycle_state_t lc_state,
74  const void *msg_prefix_1, size_t msg_prefix_1_len, const void *msg_prefix_2,
75  size_t msg_prefix_2_len, const void *msg, size_t msg_len,
76  const hmac_digest_t *digest, uint32_t *flash_exec);
77 
78 /**
79  * Transforms `kSigverifySpxSuccess` into `kErrorOk`.
80  *
81  * Callers should transform the result to a suitable error value if it is not
82  * `kErrorOk` for ease of debugging.
83  *
84  * @param v A value.
85  * @return `kErrorOk` if `v` is `kSigverifySpxSuccess`.
86  */
88 inline uint32_t sigverify_spx_success_to_ok(uint32_t v) {
89  return (v << 22 ^ v << 8 ^ v << 1) >> 20;
90 }
91 
92 #ifdef __cplusplus
93 } // extern "C"
94 #endif // __cplusplus
95 
96 #endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_SIGVERIFY_SPX_VERIFY_H_