Software APIs
util.c
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 #include "sw/device/silicon_creator/manuf/lib/util.h"
6 
7 #include <stdint.h>
8 
9 #include "sw/device/lib/base/status.h"
13 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
14 
16 #include "otp_ctrl_regs.h" // Generated.
17 
18 static_assert(
19  OTP_CTRL_PARAM_VENDOR_TEST_SIZE % sizeof(uint32_t) == 0,
20  "OTP Vendor Test partition should be an integer multiple of 32-bit words.");
21 
22 status_t manuf_util_hash_lc_transition_token(const uint32_t *raw_token,
23  size_t token_size_bytes,
24  uint64_t *hashed_token) {
26  .data = (unsigned char *)raw_token,
27  .len = token_size_bytes,
28  };
29  otcrypto_const_byte_buf_t function_name_string = {
30  .data = (unsigned char *)"",
31  .len = 0,
32  };
33  otcrypto_const_byte_buf_t customization_string = {
34  .data = (unsigned char *)"LC_CTRL",
35  .len = 7,
36  };
37 
38  // Create a temporary uint32_t buffer and copy the result from there to the
39  // uint64_t buffer.
40  // TODO(#16556): this is a workaround to avoid violating strict-aliasing; if
41  // we pass -fno-strict-aliasing, then we can cast `hashed_token` to `uint32_t
42  // *` instead.
43  size_t token_num_words = token_size_bytes / sizeof(uint32_t);
44  if (token_size_bytes % sizeof(uint32_t) != 0) {
45  token_num_words++;
46  }
47  uint32_t token_data[token_num_words];
48  memset(token_data, 0, sizeof(token_data));
49  otcrypto_hash_digest_t output = {
50  .data = token_data,
51  .len = token_num_words,
52  .mode = kOtcryptoHashXofModeCshake128,
53  };
54 
55  TRY(otcrypto_xof_cshake(input, function_name_string, customization_string,
56  output));
57  memcpy(hashed_token, token_data, sizeof(token_data));
58 
59  return OK_STATUS();
60 }
61 
62 status_t manuf_util_hash_otp_partition(const dif_otp_ctrl_t *otp_ctrl,
63  dif_otp_ctrl_partition_t partition,
64  otcrypto_word32_buf_t output) {
65  if (otp_ctrl == NULL || output.len != kSha256DigestWords) {
66  return INVALID_ARGUMENT();
67  }
68  otcrypto_hash_digest_t digest = {
69  .data = output.data,
70  .len = output.len,
71  .mode = kOtcryptoHashModeSha256,
72  };
73 
74  switch (partition) {
76  uint32_t
77  vendor_test_32bit_array[(OTP_CTRL_PARAM_VENDOR_TEST_SIZE -
78  OTP_CTRL_PARAM_VENDOR_TEST_DIGEST_SIZE) /
79  sizeof(uint32_t)];
80  TRY(otp_ctrl_testutils_dai_read32_array(
81  otp_ctrl, kDifOtpCtrlPartitionVendorTest, 0, vendor_test_32bit_array,
82  (OTP_CTRL_PARAM_VENDOR_TEST_SIZE -
83  OTP_CTRL_PARAM_VENDOR_TEST_DIGEST_SIZE) /
84  sizeof(uint32_t)));
86  .data = (unsigned char *)vendor_test_32bit_array,
87  .len = OTP_CTRL_PARAM_VENDOR_TEST_SIZE -
88  OTP_CTRL_PARAM_VENDOR_TEST_DIGEST_SIZE,
89  };
90  TRY(otcrypto_hash(input, digest));
91  } break;
94  .data = (unsigned char *)(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
95  OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
96  OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET),
97  .len = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE -
98  OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_SIZE,
99  };
100  TRY(otcrypto_hash(input, digest));
101  } break;
103  otcrypto_const_byte_buf_t input = {
104  .data = (unsigned char *)(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
105  OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
106  OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET),
107  .len = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE -
108  OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_SIZE,
109  };
110  TRY(otcrypto_hash(input, digest));
111  } break;
112  case kDifOtpCtrlPartitionRotCreatorAuthCodesign: {
113  uint32_t rot_creator_auth_codesign_32bit_array
114  [(OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE -
115  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_SIZE) /
116  sizeof(uint32_t)];
117  TRY(otp_ctrl_testutils_dai_read32_array(
118  otp_ctrl, kDifOtpCtrlPartitionRotCreatorAuthCodesign, 0,
119  rot_creator_auth_codesign_32bit_array,
120  (OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE -
121  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_SIZE) /
122  sizeof(uint32_t)));
123  otcrypto_const_byte_buf_t input = {
124  .data = (unsigned char *)rot_creator_auth_codesign_32bit_array,
125  .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE -
126  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_SIZE,
127  };
128  TRY(otcrypto_hash(input, digest));
129  } break;
130  case kDifOtpCtrlPartitionRotCreatorAuthState: {
131  uint32_t rot_creator_auth_state_32bit_array
132  [(OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE -
133  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_SIZE) /
134  sizeof(uint32_t)];
135  TRY(otp_ctrl_testutils_dai_read32_array(
136  otp_ctrl, kDifOtpCtrlPartitionRotCreatorAuthState, 0,
137  rot_creator_auth_state_32bit_array,
138  (OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE -
139  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_SIZE) /
140  sizeof(uint32_t)));
141  otcrypto_const_byte_buf_t input = {
142  .data = (unsigned char *)rot_creator_auth_state_32bit_array,
143  .len = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE -
144  OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_SIZE,
145  };
146  TRY(otcrypto_hash(input, digest));
147  } break;
148  default:
149  return INVALID_ARGUMENT();
150  }
151 
152  return OK_STATUS();
153 }