Software APIs
ecdsa_p384_keygen.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/lib/crypto/impl/ecc/ecdsa_p384_keygen.h"
6 
9 #include "sw/device/lib/crypto/drivers/otbn.h"
10 
12 
13 // Module ID for status codes.
14 #define MODULE_ID MAKE_MODULE_ID('p', '3', 'k')
15 
16 // Declare the OTBN app.
17 OTBN_DECLARE_APP_SYMBOLS(p384_ecdsa_keygen);
18 static const otbn_app_t kOtbnAppEcdsaKeygen =
19  OTBN_APP_T_INIT(p384_ecdsa_keygen);
20 
21 // Declare offsets for input and output buffers.
22 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen,
23  mode); // ECDSA keygen application mode.
24 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, d0); // Private key first share.
25 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, d1); // Private key second share.
26 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, x); // x-coordinate.
27 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, y); // y-coordinate.
28 
29 static const otbn_addr_t kOtbnVarEcdsaMode =
30  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, mode);
31 static const otbn_addr_t kOtbnVarEcdsaX =
32  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, x);
33 static const otbn_addr_t kOtbnVarEcdsaY =
34  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, y);
35 static const otbn_addr_t kOtbnVarEcdsaD0 =
36  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, d0);
37 static const otbn_addr_t kOtbnVarEcdsaD1 =
38  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, d1);
39 
40 // Declare mode constants.
41 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, MODE_KEYGEN_RANDOM);
42 OTBN_DECLARE_SYMBOL_ADDR(p384_ecdsa_keygen, MODE_KEYGEN_FROM_SEED);
43 static const uint32_t kOtbnEcdsaModeKeygen =
44  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, MODE_KEYGEN_RANDOM);
45 static const uint32_t kOtbnEcdsaModeSideloadKeygen =
46  OTBN_ADDR_T_INIT(p384_ecdsa_keygen, MODE_KEYGEN_FROM_SEED);
47 
48 enum {
49  /*
50  * Mode is represented by a single word.
51  */
52  kOtbnEcdsaModeWords = 1,
53 };
54 
55 status_t ecdsa_p384_keygen_start(void) {
56  // Load the ECDSA/P-384 app. Fails if OTBN is non-idle.
57  HARDENED_TRY(otbn_load_app(kOtbnAppEcdsaKeygen));
58 
59  // Set mode so start() will jump into sideload-keygen.
60  uint32_t mode = kOtbnEcdsaModeKeygen;
61  HARDENED_TRY(otbn_dmem_write(kOtbnEcdsaModeWords, &mode, kOtbnVarEcdsaMode));
62 
63  // Start the OTBN routine.
64  return otbn_execute();
65 }
66 
67 status_t ecdsa_p384_sideload_keygen_start(void) {
68  // Load the ECDSA/P-384 app. Fails if OTBN is non-idle.
69  HARDENED_TRY(otbn_load_app(kOtbnAppEcdsaKeygen));
70 
71  // Set mode so start() will jump into sideload-keygen.
72  uint32_t mode = kOtbnEcdsaModeSideloadKeygen;
73  HARDENED_TRY(otbn_dmem_write(kOtbnEcdsaModeWords, &mode, kOtbnVarEcdsaMode));
74 
75  // Start the OTBN routine.
76  return otbn_execute();
77 }
78 
79 status_t ecdsa_p384_keygen_finalize(p384_masked_scalar_t *private_key,
80  p384_point_t *public_key) {
81  // Spin here waiting for OTBN to complete.
82  HARDENED_TRY(otbn_busy_wait_for_done());
83 
84  // Read the masked private key from OTBN dmem.
85  HARDENED_TRY(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarEcdsaD0,
86  private_key->share0));
87  HARDENED_TRY(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarEcdsaD1,
88  private_key->share1));
89 
90  // Read the public key from OTBN dmem.
91  HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarEcdsaX, public_key->x));
92  HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarEcdsaY, public_key->y));
93 
94  // Wipe DMEM.
95  HARDENED_TRY(otbn_dmem_sec_wipe());
96 
97  return OTCRYPTO_OK;
98 }
99 
100 status_t ecdsa_p384_sideload_keygen_finalize(p384_point_t *public_key) {
101  // Spin here waiting for OTBN to complete.
102  HARDENED_TRY(otbn_busy_wait_for_done());
103 
104  // Read the public key from OTBN dmem.
105  HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarEcdsaX, public_key->x));
106  HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarEcdsaY, public_key->y));
107 
108  // Wipe DMEM.
109  HARDENED_TRY(otbn_dmem_sec_wipe());
110 
111  return OTCRYPTO_OK;
112 }