Software APIs
dif_otp_ctrl.h
Go to the documentation of this file.
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 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
5 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
6 
7 /**
8  * @file
9  * @brief <a href="/hw/top_earlgrey/ip_autogen/otp_ctrl/doc/">
10  * OTP Controller</a> Device Interface Functions
11  */
12 
13 #include <stdint.h>
14 
18 
19 #include "sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h"
20 
21 // Header Extern Guard (so header can be used from C and C++)
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * A partition within OTP memory.
28  */
29 typedef enum dif_otp_ctrl_partition {
30  /**
31  * Vendor test partition.
32  *
33  * This is reserved for manufacturing smoke checks. The OTP wrapper
34  * control logic inside prim_otp is allowed to read/write to this
35  * region. ECC uncorrectable errors seen on the functional prim_otp
36  * interface will not lead to an alert for this partition.
37  * Instead, such errors will be reported as correctable ECC errors.
38  */
40  /**
41  * Software configuration partition.
42  *
43  * This is for device-specific calibration data, e.g, clock, LDO, RNG,
44  * and configuration settings set by the ROM.
45  */
47  /**
48  * Software configuration partition.
49  *
50  * This contains data that changes software behavior in the ROM, for
51  * example enabling defensive features in ROM or selecting failure
52  * modes if verification fails.
53  */
55 #if defined(OPENTITAN_IS_EARLGREY)
56  /**
57  * This OTP partition is used to store four P-256 keys and four Sphincs+ keys.
58  *
59  * The partition requires 464
60  * bytes of software visible storage. The partition is
61  * locked at manufacturing time to protect against
62  * malicious write attempts.
63  */
64  kDifOtpCtrlPartitionRotCreatorAuthCodesign,
65  /**
66  * This OTP partition is used to capture the state of each key slot.
67  *
68  * Each key can be in one of the
69  * following states: BLANK, ENABLED, DISABLED. The
70  * encoded values are such that transitions between
71  * BLANK -> ENABLED -> DISABLED are possible without
72  * causing ECC errors (this is a mechanism similar to
73  * how we manage life cycle state transitions). The
74  * partition is left unlocked to allow STATE updates in
75  * the field. The ROM_EXT is required to lock access to
76  * the OTP Direct Access Interface to prevent DoS
77  * attacks from malicious code executing on Silicon
78  * Owner partitions. DAI write locking is available in
79  * EarlGrey.
80  */
81  kDifOtpCtrlPartitionRotCreatorAuthState,
82 #elif defined(OPENTITAN_IS_DARJEELING)
83  /**
84  * SW managed asset ownership states partition.
85  *
86  * Multibit enable value for the tracking the asset ownership states.
87  * Note that the states can be written multiple times in a device lifetime.
88  * The values to be written are engineered in the same way as the LC_CTRL
89  * state encoding words so that the ECC encoding remains valid even after
90  * updating the values.
91  *
92  * The constants can be found in the lc_ctrl_state_pkg.sv package.
93  *
94  * The programming order has to adhere to:
95  *
96  * OWNERSHIP_ST_RAW (factory all-zero state) ->
97  * OWNERSHIP_ST_LOCKED0 ->
98  * OWNERSHIP_ST_RELEASED0 ->
99  * ...
100  * OWNERSHIP_ST_SCRAPPED
101  *
102  * Note that if there are less than 4 slots available the higher slot states
103  * become logically equivalent to OWNERSHIP_SCRAPPED (firmware has to handle
104  * this correctly).
105  */
106  kDifOtpCtrlPartitionOwnershipSlotState,
107  /**
108  * Software managed creator partition.
109  *
110  */
111  kDifOtpCtrlPartitionRotCreatorAuth,
112  /**
113  * Software managed owner slot 0 partition.
114  *
115  */
116  kDifOtpCtrlPartitionRotOwnerAuthSlot0,
117  /**
118  * Software managed owner slot 1 partition.
119  *
120  */
121  kDifOtpCtrlPartitionRotOwnerAuthSlot1,
122  /**
123  * Software managed platform integrator slot 0 partition.
124  *
125  */
126  kDifOtpCtrlPartitionPlatIntegAuthSlot0,
127  /**
128  * Software managed platform integrator slot 1 partition.
129  *
130  */
131  kDifOtpCtrlPartitionPlatIntegAuthSlot1,
132  /**
133  * Software managed platform owner slot 0 partition.
134  *
135  */
136  kDifOtpCtrlPartitionPlatOwnerAuthSlot0,
137  /**
138  * Software managed platform owner slot 1 partition.
139  *
140  */
141  kDifOtpCtrlPartitionPlatOwnerAuthSlot1,
142  /**
143  * Software managed platform owner slot 2 partition.
144  *
145  */
146  kDifOtpCtrlPartitionPlatOwnerAuthSlot2,
147  /**
148  * Software managed platform owner slot 3 partition.
149  *
150  */
151  kDifOtpCtrlPartitionPlatOwnerAuthSlot3,
152  /**
153  * Anti-replay protection Strike Counters partition.
154  *
155  */
156  kDifOtpCtrlPartitionExtNvm,
157  /**
158  * ROM Patch Code section.
159  *
160  * May contain multiple signed ROM2 patches.
161  */
162  kDifOtpCtrlPartitionRomPatch,
163 #else
164 #error "dif_otp_ctrl does not support this top"
165 #endif
166  /**
167  * Hardware configuration 0 partition.
168  *
169  * This contains a device identifier and manufacturing state.
170  */
172  /**
173  * Hardware configuration 1 partition.
174  *
175  * This contains several hardware feature switches.
176  */
178  /**
179  * Secret partition 0.
180  *
181  * This contains TEST lifecycle unlock tokens.
182  */
184  /**
185  * Secret partition 1.
186  *
187  * This contains SRAM and flash scrambling keys.
188  */
190  /**
191  * Secret partition 2.
192  *
193  * This contains RMA unlock token, creator root key, and creator seed.
194  */
196 #if defined(OPENTITAN_IS_DARJEELING)
197  /**
198  * Secret partition 3.
199  *
200  * This contains the owner seed.
201  */
202  kDifOtpCtrlPartitionSecret3,
203 #elif defined(OPENTITAN_IS_EARLGREY)
204 // Earlgrey only has 3 secret partitions.
205 #else
206 #error "dif_otp_ctrl does not support this top"
207 #endif
208  /**
209  * Lifecycle partition.
210  *
211  * This contains lifecycle transition count and state. This partition
212  * cannot be locked since the life cycle state needs to advance to RMA
213  * in-field. Note that while this partition is not marked secret, it
214  * is not readable nor writeable via the DAI. Only the LC controller
215  * can access this partition, and even via the LC controller it is not
216  * possible to read the raw manufacturing life cycle state in encoded
217  * form, since that encoding is considered a netlist secret. The LC
218  * controller only exposes a decoded version of this state.
219  */
222 
223 /**
224  * Runtime configuration for OTP.
225  *
226  * This struct describes runtime information for one-time configuration of the
227  * hardware.
228  */
229 typedef struct dif_otp_ctrl_config {
230  /**
231  * The timeout for an integrity or consistency check to succeed, in cycles.
232  *
233  * 100'000 is recommended as a minimum safe value.
234  */
235  uint32_t check_timeout;
236  /**
237  * A mask for the pseudo-random integrity check period.
238  *
239  * The value of this mask limits the period of the integrity check; when the
240  * pseudo-random period is computed, this mask is applied to limit it. For
241  * example, a value of 0x3'ffff would correspond to a maximum period of about
242  * 2.8s at 24MHz.
243  *
244  * A value of zero disables the check.
245  */
247  /**
248  * A mask for the pseudo-random consistency check period.
249  *
250  * The value of this mask limits the period of the consistency check; when the
251  * pseudo-random period is computed, this mask is applied to limit it. For
252  * example, a value of 0x3ff'ffff would correspond to a maximum period of
253  * about 716s at 24MHz.
254  *
255  * A value of zero disables the check.
256  */
259 
260 /**
261  * A hardware-level status code.
262  */
264  // NOTE: This enum's API *requires* that all "error"-like codes (that is,
265  // those which have associated cause registers) be a prefix of the enum
266  // values.
267  //
268  // Note furthermore that these enum variants are intended as bit indices, so
269  // their values should not be randomized.
270  /**
271  * Indicates an error occurred in the `VendorTest` partition.
272  */
274  /**
275  * Indicates an error occurred in the `CreatorSwCfg` partition.
276  */
278  /**
279  * Indicates an error occurred in the `OwnerSwCfg` partition.
280  */
282 #if defined(OPENTITAN_IS_EARLGREY)
283  /**
284  * Indicates an error occurred in the `RotCreatorAuthCodesign` partition.
285  */
286  kDifOtpCtrlStatusCodeRotCreatorAuthCodesignError,
287  /**
288  * Indicates an error occurred in the `RotCreatorAuthState` partition.
289  */
290  kDifOtpCtrlStatusCodeRotCreatorAuthStateError,
291 #elif defined(OPENTITAN_IS_DARJEELING)
292  /**
293  * Indicates an error occurred in the `OwnershipSlotState` partition.
294  */
295  kDifOtpCtrlStatusCodeOwnershipSlotStateError,
296  /**
297  * Indicates an error occurred in the `RotCreatorAuth` partition.
298  */
299  kDifOtpCtrlStatusCodeRotCreatorAuthError,
300  /**
301  * Indicates an error occurred in the `RotOwnerAuthSlot0` partition.
302  */
303  kDifOtpCtrlStatusCodeRotOwnerAuthSlot0Error,
304  /**
305  * Indicates an error occurred in the `RotOwnerAuthSlot1` partition.
306  */
307  kDifOtpCtrlStatusCodeRotOwnerAuthSlot1Error,
308  /**
309  * Indicates an error occurred in the `PlatIntegAuthSlot0` partition.
310  */
311  kDifOtpCtrlStatusCodePlatIntegAuthSlot0Error,
312  /**
313  * Indicates an error occurred in the `PlatIntegAuthSlot1` partition.
314  */
315  kDifOtpCtrlStatusCodePlatIntegAuthSlot1Error,
316  /**
317  * Indicates an error occurred in the `PlatOwnerAuthSlot0` partition.
318  */
319  kDifOtpCtrlStatusCodePlatOwnerAuthSlot0Error,
320  /**
321  * Indicates an error occurred in the `PlatOwnerAuthSlot1` partition.
322  */
323  kDifOtpCtrlStatusCodePlatOwnerAuthSlot1Error,
324  /**
325  * Indicates an error occurred in the `PlatOwnerAuthSlot2` partition.
326  */
327  kDifOtpCtrlStatusCodePlatOwnerAuthSlot2Error,
328  /**
329  * Indicates an error occurred in the `PlatOwnerAuthSlot3` partition.
330  */
331  kDifOtpCtrlStatusCodePlatOwnerAuthSlot3Error,
332  /**
333  * Indicates an error occurred in the `ExtNvm` partition.
334  */
335  kDifOtpCtrlStatusCodeExtNvmError,
336  /**
337  * Indicates an error occurred in the `RomPatch` partition.
338  */
339  kDifOtpCtrlStatusCodeRomPatchError,
340 #else
341 #error "dif_otp_ctrl does not support this top"
342 #endif
343  /**
344  * Indicates an error occurred in the `HwCfg0` partition.
345  */
347  /**
348  * Indicates an error occurred in the `HwCfg1` partition.
349  */
351  /**
352  * Indicates an error occurred in the `Secret0` partition.
353  */
355  /**
356  * Indicates an error occurred in the `Secret1` partition.
357  */
359  /**
360  * Indicates an error occurred in the `Secret2` partition.
361  */
363 #if defined(OPENTITAN_IS_DARJEELING)
364  /**
365  * Indicates an error occurred in the `Secret3` partition.
366  */
367  kDifOtpCtrlStatusCodeSecret3Error,
368 #elif defined(OPENTITAN_IS_EARLGREY)
369 // Earlgrey only has 3 secret partitions.
370 #else
371 #error "dif_otp_ctrl does not support this top"
372 #endif
373  /**
374  * Indicates an error occurred in the `LifeCycle` partition.
375  */
377  /**
378  * Indicates an error occurred in the direct access interface.
379  */
381  /**
382  * Indicates an error occurred in the lifecycle interface.
383  */
385  /**
386  * This is not a status code; rather, it represents the last error code which
387  * has a corresponding "cause" register.
388  *
389  * See `dif_otp_ctrl_status_t` for information on how to use this.
390  */
392  /**
393  * Indicates that an integrity or consistency check has timed out.
394  *
395  * This error is unrecoverable.
396  */
398  /**
399  * Indicates that the LFSR that generates pseudo-random integrity and
400  * consistency checks is in a bad state.
401  *
402  * This error is unrecoverable.
403  */
405  /**
406  * Indicates that the scrambling hardware is in a bad state.
407  *
408  * This error is unrecoverable.
409  */
411  /**
412  * Indicates that the key derivation hardware is in a bad state.
413  *
414  * This error is unrecoverable.
415  */
417  /**
418  * Indicates a bus integrity error.
419  *
420  * This error will raise an alert.
421  */
423  /**
424  * Indicates that the direct access interface is idle.
425  */
427  /**
428  * Indicates that an integrity or consistency check is currently pending.
429  */
432 
433 /**
434  * A hardware-level error code, associated with a particular error defined in
435  * `dif_otp_ctrl_status_t`.
436  */
437 typedef enum dif_otp_ctrl_error {
438  /**
439  * Indicates no error.
440  */
442  /**
443  * Indicates that an OTP macro command was invalid or did not
444  * complete successfully.
445  *
446  * This error indicates non-recoverable hardware malfunction.
447  */
449  /**
450  * Indicates a recoverable error during a read operation.
451  *
452  * A followup read should work as expected.
453  */
455  /**
456  * Indicates an unrecoverable error during a read operation.
457  *
458  * This error indicates non-recoverable hardware malfunction.
459  */
461  /**
462  * Indicates that the blank write check failed during a write operation.
463  */
465  /**
466  * Indicates a locked memory region was accessed.
467  */
469  /**
470  * Indicates a parity, integrity or consistency check failed in the buffer
471  * registers.
472  *
473  * This error indicates non-recoverable hardware malfunction.
474  */
476  /**
477  * Indicates that the FSM of the controller is in a bad state or that the
478  * controller's FSM has been moved into its terminal state due to escalation
479  * via the alert subsystem.
480  *
481  * This error indicates that the device has been glitched by an attacker.
482  */
485 
486 /**
487  * The overall status of the OTP controller.
488  *
489  * See `dif_otp_ctrl_get_status()`.
490  */
491 typedef struct dif_otp_ctrl_status {
492  /**
493  * Currently active statuses, given as a bit vector. To check whether a
494  * particular status code was returned, write
495  *
496  * bool has_code = (status.codes >> kMyStatusCode) & 1;
497  *
498  * Note that it is possible to quickly check that the controller is idle and
499  * error-free by writing
500  *
501  * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
502  */
503  uint32_t codes;
504  /**
505  * A list of root causes for each error status code.
506  *
507  * If the error status code `error` is present in `codes`, and
508  * `error <= kDifOtpCtrlStatusCodeHasCauseLast`, then `causes[error]`
509  * will contain its root cause.
510  */
513 
514 /**
515  * Configures OTP with runtime information.
516  *
517  * This function should need to be called at most once for the lifetime of
518  * `otp`.
519  *
520  * @param otp An OTP handle.
521  * @param config Runtime configuration parameters.
522  * @return The result of the operation.
523  */
525 dif_result_t dif_otp_ctrl_configure(const dif_otp_ctrl_t *otp,
526  dif_otp_ctrl_config_t config);
527 
528 /**
529  * Runs an integrity check on the OTP hardware.
530  *
531  * This function can be used to trigger an integrity check independent of the
532  * pseudo-random hardware-generated checks.
533  *
534  * @param otp An OTP handle.
535  * @return The result of the operation.
536  */
538 dif_result_t dif_otp_ctrl_check_integrity(const dif_otp_ctrl_t *otp);
539 
540 /**
541  * Runs a consistency check on the OTP hardware.
542  *
543  * This function can be used to trigger a consistency check independent of the
544  * pseudo-random hardware-generated checks.
545  *
546  * @param otp An OTP handle.
547  * @return The result of the operation.
548  */
550 dif_result_t dif_otp_ctrl_check_consistency(const dif_otp_ctrl_t *otp);
551 
552 /**
553  * Locks out access to the direct access interface registers.
554  *
555  * This function is idempotent: calling it while functionality is locked will
556  * have no effect and return `kDifOk`.
557  *
558  * @param otp An OTP handle.
559  * @return The result of the operation.
560  */
562 dif_result_t dif_otp_ctrl_dai_lock(const dif_otp_ctrl_t *otp);
563 
564 /**
565  * Checks whether access to the direct access interface is locked.
566  *
567  * Note that besides locking the DAI out until the next reset using the
568  * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
569  * HW itself when it is busy processing a DAI command. In such a case, the
570  * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
571  *
572  * @param otp An OTP handle.
573  * @param[out] is_locked Out-param for the locked state.
574  * @return The result of the operation.
575  */
577 dif_result_t dif_otp_ctrl_dai_is_locked(const dif_otp_ctrl_t *otp,
578  bool *is_locked);
579 
580 /**
581  * Locks out `dif_otp_ctrl_configure()` function.
582  *
583  * This function is idempotent: calling it while functionality is locked will
584  * have no effect and return `kDifOk`.
585  *
586  * @param otp An OTP handle.
587  * @return The result of the operation.
588  */
590 dif_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp);
591 
592 /**
593  * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
594  *
595  * @param otp An OTP handle.
596  * @param[out] is_locked Out-param for the locked state.
597  * @return The result of the operation.
598  */
600 dif_result_t dif_otp_ctrl_config_is_locked(const dif_otp_ctrl_t *otp,
601  bool *is_locked);
602 
603 /**
604  * Locks out `dif_otp_ctrl_check_*()` functions.
605  *
606  * This function is idempotent: calling it while functionality is locked will
607  * have no effect and return `kDifOk`.
608  *
609  * @param otp An OTP handle.
610  * @return The result of the operation.
611  */
613 dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp);
614 
615 /**
616  * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
617  *
618  * @param otp An OTP handle.
619  * @param[out] is_locked Out-param for the locked state.
620  * @return The result of the operation.
621  */
623 dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp,
624  bool *is_locked);
625 
626 /**
627  * Locks out reads to a SW partition.
628  *
629  * This function should only be called on SW partitions; doing otherwise will
630  * return an error.
631  *
632  * Note that this is distinct from the write-locking performed by calling
633  * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
634  * not persist past a system reset.
635  *
636  * This function is idempotent: calling it while functionality is locked will
637  * have no effect and return `kDifOk`.
638  *
639  * @param otp An OTP handle.
640  * @param partition The SW partition to lock.
641  * @return The result of the operation.
642  */
644 dif_result_t dif_otp_ctrl_lock_reading(const dif_otp_ctrl_t *otp,
645  dif_otp_ctrl_partition_t partition);
646 
647 /**
648  * Checks whether reads to a SW partition are locked out.
649  *
650  * This function should only be called on SW partitions; doing otherwise will
651  * return an error.
652  *
653  * @param otp An OTP handle.
654  * @param partition the SW partition to check for locking.
655  * @param[out] is_locked Out-param for the locked state.
656  * @return The result of the operation.
657  */
659 dif_result_t dif_otp_ctrl_reading_is_locked(const dif_otp_ctrl_t *otp,
660  dif_otp_ctrl_partition_t partition,
661  bool *is_locked);
662 
663 /**
664  * Gets the current status of the OTP controller.
665  *
666  * @param otp An OTP handle.
667  * @param[out] status Out-param for the controller's status.
668  * @return The result of the operation.
669  */
671 dif_result_t dif_otp_ctrl_get_status(const dif_otp_ctrl_t *otp,
673 
674 /**
675  * Calculates a `relative_address` with respect to a `partition` start
676  * address.
677  *
678  * @param partition The partition to use to calculate the reference start
679  * address.
680  * @param abs_address Input address relative to the OTP memory start address.
681  * @param[out] relative_address The result relative address with respect to the
682  * `partition` start address.
683  * @return The result of the operation.
684  */
687  uint32_t abs_address,
688  uint32_t *relative_address);
689 
690 /**
691  * Schedules a read on the Direct Access Interface.
692  *
693  * Reads are performed relative to a partition; `address` should be given
694  * relative to the start of `partition`. An error is returned for out-of-bounds
695  * access.
696  *
697  * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
698  * normal partitions and eight-byte-aligned for secret partitions. An error is
699  * returned for unaligned access.
700  *
701  * @param otp An OTP handle.
702  * @param partition The partition to read from.
703  * @param address A partition-relative address to read from.
704  * @return The result of the operation.
705  */
707 dif_result_t dif_otp_ctrl_dai_read_start(const dif_otp_ctrl_t *otp,
708  dif_otp_ctrl_partition_t partition,
709  uint32_t address);
710 
711 /**
712  * Gets the result of a completed 32-bit read operation on the Direct Access
713  * Interface.
714  *
715  * Whether this function or its 64-bit variant should be called is dependent on
716  * the most recent partition read from.
717  *
718  * @param otp An OTP handle.
719  * @param[out] value Out-param for the read value.
720  * @return The result of the operation.
721  */
723 dif_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp,
724  uint32_t *value);
725 
726 /**
727  * Gets the result of a completed 64-bit read operation on the Direct Access
728  * Interface.
729  *
730  * Whether this function or its 32-bit variant should be called is dependent on
731  * the most recent partition read from.
732  *
733  * @param otp An OTP handle.
734  * @param[out] value Out-param for the read value.
735  * @return The result of the operation.
736  */
738 dif_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp,
739  uint64_t *value);
740 
741 /**
742  * Schedules a 32-bit write on the Direct Access Interface.
743  *
744  * Writes are performed relative to a partition; `address` should be given
745  * relative to the start of `partition`. An error is returned for out-of-bounds
746  * access.
747  *
748  * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
749  * a secret partition. An error is returned if neither condition is met.
750  *
751  * Note that this function cannot be used to program the digest at the end of a
752  * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
753  *
754  * @param otp An OTP handle.
755  * @param partition The partition to program.
756  * @param address A partition-relative address to program.
757  * @param value The value to program into the OTP.
758  * @return The result of the operation.
759  */
761 dif_result_t dif_otp_ctrl_dai_program32(const dif_otp_ctrl_t *otp,
762  dif_otp_ctrl_partition_t partition,
763  uint32_t address, uint32_t value);
764 
765 /**
766  * Schedules a 64-bit write on the Direct Access Interface.
767  *
768  * Writes are performed relative to a partition; `address` should be given
769  * relative to the start of `partition`. An error is returned for out-of-bounds
770  * access.
771  *
772  * Furthermore, `address` must be eight-byte-aligned, and `partition` must be
773  * a secret partition. An error is returned if neither condition is met.
774  *
775  * @param otp An OTP handle.
776  * @param partition The partition to program.
777  * @param address A partition-relative address to program.
778  * @param value The value to program into the OTP.
779  * @return The result of the operation.
780  */
782 dif_result_t dif_otp_ctrl_dai_program64(const dif_otp_ctrl_t *otp,
783  dif_otp_ctrl_partition_t partition,
784  uint32_t address, uint64_t value);
785 
786 /**
787  * Schedules a hardware digest operation on the Direct Access Interface.
788  *
789  * **This operation will also lock writes for the given partition.**
790  *
791  * If `partition` is a SW partition, `digest` must be non-zero; if it is a
792  * partition with a hardware-managed digest, `digest` *must* be zero (since the
793  * digest will be generated by the hardware). An error is returned if either
794  * precondition is not met.
795  *
796  * This function does not work with the lifecycle state partition, and will
797  * return an error in that case.
798  *
799  * @param otp An OTP handle.
800  * @param partition The partition to digest and lock.
801  * @param digest The digest to program (for SW partitions).
802  * @return The result of the operation.
803  */
805 dif_result_t dif_otp_ctrl_dai_digest(const dif_otp_ctrl_t *otp,
806  dif_otp_ctrl_partition_t partition,
807  uint64_t digest);
808 
809 /**
810  * Checks if the digest value for the given partition has been computed. Once a
811  * digest has been computed for a partition, the partition is write-locked
812  * (additionally, read-locked if the partition is secret).
813  *
814  * The lifecycle partition does not have a digest, and checking if this region
815  * has a computed digest will return an error.
816  *
817  * @param otp An OTP handle.
818  * @param partition The partition to check the digest of.
819  * @param[out] is_computed Indicates if the digest has been computed.
820  * @return The result of the operation.
821  */
823 dif_result_t dif_otp_ctrl_is_digest_computed(const dif_otp_ctrl_t *otp,
824  dif_otp_ctrl_partition_t partition,
825  bool *is_computed);
826 
827 /**
828  * Gets the buffered digest value for the given partition.
829  *
830  * Note that this value is only updated when the device is reset; if the digest
831  * has not been computed yet, or has been computed but not since device reset,
832  * this function will return an error.
833  *
834  * The lifecycle partition does not have a digest and will result in an error
835  * being returned.
836  *
837  * @param otp An OTP handle.
838  * @param partition The partition to get a digest for.
839  * @param[out] digest Out-param for the digest.
840  * @return The result of the operation.
841  */
843 dif_result_t dif_otp_ctrl_get_digest(const dif_otp_ctrl_t *otp,
844  dif_otp_ctrl_partition_t partition,
845  uint64_t *digest);
846 
847 /**
848  * Performs a memory-mapped read of the given partition, if it supports them.
849  *
850  * In particular, this function will read `len` words, starting at `address`,
851  * relative to the start of `partition`.
852  *
853  * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
854  * addition, `address + len` must also be in-range and must not overflow.
855  *
856  * This function will block until the read completes, unlike Direct Access
857  * Interface functions.
858  *
859  * @param otp An OTP handle.
860  * @param partition The partition to read from.
861  * @param address A partition-relative address to read from.
862  * @param[out] buf A buffer of words to write read values to.
863  * @param len The number of words to read.
864  * @return The result of the operation.
865  */
867 dif_result_t dif_otp_ctrl_read_blocking(const dif_otp_ctrl_t *otp,
868  dif_otp_ctrl_partition_t partition,
869  uint32_t address, uint32_t *buf,
870  size_t len);
871 
872 #ifdef __cplusplus
873 } // extern "C"
874 #endif // __cplusplus
875 
876 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_