8 #include "sw/device/lib/crypto/impl/integrity.h"
9 #include "sw/device/lib/crypto/impl/keyblob.h"
10 #include "sw/device/lib/crypto/impl/status.h"
15 #define MODULE_ID MAKE_MODULE_ID('c', 'k', 'd')
24 for (
size_t i = 0; i < buffer.len; i++) {
25 if (buffer.data[i] == 0x00) {
26 return OTCRYPTO_BAD_ARGS;
40 size_t *digest_words) {
42 switch (launder32(key_mode)) {
43 case kOtcryptoKeyModeHmacSha256:
45 *digest_words = 256 / 32;
47 case kOtcryptoKeyModeHmacSha384:
49 *digest_words = 384 / 32;
51 case kOtcryptoKeyModeHmacSha512:
53 *digest_words = 512 / 32;
56 return OTCRYPTO_BAD_ARGS;
58 HARDENED_CHECK_NE(*digest_words, 0);
68 if (output_key_material == NULL || output_key_material->keyblob == NULL ||
69 key_derivation_key.keyblob == NULL) {
70 return OTCRYPTO_BAD_ARGS;
73 if (launder32(output_key_material->config.security_level) !=
74 kOtcryptoKeySecurityLevelLow ||
75 launder32(key_derivation_key.config.security_level) !=
76 kOtcryptoKeySecurityLevelLow) {
78 return OTCRYPTO_NOT_IMPLEMENTED;
82 if (label.data == NULL && label.len != 0) {
83 return OTCRYPTO_BAD_ARGS;
87 if (context.data == NULL && context.len != 0) {
88 return OTCRYPTO_BAD_ARGS;
93 return OTCRYPTO_BAD_ARGS;
97 if (output_key_material->config.key_length == 0) {
98 return OTCRYPTO_BAD_ARGS;
102 size_t digest_word_len = 0;
103 HARDENED_TRY(digest_num_words_from_key_mode(
104 key_derivation_key.config.key_mode, &digest_word_len));
108 HARDENED_TRY(keyblob_ensure_xor_masked(output_key_material->config));
114 return OTCRYPTO_BAD_ARGS;
116 if (output_key_material->keyblob_length !=
117 keyblob_num_words(output_key_material->config) *
sizeof(uint32_t)) {
118 return OTCRYPTO_BAD_ARGS;
121 return OTCRYPTO_BAD_ARGS;
126 size_t required_byte_len = output_key_material->config.key_length;
127 size_t required_word_len =
ceil_div(required_byte_len,
sizeof(uint32_t));
128 size_t num_iterations =
ceil_div(required_word_len, digest_word_len);
129 if (launder32(num_iterations) > UINT32_MAX ||
130 launder32(required_byte_len) > UINT32_MAX / 8) {
131 return OTCRYPTO_BAD_ARGS;
133 HARDENED_CHECK_LE(num_iterations, UINT32_MAX);
134 HARDENED_CHECK_LE(required_byte_len, UINT32_MAX / 8);
135 uint32_t required_bit_len = __builtin_bswap32(required_byte_len * 8);
140 HARDENED_TRY(check_zero_byte(label));
141 HARDENED_TRY(check_zero_byte(context));
153 uint32_t output_key_material_len =
154 required_word_len + digest_word_len - required_word_len % digest_word_len;
155 uint32_t output_key_material_data[output_key_material_len];
157 for (uint32_t i = 0; i < num_iterations; i++) {
160 uint32_t counter_be = __builtin_bswap32(i + 1);
163 .data = (
const unsigned char *
const)&counter_be,
164 .len =
sizeof(counter_be)}));
169 .len =
sizeof(zero)}));
173 .data = (
const unsigned char *
const)&required_bit_len,
174 .len =
sizeof(required_bit_len)}));
175 uint32_t *tag_dest = output_key_material_data + i * digest_word_len;
182 uint32_t mask[digest_word_len];
183 memset(mask, 0,
sizeof(mask));
186 HARDENED_TRY(keyblob_from_key_and_mask(output_key_material_data, mask,
187 output_key_material->config,
188 output_key_material->keyblob));
190 output_key_material->checksum =
191 integrity_blinded_checksum(output_key_material);