【Bluedroid】蓝牙启动之 SMP_Init 源码解析
蓝牙(安全管理协议,Security Management Protocol)是蓝牙设备安全通信的核心协议,负责配对、密钥协商和安全等级管理。本文围绕 Bluedroid SMP 协议的初始化流程展开,系统解析其核心控制块(tSMP_CB
)的状态管理、与 L2CAP 层的接口注册,以及 P-256 椭圆曲线参数的初始化逻辑。通过分析SMP_Init
函数的调用链,揭示tsmp_CB
如何重置状态、初始化定时器与测试参数,smp_l2cap_if_init
如何建立与 L2CAP 的通信接口,以及p_256_init_curve
如何为安全连接(SC)提供密码学基础。这些步骤共同确保 SMP 协议栈的可靠启动与安全通信能力。
一、概述
蓝牙设备的安全通信依赖 SMP实现配对、密钥交换和安全策略协商。SMP 的初始化是协议栈启动的关键环节,涉及状态管理、资源初始化、底层接口绑定及密码学参数配置。本文聚焦以下核心内容:
1.1 核心控制块:tSMP_CB
的状态管理
tSMP_CB
是 SMP 协议的 “状态仓库”,存储协议运行中的关键数据:
-
状态与配置:记录当前协议状态(如配对阶段)、本地与对端的安全策略(如 IO 能力、是否强制安全连接)。
-
临时数据与密钥:缓存配对过程中的随机数、确认值,以及协商生成的密钥(如临时密钥 TK、长期密钥 LTK)。
-
异步事件管理:关联定时器(如响应超时、延迟认证)和回调函数(通知上层事件)。
1.2 初始化流程:从SMP_Init
到资源配置
SMP_Init
作为入口函数,调用tsmp_CB::init
完成核心初始化:
-
状态重置:通过
*this = {}
清空历史数据,确保初始状态干净。 -
资源初始化:创建定时器(
smp_rsp_timer_ent
、delayed_auth_timer_ent
)处理异步事件;调用smp_l2cap_if_init
注册 L2CAP 接口,建立与底层数据传输层的通信。 -
测试支持:配置 PTS(协议一致性测试)失败案例,满足认证需求。
1.3 L2CAP 接口绑定:smp_l2cap_if_init
的作用
L2CAP是 SMP 的底层传输载体。smp_l2cap_if_init
通过注册固定通道回调(连接、数据接收、发送完成),将 SMP 与 L2CAP 绑定:
-
BLE 场景:注册
L2CAP_SMP_CID
通道,处理低功耗蓝牙的 SMP 数据。 -
BR/EDR 场景:注册
L2CAP_SMP_BR_CID
通道,支持传统蓝牙的安全管理。
1.4 密码学基础:P-256 椭圆曲线参数初始化
蓝牙安全连接(SC)基于 ECDH(椭圆曲线 Diffie-Hellman)密钥交换,依赖 P-256 椭圆曲线的标准参数。p_256_init_curve
函数初始化曲线参数(模数p
、系数a/b
、基点G
),为 ECDH 提供数学基础,确保设备间基于相同参数生成共享密钥。
二、源码分析
SMP_Init
packages/modules/Bluetooth/system/stack/smp/smp_api.cc
tSMP_CB smp_cb;/********************************************************************************* Function SMP_Init** Description This function initializes the SMP unit.** Returns void*******************************************************************************/
void SMP_Init(uint8_t init_security_mode) { smp_cb.init(init_security_mode); }
初始化 SMP 单元。
tSMP_CB smp_cb
packages/modules/Bluetooth/system/stack/smp/smp_int.h
/* SMP control block */
class tSMP_CB {public:void init(uint8_t security_mode);void reset();public://初始化时设置的安全模式(由 SMP_Init 传入),决定配对的安全等级(如无认证、单向认证、双向认证等)uint8_t init_security_mode{0};// SMP 事件回调函数指针(用于通知上层协议(如 L2CAP)或应用层配对结果、错误等)tSMP_CALLBACK* p_callback;// SMP 响应超时定时器(若对端未在规定时间内响应,触发超时处理)alarm_t* smp_rsp_timer_ent;RawAddress pairing_bda;tSMP_STATE state;bool derive_lk;bool id_addr_rcvd;tBLE_ADDR_TYPE id_addr_type;RawAddress id_addr;bool smp_over_br;tSMP_BR_STATE br_state; /* if SMP over BR/ERD has priority over SMP */uint8_t failure;tSMP_STATUS status;tHCI_ROLE role;uint16_t flags;tSMP_EVT cb_evt;tSMP_SEC_LEVEL sec_level; // 最终协商的安全等级(如无加密、加密、加密且认证)bool connect_initialized;// 本地与对端的确认值(用于配对认证,如数值比较或 OOB 验证)Octet16 confirm;Octet16 rconfirm;// 本地与对端的随机数(用于生成确认值或密钥)Octet16 rrand; /* for SC this is peer nonce */Octet16 rand; /* for SC this is local nonce */// 本地私钥和 DH(Diffie-Hellman)共享密钥(用于安全连接的椭圆曲线密钥交换)BT_OCTET32 private_key;BT_OCTET32 dhkey;Octet16 commitment;Octet16 remote_commitment;Octet16 local_random; /* local randomizer - passkey or OOB randomizer */Octet16 peer_random; /* peer randomizer - passkey or OOB randomizer */Octet16 dhkey_check;Octet16 remote_dhkey_check;// 本地与对端的公钥(椭圆曲线公钥,用于 DH 交换)tSMP_PUBLIC_KEY loc_publ_key;tSMP_PUBLIC_KEY peer_publ_key;tSMP_OOB_DATA_TYPE req_oob_type;tSMP_SC_OOB_DATA sc_oob_data;tSMP_IO_CAP peer_io_caps;tSMP_IO_CAP local_io_capability;tSMP_OOB_FLAG peer_oob_flag;tSMP_OOB_FLAG loc_oob_flag;tSMP_AUTH_REQ peer_auth_req;tSMP_AUTH_REQ loc_auth_req;// 本地是否强制仅使用安全连接(Secure Connections,SC)模式(基于椭圆曲线加密)bool sc_only_mode_locally_required; /* true if sc_only required requiredlocally */// 对端是否强制要求安全连接模式bool sc_mode_required_by_peer; /* true if peer requires sc in pair_req orpair_rsp *//* either in Secure Connections mode or not at all */tSMP_ASSO_MODEL selected_association_model;bool key_derivation_h7_used;bool le_sc_kp_notif_is_used;tSMP_SC_KEY_TYPE local_keypress_notification;tSMP_SC_KEY_TYPE peer_keypress_notification;// 认证阶段轮次(如基于 PIN 码的配对可能分多轮交互)uint8_t round; /* authentication stage 1 round for passkey association model */// 需要显示的配对码(如 6 位数字,用于用户确认是否一致)uint32_t number_to_display;Octet16 mac_key;uint8_t peer_enc_size;uint8_t loc_enc_size;uint8_t peer_i_key;uint8_t peer_r_key;uint8_t local_i_key;uint8_t local_r_key;// 临时密钥(Temporary Key),配对过程中生成的关键临时密钥,用于推导其他密钥(如 LTK)Octet16 tk; // 长期密钥(Long Term Key),用于后续连接的加密和认证Octet16 ltk;uint16_t div;// 加密同步根密钥(Connection Signature Resolving Key),用于数据签名防篡改Octet16 csrk; /* storage for local CSRK */uint16_t ediv;BT_OCTET8 enc_rand;tBLE_ADDR_TYPE addr_type;RawAddress local_bda;bool is_pair_cancel;bool discard_sec_req;uint8_t rcvd_cmd_code;uint8_t rcvd_cmd_len;uint16_t total_tx_unacked;bool wait_for_authorization_complete;tSMP_STATUS cert_failure; /*failure case for certification */// 延迟认证定时器(用于异步授权场景)alarm_t* delayed_auth_timer_ent;tBLE_BD_ADDR pairing_ble_bd_addr;
};
tSMP_CB
类是SMP的核心控制块(Control Block),用于存储 SMP 协议运行过程中的状态、配置参数、临时数据、密钥材料等关键信息。它是 SMP 协议栈实现的核心数据结构,贯穿配对(Pairing)、密钥生成(Key Generation)、安全等级协商等全流程。
通过成员变量和方法(init
/reset
)实现以下核心能力:
-
状态管理:记录 SMP 协议当前运行阶段(如配对初始化、密钥交换、认证等)。
-
配置参数存储:保存本地与对端设备的安全策略(如是否强制安全连接、IO 能力、认证需求等)。
-
临时数据缓存:存储配对过程中生成的临时值(如随机数、确认值、DH 密钥等)。
-
密钥材料管理:保存协商或生成的密钥(如临时密钥 TK、长期密钥 LTK、CSRK 等)。
-
回调与定时器:关联协议事件回调和超时定时器,处理异步事件(如响应超时)。
tSMP_CB::init
packages/modules/Bluetooth/system/stack/smp/smp_utils.cc
void tSMP_CB::init(uint8_t security_mode) {*this = {}; // 重置控制块状态init_security_mode = security_mode; // 设置初始安全模式smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent");smp_cb.delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent");log::verbose("init_security_mode:{}", init_security_mode);// 初始化 SMP 与 L2CAP的接口smp_l2cap_if_init();// 初始化椭圆曲线参数/* initialization of P-256 parameters */p_256_init_curve();// 配置认证测试失败案例/* Initialize failure case for certification */smp_cb.cert_failure = static_cast<tSMP_STATUS>(stack_config_get_interface()->get_pts_smp_failure_case());if (smp_cb.cert_failure)log::error("PTS FAILURE MODE IN EFFECT (CASE {})", smp_cb.cert_failure);
}
为 SMP 协议运行准备干净的初始状态,包括重置控制块、初始化关键资源(定时器、L2CAP 接口、椭圆曲线参数),并处理测试相关的失败案例配置。
蓝牙安全连接(Secure Connections,SC)基于椭圆曲线 Diffie-Hellman(ECDH)密钥交换,P-256 是 SC 强制支持的椭圆曲线。
smp_l2cap_if_init
packages/modules/Bluetooth/system/stack/smp/smp_l2c.cc
/********************************************************************************* Function smp_l2cap_if_init** Description This function is called during the SMP task startup* to register interface functions with L2CAP.*******************************************************************************/
void smp_l2cap_if_init(void) {// 1. 定义 L2CAP 固定通道注册结构体// 用于配置 L2CAP 通道的回调函数和参数。其成员变量对应 L2CAP 与上层协议(如 SMP)交互的关键接口tL2CAP_FIXED_CHNL_REG fixed_reg; log::verbose("SMDBG l2c");// 2. 配置 SMP 通道的回调函数(BLE 场景)fixed_reg.pL2CA_FixedConn_Cb = smp_connect_callback; // 连接回调fixed_reg.pL2CA_FixedData_Cb = smp_data_received; // 数据接收回调fixed_reg.pL2CA_FixedTxComplete_Cb = smp_tx_complete_callback; // 发送完成回调// 3. 配置通道可选参数fixed_reg.pL2CA_FixedCong_Cb =NULL; /* do not handle congestion on this channel */fixed_reg.default_idle_tout =60; /* set 60 seconds timeout, 0xffff default idle timeout */// 4. 注册 BLE SMP 固定通道L2CA_RegisterFixedChannel(L2CAP_SMP_CID, &fixed_reg);// 5. 配置并注册 BR/EDR SMP 通道(传统蓝牙场景)fixed_reg.pL2CA_FixedConn_Cb = smp_br_connect_callback;fixed_reg.pL2CA_FixedData_Cb = smp_br_data_received;L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &fixed_reg);
}
通过向 L2CAP 注册 SMP 的连接管理、数据接收、发送完成等回调函数,使 L2CAP 能够将 SMP 通道的事件(如数据到达、连接状态变化)传递给 SMP 协议栈处理,最终实现 SMP 协议在蓝牙链路上的正常运行。
p_256_init_curve
packages/modules/Bluetooth/system/stack/smp/p_256_curvepara.cc
#define KEY_LENGTH_DWORDS_P256 8// 表示椭圆曲线上的点
typedef struct {uint32_t x[KEY_LENGTH_DWORDS_P256];uint32_t y[KEY_LENGTH_DWORDS_P256];uint32_t z[KEY_LENGTH_DWORDS_P256];
} Point;// 存储椭圆曲线的全局参数
typedef struct {// curve's coefficientsuint32_t a[KEY_LENGTH_DWORDS_P256];uint32_t b[KEY_LENGTH_DWORDS_P256];// whether a is -3int a_minus3;// prime modulusuint32_t p[KEY_LENGTH_DWORDS_P256];// Omega, p = 2^m -omegauint32_t omega[KEY_LENGTH_DWORDS_P256];// base point, a point on E of order rPoint G;} elliptic_curve_t;// 初始化 P-256 曲线参数
void p_256_init_curve() {elliptic_curve_t* ec = &curve_p256;// 1. 有限域模数 p// 组合后 p=0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF(256 位素数)ec->p[7] = 0xFFFFFFFF;ec->p[6] = 0x00000001;ec->p[5] = 0x0;ec->p[4] = 0x0;ec->p[3] = 0x0;ec->p[2] = 0xFFFFFFFF;ec->p[1] = 0xFFFFFFFF;ec->p[0] = 0xFFFFFFFF;// 2. 曲线系数 a 和 bmemset(ec->omega, 0, KEY_LENGTH_DWORDS_P256);memset(ec->a, 0, KEY_LENGTH_DWORDS_P256);ec->a_minus3 = true;// b// b 的值:0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604Bec->b[7] = 0x5ac635d8;ec->b[6] = 0xaa3a93e7;ec->b[5] = 0xb3ebbd55;ec->b[4] = 0x769886bc;ec->b[3] = 0x651d06b0;ec->b[2] = 0xcc53b0f6;ec->b[1] = 0x3bce3c3e;ec->b[0] = 0x27d2604b;// 3. 基点 G// base point// 基点 G 的 X 坐标:0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296ec->G.x[7] = 0x6b17d1f2;ec->G.x[6] = 0xe12c4247;ec->G.x[5] = 0xf8bce6e5;ec->G.x[4] = 0x63a440f2;ec->G.x[3] = 0x77037d81;ec->G.x[2] = 0x2deb33a0;ec->G.x[1] = 0xf4a13945;ec->G.x[0] = 0xd898c296;// 基点 G 的 Y 坐标:0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5ec->G.y[7] = 0x4fe342e2;ec->G.y[6] = 0xfe1a7f9b;ec->G.y[5] = 0x8ee7eb4a;ec->G.y[4] = 0x7c0f9e16;ec->G.y[3] = 0x2bce3357;ec->G.y[2] = 0x6b315ece;ec->G.y[1] = 0xcbb64068;ec->G.y[0] = 0x37bf51f5;
}
P-256 椭圆曲线是蓝牙安全连接(Secure Connections,SC)的强制支持曲线,用于实现 ECDH(椭圆曲线 Diffie-Hellman)密钥交换。p_256_init_curve
函数的初始化操作是 ECDH 的基础:
-
密钥交换流程:设备 A 生成私钥 dA 和公钥 QA=dAG,设备 B 生成 dB 和 QB=dBG,双方通过交换公钥计算共享密钥 K=dAQB=dBQA(基于椭圆曲线的离散对数难题保证安全性)。
-
参数一致性:所有支持蓝牙 SC 的设备必须使用相同的 P-256 参数(p,a,b,G),否则无法正确计算共享密钥。
通过初始化 P-256 椭圆曲线的标准参数,为蓝牙安全连接中的 ECDH 密钥交换提供了数学基础。其核心是将 P-256 的曲线方程、有限域模数和生成元(基点)写入内存,确保设备间能基于相同的密码学参数完成安全密钥协商,最终实现蓝牙设备的安全配对与通信。
椭圆曲线由方程 y2=x3+ax+b 定义(在有限域 GF(p) 上),结构体存储了该方程的系数、模数及生成元(基点)。
系数 a:标准 P-256 曲线的 a=−3,代码中通过
a_minus3 = true
显式标记,避免存储全 0 的 a(实际运算时直接使用 a=−3 以优化计算)。系数 b:存储 P-256 的标准 b 值(十六进制),是椭圆曲线方程的关键参数,决定曲线形状。
G 是椭圆曲线群的生成元,其阶 r 是一个大素数(r=0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551)。所有椭圆曲线密钥对(如 ECDH 中的公私钥)均通过 dG(标量乘法)生成(d 是私钥,dG 是公钥)
omega 用于优化模数运算(如 p=2m−omega 时,模运算可转换为减法)。P-256 的 p 接近 2256,此处初始化为全 0,可能表示未启用该优化或预留扩展
三、流程图
四、时序图
五、总结
SMP 协议的初始化是蓝牙安全通信的起点,通过tSMP_CB
控制块的状态管理、L2CAP 接口的绑定,以及 P-256 曲线参数的配置,实现了协议栈的可靠启动与安全能力。其中:
-
tSMP_CB
作为核心数据结构,贯穿配对、密钥交换全流程,确保状态与数据的一致性。 -
L2CAP 接口的注册建立了 SMP 与底层传输的桥梁,支撑协议消息的收发。
-
P-256 曲线参数的初始化则为安全连接(SC)提供了密码学保障,是 ECDH 密钥交换的基础。