Software APIs
kdf.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 
6 
8 #include "sw/device/lib/crypto/drivers/kmac.h"
9 #include "sw/device/lib/crypto/impl/integrity.h"
10 #include "sw/device/lib/crypto/impl/keyblob.h"
11 #include "sw/device/lib/crypto/impl/status.h"
14 
15 // Module ID for status codes.
16 #define MODULE_ID MAKE_MODULE_ID('k', 'd', 'f')
17 
18 /**
19  * Check if the string contains a 0x00 byte.
20  *
21  * @param buffer Inspected string.
22  * @return OK or error.
23  */
24 static status_t check_zero_byte(const otcrypto_const_byte_buf_t buffer) {
25  for (size_t i = 0; i < buffer.len; i++) {
26  if (buffer.data[i] == 0x00) {
27  return OTCRYPTO_BAD_ARGS;
28  }
29  }
30  return OTCRYPTO_OK;
31 }
32 
33 /**
34  * Infer the digest length in 32-bit words for the given hash function.
35  *
36  * @param key_mode HMAC key mode.
37  * @param[out] digest_words Number of words in the hash digest.
38  * @return OK or error.
39  */
40 static status_t digest_num_words_from_key_mode(otcrypto_key_mode_t key_mode,
41  size_t *digest_words) {
42  *digest_words = 0;
43  switch (launder32(key_mode)) {
44  case kOtcryptoKeyModeHmacSha256:
45  HARDENED_CHECK_EQ(key_mode, kOtcryptoKeyModeHmacSha256);
46  *digest_words = 256 / 32;
47  break;
48  case kOtcryptoKeyModeHmacSha384:
49  HARDENED_CHECK_EQ(key_mode, kOtcryptoKeyModeHmacSha384);
50  *digest_words = 384 / 32;
51  break;
52  case kOtcryptoKeyModeHmacSha512:
53  HARDENED_CHECK_EQ(key_mode, kOtcryptoKeyModeHmacSha512);
54  *digest_words = 512 / 32;
55  break;
56  default:
57  return OTCRYPTO_BAD_ARGS;
58  }
59  HARDENED_CHECK_NE(*digest_words, 0);
60  return OTCRYPTO_OK;
61 }
62 
64  const otcrypto_blinded_key_t key_derivation_key,
65  const otcrypto_const_byte_buf_t kdf_label,
66  const otcrypto_const_byte_buf_t kdf_context, size_t required_byte_len,
67  otcrypto_blinded_key_t *keying_material) {
68  // Check NULL pointers.
69  if (keying_material == NULL || keying_material->keyblob == NULL ||
70  key_derivation_key.keyblob == NULL) {
71  return OTCRYPTO_BAD_ARGS;
72  }
73 
74  if (launder32(keying_material->config.security_level) !=
75  kOtcryptoKeySecurityLevelLow ||
76  launder32(key_derivation_key.config.security_level) !=
77  kOtcryptoKeySecurityLevelLow) {
78  // The underlying HMAC implementation is not currently hardened.
79  return OTCRYPTO_NOT_IMPLEMENTED;
80  }
81 
82  // Check for null label with nonzero length.
83  if (kdf_label.data == NULL && kdf_label.len != 0) {
84  return OTCRYPTO_BAD_ARGS;
85  }
86 
87  // Check for null context with nonzero length.
88  if (kdf_context.data == NULL && kdf_context.len != 0) {
89  return OTCRYPTO_BAD_ARGS;
90  }
91 
92  // Check the private key checksum.
93  if (integrity_blinded_key_check(&key_derivation_key) != kHardenedBoolTrue) {
94  return OTCRYPTO_BAD_ARGS;
95  }
96 
97  // Check non-zero length for keying_material.
98  if (required_byte_len == 0) {
99  return OTCRYPTO_BAD_ARGS;
100  }
101 
102  // Infer the digest size.
103  size_t digest_word_len = 0;
104  HARDENED_TRY(digest_num_words_from_key_mode(
105  key_derivation_key.config.key_mode, &digest_word_len));
106 
107  // Ensure that the derived key is a symmetric key masked with XOR and is not
108  // supposed to be hardware-backed.
109  HARDENED_TRY(keyblob_ensure_xor_masked(keying_material->config));
110 
111  // Check `keying_material` key length.
112  if (keying_material->config.hw_backed == kHardenedBoolTrue) {
113  // The case where `keying_material` is hw_backed is addressed by
114  // `otcrypto_hw_backed_key` function in `key_transport.h`.
115  return OTCRYPTO_BAD_ARGS;
116  } else if (keying_material->config.hw_backed == kHardenedBoolFalse) {
117  if (keying_material->config.key_length != required_byte_len ||
118  keying_material->keyblob_length !=
119  keyblob_num_words(keying_material->config) * sizeof(uint32_t)) {
120  return OTCRYPTO_BAD_ARGS;
121  }
122  } else {
123  return OTCRYPTO_BAD_ARGS;
124  }
125 
126  // Check that the unmasked key length is not too large for HMAC CTR
127  // (see NIST SP 800-108r1, section 4.1)
128  size_t required_word_len = ceil_div(required_byte_len, sizeof(uint32_t));
129  size_t num_iterations = ceil_div(required_word_len, digest_word_len);
130  if (launder32(num_iterations) > UINT32_MAX) {
131  return OTCRYPTO_BAD_ARGS;
132  }
133  HARDENED_CHECK_LE(num_iterations, UINT32_MAX);
134 
135  // Check if label or context contain 0x00 bytes
136  // Since 0x00 is used as the delimiter between label and context
137  // there shouldn't be multiple instances of them in input data
138  HARDENED_TRY(check_zero_byte(kdf_label));
139  HARDENED_TRY(check_zero_byte(kdf_context));
140 
141  // Setup
142  uint8_t zero = 0x00;
143  HARDENED_CHECK_LE(required_byte_len, UINT32_MAX / 8);
144  uint32_t required_bit_len = __builtin_bswap32(required_byte_len * 8);
145 
146  // Repeatedly call HMAC to generate the derived key based on input data:
147  // [i]_2 || Label || 0x00 || Context || [L]_2
148  // (see NIST SP 800-108r1, section 4.1)
149  // [i]_2 is the binary representation of the counter value
150  // [L]_2 is the binary representation of the required bit length
151  // The counter value is updated within the loop
152 
153  uint32_t keying_material_len =
154  required_word_len + digest_word_len - required_word_len % digest_word_len;
155  uint32_t keying_material_data[keying_material_len];
156 
157  for (uint32_t i = 0; i < num_iterations; i++) {
159  HARDENED_TRY(otcrypto_hmac_init(&ctx, &key_derivation_key));
160  uint32_t counter_be = __builtin_bswap32(i + 1);
161  HARDENED_TRY(otcrypto_hmac_update(
163  .data = (const unsigned char *const)&counter_be,
164  .len = sizeof(counter_be)}));
165  HARDENED_TRY(otcrypto_hmac_update(&ctx, kdf_label));
166  HARDENED_TRY(otcrypto_hmac_update(
167  &ctx,
168  (otcrypto_const_byte_buf_t){.data = (const unsigned char *const)&zero,
169  .len = sizeof(zero)}));
170  HARDENED_TRY(otcrypto_hmac_update(&ctx, kdf_context));
171  HARDENED_TRY(otcrypto_hmac_update(
173  .data = (const unsigned char *const)&required_bit_len,
174  .len = sizeof(required_bit_len)}));
175  uint32_t *tag_dest = keying_material_data + i * digest_word_len;
176  HARDENED_TRY(otcrypto_hmac_final(
177  &ctx,
178  (otcrypto_word32_buf_t){.data = tag_dest, .len = digest_word_len}));
179  }
180 
181  // Generate a mask (all-zero for now, since HMAC is unhardened anyway).
182  uint32_t mask[digest_word_len];
183  memset(mask, 0, sizeof(mask));
184 
185  // Construct a blinded key.
186  HARDENED_TRY(keyblob_from_key_and_mask(keying_material_data, mask,
187  keying_material->config,
188  keying_material->keyblob));
189 
190  keying_material->checksum = integrity_blinded_checksum(keying_material);
191 
192  return OTCRYPTO_OK;
193 }
194 
196  const otcrypto_blinded_key_t key_derivation_key,
197  otcrypto_kmac_mode_t kmac_mode, const otcrypto_const_byte_buf_t kdf_label,
198  const otcrypto_const_byte_buf_t kdf_context, size_t required_byte_len,
199  otcrypto_blinded_key_t *keying_material) {
200  // Check NULL pointers.
201  if (key_derivation_key.keyblob == NULL || keying_material == NULL ||
202  keying_material->keyblob == NULL) {
203  return OTCRYPTO_BAD_ARGS;
204  }
205 
206  // Check for null label with nonzero length.
207  if (kdf_label.data == NULL && kdf_label.len != 0) {
208  return OTCRYPTO_BAD_ARGS;
209  }
210  // Because of KMAC HWIPs prefix limitation, `label` should not exceed
211  // `kKmacCustStrMaxSize` bytes.
212  if (kdf_label.len > kKmacCustStrMaxSize) {
213  return OTCRYPTO_BAD_ARGS;
214  }
215 
216  // Check for null context with nonzero length.
217  if (kdf_context.data == NULL && kdf_context.len != 0) {
218  return OTCRYPTO_BAD_ARGS;
219  }
220 
221  // Check the private key checksum.
222  if (integrity_blinded_key_check(&key_derivation_key) != kHardenedBoolTrue) {
223  return OTCRYPTO_BAD_ARGS;
224  }
225 
226  // Check `key_len` is supported by KMAC HWIP.
227  // The set of supported key sizes is {128, 192, 256, 384, 512).
228  HARDENED_TRY(kmac_key_length_check(key_derivation_key.config.key_length));
229 
230  kmac_blinded_key_t kmac_key = {
231  .share0 = NULL,
232  .share1 = NULL,
233  .hw_backed = key_derivation_key.config.hw_backed,
234  .len = key_derivation_key.config.key_length,
235  };
236  // Validate key length of `key_derivation_key`.
237  if (key_derivation_key.config.hw_backed == kHardenedBoolTrue) {
238  // Check that 1) key size matches sideload port size, 2) keyblob length
239  // matches diversification length.
240  if (keyblob_share_num_words(key_derivation_key.config) * sizeof(uint32_t) !=
241  kKmacSideloadKeyLength / 8) {
242  return OTCRYPTO_BAD_ARGS;
243  }
244  // Configure keymgr with diversification input and then generate the
245  // sideload key.
246  keymgr_diversification_t diversification;
247  // Diversification call also checks that `key_derivation_key.keyblob_length`
248  // is 8 words long.
249  HARDENED_TRY(keyblob_to_keymgr_diversification(&key_derivation_key,
250  &diversification));
251  HARDENED_TRY(keymgr_generate_key_kmac(diversification));
252  } else if (key_derivation_key.config.hw_backed == kHardenedBoolFalse) {
253  if (key_derivation_key.keyblob_length !=
254  keyblob_num_words(key_derivation_key.config) * sizeof(uint32_t)) {
255  return OTCRYPTO_BAD_ARGS;
256  }
257  HARDENED_TRY(keyblob_to_shares(&key_derivation_key, &kmac_key.share0,
258  &kmac_key.share1));
259  } else {
260  return OTCRYPTO_BAD_ARGS;
261  }
262 
263  // Check non-zero length for keying_material.
264  if (required_byte_len == 0) {
265  return OTCRYPTO_BAD_ARGS;
266  }
267  // At the moment, `kmac_kmac_128/256` only supports word-sized digest lenghts.
268  if (required_byte_len % sizeof(uint32_t) != 0) {
269  return OTCRYPTO_NOT_IMPLEMENTED;
270  }
271 
272  // Check `keying_material` key length.
273  if (keying_material->config.hw_backed == kHardenedBoolTrue) {
274  // The case where `keying_material` is hw_backed is addressed by
275  // `otcrypto_hw_backed_key` function in `key_transport.h`.
276  return OTCRYPTO_BAD_ARGS;
277  } else if (keying_material->config.hw_backed == kHardenedBoolFalse) {
278  if (keying_material->config.key_length != required_byte_len ||
279  keying_material->keyblob_length !=
280  keyblob_num_words(keying_material->config) * sizeof(uint32_t)) {
281  return OTCRYPTO_BAD_ARGS;
282  }
283  } else {
284  return OTCRYPTO_BAD_ARGS;
285  }
286 
287  if (kmac_mode == kOtcryptoKmacModeKmac128) {
288  // Check if `key_mode` of the key derivation key matches `kmac_mode`.
289  if (key_derivation_key.config.key_mode != kOtcryptoKeyModeKdfKmac128) {
290  return OTCRYPTO_BAD_ARGS;
291  }
292  // No need to further check key size against security level because
293  // `kmac_key_length_check` ensures that the key is at least 128-bit.
294  HARDENED_TRY(kmac_kmac_128(&kmac_key, kdf_context.data, kdf_context.len,
295  kdf_label.data, kdf_label.len,
296  keying_material->keyblob,
297  required_byte_len / sizeof(uint32_t)));
298  } else if (kmac_mode == kOtcryptoKmacModeKmac256) {
299  // Check if `key_mode` of the key derivation key matches `kmac_mode`.
300  if (key_derivation_key.config.key_mode != kOtcryptoKeyModeKdfKmac256) {
301  return OTCRYPTO_BAD_ARGS;
302  }
303  // Check that key size matches the security strength. It should be at least
304  // 256-bit.
305  if (key_derivation_key.config.key_length < 256 / 8) {
306  return OTCRYPTO_BAD_ARGS;
307  }
308  HARDENED_TRY(kmac_kmac_256(&kmac_key, kdf_context.data, kdf_context.len,
309  kdf_label.data, kdf_label.len,
310  keying_material->keyblob,
311  required_byte_len / sizeof(uint32_t)));
312  } else {
313  return OTCRYPTO_BAD_ARGS;
314  }
315 
316  keying_material->checksum = integrity_blinded_checksum(keying_material);
317 
318  if (key_derivation_key.config.hw_backed == kHardenedBoolTrue) {
319  HARDENED_TRY(keymgr_sideload_clear_kmac());
320  } else if (key_derivation_key.config.hw_backed != kHardenedBoolFalse) {
321  return OTCRYPTO_BAD_ARGS;
322  }
323 
324  return OTCRYPTO_OK;
325 }
326 
330  otcrypto_blinded_key_t *okm) {
331  // Infer the digest length.
332  size_t digest_wordlen;
333  HARDENED_TRY(
334  digest_num_words_from_key_mode(ikm.config.key_mode, &digest_wordlen));
335  size_t digest_bytelen = digest_wordlen * sizeof(uint32_t);
336 
337  // Construct a blinded key struct for the intermediate key.
338  otcrypto_key_config_t prk_config = {
339  .version = kOtcryptoLibVersion1,
340  .key_mode = ikm.config.key_mode,
341  .key_length = digest_bytelen,
342  .hw_backed = kHardenedBoolFalse,
343  .exportable = kHardenedBoolFalse,
344  .security_level = kOtcryptoKeySecurityLevelLow,
345  };
346  size_t keyblob_wordlen = keyblob_num_words(prk_config);
347  uint32_t keyblob[keyblob_wordlen];
348  otcrypto_blinded_key_t prk = {
349  .config = prk_config,
350  .keyblob = keyblob,
351  .keyblob_length = sizeof(keyblob),
352  };
353 
354  // Call extract and expand.
355  HARDENED_TRY(otcrypto_kdf_hkdf_extract(ikm, salt, &prk));
356  return otcrypto_kdf_hkdf_expand(prk, info, okm);
357 }
358 
359 /**
360  * Check that an HKDF pseudo-random key is correctly configured.
361  *
362  * Ensures that the key mode, length, and allocated keyblob length are suitable
363  * for an HKDF pseudo-random key (i.e. the input for extract and the output for
364  * expand). Does not dereference the keyblob, so it is safe to call this before
365  * the keyblob is initialized.
366  *
367  * @param digest_words Length of the hash digest in 32-bit words.
368  * @param prk Pseudo-random key struct to check.
369  * @return OK if the PRK is acceptable, otherwise OTCRYPTO_BAD_ARGS.
370  */
371 static status_t hkdf_check_prk(size_t digest_words,
372  const otcrypto_blinded_key_t *prk) {
373  if (launder32(prk->config.key_mode) >> 16 != kOtcryptoKeyTypeHmac) {
374  return OTCRYPTO_BAD_ARGS;
375  }
376  HARDENED_CHECK_EQ(prk->config.key_mode >> 16, kOtcryptoKeyTypeHmac);
377 
378  // PRK should be the same length as the digest.
379  size_t digest_bytelen = digest_words * sizeof(uint32_t);
380  if (launder32(prk->config.key_length) != digest_bytelen) {
381  return OTCRYPTO_BAD_ARGS;
382  }
383  HARDENED_CHECK_EQ(prk->config.key_length, digest_bytelen);
384 
385  // Check the keyblob length.
386  size_t keyblob_bytelen = keyblob_num_words(prk->config) * sizeof(uint32_t);
387  if (launder32(prk->keyblob_length) != keyblob_bytelen) {
388  return OTCRYPTO_BAD_ARGS;
389  }
390  HARDENED_CHECK_EQ(prk->keyblob_length, keyblob_bytelen);
391 
392  // Ensure that the PRK is a symmetric key masked with XOR and is not supposed
393  // to be hardware-backed.
394  HARDENED_TRY(keyblob_ensure_xor_masked(prk->config));
395 
396  return OTCRYPTO_OK;
397 }
398 
401  otcrypto_blinded_key_t *prk) {
402  // Check for null pointers.
403  if (ikm.keyblob == NULL || prk == NULL || prk->keyblob == NULL) {
404  return OTCRYPTO_BAD_ARGS;
405  }
406  if (salt.data == NULL && salt.len != 0) {
407  return OTCRYPTO_BAD_ARGS;
408  }
409 
410  // Check the private key checksum.
411  if (integrity_blinded_key_check(&ikm) != kHardenedBoolTrue) {
412  return OTCRYPTO_BAD_ARGS;
413  }
414 
415  if (launder32(ikm.config.security_level) != kOtcryptoKeySecurityLevelLow ||
416  launder32(prk->config.security_level) != kOtcryptoKeySecurityLevelLow) {
417  // The underlying HMAC implementation is not currently hardened.
418  return OTCRYPTO_NOT_IMPLEMENTED;
419  }
420  HARDENED_CHECK_EQ(ikm.config.security_level, kOtcryptoKeySecurityLevelLow);
421  HARDENED_CHECK_EQ(prk->config.security_level, kOtcryptoKeySecurityLevelLow);
422 
423  // Ensure the key modes match.
424  if (launder32(prk->config.key_mode) != launder32(ikm.config.key_mode)) {
425  return OTCRYPTO_BAD_ARGS;
426  }
427  HARDENED_CHECK_EQ(prk->config.key_mode, ikm.config.key_mode);
428 
429  // Infer the digest size. This step also ensures that the key mode is
430  // supported.
431  size_t digest_words = 0;
432  HARDENED_TRY(
433  digest_num_words_from_key_mode(ikm.config.key_mode, &digest_words));
434 
435  // Validate the PRK configuration.
436  HARDENED_TRY(hkdf_check_prk(digest_words, prk));
437 
438  // Copy the salt into a 32-bit aligned buffer. If the salt is empty, replace
439  // it with a string of `hashLen` zeroes as specified in RFC 5869.
440  size_t salt_bytelen =
441  (salt.len == 0) ? digest_words * sizeof(uint32_t) : salt.len;
442  size_t salt_wordlen = ceil_div(salt_bytelen, sizeof(uint32_t));
443  uint32_t salt_aligned_data[salt_wordlen];
444  memset(salt_aligned_data, 0, sizeof(salt_aligned_data));
445  if (salt.len > 0) {
446  memcpy(salt_aligned_data, salt.data, salt.len);
447  }
448 
449  // The extract stage uses `salt` as the key and the input key as the message.
450  // We therefore need to unmask the key and package the salt in a blinded key
451  // struct.
452 
453  // Unmask the input key.
454  uint32_t *ikm_share0;
455  uint32_t *ikm_share1;
456  HARDENED_TRY(keyblob_to_shares(&ikm, &ikm_share0, &ikm_share1));
457  uint32_t unmasked_ikm_data[keyblob_share_num_words(ikm.config)];
458  for (size_t i = 0; i < ARRAYSIZE(unmasked_ikm_data); i++) {
459  unmasked_ikm_data[i] = ikm_share0[i] ^ ikm_share1[i];
460  }
461  otcrypto_const_byte_buf_t unmasked_ikm = {
462  .data = (unsigned char *)unmasked_ikm_data,
463  .len = ikm.config.key_length,
464  };
465 
466  // Package the salt value in a blinded key, using an all-zero mask because
467  // the salt is not actually secret.
468  uint32_t salt_mask[ARRAYSIZE(salt_aligned_data)];
469  memset(salt_mask, 0, sizeof(salt_mask));
470  otcrypto_key_config_t salt_key_config = {
471  .version = kOtcryptoLibVersion1,
472  .key_mode = ikm.config.key_mode,
473  .key_length = salt_bytelen,
474  .hw_backed = kHardenedBoolFalse,
475  .exportable = kHardenedBoolFalse,
476  .security_level = kOtcryptoKeySecurityLevelLow,
477  };
478  uint32_t salt_keyblob[keyblob_num_words(salt_key_config)];
479  TRY(keyblob_from_key_and_mask(salt_aligned_data, salt_mask, salt_key_config,
480  salt_keyblob));
481  otcrypto_blinded_key_t salt_key = {
482  .config = salt_key_config,
483  .keyblob = salt_keyblob,
484  .keyblob_length = sizeof(salt_keyblob),
485  };
486 
487  // Call HMAC(salt, IKM).
488  uint32_t tag_data[digest_words];
489  otcrypto_word32_buf_t tag = {.data = tag_data, .len = ARRAYSIZE(tag_data)};
490  HARDENED_TRY(otcrypto_hmac(&salt_key, unmasked_ikm, tag));
491 
492  // Construct the blinded keyblob for PRK (with an all-zero mask for now
493  // because HMAC is unhardened anyway).
494  uint32_t prk_mask[digest_words];
495  memset(prk_mask, 0, sizeof(prk_mask));
496  HARDENED_TRY(
497  keyblob_from_key_and_mask(tag_data, prk_mask, prk->config, prk->keyblob));
498  prk->checksum = integrity_blinded_checksum(prk);
499  return OTCRYPTO_OK;
500 }
501 
504  otcrypto_blinded_key_t *okm) {
505  if (okm == NULL || okm->keyblob == NULL || prk.keyblob == NULL) {
506  return OTCRYPTO_BAD_ARGS;
507  }
508  if (info.data == NULL && info.len != 0) {
509  return OTCRYPTO_BAD_ARGS;
510  }
511 
512  if (launder32(okm->config.security_level) != kOtcryptoKeySecurityLevelLow ||
513  launder32(prk.config.security_level) != kOtcryptoKeySecurityLevelLow) {
514  // The underlying HMAC implementation is not currently hardened.
515  return OTCRYPTO_NOT_IMPLEMENTED;
516  }
517 
518  // Infer the digest size.
519  size_t digest_words = 0;
520  HARDENED_TRY(
521  digest_num_words_from_key_mode(prk.config.key_mode, &digest_words));
522 
523  // Check the PRK configuration.
524  HARDENED_TRY(hkdf_check_prk(digest_words, &prk));
525 
526  // Ensure that the derived key is a symmetric key masked with XOR and is not
527  // supposed to be hardware-backed.
528  HARDENED_TRY(keyblob_ensure_xor_masked(okm->config));
529 
530  // Check the keyblob length.
531  size_t keyblob_bytelen = keyblob_num_words(okm->config) * sizeof(uint32_t);
532  if (launder32(okm->keyblob_length) != keyblob_bytelen) {
533  return OTCRYPTO_BAD_ARGS;
534  }
535  HARDENED_CHECK_EQ(okm->keyblob_length, keyblob_bytelen);
536 
537  // Check that the unmasked key length is not too large for HKDF (see RFC
538  // 5869, section 2.3).
539  size_t okm_bytelen = okm->config.key_length;
540  size_t okm_wordlen = ceil_div(okm_bytelen, sizeof(uint32_t));
541  size_t num_iterations = ceil_div(okm_wordlen, digest_words);
542  if (launder32(num_iterations) > 255) {
543  return OTCRYPTO_BAD_ARGS;
544  }
545  HARDENED_CHECK_LE(num_iterations, 255);
546 
547  // Create a buffer that holds `info` and a one-byte counter.
548  uint8_t info_and_counter_data[info.len + 1];
549  memcpy(info_and_counter_data, info.data, info.len);
550  info_and_counter_data[info.len] = 0x00;
551  otcrypto_const_byte_buf_t info_and_counter = {
552  .data = info_and_counter_data,
553  .len = sizeof(info_and_counter_data),
554  };
555 
556  // Repeatedly call HMAC to generate the derived key (see RFC 5869, section
557  // 2.3):
558  uint32_t okm_data[okm_wordlen];
559  uint32_t *t_data = okm_data;
560  for (uint8_t i = 0; i < num_iterations; i++) {
561  info_and_counter_data[info.len] = i + 1;
563  HARDENED_TRY(otcrypto_hmac_init(&ctx, &prk));
564  if (launder32(i) != 0) {
565  otcrypto_const_byte_buf_t t_bytes = {
566  .data = (unsigned char *)t_data,
567  .len = digest_words * sizeof(uint32_t),
568  };
569  HARDENED_TRY(otcrypto_hmac_update(&ctx, t_bytes));
570  t_data += digest_words;
571  }
572  HARDENED_TRY(otcrypto_hmac_update(&ctx, info_and_counter));
573  otcrypto_word32_buf_t t_words = {
574  .data = t_data,
575  .len = digest_words,
576  };
577  HARDENED_TRY(otcrypto_hmac_final(&ctx, t_words));
578  }
579 
580  // Generate a mask (all-zero for now, since HMAC is unhardened anyway).
581  uint32_t mask[digest_words];
582  memset(mask, 0, sizeof(mask));
583 
584  // Construct a blinded key.
585  HARDENED_TRY(
586  keyblob_from_key_and_mask(okm_data, mask, okm->config, okm->keyblob));
587  okm->checksum = integrity_blinded_checksum(okm);
588  return OTCRYPTO_OK;
589 }