Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2c262dd authored by Josh Wu's avatar Josh Wu
Browse files

RootCanal: Move link key notification to pairing

* Move link_key_notification to pairing because they are not a part of
  auth and pairing info is required to determine key type later.
* Properly return comb key in legacy pairing

Tag: #refactor
Test: atest liblmp_tests --host
Bug: 235777894
Change-Id: Iaee68ebe5d1525072e99bc1a7a55cfe5865d3a9b
parent a51fe0d8
Loading
Loading
Loading
Loading
+24 −63
Original line number Diff line number Diff line
@@ -25,9 +25,23 @@ async fn secure_simple_pairing_supported(ctx: &impl Context) -> bool {
    local_supported && peer_supported.await
}

pub async fn send_authentication_challenge(ctx: &impl Context, transaction_id: u8) {
    ctx.send_lmp_packet(lmp::AuRandBuilder { transaction_id, random_number: [0; 16] }.build());
    let _ = ctx.receive_lmp_packet::<lmp::SresPacket>().await;
pub async fn send_challenge(
    ctx: &impl Context,
    transaction_id: u8,
    _link_key: [u8; 16],
) -> Result<(), ()> {
    let random_number = [0; 16];
    ctx.send_lmp_packet(lmp::AuRandBuilder { transaction_id, random_number }.build());

    match ctx.receive_lmp_packet::<Either<lmp::SresPacket, lmp::NotAcceptedPacket>>().await {
        Either::Left(_response) => Ok(()),
        Either::Right(_) => Err(()),
    }
}

pub async fn receive_challenge(ctx: &impl Context, _link_key: [u8; 16]) {
    let _random_number = *ctx.receive_lmp_packet::<lmp::AuRandPacket>().await.get_random_number();
    ctx.send_lmp_packet(lmp::SresBuilder { transaction_id: 0, authentication_rsp: [0; 4] }.build());
}

pub async fn initiate(ctx: &impl Context) {
@@ -42,7 +56,7 @@ pub async fn initiate(ctx: &impl Context) {

    ctx.send_hci_event(hci::LinkKeyRequestBuilder { bd_addr: ctx.peer_address() }.build());

    let pairing = match ctx.receive_hci_command::<Either<
    let status = match ctx.receive_hci_command::<Either<
        hci::LinkKeyRequestReplyPacket,
        hci::LinkKeyRequestNegativeReplyPacket,
    >>().await {
@@ -55,7 +69,7 @@ pub async fn initiate(ctx: &impl Context) {
                }
                .build(),
            );
            false
            hci::ErrorCode::Success
        },
        Either::Right(_) => {
            ctx.send_hci_event(
@@ -73,47 +87,15 @@ pub async fn initiate(ctx: &impl Context) {
                legacy_pairing::initiate(ctx).await
            };

            if result.is_err() {
                ctx.send_hci_event(
                    hci::AuthenticationCompleteBuilder {
                        status: hci::ErrorCode::AuthenticationFailure,
                        connection_handle: ctx.peer_handle(),
            match result {
                Ok(_) => hci::ErrorCode::Success,
                Err(_) => hci::ErrorCode::AuthenticationFailure
            }
                    .build(),
                );
                return;
            }
            true
        }
    };

    send_authentication_challenge(ctx, 0).await;

    // Link Key Calculation
    if pairing {
        let _random_number = ctx.receive_lmp_packet::<lmp::AuRandPacket>().await;

        // TODO: Resolve authentication challenge
        ctx.send_lmp_packet(
            lmp::SresBuilder { transaction_id: 0, authentication_rsp: [0; 4] }.build(),
        );

    ctx.send_hci_event(
            hci::LinkKeyNotificationBuilder {
                bd_addr: ctx.peer_address(),
                key_type: hci::KeyType::AuthenticatedP192,
                link_key: [0; 16],
            }
            .build(),
        );
    }

    ctx.send_hci_event(
        hci::AuthenticationCompleteBuilder {
            status: hci::ErrorCode::Success,
            connection_handle: ctx.peer_handle(),
        }
        .build(),
        hci::AuthenticationCompleteBuilder { status, connection_handle: ctx.peer_handle() }.build(),
    );
}

@@ -130,33 +112,12 @@ pub async fn respond(ctx: &impl Context) {
            ctx.send_lmp_packet(lmp::SresBuilder { transaction_id: 0, authentication_rsp: [0; 4] }.build());
        },
        Either::Right(pairing) => {
            let result = match pairing {
            let _result = match pairing {
                Either::Left(io_capability_request) =>
                    secure_simple_pairing::respond(ctx, io_capability_request).await,
                Either::Right(in_rand) =>
                    legacy_pairing::respond(ctx, in_rand).await,
            };

            if result.is_err() {
                return;
            }

            // Link Key Calculation

            let _random_number = ctx.receive_lmp_packet::<lmp::AuRandPacket>().await;
            // TODO: Resolve authentication challenge
            ctx.send_lmp_packet(lmp::SresBuilder { transaction_id: 0, authentication_rsp: [0; 4] }.build());

            send_authentication_challenge(ctx, 0).await;

            ctx.send_hci_event(
                hci::LinkKeyNotificationBuilder {
                    bd_addr: ctx.peer_address(),
                    key_type: hci::KeyType::AuthenticatedP192,
                    link_key: [0; 16],
                }
                .build(),
            );
        }
    }
}
+35 −1
Original line number Diff line number Diff line
// Bluetooth Core, Vol 2, Part C, 4.2.2

use crate::packets::{hci, lmp};
use crate::procedure::Context;
use crate::procedure::{authentication, Context};

use crate::num_hci_command_packets;

@@ -30,6 +30,23 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {

    let _ = ctx.receive_lmp_packet::<lmp::CombKeyPacket>().await;

    // Post pairing authentication
    let link_key = [0; 16];
    let auth_result = authentication::send_challenge(ctx, 0, link_key).await;
    authentication::receive_challenge(ctx, link_key).await;

    if auth_result.is_err() {
        return Err(());
    }
    ctx.send_hci_event(
        hci::LinkKeyNotificationBuilder {
            bd_addr: ctx.peer_address(),
            key_type: hci::KeyType::Combination,
            link_key,
        }
        .build(),
    );

    Ok(())
}

@@ -55,5 +72,22 @@ pub async fn respond(ctx: &impl Context, _request: lmp::InRandPacket) -> Result<

    ctx.send_lmp_packet(lmp::CombKeyBuilder { transaction_id: 0, random_number: [0; 16] }.build());

    // Post pairing authentication
    let link_key = [0; 16];
    authentication::receive_challenge(ctx, link_key).await;
    let auth_result = authentication::send_challenge(ctx, 0, link_key).await;

    if auth_result.is_err() {
        return Err(());
    }
    ctx.send_hci_event(
        hci::LinkKeyNotificationBuilder {
            bd_addr: ctx.peer_address(),
            key_type: hci::KeyType::Combination,
            link_key,
        }
        .build(),
    );

    Ok(())
}
+36 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ use num_traits::{FromPrimitive, ToPrimitive};

