Software APIs
ecc.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 
7 #include "sw/device/lib/crypto/drivers/entropy.h"
8 #include "sw/device/lib/crypto/drivers/hmac.h"
9 #include "sw/device/lib/crypto/impl/ecc/p256.h"
10 #include "sw/device/lib/crypto/impl/ecc/p384.h"
11 #include "sw/device/lib/crypto/impl/integrity.h"
12 #include "sw/device/lib/crypto/impl/keyblob.h"
14 
15 // Module ID for status codes.
16 #define MODULE_ID MAKE_MODULE_ID('e', 'c', 'c')
17 
19  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
20  HARDENED_TRY(otcrypto_ecdsa_p256_keygen_async_start(private_key));
21  return otcrypto_ecdsa_p256_keygen_async_finalize(private_key, public_key);
22 }
23 
25  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
26  HARDENED_TRY(otcrypto_ecdsa_p384_keygen_async_start(private_key));
27  return otcrypto_ecdsa_p384_keygen_async_finalize(private_key, public_key);
28 }
29 
31  const otcrypto_blinded_key_t *private_key,
32  const otcrypto_hash_digest_t message_digest,
33  otcrypto_word32_buf_t signature) {
34  HARDENED_TRY(
35  otcrypto_ecdsa_p256_sign_async_start(private_key, message_digest));
37 }
38 
40  const otcrypto_blinded_key_t *private_key,
41  const otcrypto_hash_digest_t message_digest,
42  otcrypto_word32_buf_t signature) {
43  HARDENED_TRY(
44  otcrypto_ecdsa_p384_sign_async_start(private_key, message_digest));
46 }
47 
49  const otcrypto_unblinded_key_t *public_key,
50  const otcrypto_hash_digest_t message_digest,
52  hardened_bool_t *verification_result) {
54  public_key, message_digest, signature));
56  verification_result);
57 }
58 
60  const otcrypto_unblinded_key_t *public_key,
61  const otcrypto_hash_digest_t message_digest,
63  hardened_bool_t *verification_result) {
65  public_key, message_digest, signature));
67  verification_result);
68 }
69 
71  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
72  HARDENED_TRY(otcrypto_ecdh_p256_keygen_async_start(private_key));
73  return otcrypto_ecdh_p256_keygen_async_finalize(private_key, public_key);
74 }
75 
77  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
78  HARDENED_TRY(otcrypto_ecdh_p384_keygen_async_start(private_key));
79  return otcrypto_ecdh_p384_keygen_async_finalize(private_key, public_key);
80 }
81 
83  const otcrypto_unblinded_key_t *public_key,
84  const otcrypto_ecc_curve_t *elliptic_curve,
85  otcrypto_blinded_key_t *shared_secret) {
86  HARDENED_TRY(
87  otcrypto_ecdh_async_start(private_key, public_key, elliptic_curve));
88  return otcrypto_ecdh_async_finalize(elliptic_curve, shared_secret);
89 }
90 
92  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
93  // TODO: Ed25519 is not yet implemented.
94  return OTCRYPTO_NOT_IMPLEMENTED;
95 }
96 
98  const otcrypto_blinded_key_t *private_key,
99  otcrypto_const_byte_buf_t input_message,
100  otcrypto_eddsa_sign_mode_t sign_mode, otcrypto_word32_buf_t signature) {
101  // TODO: Ed25519 is not yet implemented.
102  return OTCRYPTO_NOT_IMPLEMENTED;
103 }
104 
106  const otcrypto_unblinded_key_t *public_key,
107  otcrypto_const_byte_buf_t input_message,
109  hardened_bool_t *verification_result) {
110  // TODO: Ed25519 is not yet implemented.
111  return OTCRYPTO_NOT_IMPLEMENTED;
112 }
113 
115  otcrypto_unblinded_key_t *public_key) {
116  // TODO: Connect X25519 operations to API.
117  return OTCRYPTO_NOT_IMPLEMENTED;
118 }
119 
121  const otcrypto_unblinded_key_t *public_key,
122  otcrypto_blinded_key_t *shared_secret) {
123  // TODO: Connect X25519 operations to API.
124  return OTCRYPTO_NOT_IMPLEMENTED;
125 }
126 
127 /**
128  * Calls keymgr to sideload key material into OTBN.
129  *
130  * This routine should only ever be called on hardware-backed keys.
131  *
132  * @param private_key Sideloaded key handle.
133  * @return OK or error.
134  */
136 static status_t sideload_key_seed(const otcrypto_blinded_key_t *private_key) {
137  keymgr_diversification_t diversification;
138  HARDENED_TRY(
139  keyblob_to_keymgr_diversification(private_key, &diversification));
140  return keymgr_generate_key_otbn(diversification);
141 }
142 
143 /**
144  * Calls P-256 key generation.
145  *
146  * Can be used for both ECDSA and ECDH. If the key is hardware-backed, loads
147  * the data from key manager and calls the sideloaded key generation routine.
148  *
149  * @param private_key Sideloaded key handle.
150  * @return OK or error.
151  */
153 static status_t internal_p256_keygen_start(
154  const otcrypto_blinded_key_t *private_key) {
155  // Check that the entropy complex is initialized.
156  HARDENED_TRY(entropy_complex_check());
157 
158  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
159  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
160  HARDENED_TRY(sideload_key_seed(private_key));
161  return p256_sideload_keygen_start();
162  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
163  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
164  return p256_keygen_start();
165  } else {
166  return OTCRYPTO_BAD_ARGS;
167  }
168  return OTCRYPTO_OK;
169 }
170 
172  const otcrypto_blinded_key_t *private_key) {
173  if (private_key == NULL || private_key->keyblob == NULL) {
174  return OTCRYPTO_BAD_ARGS;
175  }
176 
177  // Check the key mode.
178  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP256) {
179  return OTCRYPTO_BAD_ARGS;
180  }
181  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP256);
182 
183  return internal_p256_keygen_start(private_key);
184 }
185 
186 /**
187  * Calls P-384 key generation.
188  *
189  * Can be used for both ECDSA and ECDH. If the key is hardware-backed, loads
190  * the data from key manager and calls the sideloaded key generation routine.
191  *
192  * @param private_key Sideloaded key handle.
193  * @return OK or error.
194  */
196 static status_t internal_p384_keygen_start(
197  const otcrypto_blinded_key_t *private_key) {
198  // Check that the entropy complex is initialized.
199  HARDENED_TRY(entropy_complex_check());
200 
201  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
202  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
203  HARDENED_TRY(sideload_key_seed(private_key));
204  return p384_sideload_keygen_start();
205  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
206  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
207  return p384_keygen_start();
208  } else {
209  return OTCRYPTO_BAD_ARGS;
210  }
211  return OTCRYPTO_OK;
212 }
213 
215  const otcrypto_blinded_key_t *private_key) {
216  if (private_key == NULL || private_key->keyblob == NULL) {
217  return OTCRYPTO_BAD_ARGS;
218  }
219 
220  // Check the key mode.
221  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP384) {
222  return OTCRYPTO_BAD_ARGS;
223  }
224  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP384);
225 
226  return internal_p384_keygen_start(private_key);
227 }
228 
229 /**
230  * Check the lengths of private keys for curve P-256.
231  *
232  * Checks the length of caller-allocated buffers for a P-256 private key. This
233  * function may be used for both ECDSA and ECDH keys, since the key structure
234  * is the same.
235  *
236  * If this check passes and `hw_backed` is false, it is safe to interpret
237  * `private_key->keyblob` as a `p256_masked_scalar_t *`.
238  *
239  * @param private_key Private key struct to check.
240  * @return OK if the lengths are correct or BAD_ARGS otherwise.
241  */
243 static status_t p256_private_key_length_check(
244  const otcrypto_blinded_key_t *private_key) {
245  if (private_key->keyblob == NULL) {
246  return OTCRYPTO_BAD_ARGS;
247  }
248 
249  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
250  // Skip the length check in this case; if the salt is the wrong length, the
251  // keyblob library will catch it before we sideload the key.
252  return OTCRYPTO_OK;
253  }
254  HARDENED_CHECK_NE(private_key->config.hw_backed, kHardenedBoolTrue);
255 
256  // Check the unmasked length.
257  if (launder32(private_key->config.key_length) != kP256ScalarBytes) {
258  return OTCRYPTO_BAD_ARGS;
259  }
260  HARDENED_CHECK_EQ(private_key->config.key_length, kP256ScalarBytes);
261 
262  // Check the single-share length.
263  if (launder32(keyblob_share_num_words(private_key->config)) !=
264  kP256MaskedScalarShareWords) {
265  return OTCRYPTO_BAD_ARGS;
266  }
267  HARDENED_CHECK_EQ(keyblob_share_num_words(private_key->config),
268  kP256MaskedScalarShareWords);
269 
270  // Check the keyblob length.
271  if (launder32(private_key->keyblob_length) != sizeof(p256_masked_scalar_t)) {
272  return OTCRYPTO_BAD_ARGS;
273  }
274  HARDENED_CHECK_EQ(private_key->keyblob_length, sizeof(p256_masked_scalar_t));
275 
276  return OTCRYPTO_OK;
277 }
278 
279 /**
280  * Check the lengths of public keys for curve P-256.
281  *
282  * Checks the length of caller-allocated buffers for a P-256 public key. This
283  * function may be used for both ECDSA and ECDH keys, since the key structure
284  * is the same.
285  *
286  * If this check passes, it is safe to interpret public_key->key as a
287  * `p256_point_t *`.
288  *
289  * @param public_key Public key struct to check.
290  * @return OK if the lengths are correct or BAD_ARGS otherwise.
291  */
293 static status_t p256_public_key_length_check(
294  const otcrypto_unblinded_key_t *public_key) {
295  if (launder32(public_key->key_length) != sizeof(p256_point_t)) {
296  return OTCRYPTO_BAD_ARGS;
297  }
298  HARDENED_CHECK_EQ(public_key->key_length, sizeof(p256_point_t));
299  return OTCRYPTO_OK;
300 }
301 
302 /**
303  * Check the lengths of private keys for curve P-384.
304  *
305  * Checks the length of caller-allocated buffers for a P-384 private key. This
306  * function may be used for both ECDSA and ECDH keys, since the key structure
307  * is the same.
308  *
309  * If this check passes and `hw_backed` is false, it is safe to interpret
310  * `private_key->keyblob` as a `p384_masked_scalar_t *`.
311  *
312  * @param private_key Private key struct to check.
313  * @return OK if the lengths are correct or BAD_ARGS otherwise.
314  */
316 static status_t p384_private_key_length_check(
317  const otcrypto_blinded_key_t *private_key) {
318  if (private_key->keyblob == NULL) {
319  return OTCRYPTO_BAD_ARGS;
320  }
321 
322  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
323  // Skip the length check in this case; if the salt is the wrong length, the
324  // keyblob library will catch it before we sideload the key.
325  return OTCRYPTO_OK;
326  }
327  HARDENED_CHECK_NE(private_key->config.hw_backed, kHardenedBoolTrue);
328 
329  // Check the unmasked length.
330  if (launder32(private_key->config.key_length) != kP384ScalarBytes) {
331  return OTCRYPTO_BAD_ARGS;
332  }
333  HARDENED_CHECK_EQ(private_key->config.key_length, kP384ScalarBytes);
334 
335  // Check the single-share length.
336  if (launder32(keyblob_share_num_words(private_key->config)) !=
337  kP384MaskedScalarShareWords) {
338  return OTCRYPTO_BAD_ARGS;
339  }
340  HARDENED_CHECK_EQ(keyblob_share_num_words(private_key->config),
341  kP384MaskedScalarShareWords);
342 
343  // Check the keyblob length.
344  if (launder32(private_key->keyblob_length) != sizeof(p384_masked_scalar_t)) {
345  return OTCRYPTO_BAD_ARGS;
346  }
347  HARDENED_CHECK_EQ(private_key->keyblob_length, sizeof(p384_masked_scalar_t));
348 
349  return OTCRYPTO_OK;
350 }
351 
352 /**
353  * Check the lengths of public keys for curve P-384.
354  *
355  * Checks the length of caller-allocated buffers for a P-384 public key. This
356  * function may be used for both ECDSA and ECDH keys, since the key structure
357  * is the same.
358  *
359  * If this check passes, it is safe to interpret public_key->key as a
360  * `p384_point_t *`.
361  *
362  * @param public_key Public key struct to check.
363  * @return OK if the lengths are correct or BAD_ARGS otherwise.
364  */
366 static status_t p384_public_key_length_check(
367  const otcrypto_unblinded_key_t *public_key) {
368  if (launder32(public_key->key_length) != sizeof(p384_point_t)) {
369  return OTCRYPTO_BAD_ARGS;
370  }
371  HARDENED_CHECK_EQ(public_key->key_length, sizeof(p384_point_t));
372  return OTCRYPTO_OK;
373 }
374 
375 /**
376  * Finalize a keypair generation operation for curve P-256.
377  *
378  * This function assumes that space is already allocated for all key material
379  * and that the length parameters on the structs are set accordingly, in the
380  * same way as for `otcrypto_ecdh_p256_keygen_async_finalize` and
381  * `otcrypto_ecdsa_p256_keygen_async_finalize`.
382  *
383  * @param[out] private_key Private key to populate.
384  * @param[out] public_key Public key to populate.
385  * @return OK or error.
386  */
388 static status_t internal_p256_keygen_finalize(
389  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
390  // Check the lengths of caller-allocated buffers.
391  HARDENED_TRY(p256_private_key_length_check(private_key));
392  HARDENED_TRY(p256_public_key_length_check(public_key));
393  p256_point_t *pk = (p256_point_t *)public_key->key;
394 
395  // Note: The `finalize` operations wipe DMEM after retrieving the keys, so if
396  // an error occurs after this point then the keys would be unrecoverable.
397  // The `finalize` call should be the last potentially error-causing line
398  // before returning to the caller.
399 
400  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
401  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
402  HARDENED_TRY(p256_sideload_keygen_finalize(pk));
403  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
404  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
405  p256_masked_scalar_t *sk = (p256_masked_scalar_t *)private_key->keyblob;
406  HARDENED_TRY(p256_keygen_finalize(sk, pk));
407  private_key->checksum = integrity_blinded_checksum(private_key);
408  } else {
409  return OTCRYPTO_BAD_ARGS;
410  }
411 
412  // Prepare the public key.
413  public_key->checksum = integrity_unblinded_checksum(public_key);
414 
415  // Clear the OTBN sideload slot (in case the seed was sideloaded).
416  return keymgr_sideload_clear_otbn();
417 }
418 
419 /**
420  * Finalize a keypair generation operation for curve P-384.
421  *
422  * This function assumes that space is already allocated for all key material
423  * and that the length parameters on the structs are set accordingly, in the
424  * same way as for `otcrypto_ecdh_p384_keygen_async_finalize` and
425  * `otcrypto_ecdsa_p384_keygen_async_finalize`.
426  *
427  * @param[out] private_key Private key to populate.
428  * @param[out] public_key Public key to populate.
429  * @return OK or error.
430  */
432 static status_t internal_p384_keygen_finalize(
433  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
434  // Check the lengths of caller-allocated buffers.
435  HARDENED_TRY(p384_private_key_length_check(private_key));
436  HARDENED_TRY(p384_public_key_length_check(public_key));
437 
438  // Interpret the key buffer as a P-384 point.
439  p384_point_t *pk = (p384_point_t *)public_key->key;
440 
441  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
442  // Note: This operation wipes DMEM after retrieving the keys, so if an error
443  // occurs after this point then the keys would be unrecoverable. This should
444  // be the last potentially error-causing line before returning to the
445  // caller.
446  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
447  HARDENED_TRY(p384_sideload_keygen_finalize(pk));
448  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
449  p384_masked_scalar_t *sk = (p384_masked_scalar_t *)private_key->keyblob;
450  // Note: This operation wipes DMEM after retrieving the keys, so if an error
451  // occurs after this point then the keys would be unrecoverable. This should
452  // be the last potentially error-causing line before returning to the
453  // caller.
454  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
455  HARDENED_TRY(p384_keygen_finalize(sk, pk));
456  private_key->checksum = integrity_blinded_checksum(private_key);
457  } else {
458  return OTCRYPTO_BAD_ARGS;
459  }
460 
461  public_key->checksum = integrity_unblinded_checksum(public_key);
462  return OTCRYPTO_OK;
463 }
464 
466  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
467  // Check for any NULL pointers.
468  if (private_key == NULL || public_key == NULL ||
469  private_key->keyblob == NULL || public_key->key == NULL) {
470  return OTCRYPTO_BAD_ARGS;
471  }
472 
473  // Check the key modes.
474  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP256 ||
475  launder32(public_key->key_mode) != kOtcryptoKeyModeEcdsaP256) {
476  return OTCRYPTO_BAD_ARGS;
477  }
478  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP256);
479  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdsaP256);
480 
481  return internal_p256_keygen_finalize(private_key, public_key);
482 }
483 
485  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
486  // Check for any NULL pointers.
487  if (private_key == NULL || public_key == NULL ||
488  private_key->keyblob == NULL || public_key->key == NULL) {
489  return OTCRYPTO_BAD_ARGS;
490  }
491 
492  // Check the key modes.
493  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP384 ||
494  launder32(public_key->key_mode) != kOtcryptoKeyModeEcdsaP384) {
495  return OTCRYPTO_BAD_ARGS;
496  }
497  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP384);
498  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdsaP384);
499 
500  HARDENED_TRY(internal_p384_keygen_finalize(private_key, public_key));
501 
502  // Clear the OTBN sideload slot (in case the seed was sideloaded).
503  return keymgr_sideload_clear_otbn();
504 }
505 
507  const otcrypto_blinded_key_t *private_key,
508  const otcrypto_hash_digest_t message_digest) {
509  if (private_key == NULL || private_key->keyblob == NULL ||
510  message_digest.data == NULL) {
511  return OTCRYPTO_BAD_ARGS;
512  }
513 
514  // Check the integrity of the private key.
515  if (launder32(integrity_blinded_key_check(private_key)) !=
517  return OTCRYPTO_BAD_ARGS;
518  }
519  HARDENED_CHECK_EQ(integrity_blinded_key_check(private_key),
521 
522  // Check that the entropy complex is initialized.
523  HARDENED_TRY(entropy_complex_check());
524 
525  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP256) {
526  return OTCRYPTO_BAD_ARGS;
527  }
528  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP256);
529 
530  // Check the digest length.
531  if (launder32(message_digest.len) != kP256ScalarWords) {
532  return OTCRYPTO_BAD_ARGS;
533  }
534  HARDENED_CHECK_EQ(message_digest.len, kP256ScalarWords);
535 
536  // Check the key length.
537  HARDENED_TRY(p256_private_key_length_check(private_key));
538 
539  if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
540  // Start the asynchronous signature-generation routine.
541  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
542  p256_masked_scalar_t *sk = (p256_masked_scalar_t *)private_key->keyblob;
543  return p256_ecdsa_sign_start(message_digest.data, sk);
544  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
545  // Load the key and start in sideloaded-key mode.
546  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
547  HARDENED_TRY(sideload_key_seed(private_key));
548  return p256_ecdsa_sideload_sign_start(message_digest.data);
549  }
550 
551  // Invalid value for private_key->hw_backed.
552  return OTCRYPTO_BAD_ARGS;
553 }
554 
556  const otcrypto_blinded_key_t *private_key,
557  const otcrypto_hash_digest_t message_digest) {
558  if (private_key == NULL || private_key->keyblob == NULL ||
559  message_digest.data == NULL) {
560  return OTCRYPTO_BAD_ARGS;
561  }
562 
563  // Check the integrity of the private key.
564  if (launder32(integrity_blinded_key_check(private_key)) !=
566  return OTCRYPTO_BAD_ARGS;
567  }
568  HARDENED_CHECK_EQ(integrity_blinded_key_check(private_key),
570 
571  // Check that the entropy complex is initialized.
572  HARDENED_TRY(entropy_complex_check());
573 
574  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdsaP384) {
575  return OTCRYPTO_BAD_ARGS;
576  }
577  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdsaP384);
578 
579  // Check the digest length.
580  if (launder32(message_digest.len) != kP384ScalarWords) {
581  return OTCRYPTO_BAD_ARGS;
582  }
583  HARDENED_CHECK_EQ(message_digest.len, kP384ScalarWords);
584 
585  // Check the key length.
586  HARDENED_TRY(p384_private_key_length_check(private_key));
587 
588  if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
589  // Start the asynchronous signature-generation routine.
590  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
591  p384_masked_scalar_t *sk = (p384_masked_scalar_t *)private_key->keyblob;
592  return p384_ecdsa_sign_start(message_digest.data, sk);
593  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
594  // Load the key and start in sideloaded-key mode.
595  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
596  HARDENED_TRY(sideload_key_seed(private_key));
597  return p384_ecdsa_sideload_sign_start(message_digest.data);
598  }
599 
600  // Invalid value for private_key->hw_backed.
601  return OTCRYPTO_BAD_ARGS;
602 }
603 
604 /**
605  * Check the length of a signature buffer for ECDSA with P-256.
606  *
607  * If this check passes on `signature.len`, it is safe to interpret
608  * `signature.data` as `p256_ecdsa_signature_t *`.
609  *
610  * @param len Length to check.
611  * @return OK if the lengths are correct or BAD_ARGS otherwise.
612  */
614 static status_t p256_signature_length_check(size_t len) {
615  if (launder32(len) > UINT32_MAX / sizeof(uint32_t) ||
616  launder32(len) * sizeof(uint32_t) != sizeof(p256_ecdsa_signature_t)) {
617  return OTCRYPTO_BAD_ARGS;
618  }
619  HARDENED_CHECK_EQ(len * sizeof(uint32_t), sizeof(p256_ecdsa_signature_t));
620 
621  return OTCRYPTO_OK;
622 }
623 
624 /**
625  * Check the length of a signature buffer for ECDSA with P-384.
626  *
627  * If this check passes on `signature.len`, it is safe to interpret
628  * `signature.data` as `p384_ecdsa_signature_t *`.
629  *
630  * @param len Length to check.
631  * @return OK if the lengths are correct or BAD_ARGS otherwise.
632  */
634 static status_t p384_signature_length_check(size_t len) {
635  if (launder32(len) > UINT32_MAX / sizeof(uint32_t) ||
636  launder32(len) * sizeof(uint32_t) != sizeof(p384_ecdsa_signature_t)) {
637  return OTCRYPTO_BAD_ARGS;
638  }
639  HARDENED_CHECK_EQ(len * sizeof(uint32_t), sizeof(p384_ecdsa_signature_t));
640 
641  return OTCRYPTO_OK;
642 }
643 
645  otcrypto_word32_buf_t signature) {
646  if (signature.data == NULL) {
647  return OTCRYPTO_BAD_ARGS;
648  }
649 
650  HARDENED_TRY(p256_signature_length_check(signature.len));
651  p256_ecdsa_signature_t *sig_p256 = (p256_ecdsa_signature_t *)signature.data;
652  // Note: This operation wipes DMEM, so if an error occurs after this
653  // point then the signature would be unrecoverable. This should be the
654  // last potentially error-causing line before returning to the caller.
655  HARDENED_TRY(p256_ecdsa_sign_finalize(sig_p256));
656 
657  // Clear the OTBN sideload slot (in case the key was sideloaded).
658  return keymgr_sideload_clear_otbn();
659 }
660 
662  otcrypto_word32_buf_t signature) {
663  if (signature.data == NULL) {
664  return OTCRYPTO_BAD_ARGS;
665  }
666 
667  HARDENED_TRY(p384_signature_length_check(signature.len));
668  p384_ecdsa_signature_t *sig_p384 = (p384_ecdsa_signature_t *)signature.data;
669  // Note: This operation wipes DMEM, so if an error occurs after this
670  // point then the signature would be unrecoverable. This should be the
671  // last potentially error-causing line before returning to the caller.
672  HARDENED_TRY(p384_ecdsa_sign_finalize(sig_p384));
673 
674  // Clear the OTBN sideload slot (in case the key was sideloaded).
675  return keymgr_sideload_clear_otbn();
676 }
677 
679  const otcrypto_unblinded_key_t *public_key,
680  const otcrypto_hash_digest_t message_digest,
681  otcrypto_const_word32_buf_t signature) {
682  if (public_key == NULL || signature.data == NULL ||
683  message_digest.data == NULL || public_key->key == NULL) {
684  return OTCRYPTO_BAD_ARGS;
685  }
686 
687  // Check the integrity of the public key.
688  if (launder32(integrity_unblinded_key_check(public_key)) !=
690  return OTCRYPTO_BAD_ARGS;
691  }
692  HARDENED_CHECK_EQ(integrity_unblinded_key_check(public_key),
694 
695  // Check the public key mode.
696  if (launder32(public_key->key_mode) != kOtcryptoKeyModeEcdsaP256) {
697  return OTCRYPTO_BAD_ARGS;
698  }
699  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdsaP256);
700 
701  // Check the public key size.
702  HARDENED_TRY(p256_public_key_length_check(public_key));
703  p256_point_t *pk = (p256_point_t *)public_key->key;
704 
705  // Check the digest length.
706  if (launder32(message_digest.len) != kP256ScalarWords) {
707  return OTCRYPTO_BAD_ARGS;
708  }
709  HARDENED_CHECK_EQ(message_digest.len, kP256ScalarWords);
710 
711  // Check the signature lengths.
712  HARDENED_TRY(p256_signature_length_check(signature.len));
713  p256_ecdsa_signature_t *sig = (p256_ecdsa_signature_t *)signature.data;
714 
715  // Start the asynchronous signature-verification routine.
716  return p256_ecdsa_verify_start(sig, message_digest.data, pk);
717 }
718 
720  otcrypto_const_word32_buf_t signature,
721  hardened_bool_t *verification_result) {
722  if (verification_result == NULL) {
723  return OTCRYPTO_BAD_ARGS;
724  }
725 
726  HARDENED_TRY(p256_signature_length_check(signature.len));
727  p256_ecdsa_signature_t *sig_p256 = (p256_ecdsa_signature_t *)signature.data;
728  return p256_ecdsa_verify_finalize(sig_p256, verification_result);
729 }
730 
732  const otcrypto_unblinded_key_t *public_key,
733  const otcrypto_hash_digest_t message_digest,
734  otcrypto_const_word32_buf_t signature) {
735  if (public_key == NULL || signature.data == NULL ||
736  message_digest.data == NULL || public_key->key == NULL) {
737  return OTCRYPTO_BAD_ARGS;
738  }
739 
740  // Check the integrity of the public key.
741  if (launder32(integrity_unblinded_key_check(public_key)) !=
743  return OTCRYPTO_BAD_ARGS;
744  }
745  HARDENED_CHECK_EQ(integrity_unblinded_key_check(public_key),
747 
748  // Check the public key mode.
749  if (launder32(public_key->key_mode) != kOtcryptoKeyModeEcdsaP384) {
750  return OTCRYPTO_BAD_ARGS;
751  }
752  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdsaP384);
753 
754  // Check the public key size.
755  HARDENED_TRY(p384_public_key_length_check(public_key));
756  p384_point_t *pk = (p384_point_t *)public_key->key;
757 
758  // Check the digest length.
759  if (launder32(message_digest.len) != kP384ScalarWords) {
760  return OTCRYPTO_BAD_ARGS;
761  }
762  HARDENED_CHECK_EQ(message_digest.len, kP384ScalarWords);
763 
764  // Check the signature lengths.
765  HARDENED_TRY(p384_signature_length_check(signature.len));
766  p384_ecdsa_signature_t *sig = (p384_ecdsa_signature_t *)signature.data;
767 
768  // Start the asynchronous signature-verification routine.
769  return p384_ecdsa_verify_start(sig, message_digest.data, pk);
770 }
771 
773  otcrypto_const_word32_buf_t signature,
774  hardened_bool_t *verification_result) {
775  if (verification_result == NULL) {
776  return OTCRYPTO_BAD_ARGS;
777  }
778 
779  HARDENED_TRY(p384_signature_length_check(signature.len));
780  p384_ecdsa_signature_t *sig_p384 = (p384_ecdsa_signature_t *)signature.data;
781  return p384_ecdsa_verify_finalize(sig_p384, verification_result);
782 }
783 
785  const otcrypto_blinded_key_t *private_key) {
786  if (private_key == NULL || private_key->keyblob == NULL) {
787  return OTCRYPTO_BAD_ARGS;
788  }
789 
790  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP256) {
791  return OTCRYPTO_BAD_ARGS;
792  }
793  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP256);
794  return internal_p256_keygen_start(private_key);
795 }
796 
798  const otcrypto_blinded_key_t *private_key) {
799  if (private_key == NULL || private_key->keyblob == NULL) {
800  return OTCRYPTO_BAD_ARGS;
801  }
802 
803  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP384) {
804  return OTCRYPTO_BAD_ARGS;
805  }
806  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP384);
807  return internal_p384_keygen_start(private_key);
808 }
809 
811  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
812  // Check for any NULL pointers.
813  if (private_key == NULL || public_key == NULL ||
814  private_key->keyblob == NULL || public_key->key == NULL) {
815  return OTCRYPTO_BAD_ARGS;
816  }
817 
818  if (launder32(public_key->key_mode) != kOtcryptoKeyModeEcdhP256 ||
819  launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP256) {
820  return OTCRYPTO_BAD_ARGS;
821  }
822  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdhP256);
823  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP256);
824  return internal_p256_keygen_finalize(private_key, public_key);
825 }
826 
828  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
829  // Check for any NULL pointers.
830  if (private_key == NULL || public_key == NULL ||
831  private_key->keyblob == NULL || public_key->key == NULL) {
832  return OTCRYPTO_BAD_ARGS;
833  }
834 
835  if (launder32(public_key->key_mode) != kOtcryptoKeyModeEcdhP384 ||
836  launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP384) {
837  return OTCRYPTO_BAD_ARGS;
838  }
839  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdhP384);
840  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP384);
841  return internal_p384_keygen_finalize(private_key, public_key);
842 }
843 
844 /**
845  * Start an ECDH shared key generation operation for curve P-256.
846  *
847  * @param private_key Private key for key exchange.
848  * @param public_key Public key for key exchange.
849  * @return OK or error.
850  */
852 static status_t internal_ecdh_p256_start(
853  const otcrypto_blinded_key_t *private_key,
854  const otcrypto_unblinded_key_t *public_key) {
855  HARDENED_TRY(p256_private_key_length_check(private_key));
856  HARDENED_TRY(p256_public_key_length_check(public_key));
857  p256_point_t *pk = (p256_point_t *)public_key->key;
858 
859  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
860  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
861  HARDENED_TRY(sideload_key_seed(private_key));
862  return p256_sideload_ecdh_start(pk);
863  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
864  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
865  p256_masked_scalar_t *sk = (p256_masked_scalar_t *)private_key->keyblob;
866  return p256_ecdh_start(sk, pk);
867  }
868 
869  // Invalid value for `hw_backed`.
870  return OTCRYPTO_BAD_ARGS;
871 }
872 
873 /**
874  * Start an ECDH shared key generation operation for curve P-384.
875  *
876  * @param private_key Private key for key exchange.
877  * @param public_key Public key for key exchange.
878  * @return OK or error.
879  */
881 static status_t internal_ecdh_p384_start(
882  const otcrypto_blinded_key_t *private_key,
883  const otcrypto_unblinded_key_t *public_key) {
884  HARDENED_TRY(p384_private_key_length_check(private_key));
885  HARDENED_TRY(p384_public_key_length_check(public_key));
886  p384_point_t *pk = (p384_point_t *)public_key->key;
887 
888  if (launder32(private_key->config.hw_backed) == kHardenedBoolTrue) {
889  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolTrue);
890  HARDENED_TRY(sideload_key_seed(private_key));
891  return p384_sideload_ecdh_start(pk);
892  } else if (launder32(private_key->config.hw_backed) == kHardenedBoolFalse) {
893  HARDENED_CHECK_EQ(private_key->config.hw_backed, kHardenedBoolFalse);
894  p384_masked_scalar_t *sk = (p384_masked_scalar_t *)private_key->keyblob;
895  return p384_ecdh_start(sk, pk);
896  }
897 
898  // Invalid value for `hw_backed`.
899  return OTCRYPTO_BAD_ARGS;
900 }
901 
903  const otcrypto_blinded_key_t *private_key,
904  const otcrypto_unblinded_key_t *public_key,
905  const otcrypto_ecc_curve_t *elliptic_curve) {
906  if (private_key == NULL || public_key == NULL || elliptic_curve == NULL ||
907  public_key->key == NULL || private_key->keyblob == NULL) {
908  return OTCRYPTO_BAD_ARGS;
909  }
910 
911  // Check the integrity of the keys.
912  if (launder32(integrity_blinded_key_check(private_key)) !=
914  launder32(integrity_unblinded_key_check(public_key)) !=
916  return OTCRYPTO_BAD_ARGS;
917  }
918  HARDENED_CHECK_EQ(integrity_blinded_key_check(private_key),
920  HARDENED_CHECK_EQ(integrity_unblinded_key_check(public_key),
922 
923  // Select the correct ECDH operation and start it.
924  switch (launder32(elliptic_curve->curve_type)) {
925  case kOtcryptoEccCurveTypeNistP256:
926  HARDENED_CHECK_EQ(elliptic_curve->curve_type,
927  kOtcryptoEccCurveTypeNistP256);
928  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP256 ||
929  launder32(public_key->key_mode) != kOtcryptoKeyModeEcdhP256) {
930  return OTCRYPTO_BAD_ARGS;
931  }
932  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP256);
933  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdhP256);
934  HARDENED_TRY(internal_ecdh_p256_start(private_key, public_key));
935  return OTCRYPTO_OK;
936  case kOtcryptoEccCurveTypeNistP384:
937  HARDENED_CHECK_EQ(elliptic_curve->curve_type,
938  kOtcryptoEccCurveTypeNistP384);
939  if (launder32(private_key->config.key_mode) != kOtcryptoKeyModeEcdhP384 ||
940  launder32(public_key->key_mode) != kOtcryptoKeyModeEcdhP384) {
941  return OTCRYPTO_BAD_ARGS;
942  }
943  HARDENED_CHECK_EQ(private_key->config.key_mode, kOtcryptoKeyModeEcdhP384);
944  HARDENED_CHECK_EQ(public_key->key_mode, kOtcryptoKeyModeEcdhP384);
945  HARDENED_TRY(internal_ecdh_p384_start(private_key, public_key));
946  return OTCRYPTO_OK;
947  case kEccCurveTypeBrainpoolP256R1:
949  case kOtcryptoEccCurveTypeCustom:
950  // TODO: Implement support for other curves.
951  return OTCRYPTO_NOT_IMPLEMENTED;
952  default:
953  return OTCRYPTO_BAD_ARGS;
954  }
955 
956  // Should never get here.
957  HARDENED_TRAP();
958  return OTCRYPTO_FATAL_ERR;
959 }
960 
961 /**
962  * Finish an ECDH shared key generation operation for curve P-256.
963  *
964  * @param[out] shared_secret Resulting shared secret.
965  * @return OK or error.
966  */
968 static status_t internal_ecdh_p256_finalize(
969  otcrypto_blinded_key_t *shared_secret) {
970  if (launder32(shared_secret->config.hw_backed) != kHardenedBoolFalse) {
971  // Shared keys cannot be sideloaded because they are software-generated.
972  return OTCRYPTO_BAD_ARGS;
973  }
974  HARDENED_CHECK_EQ(shared_secret->config.hw_backed, kHardenedBoolFalse);
975 
976  if (shared_secret->keyblob == NULL) {
977  return OTCRYPTO_BAD_ARGS;
978  }
979 
980  if (launder32(shared_secret->config.key_length) != kP256CoordBytes) {
981  return OTCRYPTO_BAD_ARGS;
982  }
983  HARDENED_CHECK_EQ(shared_secret->config.key_length, kP256CoordBytes);
984 
985  if (launder32(shared_secret->keyblob_length) !=
986  keyblob_num_words(shared_secret->config) * sizeof(uint32_t)) {
987  return OTCRYPTO_BAD_ARGS;
988  }
990  shared_secret->keyblob_length,
991  keyblob_num_words(shared_secret->config) * sizeof(uint32_t));
992 
993  // Note: This operation wipes DMEM after retrieving the keys, so if an error
994  // occurs after this point then the keys would be unrecoverable. This should
995  // be the last potentially error-causing line before returning to the caller.
997  HARDENED_TRY(p256_ecdh_finalize(&ss));
998 
999  keyblob_from_shares(ss.share0, ss.share1, shared_secret->config,
1000  shared_secret->keyblob);
1001 
1002  // Set the checksum.
1003  shared_secret->checksum = integrity_blinded_checksum(shared_secret);
1004 
1005  // Clear the OTBN sideload slot (in case the seed was sideloaded).
1006  return keymgr_sideload_clear_otbn();
1007 }
1008 
1009 /**
1010  * Finish an ECDH shared key generation operation for curve P-384.
1011  *
1012  * @param[out] shared_secret Resulting shared secret.
1013  * @return OK or error.
1014  */
1016 static status_t internal_ecdh_p384_finalize(
1017  otcrypto_blinded_key_t *shared_secret) {
1018  if (launder32(shared_secret->config.hw_backed) != kHardenedBoolFalse) {
1019  // Shared keys cannot be sideloaded because they are software-generated.
1020  return OTCRYPTO_BAD_ARGS;
1021  }
1022  HARDENED_CHECK_EQ(shared_secret->config.hw_backed, kHardenedBoolFalse);
1023 
1024  if (shared_secret->keyblob == NULL) {
1025  return OTCRYPTO_BAD_ARGS;
1026  }
1027 
1028  if (launder32(shared_secret->config.key_length) != kP384CoordBytes) {
1029  return OTCRYPTO_BAD_ARGS;
1030  }
1031  HARDENED_CHECK_EQ(shared_secret->config.key_length, kP384CoordBytes);
1032 
1033  if (launder32(shared_secret->keyblob_length) !=
1034  keyblob_num_words(shared_secret->config) * sizeof(uint32_t)) {
1035  return OTCRYPTO_BAD_ARGS;
1036  }
1038  shared_secret->keyblob_length,
1039  keyblob_num_words(shared_secret->config) * sizeof(uint32_t));
1040 
1041  // Note: This operation wipes DMEM after retrieving the keys, so if an error
1042  // occurs after this point then the keys would be unrecoverable. This should
1043  // be the last potentially error-causing line before returning to the caller.
1045  HARDENED_TRY(p384_ecdh_finalize(&ss));
1046 
1047  keyblob_from_shares(ss.share0, ss.share1, shared_secret->config,
1048  shared_secret->keyblob);
1049 
1050  // Set the checksum.
1051  shared_secret->checksum = integrity_blinded_checksum(shared_secret);
1052 
1053  // Clear the OTBN sideload slot (in case the seed was sideloaded).
1054  return keymgr_sideload_clear_otbn();
1055 }
1056 
1058  const otcrypto_ecc_curve_t *elliptic_curve,
1059  otcrypto_blinded_key_t *shared_secret) {
1060  if (shared_secret == NULL || elliptic_curve == NULL) {
1061  return OTCRYPTO_BAD_ARGS;
1062  }
1063 
1064  // Select the correct ECDH operation and finalize it.
1065  switch (launder32(elliptic_curve->curve_type)) {
1066  case kOtcryptoEccCurveTypeNistP256:
1067  HARDENED_CHECK_EQ(elliptic_curve->curve_type,
1068  kOtcryptoEccCurveTypeNistP256);
1069  HARDENED_TRY(internal_ecdh_p256_finalize(shared_secret));
1070  break;
1071  case kOtcryptoEccCurveTypeNistP384:
1072  HARDENED_CHECK_EQ(elliptic_curve->curve_type,
1073  kOtcryptoEccCurveTypeNistP384);
1074  HARDENED_TRY(internal_ecdh_p384_finalize(shared_secret));
1075  break;
1076  case kEccCurveTypeBrainpoolP256R1:
1078  case kOtcryptoEccCurveTypeCustom:
1079  // TODO: Implement support for other curves.
1080  return OTCRYPTO_NOT_IMPLEMENTED;
1081  default:
1082  return OTCRYPTO_BAD_ARGS;
1083  }
1084 
1085  // Clear the OTBN sideload slot (in case the key was sideloaded).
1086  return keymgr_sideload_clear_otbn();
1087 }
1088 
1090  const otcrypto_blinded_key_t *private_key) {
1091  // TODO: Ed25519 is not yet implemented.
1092  return OTCRYPTO_NOT_IMPLEMENTED;
1093 }
1094 
1096  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
1097  // TODO: Ed25519 is not yet implemented.
1098  return OTCRYPTO_NOT_IMPLEMENTED;
1099 }
1100 
1102  const otcrypto_blinded_key_t *private_key,
1103  otcrypto_const_byte_buf_t input_message,
1104  otcrypto_eddsa_sign_mode_t sign_mode, otcrypto_word32_buf_t signature) {
1105  // TODO: Ed25519 is not yet implemented.
1106  return OTCRYPTO_NOT_IMPLEMENTED;
1107 }
1108 
1110  otcrypto_word32_buf_t signature) {
1111  // TODO: Ed25519 is not yet implemented.
1112  return OTCRYPTO_NOT_IMPLEMENTED;
1113 }
1114 
1116  const otcrypto_unblinded_key_t *public_key,
1117  otcrypto_const_byte_buf_t input_message,
1118  otcrypto_eddsa_sign_mode_t sign_mode,
1119  otcrypto_const_word32_buf_t signature) {
1120  // TODO: Ed25519 is not yet implemented.
1121  return OTCRYPTO_NOT_IMPLEMENTED;
1122 }
1123 
1125  hardened_bool_t *verification_result) {
1126  // TODO: Ed25519 is not yet implemented.
1127  return OTCRYPTO_NOT_IMPLEMENTED;
1128 }
1129 
1131  const otcrypto_blinded_key_t *private_key) {
1132  // TODO: X25519 is not yet implemented.
1133  return OTCRYPTO_NOT_IMPLEMENTED;
1134 }
1135 
1137  otcrypto_blinded_key_t *private_key, otcrypto_unblinded_key_t *public_key) {
1138  // TODO: X25519 is not yet implemented.
1139  return OTCRYPTO_NOT_IMPLEMENTED;
1140 }
1141 
1143  const otcrypto_blinded_key_t *private_key,
1144  const otcrypto_unblinded_key_t *public_key) {
1145  // TODO: X25519 is not yet implemented.
1146  return OTCRYPTO_NOT_IMPLEMENTED;
1147 }
1148 
1150  otcrypto_blinded_key_t *shared_secret) {
1151  // TODO: X25519 is not yet implemented.
1152  return OTCRYPTO_NOT_IMPLEMENTED;
1153 }