1 /* ecc.h - ECDH helpers */
2 
3 /*
4  * Copyright (c) 2016 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stdbool.h>
10 #include <stdint.h>
11 
12 #include <zephyr/sys/slist.h>
13 
14 /** Key size used in Bluetooth's ECC domain. */
15 #define BT_ECC_KEY_SIZE            32
16 /** Length of a Bluetooth ECC public key coordinate. */
17 #define BT_PUB_KEY_COORD_LEN       (BT_ECC_KEY_SIZE)
18 /** Length of a Bluetooth ECC public key. */
19 #define BT_PUB_KEY_LEN             (2 * (BT_PUB_KEY_COORD_LEN))
20 /** Length of a Bluetooth ECC private key. */
21 #define BT_PRIV_KEY_LEN            (BT_ECC_KEY_SIZE)
22 /** Length of a Bluetooth Diffie-Hellman key. */
23 #define BT_DH_KEY_LEN              (BT_ECC_KEY_SIZE)
24 
25 /*  @brief Container for public key callback */
26 struct bt_pub_key_cb {
27 	/** @brief Callback type for Public Key generation.
28 	 *
29 	 *  Used to notify of the local public key or that the local key is not
30 	 *  available (either because of a failure to read it or because it is
31 	 *  being regenerated).
32 	 *
33 	 *  @param key The local public key, or NULL in case of no key.
34 	 */
35 	void (*func)(const uint8_t key[BT_PUB_KEY_LEN]);
36 
37 	/* Internal */
38 	sys_snode_t node;
39 };
40 
41 /*  @brief Check if public key is equal to the debug public key.
42  *
43  *  Compare the Public key to the Bluetooth specification defined debug public
44  *  key.
45  *
46  *  @param cmp_pub_key The public key to compare.
47  *
48  *  @return True if the public key is the debug public key.
49  */
50 bool bt_pub_key_is_debug(uint8_t *cmp_pub_key);
51 
52 /*  @brief Check if public key is valid.
53  *
54  *  Verify that the public key is valid, e.g. that its coordinates lie on the elliptic curve.
55  *
56  *  @param key The public key to validate.
57  *
58  *  @return True if the public key is valid.
59  */
60 bool bt_pub_key_is_valid(const uint8_t key[BT_PUB_KEY_LEN]);
61 
62 /*  @brief Generate a new Public Key.
63  *
64  *  Generate a new ECC Public Key. Provided cb must persists until callback
65  *  is called. Callee adds the callback structure to a linked list. Registering
66  *  multiple callbacks requires multiple calls to bt_pub_key_gen() and separate
67  *  callback structures. This method cannot be called directly from result
68  *  callback. After calling all the registered callbacks the linked list
69  *  is cleared.
70  *
71  *  @param cb Callback to notify the new key.
72  *
73  *  @return Zero on success or negative error code otherwise
74  */
75 int bt_pub_key_gen(struct bt_pub_key_cb *cb);
76 
77 /*  @brief Cleanup public key callbacks when HCI is disrupted.
78  *
79  *  Clear the pub_key_cb_slist and clear the BT_DEV_PUB_KEY_BUSY flag.
80  */
81 void bt_pub_key_hci_disrupted(void);
82 
83 /*  @brief Get the current Public Key.
84  *
85  *  Get the current ECC Public Key.
86  *
87  *  @return Current key, or NULL if not available.
88  */
89 const uint8_t *bt_pub_key_get(void);
90 
91 /*  @typedef bt_dh_key_cb_t
92  *  @brief Callback type for DH Key calculation.
93  *
94  *  Used to notify of the calculated DH Key.
95  *
96  *  @param key The DH Key, or NULL in case of failure.
97  */
98 typedef void (*bt_dh_key_cb_t)(const uint8_t key[BT_DH_KEY_LEN]);
99 
100 /*  @brief Calculate a DH Key from a remote Public Key.
101  *
102  *  Calculate a DH Key from the remote Public Key.
103  *
104  *  @param remote_pk Remote Public Key.
105  *  @param cb Callback to notify the calculated key.
106  *
107  *  @return Zero on success or negative error code otherwise
108  */
109 int bt_dh_key_gen(const uint8_t remote_pk[BT_PUB_KEY_LEN], bt_dh_key_cb_t cb);
110