use crate::either::Either;
use crate::packets::{hci, lmp};
use crate::procedure::Context;
use crate::procedure::{authentication, Context};

use crate::num_hci_command_packets;

@@ -458,6 +458,23 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {
        .build(),
    );

    // Link Key Calculation
    let link_key = [0; 16];
    let auth_result = authentication::send_challenge(ctx, 0, link_key).await;
    authentication::receive_challenge(ctx, link_key).await;

    if auth_result.is_err() {
        return Err(());
    }
    ctx.send_hci_event(
        hci::LinkKeyNotificationBuilder {
            bd_addr: ctx.peer_address(),
            key_type: hci::KeyType::AuthenticatedP192,
            link_key,
        }
        .build(),
    );

    Ok(())
}

@@ -616,6 +633,23 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReqPacket) ->
        .build(),
    );

    // Link Key Calculation
    let link_key = [0; 16];
    authentication::receive_challenge(ctx, link_key).await;
    let auth_result = authentication::send_challenge(ctx, 0, link_key).await;

    if auth_result.is_err() {
        return Err(());
    }
    ctx.send_hci_event(
        hci::LinkKeyNotificationBuilder {
            bd_addr: ctx.peer_address(),
            key_type: hci::KeyType::AuthenticatedP192,
            link_key,
        }
        .build(),
    );

    Ok(())
}

@@ -639,7 +673,7 @@ mod tests {
            assert!(size < limit)
        }

        assert_max_size(procedure, 250);
        assert_max_size(procedure, 300);
    }

    #[test]