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
23extern "C" {
24#endif // __cplusplus
25
26/**
27 * A partition within OTP memory.
28 */
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 */
221
222 /**
223 * This is not a partition; rather, it represents the total number of
224 * partitions.
225 */
227
228 /**
229 * The following two are not partitions; rather they represent error codes
230 * that have a corresponding entry in dif_otp_ctrl_status_t.causes.
231 */
233 kDifOtpCtrlPartitionLciError,
234
235 /**
236 * This is not a partition; rather, it represents the total number of entries
237 * in dif_otp_ctrl_status_t.causes.
238 */
240
242
243/**
244 * Runtime configuration for OTP.
245 *
246 * This struct describes runtime information for one-time configuration of the
247 * hardware.
248 */
249typedef struct dif_otp_ctrl_config {
250 /**
251 * The timeout for an integrity or consistency check to succeed, in cycles.
252 *
253 * 100'000 is recommended as a minimum safe value.
254 */
256 /**
257 * A mask for the pseudo-random integrity check period.
258 *
259 * The value of this mask limits the period of the integrity check; when the
260 * pseudo-random period is computed, this mask is applied to limit it. For
261 * example, a value of 0x3'ffff would correspond to a maximum period of about
262 * 2.8s at 24MHz.
263 *
264 * A value of zero disables the check.
265 */
267 /**
268 * A mask for the pseudo-random consistency check period.
269 *
270 * The value of this mask limits the period of the consistency check; when the
271 * pseudo-random period is computed, this mask is applied to limit it. For
272 * example, a value of 0x3ff'ffff would correspond to a maximum period of
273 * about 716s at 24MHz.
274 *
275 * A value of zero disables the check.
276 */
279
280/**
281 * A hardware-level status code.
282 */
284 // Note that these enum variants are intended as bit indices, so
285 // their values should not be randomized.
286 /**
287 * Indicates that at least one partition raised an error.
288 */
290 /**
291 * Indicates an error occurred in the direct access interface.
292 */
294 /**
295 * Indicates an error occurred in the lifecycle interface.
296 */
298 /**
299 * Indicates that an integrity or consistency check has timed out.
300 *
301 * This error is unrecoverable.
302 */
304 /**
305 * Indicates that the LFSR that generates pseudo-random integrity and
306 * consistency checks is in a bad state.
307 *
308 * This error is unrecoverable.
309 */
311 /**
312 * Indicates that the scrambling hardware is in a bad state.
313 *
314 * This error is unrecoverable.
315 */
317 /**
318 * Indicates that the key derivation hardware is in a bad state.
319 *
320 * This error is unrecoverable.
321 */
323 /**
324 * Indicates a bus integrity error.
325 *
326 * This error will raise an alert.
327 */
329 /**
330 * Indicates that the direct access interface is idle.
331 */
333 /**
334 * Indicates that an integrity or consistency check is currently pending.
335 */
338
339/**
340 * A hardware-level error code, associated with a particular error defined in
341 * `dif_otp_ctrl_status_t`.
342 */
343typedef enum dif_otp_ctrl_error {
344 /**
345 * Indicates no error.
346 */
348 /**
349 * Indicates that an OTP macro command was invalid or did not
350 * complete successfully.
351 *
352 * This error indicates non-recoverable hardware malfunction.
353 */
355 /**
356 * Indicates a recoverable error during a read operation.
357 *
358 * A followup read should work as expected.
359 */
361 /**
362 * Indicates an unrecoverable error during a read operation.
363 *
364 * This error indicates non-recoverable hardware malfunction.
365 */
367 /**
368 * Indicates that the blank write check failed during a write operation.
369 */
371 /**
372 * Indicates a locked memory region was accessed.
373 */
375 /**
376 * Indicates a parity, integrity or consistency check failed in the buffer
377 * registers.
378 *
379 * This error indicates non-recoverable hardware malfunction.
380 */
382 /**
383 * Indicates that the FSM of the controller is in a bad state or that the
384 * controller's FSM has been moved into its terminal state due to escalation
385 * via the alert subsystem.
386 *
387 * This error indicates that the device has been glitched by an attacker.
388 */
391
392/**
393 * The overall status of the OTP controller.
394 *
395 * See `dif_otp_ctrl_get_status()`.
396 */
397typedef struct dif_otp_ctrl_status {
398 /**
399 * Currently active statuses, given as a bit vector. To check whether a
400 * particular status code was returned, write
401 *
402 * bool has_code = (status.codes >> kMyStatusCode) & 1;
403 *
404 * Note that it is possible to quickly check that the controller is idle and
405 * error-free by writing
406 *
407 * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
408 *
409 * Note this mapes to the "status" hw register.
410 */
411 uint32_t codes;
412 /**
413 * A list of root causes for each partition as well as for DAI and LCI.
414 * dif_otp_ctrl_partition_t can be used for indexing.
415 */
418
419/**
420 * Configures OTP with runtime information.
421 *
422 * This function should need to be called at most once for the lifetime of
423 * `otp`.
424 *
425 * @param otp An OTP handle.
426 * @param config Runtime configuration parameters.
427 * @return The result of the operation.
428 */
431 dif_otp_ctrl_config_t config);
432
433/**
434 * Runs an integrity check on the OTP hardware.
435 *
436 * This function can be used to trigger an integrity check independent of the
437 * pseudo-random hardware-generated checks.
438 *
439 * @param otp An OTP handle.
440 * @return The result of the operation.
441 */
444
445/**
446 * Runs a consistency check on the OTP hardware.
447 *
448 * This function can be used to trigger a consistency check independent of the
449 * pseudo-random hardware-generated checks.
450 *
451 * @param otp An OTP handle.
452 * @return The result of the operation.
453 */
456
457/**
458 * Locks out access to the direct access interface registers.
459 *
460 * This function is idempotent: calling it while functionality is locked will
461 * have no effect and return `kDifOk`.
462 *
463 * @param otp An OTP handle.
464 * @return The result of the operation.
465 */
468
469/**
470 * Checks whether access to the direct access interface is locked.
471 *
472 * Note that besides locking the DAI out until the next reset using the
473 * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
474 * HW itself when it is busy processing a DAI command. In such a case, the
475 * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
476 *
477 * @param otp An OTP handle.
478 * @param[out] is_locked Out-param for the locked state.
479 * @return The result of the operation.
480 */
483 bool *is_locked);
484
485/**
486 * Locks out `dif_otp_ctrl_configure()` function.
487 *
488 * This function is idempotent: calling it while functionality is locked will
489 * have no effect and return `kDifOk`.
490 *
491 * @param otp An OTP handle.
492 * @return The result of the operation.
493 */
496
497/**
498 * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
499 *
500 * @param otp An OTP handle.
501 * @param[out] is_locked Out-param for the locked state.
502 * @return The result of the operation.
503 */
506 bool *is_locked);
507
508/**
509 * Locks out `dif_otp_ctrl_check_*()` functions.
510 *
511 * This function is idempotent: calling it while functionality is locked will
512 * have no effect and return `kDifOk`.
513 *
514 * @param otp An OTP handle.
515 * @return The result of the operation.
516 */
519
520/**
521 * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
522 *
523 * @param otp An OTP handle.
524 * @param[out] is_locked Out-param for the locked state.
525 * @return The result of the operation.
526 */
529 bool *is_locked);
530
531/**
532 * Locks out reads to a SW partition.
533 *
534 * This function should only be called on SW partitions; doing otherwise will
535 * return an error.
536 *
537 * Note that this is distinct from the write-locking performed by calling
538 * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
539 * not persist past a system reset.
540 *
541 * This function is idempotent: calling it while functionality is locked will
542 * have no effect and return `kDifOk`.
543 *
544 * @param otp An OTP handle.
545 * @param partition The SW partition to lock.
546 * @return The result of the operation.
547 */
550 dif_otp_ctrl_partition_t partition);
551
552/**
553 * Checks whether reads to a SW partition are locked out.
554 *
555 * This function should only be called on SW partitions; doing otherwise will
556 * return an error.
557 *
558 * @param otp An OTP handle.
559 * @param partition the SW partition to check for locking.
560 * @param[out] is_locked Out-param for the locked state.
561 * @return The result of the operation.
562 */
565 dif_otp_ctrl_partition_t partition,
566 bool *is_locked);
567
568/**
569 * Gets the current status of the OTP controller.
570 *
571 * @param otp An OTP handle.
572 * @param[out] status Out-param for the controller's status.
573 * @return The result of the operation.
574 */
578
579/**
580 * Calculates a `relative_address` with respect to a `partition` start
581 * address.
582 *
583 * @param partition The partition to use to calculate the reference start
584 * address.
585 * @param abs_address Input address relative to the OTP memory start address.
586 * @param[out] relative_address The result relative address with respect to the
587 * `partition` start address.
588 * @return The result of the operation.
589 */
592 uint32_t abs_address,
593 uint32_t *relative_address);
594
595/**
596 * Schedules a read on the Direct Access Interface.
597 *
598 * Reads are performed relative to a partition; `address` should be given
599 * relative to the start of `partition`. An error is returned for out-of-bounds
600 * access.
601 *
602 * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
603 * normal partitions and eight-byte-aligned for secret partitions. An error is
604 * returned for unaligned access.
605 *
606 * @param otp An OTP handle.
607 * @param partition The partition to read from.
608 * @param address A partition-relative address to read from.
609 * @return The result of the operation.
610 */
613 dif_otp_ctrl_partition_t partition,
614 uint32_t address);
615
616/**
617 * Gets the result of a completed 32-bit read operation on the Direct Access
618 * Interface.
619 *
620 * Whether this function or its 64-bit variant should be called is dependent on
621 * the most recent partition read from.
622 *
623 * @param otp An OTP handle.
624 * @param[out] value Out-param for the read value.
625 * @return The result of the operation.
626 */
629 uint32_t *value);
630
631/**
632 * Gets the result of a completed 64-bit read operation on the Direct Access
633 * Interface.
634 *
635 * Whether this function or its 32-bit variant should be called is dependent on
636 * the most recent partition read from.
637 *
638 * @param otp An OTP handle.
639 * @param[out] value Out-param for the read value.
640 * @return The result of the operation.
641 */
644 uint64_t *value);
645
646/**
647 * Schedules a 32-bit write on the Direct Access Interface.
648 *
649 * Writes are performed relative to a partition; `address` should be given
650 * relative to the start of `partition`. An error is returned for out-of-bounds
651 * access.
652 *
653 * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
654 * a secret partition. An error is returned if neither condition is met.
655 *
656 * Note that this function cannot be used to program the digest at the end of a
657 * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
658 *
659 * @param otp An OTP handle.
660 * @param partition The partition to program.
661 * @param address A partition-relative address to program.
662 * @param value The value to program into the OTP.
663 * @return The result of the operation.
664 */
667 dif_otp_ctrl_partition_t partition,
668 uint32_t address, uint32_t value);
669
670/**
671 * Schedules a 64-bit write on the Direct Access Interface.
672 *
673 * Writes are performed relative to a partition; `address` should be given
674 * relative to the start of `partition`. An error is returned for out-of-bounds
675 * access.
676 *
677 * Furthermore, `address` must be eight-byte-aligned, and `partition` must be
678 * a secret partition. An error is returned if neither condition is met.
679 *
680 * @param otp An OTP handle.
681 * @param partition The partition to program.
682 * @param address A partition-relative address to program.
683 * @param value The value to program into the OTP.
684 * @return The result of the operation.
685 */
688 dif_otp_ctrl_partition_t partition,
689 uint32_t address, uint64_t value);
690
691/**
692 * Schedules a hardware digest operation on the Direct Access Interface.
693 *
694 * **This operation will also lock writes for the given partition.**
695 *
696 * If `partition` is a SW partition, `digest` must be non-zero; if it is a
697 * partition with a hardware-managed digest, `digest` *must* be zero (since the
698 * digest will be generated by the hardware). An error is returned if either
699 * precondition is not met.
700 *
701 * This function does not work with the lifecycle state partition, and will
702 * return an error in that case.
703 *
704 * @param otp An OTP handle.
705 * @param partition The partition to digest and lock.
706 * @param digest The digest to program (for SW partitions).
707 * @return The result of the operation.
708 */
711 dif_otp_ctrl_partition_t partition,
712 uint64_t digest);
713
714/**
715 * Checks if the digest value for the given partition has been computed. Once a
716 * digest has been computed for a partition, the partition is write-locked
717 * (additionally, read-locked if the partition is secret).
718 *
719 * The lifecycle partition does not have a digest, and checking if this region
720 * has a computed digest will return an error.
721 *
722 * @param otp An OTP handle.
723 * @param partition The partition to check the digest of.
724 * @param[out] is_computed Indicates if the digest has been computed.
725 * @return The result of the operation.
726 */
729 dif_otp_ctrl_partition_t partition,
730 bool *is_computed);
731
732/**
733 * Gets the buffered digest value for the given partition.
734 *
735 * Note that this value is only updated when the device is reset; if the digest
736 * has not been computed yet, or has been computed but not since device reset,
737 * this function will return an error.
738 *
739 * The lifecycle partition does not have a digest and will result in an error
740 * being returned.
741 *
742 * @param otp An OTP handle.
743 * @param partition The partition to get a digest for.
744 * @param[out] digest Out-param for the digest.
745 * @return The result of the operation.
746 */
749 dif_otp_ctrl_partition_t partition,
750 uint64_t *digest);
751
752/**
753 * Performs a memory-mapped read of the given partition, if it supports them.
754 *
755 * In particular, this function will read `len` words, starting at `address`,
756 * relative to the start of `partition`.
757 *
758 * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
759 * addition, `address + len` must also be in-range and must not overflow.
760 *
761 * This function will block until the read completes, unlike Direct Access
762 * Interface functions.
763 *
764 * @param otp An OTP handle.
765 * @param partition The partition to read from.
766 * @param address A partition-relative address to read from.
767 * @param[out] buf A buffer of words to write read values to.
768 * @param len The number of words to read.
769 * @return The result of the operation.
770 */
773 dif_otp_ctrl_partition_t partition,
774 uint32_t address, uint32_t *buf,
775 size_t len);
776
777#ifdef __cplusplus
778} // extern "C"
779#endif // __cplusplus
780
781#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_