1 // Copyright 2022 Google LLC 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 use ldt_np_adv::{V0IdentityToken, V0Salt}; 16 17 /// Format || salt || token 18 const ADV_HEADER_MAX_LEN: usize = 1 + 2 + 14; 19 20 /// Serializes a V0 header. 21 /// 22 /// Does not include the overall NP version header byte that defines the adv 23 /// version. 24 pub struct V0Header { 25 header_bytes: tinyvec::ArrayVec<[u8; ADV_HEADER_MAX_LEN]>, 26 } 27 28 impl V0Header { unencrypted() -> Self29 pub(crate) fn unencrypted() -> Self { 30 let header_bytes = tinyvec::ArrayVec::new(); 31 Self { header_bytes } 32 } 33 ldt_short_salt(salt: V0Salt, identity_token: V0IdentityToken) -> Self34 pub(crate) fn ldt_short_salt(salt: V0Salt, identity_token: V0IdentityToken) -> Self { 35 let mut header_bytes = tinyvec::ArrayVec::new(); 36 header_bytes.extend_from_slice(salt.bytes().as_slice()); 37 header_bytes.extend_from_slice(identity_token.as_slice()); 38 Self { header_bytes } 39 } 40 41 /// The returned slice must be shorter than [crate::legacy::BLE_4_ADV_SVC_MAX_CONTENT_LEN] - 1. as_slice(&self) -> &[u8]42 pub(crate) fn as_slice(&self) -> &[u8] { 43 self.header_bytes.as_slice() 44 } 45 } 46 47 #[cfg(test)] 48 mod tests { 49 use super::*; 50 use ldt_np_adv::{V0_IDENTITY_TOKEN_LEN, V0_SALT_LEN}; 51 52 const SHORT_SALT_BYTES: [u8; V0_SALT_LEN] = [0x10, 0x11]; 53 const TOKEN_BYTES: [u8; V0_IDENTITY_TOKEN_LEN] = 54 [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D]; 55 56 #[test] unencrypted_slice()57 fn unencrypted_slice() { 58 assert_eq!(&[0_u8; 0], V0Header::unencrypted().as_slice()); 59 } 60 61 #[rustfmt::skip] 62 #[test] ldt_short_salt_slice()63 fn ldt_short_salt_slice() { 64 assert_eq!( 65 &[ 66 // salt 67 0x10, 0x11, 68 // token 69 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D 70 ], 71 V0Header::ldt_short_salt(SHORT_SALT_BYTES.into(), TOKEN_BYTES.into()).as_slice() 72 ); 73 } 74 } 75