Software APIs
error.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_ERROR_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_ERROR_H_
7
10
11#define USING_INTERNAL_STATUS
12#include "sw/device/lib/base/internal/status.h"
13#undef USING_INTERNAL_STATUS
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
19/**
20 * List of modules which can produce errors.
21 *
22 * Choose a two-letter identifier for each module and encode the module
23 * identifier the concatenated ASCII representation of those letters.
24 */
25#define MODULE_CODE(ch0_, ch1_) ((ch0_) << 8 | (ch1_))
26enum module_ {
27 // clang-format off
28 kModuleUnknown = 0,
29 kModuleAlertHandler = MODULE_CODE('A', 'H'),
30 kModuleSigverify = MODULE_CODE('S', 'V'),
31 kModuleKeymgr = MODULE_CODE('K', 'M'),
32 kModuleManifest = MODULE_CODE('M', 'A'),
33 kModuleRom = MODULE_CODE('M', 'R'),
34 kModuleInterrupt = MODULE_CODE('I', 'R'),
35 kModuleEpmp = MODULE_CODE('E', 'P'),
36 kModuleKmac = MODULE_CODE('K', 'C'),
37 kModuleOtbn = MODULE_CODE('B', 'N'),
38 kModuleFlashCtrl = MODULE_CODE('F', 'C'),
39 kModuleBootPolicy = MODULE_CODE('B', 'P'),
40 kModuleBootstrap = MODULE_CODE('B', 'S'),
41 kModuleLog = MODULE_CODE('L', 'G'),
42 kModuleBootData = MODULE_CODE('B', 'D'),
43 kModuleSpiDevice = MODULE_CODE('S', 'P'),
44 kModuleAst = MODULE_CODE('A', 'S'),
45 kModuleRstmgr = MODULE_CODE('R', 'S'),
46 KModuleRnd = MODULE_CODE('R', 'N'),
47 kModuleBootSvc = MODULE_CODE('B', 'C'),
48 kModuleBootLog = MODULE_CODE('B', 'L'),
49 kModuleRomExt = MODULE_CODE('R', 'E'),
50 kModuleRomExtInterrupt = MODULE_CODE('R', 'I'),
51 kModuleAsn1 = MODULE_CODE('A', '1'),
52 kModuleRetRam = MODULE_CODE('R', 'R'),
53 kModuleXModem = MODULE_CODE('X', 'M'),
54 kModuleRescue = MODULE_CODE('R', 'C'),
55 kModuleCert = MODULE_CODE('C', 'E'),
56 kModuleOwnership = MODULE_CODE('O', 'W'),
57 kModulePersoTlv = MODULE_CODE('P', 'T'),
58 kModuleDice = MODULE_CODE('D', 'C'),
59 kModulePwrmgr = MODULE_CODE('P', 'M'),
60 kModuleGpio = MODULE_CODE('G', 'I'),
61 kModuleUsb = MODULE_CODE('U', 'S'),
62 kModuleNvmCtrl = MODULE_CODE('N', 'V'),
63 kModuleRramCtrl = MODULE_CODE('R', 'M'),
64 // clang-format on
65};
66
67/**
68 * Field definitions for the different fields of the error word.
69 */
70#define ROM_ERROR_FIELD_ERROR ((bitfield_field32_t){.mask = 0xFF, .index = 24})
71#define ROM_ERROR_FIELD_MODULE \
72 ((bitfield_field32_t){.mask = 0xFFFF, .index = 8})
73#define ROM_ERROR_FIELD_STATUS ((bitfield_field32_t){.mask = 0xFF, .index = 0})
74
75/**
76 * Helper macro for building up error codes.
77 * @param status_ An appropriate general status code from absl_staus.h.
78 * @param module_ The module identifier which produces this error.
79 * @param error_ The unique error id in that module. Error ids must not
80 * repeat within a module.
81 */
82#define ERROR_(error_, module_, status_) \
83 ((error_ << 24) | (module_ << 8) | (status_))
84
85// clang-format off
86// Use an X-macro to facilitate writing unit tests.
87// Note: This list is extend-only and you may not renumber errors after they
88// have been created. This is required for error-space stability
89// after the ROM is frozen.
90#define DEFINE_ERRORS(X) \
91 X(kErrorOk, 0x739), \
92 X(kErrorWriteBootdataThenReboot, 0x2ea), \
93 X(kErrorNoData, 0x4d7), \
94 X(kErrorUnknown, 0xffffffff), \
95 \
96 X(kErrorSigverifyBadRsaSignature, ERROR_(1, kModuleSigverify, kInvalidArgument)), \
97 X(kErrorSigverifyBadSpxSignature, ERROR_(2, kModuleSigverify, kInvalidArgument)), \
98 X(kErrorSigverifyBadKey, ERROR_(3, kModuleSigverify, kInvalidArgument)), \
99 X(kErrorSigverifyBadRsaKey, ERROR_(4, kModuleSigverify, kInvalidArgument)), \
100 X(kErrorSigverifyBadSpxKey, ERROR_(5, kModuleSigverify, kInvalidArgument)), \
101 X(kErrorSigverifyLargeRsaSignature, ERROR_(6, kModuleSigverify, kInvalidArgument)), \
102 X(kErrorSigverifyBadEcdsaSignature, ERROR_(7, kModuleSigverify, kInvalidArgument)), \
103 X(kErrorSigverifyBadAuthPartition, ERROR_(8, kModuleSigverify, kInvalidArgument)), \
104 X(kErrorSigverifyBadEcdsaKey, ERROR_(9, kModuleSigverify, kInvalidArgument)), \
105 X(kErrorSigverifyBadSpxConfig, ERROR_(10, kModuleSigverify, kInvalidArgument)), \
106 X(kErrorSigverifyEcdsaNotFound, ERROR_(11, kModuleSigverify, kNotFound)), \
107 X(kErrorSigverifySpxNotFound, ERROR_(12, kModuleSigverify, kNotFound)), \
108 \
109 X(kErrorKeymgrInternal, ERROR_(1, kModuleKeymgr, kInternal)), \
110 \
111 X(kErrorManifestBadEntryPoint, ERROR_(1, kModuleManifest, kInternal)), \
112 X(kErrorManifestBadCodeRegion, ERROR_(2, kModuleManifest, kInternal)), \
113 X(kErrorManifestBadSignedRegion, ERROR_(3, kModuleManifest, kInternal)), \
114 X(kErrorManifestBadExtension, ERROR_(4, kModuleManifest, kInternal)), \
115 X(kErrorManifestBadVersionMajor, ERROR_(5, kModuleManifest, kInternal)), \
116 \
117 X(kErrorAlertBadIndex, ERROR_(1, kModuleAlertHandler, kInvalidArgument)), \
118 X(kErrorAlertBadClass, ERROR_(2, kModuleAlertHandler, kInvalidArgument)), \
119 X(kErrorAlertBadEnable, ERROR_(3, kModuleAlertHandler, kInvalidArgument)), \
120 X(kErrorAlertBadEscalation, ERROR_(4, kModuleAlertHandler, kInvalidArgument)), \
121 X(kErrorAlertBadCrc32, ERROR_(5, kModuleAlertHandler, kInvalidArgument)), \
122 \
123 X(kErrorRomBootFailed, ERROR_(1, kModuleRom, kFailedPrecondition)), \
124 X(kErrorRomResetReasonFault, ERROR_(2, kModuleRom, kUnknown)), \
125 X(kErrorRomImmSection, ERROR_(3, kModuleRom, kInvalidArgument)), \
126 \
127 /* The high-byte of kErrorInterrupt is modified with the interrupt cause */ \
128 X(kErrorInterrupt, ERROR_(0, kModuleInterrupt, kUnknown)), \
129 \
130 X(kErrorEpmpBadCheck, ERROR_(1, kModuleEpmp, kInternal)), \
131 \
132 X(kErrorKmacInvalidStatus, ERROR_(1, kModuleKmac, kInternal)), \
133 X(kErrorKmacInvalidKeySize, ERROR_(2, kModuleKmac, kInvalidArgument)), \
134 \
135 X(kErrorOtbnInvalidArgument, ERROR_(1, kModuleOtbn, kInvalidArgument)), \
136 X(kErrorOtbnBadOffsetLen, ERROR_(2, kModuleOtbn, kInvalidArgument)), \
137 X(kErrorOtbnExecutionFailed, ERROR_(3, kModuleOtbn, kInternal)), \
138 X(kErrorOtbnSecWipeImemFailed, ERROR_(4, kModuleOtbn, kInternal)), \
139 X(kErrorOtbnSecWipeDmemFailed, ERROR_(5, kModuleOtbn, kInternal)), \
140 X(kErrorOtbnBadInsnCount, ERROR_(6, kModuleOtbn, kInternal)), \
141 X(kErrorOtbnUnavailable, ERROR_(7, kModuleOtbn, kInternal)), \
142 X(kErrorOtbnBadChecksum, ERROR_(8, kModuleOtbn, kInternal)), \
143 \
144 X(kErrorFlashCtrlDataRead, ERROR_(1, kModuleFlashCtrl, kInternal)), \
145 X(kErrorFlashCtrlInfoRead, ERROR_(2, kModuleFlashCtrl, kInternal)), \
146 X(kErrorFlashCtrlDataWrite, ERROR_(3, kModuleFlashCtrl, kInternal)), \
147 X(kErrorFlashCtrlInfoWrite, ERROR_(4, kModuleFlashCtrl, kInternal)), \
148 X(kErrorFlashCtrlDataErase, ERROR_(5, kModuleFlashCtrl, kInternal)), \
149 X(kErrorFlashCtrlInfoErase, ERROR_(6, kModuleFlashCtrl, kInternal)), \
150 X(kErrorFlashCtrlDataEraseVerify, ERROR_(7, kModuleFlashCtrl, kInternal)), \
151 \
152 X(kErrorRramCtrlDataRead, ERROR_(1, kModuleRramCtrl, kInternal)), \
153 X(kErrorRramCtrlInfoRead, ERROR_(2, kModuleRramCtrl, kInternal)), \
154 X(kErrorRramCtrlDataWrite, ERROR_(3, kModuleRramCtrl, kInternal)), \
155 X(kErrorRramCtrlInfoWrite, ERROR_(4, kModuleRramCtrl, kInternal)), \
156 \
157 X(kErrorBootPolicyBadIdentifier, ERROR_(1, kModuleBootPolicy, kInternal)), \
158 X(kErrorBootPolicyBadLength, ERROR_(2, kModuleBootPolicy, kInternal)), \
159 X(kErrorBootPolicyRollback, ERROR_(3, kModuleBootPolicy, kInternal)), \
160 \
161 X(kErrorBootstrapEraseAddress, ERROR_(1, kModuleBootstrap, kInvalidArgument)), \
162 X(kErrorBootstrapProgramAddress, ERROR_(2, kModuleBootstrap, kInvalidArgument)), \
163 X(kErrorBootstrapInvalidState, ERROR_(3, kModuleBootstrap, kInvalidArgument)), \
164 X(kErrorBootstrapNotRequested, ERROR_(4, kModuleBootstrap, kInternal)), \
165 X(kErrorBootstrapDisabledRomExt, ERROR_(5, kModuleBootstrap, kInternal)), \
166 \
167 X(kErrorLogBadFormatSpecifier, ERROR_(1, kModuleLog, kInternal)), \
168 \
169 X(kErrorBootDataNotFound, ERROR_(1, kModuleBootData, kInternal)), \
170 X(kErrorBootDataWriteCheck, ERROR_(2, kModuleBootData, kInternal)), \
171 X(kErrorBootDataInvalid, ERROR_(3, kModuleBootData, kInternal)), \
172 \
173 X(kErrorSpiDevicePayloadOverflow, ERROR_(1, kModuleSpiDevice, kInternal)), \
174 \
175 X(kErrorAstInitNotDone, ERROR_(1, kModuleAst, kInternal)), \
176 \
177 X(kErrorRstmgrBadInit, ERROR_(1, kModuleRstmgr, kInternal)), \
178 \
179 X(kErrorRndBadCrc32, ERROR_(1, KModuleRnd, kInvalidArgument)), \
180 \
181 X(kErrorBootSvcBadHeader, ERROR_(1, kModuleBootSvc, kInternal)), \
182 X(kErrorBootSvcBadSlot, ERROR_(2, kModuleBootSvc, kInvalidArgument)), \
183 X(kErrorBootSvcBadSecVer, ERROR_(3, kModuleBootSvc, kInvalidArgument)), \
184 \
185 X(kErrorRomExtBootFailed, ERROR_(1, kModuleRomExt, kFailedPrecondition)), \
186 \
187 X(kErrorXModemTimeoutStart, ERROR_(1, kModuleXModem, kDeadlineExceeded)), \
188 X(kErrorXModemTimeoutPacket, ERROR_(2, kModuleXModem, kDeadlineExceeded)), \
189 X(kErrorXModemTimeoutData, ERROR_(3, kModuleXModem, kDeadlineExceeded)), \
190 X(kErrorXModemTimeoutCrc, ERROR_(4, kModuleXModem, kDeadlineExceeded)), \
191 X(kErrorXModemTimeoutAck, ERROR_(5, kModuleXModem, kDeadlineExceeded)), \
192 X(kErrorXModemCrc, ERROR_(6, kModuleXModem, kDataLoss)), \
193 X(kErrorXModemEndOfFile, ERROR_(7, kModuleXModem, kOutOfRange)), \
194 X(kErrorXModemCancel, ERROR_(8, kModuleXModem, kCancelled)), \
195 X(kErrorXModemUnknown, ERROR_(9, kModuleXModem, kUnknown)), \
196 X(kErrorXModemProtocol, ERROR_(10, kModuleXModem, kInvalidArgument)), \
197 X(kErrorXModemTooManyErrors, ERROR_(11, kModuleXModem, kFailedPrecondition)), \
198 X(kErrorXModemBadLength, ERROR_(12, kModuleXModem, kInvalidArgument)), \
199 \
200 /* The high-byte of kErrorInterrupt is modified with the interrupt cause */ \
201 X(kErrorRomExtInterrupt, ERROR_(0, kModuleRomExtInterrupt, kUnknown)), \
202 \
203 X(kErrorBootLogInvalid, ERROR_(1, kModuleBootLog, kInternal)), \
204 \
205 X(kErrorAsn1Internal, ERROR_(1, kModuleAsn1, kInternal)), \
206 X(kErrorAsn1StartInvalidArgument, ERROR_(2, kModuleAsn1, kInvalidArgument)), \
207 X(kErrorAsn1PushBytesInvalidArgument, ERROR_(3, kModuleAsn1, kInvalidArgument)), \
208 X(kErrorAsn1PushIntegerPadInvalidArgument, ERROR_(4, kModuleAsn1, kInvalidArgument)), \
209 X(kErrorAsn1PushIntegerInvalidArgument, ERROR_(5, kModuleAsn1, kInvalidArgument)), \
210 X(kErrorAsn1FinishBitstringInvalidArgument, ERROR_(6, kModuleAsn1, kInvalidArgument)), \
211 X(kErrorAsn1BufferExhausted, ERROR_(7, kModuleAsn1, kResourceExhausted)), \
212 \
213 X(kErrorRetRamBadVersion, ERROR_(1, kModuleRetRam, kUnknown)), \
214 \
215 X(kErrorRescueReboot, ERROR_(0, kModuleRescue, kInternal)), \
216 X(kErrorRescueBadMode, ERROR_(1, kModuleRescue, kInvalidArgument)), \
217 X(kErrorRescueImageTooBig, ERROR_(2, kModuleRescue, kFailedPrecondition)), \
218 X(kErrorRescueSendStart, ERROR_(4, kModuleRescue, kInternal)), \
219 X(kErrorRescueInactivity, ERROR_(5, kModuleRescue, kDeadlineExceeded)), \
220 \
221 X(kErrorCertInternal, ERROR_(0, kModuleCert, kInternal)), \
222 X(kErrorCertInvalidArgument, ERROR_(1, kModuleCert, kInvalidArgument)), \
223 X(kErrorCertInvalidSize, ERROR_(2, kModuleCert, kDataLoss)), \
224 \
225 X(kErrorOwnershipInvalidNonce, ERROR_(0, kModuleOwnership, kInvalidArgument)), \
226 X(kErrorOwnershipInvalidMode, ERROR_(1, kModuleOwnership, kInvalidArgument)), \
227 X(kErrorOwnershipInvalidSignature, ERROR_(2, kModuleOwnership, kInvalidArgument)), \
228 X(kErrorOwnershipInvalidState, ERROR_(3, kModuleOwnership, kInvalidArgument)), \
229 X(kErrorOwnershipInvalidRequest, ERROR_(4, kModuleOwnership, kInvalidArgument)), \
230 X(kErrorOwnershipInvalidTag, ERROR_(5, kModuleOwnership, kInvalidArgument)), \
231 X(kErrorOwnershipInvalidTagLength, ERROR_(6, kModuleOwnership, kInvalidArgument)), \
232 X(kErrorOwnershipDuplicateItem, ERROR_(7, kModuleOwnership, kAlreadyExists)), \
233 X(kErrorOwnershipNvmConfigLength, ERROR_(8, kModuleOwnership, kOutOfRange)), \
234 X(kErrorOwnershipInvalidInfoPage, ERROR_(9, kModuleOwnership, kInvalidArgument)), \
235 X(kErrorOwnershipBadInfoPage, ERROR_(10, kModuleOwnership, kInternal)), \
236 X(kErrorOwnershipNoOwner, ERROR_(11, kModuleOwnership, kInternal)), \
237 X(kErrorOwnershipKeyNotFound, ERROR_(12, kModuleOwnership, kNotFound)), \
238 X(kErrorOwnershipInvalidDin, ERROR_(13, kModuleOwnership, kInvalidArgument)), \
239 X(kErrorOwnershipUnlockDenied, ERROR_(14, kModuleOwnership, kPermissionDenied)), \
240 X(kErrorOwnershipNvmConfigRomExt, ERROR_(15, kModuleOwnership, kInvalidArgument)), \
241 X(kErrorOwnershipNvmConfigBounds, ERROR_(16, kModuleOwnership, kInvalidArgument)), \
242 X(kErrorOwnershipInvalidAlgorithm, ERROR_(17, kModuleOwnership, kInvalidArgument)), \
243 X(kErrorOwnershipNvmConfigSlots, ERROR_(18, kModuleOwnership, kInvalidArgument)), \
244 X(kErrorOwnershipInvalidRescueBounds, ERROR_(19, kModuleOwnership, kInvalidArgument)), \
245 X(kErrorOwnershipSignatureNotFound, ERROR_(20, kModuleOwnership, kNotFound)), \
246 /* Group all of the ISFB error codes together */ \
247 X(kErrorOwnershipISFBNotPresent, ERROR_(0x60, kModuleOwnership, kNotFound)), \
248 X(kErrorOwnershipISFBProductExpCnt, ERROR_(0x61, kModuleOwnership, kOutOfRange)), \
249 X(kErrorOwnershipISFBStrikeMask, ERROR_(0x62, kModuleOwnership, kPermissionDenied)), \
250 X(kErrorOwnershipISFBProductExp, ERROR_(0x63, kModuleOwnership, kPermissionDenied)), \
251 X(kErrorOwnershipISFBFailed, ERROR_(0x64, kModuleOwnership, kInternal)), \
252 X(kErrorOwnershipISFBPage, ERROR_(0x65, kModuleOwnership, kInvalidArgument)), \
253 X(kErrorOwnershipISFBSize, ERROR_(0x66, kModuleOwnership, kInvalidArgument)), \
254 /* Group all of the tag version error codes together */ \
255 X(kErrorOwnershipOWNRVersion, ERROR_(0x70, kModuleOwnership, kInvalidArgument)), \
256 X(kErrorOwnershipAPPKVersion, ERROR_(0x71, kModuleOwnership, kInvalidArgument)), \
257 X(kErrorOwnershipFLSHVersion, ERROR_(0x72, kModuleOwnership, kInvalidArgument)), \
258 X(kErrorOwnershipINFOVersion, ERROR_(0x73, kModuleOwnership, kInvalidArgument)), \
259 X(kErrorOwnershipRESQVersion, ERROR_(0x74, kModuleOwnership, kInvalidArgument)), \
260 X(kErrorOwnershipISFBVersion, ERROR_(0x75, kModuleOwnership, kInvalidArgument)), \
261 \
262 X(kErrorPersoTlvInternal, ERROR_(0, kModulePersoTlv, kInternal)), \
263 X(kErrorPersoTlvCertObjNotFound, ERROR_(1, kModulePersoTlv, kNotFound)), \
264 X(kErrorPersoTlvCertNameTooLong, ERROR_(2, kModulePersoTlv, kOutOfRange)), \
265 X(kErrorPersoTlvOutputBufTooSmall, ERROR_(3, kModulePersoTlv, kOutOfRange)), \
266 \
267 X(kErrorDiceInternal, ERROR_(0, kModuleDice, kInternal)), \
268 X(kErrorDiceCwtCoseKeyNotFound, ERROR_(1, kModuleDice, kNotFound)), \
269 X(kErrorDiceCwtCoseKeyBadSize, ERROR_(1, kModuleDice, kInternal)), \
270 X(kErrorDiceCwtKeyCoordsNotFound, ERROR_(2, kModuleDice, kNotFound)), \
271 X(kErrorDicePageCorrupted, ERROR_(3, kModuleDice, kInvalidArgument)), \
272 \
273 X(kErrorPwrmgrUnknownRequestSource, ERROR_(1, kModulePwrmgr, kInvalidArgument)), \
274 X(kErrorPwrmgrInvalidRequestType, ERROR_(2, kModulePwrmgr, kInvalidArgument)), \
275 \
276 X(kErrorGpioInvalidPin, ERROR_(0, kModuleGpio, kInvalidArgument)), \
277 X(kErrorUsbBadSetup, ERROR_(0, kModuleUsb, kInvalidArgument)), \
278 X(kErrorUsbBadEndpointNumber, ERROR_(1, kModuleUsb, kInvalidArgument)), \
279 \
280 X(kErrorNvmCtrlInvalidInfoPage, ERROR_(1, kModuleNvmCtrl, kInvalidArgument)), \
281 \
282 /* This comment prevent clang from trying to format the macro. */
283
284// clang-format on
285
286#define ERROR_ENUM_INIT(name_, value_) name_ = value_
287
288/**
289 * Unified set of errors for ROM and ROM_EXT.
290 */
291typedef enum rom_error { DEFINE_ERRORS(ERROR_ENUM_INIT) } rom_error_t;
292
293/**
294 * Evaluate an expression and return if the result is an error.
295 *
296 * @param expr_ An expression which results in a `rom_error_t`.
297 */
298#define RETURN_IF_ERROR(expr_) \
299 do { \
300 rom_error_t local_error_ = expr_; \
301 if (local_error_ != kErrorOk) { \
302 return local_error_; \
303 } \
304 } while (false)
305
306/**
307 * Hardened version of `RETURN_IF_ERROR()`.
308 *
309 * See `launder32()` and `HARDENED_CHECK_EQ()` in
310 * `sw/device/lib/base/hardened.h` for more details.
311 *
312 * @param expr_ An expression which results in a `rom_error_t`.
313 */
314#define HARDENED_RETURN_IF_ERROR(expr_) \
315 do { \
316 rom_error_t error_ = expr_; \
317 if (launder32(error_) != kErrorOk) { \
318 return error_; \
319 } \
320 HARDENED_CHECK_EQ(error_, kErrorOk); \
321 } while (false)
322
323#ifdef __cplusplus
324}
325#endif
326#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_ERROR_H_