Bluetooth: Add support for encryption key refresh
With LE/SMP the completion of a security level elavation from medium to high is indicated by a HCI Encryption Key Refresh Complete event. The necessary behavior upon receiving this event is a mix of what's done for auth_complete and encryption_change, which is also where most of the event handling code has been copied from. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This commit is contained in:
		
					parent
					
						
							
								4dab786482
							
						
					
				
			
			
				commit
				
					
						1c2e004183
					
				
			
		
					 2 changed files with 54 additions and 0 deletions
				
			
		|  | @ -1144,6 +1144,12 @@ struct extended_inquiry_info { | ||||||
| 	__u8     data[240]; | 	__u8     data[240]; | ||||||
| } __packed; | } __packed; | ||||||
| 
 | 
 | ||||||
|  | #define HCI_EV_KEY_REFRESH_COMPLETE	0x30 | ||||||
|  | struct hci_ev_key_refresh_complete { | ||||||
|  | 	__u8	status; | ||||||
|  | 	__le16	handle; | ||||||
|  | } __packed; | ||||||
|  | 
 | ||||||
| #define HCI_EV_IO_CAPA_REQUEST		0x31 | #define HCI_EV_IO_CAPA_REQUEST		0x31 | ||||||
| struct hci_ev_io_capa_request { | struct hci_ev_io_capa_request { | ||||||
| 	bdaddr_t bdaddr; | 	bdaddr_t bdaddr; | ||||||
|  |  | ||||||
|  | @ -3043,6 +3043,50 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | ||||||
| 	hci_dev_unlock(hdev); | 	hci_dev_unlock(hdev); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | ||||||
|  | 					 struct sk_buff *skb) | ||||||
|  | { | ||||||
|  | 	struct hci_ev_key_refresh_complete *ev = (void *) skb->data; | ||||||
|  | 	struct hci_conn *conn; | ||||||
|  | 
 | ||||||
|  | 	BT_DBG("%s status %u handle %u", hdev->name, ev->status, | ||||||
|  | 	       __le16_to_cpu(ev->handle)); | ||||||
|  | 
 | ||||||
|  | 	hci_dev_lock(hdev); | ||||||
|  | 
 | ||||||
|  | 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||||||
|  | 	if (!conn) | ||||||
|  | 		goto unlock; | ||||||
|  | 
 | ||||||
|  | 	if (!ev->status) | ||||||
|  | 		conn->sec_level = conn->pending_sec_level; | ||||||
|  | 
 | ||||||
|  | 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||||||
|  | 
 | ||||||
|  | 	if (ev->status && conn->state == BT_CONNECTED) { | ||||||
|  | 		hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); | ||||||
|  | 		hci_conn_put(conn); | ||||||
|  | 		goto unlock; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (conn->state == BT_CONFIG) { | ||||||
|  | 		if (!ev->status) | ||||||
|  | 			conn->state = BT_CONNECTED; | ||||||
|  | 
 | ||||||
|  | 		hci_proto_connect_cfm(conn, ev->status); | ||||||
|  | 		hci_conn_put(conn); | ||||||
|  | 	} else { | ||||||
|  | 		hci_auth_cfm(conn, ev->status); | ||||||
|  | 
 | ||||||
|  | 		hci_conn_hold(conn); | ||||||
|  | 		conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||||||
|  | 		hci_conn_put(conn); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | unlock: | ||||||
|  | 	hci_dev_unlock(hdev); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static inline u8 hci_get_auth_req(struct hci_conn *conn) | static inline u8 hci_get_auth_req(struct hci_conn *conn) | ||||||
| { | { | ||||||
| 	/* If remote requests dedicated bonding follow that lead */ | 	/* If remote requests dedicated bonding follow that lead */ | ||||||
|  | @ -3559,6 +3603,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | ||||||
| 		hci_extended_inquiry_result_evt(hdev, skb); | 		hci_extended_inquiry_result_evt(hdev, skb); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
|  | 	case HCI_EV_KEY_REFRESH_COMPLETE: | ||||||
|  | 		hci_key_refresh_complete_evt(hdev, skb); | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
| 	case HCI_EV_IO_CAPA_REQUEST: | 	case HCI_EV_IO_CAPA_REQUEST: | ||||||
| 		hci_io_capa_request_evt(hdev, skb); | 		hci_io_capa_request_evt(hdev, skb); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Johan Hedberg
				Johan Hedberg