• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Bluetooth Core, Vol 2, Part C, 4.2.5
16 
17 use super::features;
18 use crate::lmp::procedure::Context;
19 use crate::num_hci_command_packets;
20 use crate::packets::{hci, lmp};
21 
22 use hci::LMPFeaturesPage1Bits::SecureConnectionsHostSupport;
23 use hci::LMPFeaturesPage2Bits::SecureConnectionsControllerSupport;
24 
initiate(ctx: &impl Context)25 pub async fn initiate(ctx: &impl Context) {
26     // TODO: handle turn off
27     let _ = ctx.receive_hci_command::<hci::SetConnectionEncryption>().await;
28     ctx.send_hci_event(
29         hci::SetConnectionEncryptionStatusBuilder {
30             num_hci_command_packets,
31             status: hci::ErrorCode::Success,
32         }
33         .build(),
34     );
35 
36     // TODO: handle failure
37     let _ = ctx
38         .send_accepted_lmp_packet(
39             lmp::EncryptionModeReqBuilder { transaction_id: 0, encryption_mode: 0x1 }.build(),
40         )
41         .await;
42 
43     // TODO: handle failure
44     let _ = ctx
45         .send_accepted_lmp_packet(
46             lmp::EncryptionKeySizeReqBuilder { transaction_id: 0, key_size: 16 }.build(),
47         )
48         .await;
49 
50     // TODO: handle failure
51     let _ = ctx
52         .send_accepted_lmp_packet(
53             lmp::StartEncryptionReqBuilder { transaction_id: 0, random_number: [0; 16] }.build(),
54         )
55         .await;
56 
57     let aes_ccm = features::supported_on_both_page1(ctx, SecureConnectionsHostSupport).await
58         && features::supported_on_both_page2(ctx, SecureConnectionsControllerSupport).await;
59 
60     ctx.send_hci_event(
61         hci::EncryptionChangeBuilder {
62             status: hci::ErrorCode::Success,
63             connection_handle: ctx.peer_handle(),
64             encryption_enabled: if aes_ccm {
65                 hci::EncryptionEnabled::BrEdrAesCcm
66             } else {
67                 hci::EncryptionEnabled::On
68             },
69         }
70         .build(),
71     );
72 }
73 
respond(ctx: &impl Context)74 pub async fn respond(ctx: &impl Context) {
75     // TODO: handle
76     let _ = ctx.receive_lmp_packet::<lmp::EncryptionModeReq>().await;
77     ctx.send_lmp_packet(
78         lmp::AcceptedBuilder { transaction_id: 0, accepted_opcode: lmp::Opcode::EncryptionModeReq }
79             .build(),
80     );
81 
82     let _ = ctx.receive_lmp_packet::<lmp::EncryptionKeySizeReq>().await;
83     ctx.send_lmp_packet(
84         lmp::AcceptedBuilder {
85             transaction_id: 0,
86             accepted_opcode: lmp::Opcode::EncryptionKeySizeReq,
87         }
88         .build(),
89     );
90 
91     let _ = ctx.receive_lmp_packet::<lmp::StartEncryptionReq>().await;
92     ctx.send_lmp_packet(
93         lmp::AcceptedBuilder {
94             transaction_id: 0,
95             accepted_opcode: lmp::Opcode::StartEncryptionReq,
96         }
97         .build(),
98     );
99 
100     let aes_ccm = features::supported_on_both_page1(ctx, SecureConnectionsHostSupport).await
101         && features::supported_on_both_page2(ctx, SecureConnectionsControllerSupport).await;
102 
103     ctx.send_hci_event(
104         hci::EncryptionChangeBuilder {
105             status: hci::ErrorCode::Success,
106             connection_handle: ctx.peer_handle(),
107             encryption_enabled: if aes_ccm {
108                 hci::EncryptionEnabled::BrEdrAesCcm
109             } else {
110                 hci::EncryptionEnabled::On
111             },
112         }
113         .build(),
114     );
115 }
116 
117 #[cfg(test)]
118 mod tests {
119     use super::initiate;
120     use super::respond;
121     use crate::lmp::procedure::Context;
122     use crate::lmp::test::{sequence, TestContext};
123 
124     use crate::packets::hci::LMPFeaturesPage1Bits::SecureConnectionsHostSupport;
125     use crate::packets::hci::LMPFeaturesPage2Bits::SecureConnectionsControllerSupport;
126 
127     #[test]
accept_encryption()128     fn accept_encryption() {
129         let context = TestContext::new();
130         let procedure = respond;
131 
132         include!("../../../test/ENC/BV-01-C.in");
133     }
134 
135     #[test]
initiate_encryption()136     fn initiate_encryption() {
137         let context = TestContext::new();
138         let procedure = initiate;
139 
140         include!("../../../test/ENC/BV-05-C.in");
141     }
142 
143     #[test]
accept_aes_ccm_encryption_request()144     fn accept_aes_ccm_encryption_request() {
145         let context = TestContext::new()
146             .with_page_1_feature(SecureConnectionsHostSupport)
147             .with_page_2_feature(SecureConnectionsControllerSupport)
148             .with_peer_page_1_feature(SecureConnectionsHostSupport)
149             .with_peer_page_2_feature(SecureConnectionsControllerSupport);
150         let procedure = respond;
151 
152         include!("../../../test/ENC/BV-26-C.in");
153     }
154 
155     #[test]
initiate_aes_ccm_encryption()156     fn initiate_aes_ccm_encryption() {
157         let context = TestContext::new()
158             .with_page_1_feature(SecureConnectionsHostSupport)
159             .with_page_2_feature(SecureConnectionsControllerSupport)
160             .with_peer_page_1_feature(SecureConnectionsHostSupport)
161             .with_peer_page_2_feature(SecureConnectionsControllerSupport);
162         let procedure = initiate;
163 
164         include!("../../../test/ENC/BV-34-C.in");
165     }
166 }
167