xref: /openbmc/linux/net/bluetooth/smp.h (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1ac4b7236SMarcel Holtmann /*
2ac4b7236SMarcel Holtmann    BlueZ - Bluetooth protocol stack for Linux
3ac4b7236SMarcel Holtmann    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4ac4b7236SMarcel Holtmann 
5ac4b7236SMarcel Holtmann    This program is free software; you can redistribute it and/or modify
6ac4b7236SMarcel Holtmann    it under the terms of the GNU General Public License version 2 as
7ac4b7236SMarcel Holtmann    published by the Free Software Foundation;
8ac4b7236SMarcel Holtmann 
9ac4b7236SMarcel Holtmann    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10ac4b7236SMarcel Holtmann    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11ac4b7236SMarcel Holtmann    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12ac4b7236SMarcel Holtmann    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13ac4b7236SMarcel Holtmann    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14ac4b7236SMarcel Holtmann    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15ac4b7236SMarcel Holtmann    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16ac4b7236SMarcel Holtmann    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17ac4b7236SMarcel Holtmann 
18ac4b7236SMarcel Holtmann    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19ac4b7236SMarcel Holtmann    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20ac4b7236SMarcel Holtmann    SOFTWARE IS DISCLAIMED.
21ac4b7236SMarcel Holtmann */
22ac4b7236SMarcel Holtmann 
23ac4b7236SMarcel Holtmann #ifndef __SMP_H
24ac4b7236SMarcel Holtmann #define __SMP_H
25ac4b7236SMarcel Holtmann 
26ac4b7236SMarcel Holtmann struct smp_command_hdr {
27ac4b7236SMarcel Holtmann 	__u8	code;
28ac4b7236SMarcel Holtmann } __packed;
29ac4b7236SMarcel Holtmann 
30ac4b7236SMarcel Holtmann #define SMP_CMD_PAIRING_REQ	0x01
31ac4b7236SMarcel Holtmann #define SMP_CMD_PAIRING_RSP	0x02
32ac4b7236SMarcel Holtmann struct smp_cmd_pairing {
33ac4b7236SMarcel Holtmann 	__u8	io_capability;
34ac4b7236SMarcel Holtmann 	__u8	oob_flag;
35ac4b7236SMarcel Holtmann 	__u8	auth_req;
36ac4b7236SMarcel Holtmann 	__u8	max_key_size;
37ac4b7236SMarcel Holtmann 	__u8	init_key_dist;
38ac4b7236SMarcel Holtmann 	__u8	resp_key_dist;
39ac4b7236SMarcel Holtmann } __packed;
40ac4b7236SMarcel Holtmann 
41ac4b7236SMarcel Holtmann #define SMP_IO_DISPLAY_ONLY	0x00
42ac4b7236SMarcel Holtmann #define SMP_IO_DISPLAY_YESNO	0x01
43ac4b7236SMarcel Holtmann #define SMP_IO_KEYBOARD_ONLY	0x02
44ac4b7236SMarcel Holtmann #define SMP_IO_NO_INPUT_OUTPUT	0x03
45ac4b7236SMarcel Holtmann #define SMP_IO_KEYBOARD_DISPLAY	0x04
46ac4b7236SMarcel Holtmann 
47ac4b7236SMarcel Holtmann #define SMP_OOB_NOT_PRESENT	0x00
48ac4b7236SMarcel Holtmann #define SMP_OOB_PRESENT		0x01
49ac4b7236SMarcel Holtmann 
50ac4b7236SMarcel Holtmann #define SMP_DIST_ENC_KEY	0x01
51ac4b7236SMarcel Holtmann #define SMP_DIST_ID_KEY		0x02
52ac4b7236SMarcel Holtmann #define SMP_DIST_SIGN		0x04
53e65392e2SJohan Hedberg #define SMP_DIST_LINK_KEY	0x08
54ac4b7236SMarcel Holtmann 
55ac4b7236SMarcel Holtmann #define SMP_AUTH_NONE		0x00
56ac4b7236SMarcel Holtmann #define SMP_AUTH_BONDING	0x01
57ac4b7236SMarcel Holtmann #define SMP_AUTH_MITM		0x04
58e65392e2SJohan Hedberg #define SMP_AUTH_SC		0x08
59e65392e2SJohan Hedberg #define SMP_AUTH_KEYPRESS	0x10
60a62da6f1SJohan Hedberg #define SMP_AUTH_CT2		0x20
61ac4b7236SMarcel Holtmann 
62ac4b7236SMarcel Holtmann #define SMP_CMD_PAIRING_CONFIRM	0x03
63ac4b7236SMarcel Holtmann struct smp_cmd_pairing_confirm {
64ac4b7236SMarcel Holtmann 	__u8	confirm_val[16];
65ac4b7236SMarcel Holtmann } __packed;
66ac4b7236SMarcel Holtmann 
67ac4b7236SMarcel Holtmann #define SMP_CMD_PAIRING_RANDOM	0x04
68ac4b7236SMarcel Holtmann struct smp_cmd_pairing_random {
69ac4b7236SMarcel Holtmann 	__u8	rand_val[16];
70ac4b7236SMarcel Holtmann } __packed;
71ac4b7236SMarcel Holtmann 
72ac4b7236SMarcel Holtmann #define SMP_CMD_PAIRING_FAIL	0x05
73ac4b7236SMarcel Holtmann struct smp_cmd_pairing_fail {
74ac4b7236SMarcel Holtmann 	__u8	reason;
75ac4b7236SMarcel Holtmann } __packed;
76ac4b7236SMarcel Holtmann 
77ac4b7236SMarcel Holtmann #define SMP_CMD_ENCRYPT_INFO	0x06
78ac4b7236SMarcel Holtmann struct smp_cmd_encrypt_info {
79ac4b7236SMarcel Holtmann 	__u8	ltk[16];
80ac4b7236SMarcel Holtmann } __packed;
81ac4b7236SMarcel Holtmann 
82*fad646e1SArchie Pusaka #define SMP_CMD_INITIATOR_IDENT	0x07
83*fad646e1SArchie Pusaka struct smp_cmd_initiator_ident {
84ac4b7236SMarcel Holtmann 	__le16	ediv;
85fe39c7b2SMarcel Holtmann 	__le64	rand;
86ac4b7236SMarcel Holtmann } __packed;
87ac4b7236SMarcel Holtmann 
88ac4b7236SMarcel Holtmann #define SMP_CMD_IDENT_INFO	0x08
89ac4b7236SMarcel Holtmann struct smp_cmd_ident_info {
90ac4b7236SMarcel Holtmann 	__u8	irk[16];
91ac4b7236SMarcel Holtmann } __packed;
92ac4b7236SMarcel Holtmann 
93ac4b7236SMarcel Holtmann #define SMP_CMD_IDENT_ADDR_INFO	0x09
94ac4b7236SMarcel Holtmann struct smp_cmd_ident_addr_info {
95ac4b7236SMarcel Holtmann 	__u8	addr_type;
96ac4b7236SMarcel Holtmann 	bdaddr_t bdaddr;
97ac4b7236SMarcel Holtmann } __packed;
98ac4b7236SMarcel Holtmann 
99ac4b7236SMarcel Holtmann #define SMP_CMD_SIGN_INFO	0x0a
100ac4b7236SMarcel Holtmann struct smp_cmd_sign_info {
101ac4b7236SMarcel Holtmann 	__u8	csrk[16];
102ac4b7236SMarcel Holtmann } __packed;
103ac4b7236SMarcel Holtmann 
104ac4b7236SMarcel Holtmann #define SMP_CMD_SECURITY_REQ	0x0b
105ac4b7236SMarcel Holtmann struct smp_cmd_security_req {
106ac4b7236SMarcel Holtmann 	__u8	auth_req;
107ac4b7236SMarcel Holtmann } __packed;
108ac4b7236SMarcel Holtmann 
109e65392e2SJohan Hedberg #define SMP_CMD_PUBLIC_KEY	0x0c
110e65392e2SJohan Hedberg struct smp_cmd_public_key {
111e65392e2SJohan Hedberg 	__u8	x[32];
112e65392e2SJohan Hedberg 	__u8	y[32];
113e65392e2SJohan Hedberg } __packed;
114e65392e2SJohan Hedberg 
115e65392e2SJohan Hedberg #define SMP_CMD_DHKEY_CHECK	0x0d
116e65392e2SJohan Hedberg struct smp_cmd_dhkey_check {
117e65392e2SJohan Hedberg 	__u8	e[16];
118e65392e2SJohan Hedberg } __packed;
119e65392e2SJohan Hedberg 
120e65392e2SJohan Hedberg #define SMP_CMD_KEYPRESS_NOTIFY	0x0e
121e65392e2SJohan Hedberg struct smp_cmd_keypress_notify {
122e65392e2SJohan Hedberg 	__u8	value;
123e65392e2SJohan Hedberg } __packed;
124e65392e2SJohan Hedberg 
125e65392e2SJohan Hedberg #define SMP_CMD_MAX		0x0e
126b28b4943SJohan Hedberg 
127ac4b7236SMarcel Holtmann #define SMP_PASSKEY_ENTRY_FAILED	0x01
128ac4b7236SMarcel Holtmann #define SMP_OOB_NOT_AVAIL		0x02
129ac4b7236SMarcel Holtmann #define SMP_AUTH_REQUIREMENTS		0x03
130ac4b7236SMarcel Holtmann #define SMP_CONFIRM_FAILED		0x04
131ac4b7236SMarcel Holtmann #define SMP_PAIRING_NOTSUPP		0x05
132ac4b7236SMarcel Holtmann #define SMP_ENC_KEY_SIZE		0x06
133ac4b7236SMarcel Holtmann #define SMP_CMD_NOTSUPP			0x07
134ac4b7236SMarcel Holtmann #define SMP_UNSPECIFIED			0x08
135ac4b7236SMarcel Holtmann #define SMP_REPEATED_ATTEMPTS		0x09
13638e4a915SJohan Hedberg #define SMP_INVALID_PARAMS		0x0a
137e65392e2SJohan Hedberg #define SMP_DHKEY_CHECK_FAILED		0x0b
138e65392e2SJohan Hedberg #define SMP_NUMERIC_COMP_FAILED		0x0c
139e65392e2SJohan Hedberg #define SMP_BREDR_PAIRING_IN_PROGRESS	0x0d
140e65392e2SJohan Hedberg #define SMP_CROSS_TRANSP_NOT_ALLOWED	0x0e
141ac4b7236SMarcel Holtmann 
142ac4b7236SMarcel Holtmann #define SMP_MIN_ENC_KEY_SIZE		7
143ac4b7236SMarcel Holtmann #define SMP_MAX_ENC_KEY_SIZE		16
144ac4b7236SMarcel Holtmann 
1452ceba539SJohan Hedberg /* LTK types used in internal storage (struct smp_ltk) */
1462ceba539SJohan Hedberg enum {
1472ceba539SJohan Hedberg 	SMP_STK,
1482ceba539SJohan Hedberg 	SMP_LTK,
149*fad646e1SArchie Pusaka 	SMP_LTK_RESPONDER,
15023fb8de3SJohan Hedberg 	SMP_LTK_P256,
15123fb8de3SJohan Hedberg 	SMP_LTK_P256_DEBUG,
1522ceba539SJohan Hedberg };
1532ceba539SJohan Hedberg 
smp_ltk_is_sc(struct smp_ltk * key)15423fb8de3SJohan Hedberg static inline bool smp_ltk_is_sc(struct smp_ltk *key)
15523fb8de3SJohan Hedberg {
15623fb8de3SJohan Hedberg 	switch (key->type) {
15723fb8de3SJohan Hedberg 	case SMP_LTK_P256:
15823fb8de3SJohan Hedberg 	case SMP_LTK_P256_DEBUG:
15923fb8de3SJohan Hedberg 		return true;
16023fb8de3SJohan Hedberg 	}
16123fb8de3SJohan Hedberg 
16223fb8de3SJohan Hedberg 	return false;
16323fb8de3SJohan Hedberg }
16423fb8de3SJohan Hedberg 
smp_ltk_sec_level(struct smp_ltk * key)165a6f7833cSJohan Hedberg static inline u8 smp_ltk_sec_level(struct smp_ltk *key)
166a6f7833cSJohan Hedberg {
1678f5eeca3SJohan Hedberg 	if (key->authenticated) {
1688f5eeca3SJohan Hedberg 		if (smp_ltk_is_sc(key))
1698f5eeca3SJohan Hedberg 			return BT_SECURITY_FIPS;
1708f5eeca3SJohan Hedberg 		else
171a6f7833cSJohan Hedberg 			return BT_SECURITY_HIGH;
1728f5eeca3SJohan Hedberg 	}
173a6f7833cSJohan Hedberg 
174a6f7833cSJohan Hedberg 	return BT_SECURITY_MEDIUM;
175a6f7833cSJohan Hedberg }
176a6f7833cSJohan Hedberg 
17735dc6f83SJohan Hedberg /* Key preferences for smp_sufficient security */
17835dc6f83SJohan Hedberg enum smp_key_pref {
17935dc6f83SJohan Hedberg 	SMP_ALLOW_STK,
18035dc6f83SJohan Hedberg 	SMP_USE_LTK,
18135dc6f83SJohan Hedberg };
18235dc6f83SJohan Hedberg 
183ac4b7236SMarcel Holtmann /* SMP Commands */
184cb28c306SMatias Karhumaa int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
185cb28c306SMatias Karhumaa 				  u8 addr_type);
18635dc6f83SJohan Hedberg bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
18735dc6f83SJohan Hedberg 			     enum smp_key_pref key_pref);
188ac4b7236SMarcel Holtmann int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
189ac4b7236SMarcel Holtmann int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
190ac4b7236SMarcel Holtmann 
191cd082797SJohan Hedberg bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
192cd082797SJohan Hedberg 		     const bdaddr_t *bdaddr);
193cd082797SJohan Hedberg int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa);
19460a27d65SMarcel Holtmann int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]);
19560478054SJohan Hedberg 
19682493316SClaire Chang int smp_force_bredr(struct hci_dev *hdev, bool enable);
19782493316SClaire Chang 
198711eafe3SJohan Hedberg int smp_register(struct hci_dev *hdev);
199711eafe3SJohan Hedberg void smp_unregister(struct hci_dev *hdev);
200711eafe3SJohan Hedberg 
2010a2b0f04SJohan Hedberg #if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
2020a2b0f04SJohan Hedberg 
2030a2b0f04SJohan Hedberg int bt_selftest_smp(void);
2040a2b0f04SJohan Hedberg 
2050a2b0f04SJohan Hedberg #else
2060a2b0f04SJohan Hedberg 
bt_selftest_smp(void)2070a2b0f04SJohan Hedberg static inline int bt_selftest_smp(void)
2080a2b0f04SJohan Hedberg {
2090a2b0f04SJohan Hedberg 	return 0;
2100a2b0f04SJohan Hedberg }
2110a2b0f04SJohan Hedberg 
2120a2b0f04SJohan Hedberg #endif
2130a2b0f04SJohan Hedberg 
214ac4b7236SMarcel Holtmann #endif /* __SMP_H */
215