本篇博客代码部分的介绍,主要基于nRF Connect SDK2.9.0
1.2 配件广播配件处于不同状态时,广播的内容有所不同。有三种广播,分别是快速配对可发现广播(Fast Pair Discoverable Advertising),快速配对不可发现广播(Fast Pair not Discoverable Advertising)和FMDN frame广播。Fast Pair Discoverable Advertising广播连接后,用于设备配置(关联);Fast Pair not Discoverable Advertising广播连接后用于时钟同步。配置(关联)成功之后的设备,断开连接后,进行FMDN frame广播。配件复位后,按下button1(nRF52840 DK),开始Fast pair广播。如果配件上已经存储了account key,则进行Fast Pair not Discoverable Advertising;否则,则进行Fast Pair Discoverable Advertising。如下图:
关于Fast Pair广播的内容可以参考前一篇博客。FMDN frame广播在规范里的定义如下:
选择的椭圆曲线方程不同,计算出来的ephemeral identifier长度就不同,FMDN frame的长度也不同。例子默认选择了SECP160R1(CONFIG_BT_FAST_PAIR_FMDN_ECC_SECP160R1=y)
choice BT_FAST_PAIR_FMDN_ECC_TYPE prompt "Elliptic Curve selection" default BT_FAST_PAIR_FMDN_ECC_SECP160R1 help Select the Elliptic Curve used for encryption in FMDN modules.config BT_FAST_PAIR_FMDN_ECC_SECP160R1 bool "FMDN with the SECP160R1 Elliptic Curve" depends on BT_FAST_PAIR_CRYPTO_SECP160R1_SUPPORT help Select the SECP160R1 Elliptic Curve for FMDN. This curve type is less secure than the SECP256R1 variant, but it can be used with Bluetooth Legacy Advertising because of its limited size (160 bits).config BT_FAST_PAIR_FMDN_ECC_SECP256R1 bool "FMDN with the SECP256R1 Elliptic Curve" depends on BT_FAST_PAIR_CRYPTO_SECP256R1_SUPPORT help Select the SECP256R1 Elliptic Curve for FMDN. This curve type is more secure than the SECP160R1 variant but requires using Bluetooth Extended Advertising due to its extended size (256 bits).
EID(ephemeral identifier)的计算方法如下:
1)计算一个random数据:通过对如下数据结构的数据,用ephemeral identity key和AES-ECB-256算法加密后产生一个伪随机数,记作r'
Note: The device is assumed to have a 32-bit time counter in seconds.
设备提供一个以秒为单位的32位时间计数器。在将其放入数据结构之前,需要将其转换为32位大端字节序格式,并且将最低的K(这里是10)位清零。这意味着时间计数器的精度被降低到了2^10秒(即1024秒)的倍数。
Rotation period exponent is fixed and set to 10, corresponding to 1024 seconds. 该指数K是固定的,设置为 10,对应于 1024 秒。
2)选择SECP160R1或SECP256R1用于椭圆曲线加密操作。有关曲线定义,请参考《SEC 2:推荐的椭圆曲线域参数》,它定义了接下来运算所涉及的Fp,n和G。(https://www.secg.org/SEC2-Ver-1.0.pdf)
3)r = r' mod n(模运算是为了保证r小于基点G的阶n, 基点 G 的阶 n 是指最小的正整数,使得 nG 等于椭圆曲线上的无穷远点。
4)计算R = r* G,R是曲线上的一个点,它代表正在使用的公钥。(FMDN frame)信标将R的x坐标Rx作为其临时标识符(ephemeral identifier)进行广播。
椭圆曲线加密计算对应的主要代码如下:
int fp_crypto_ecc_secp160r1_calculate(uint8_t *out, uint8_t *mod, const uint8_t *in, size_t datalen){ /* SECP160R1 key length corresponds to one coordinate. */ uint8_t public_key[FP_CRYPTO_ECC_SECP160R1_KEY_LEN * 2]; ocrypto_sc_p160 mod_le; /* Verify the input length. */ if (datalen != SECP160R1_DATA_LEN) { return -ENOTSUP; } /* Compute the intermediate modulo result. * Store it in the output buffer after little-endian to big-endian conversion. */ ocrypto_sc_p160_from32bytes_alt(&mod_le, in); sys_memcpy_swap(mod, mod_le.w, FP_CRYPTO_ECC_SECP160R1_MOD_LEN); /* Calculate the public key and store the X coordinate in the output buffer. */ ocrypto_p160_scalar_mult_alt(public_key, in); memcpy(out, public_key, FP_CRYPTO_ECC_SECP160R1_KEY_LEN); return 0;}int fp_crypto_ecc_secp256r1_calculate(uint8_t *out, uint8_t *mod, const uint8_t *in, size_t datalen){ ocrypto_cp_p256 public_key; ocrypto_sc_p256 mod_le; /* Verify the input length. */ if (datalen != SECP256R1_DATA_LEN) { return -ENOTSUP; } /* Compute the intermediate modulo result. * Store it in the output buffer after little-endian to big-endian conversion. */ (void) ocrypto_sc_p256_from32bytes(&mod_le, in); sys_memcpy_swap(mod, mod_le.w, FP_CRYPTO_ECC_SECP256R1_MOD_LEN); /* Calculate the public key and store the X coordinate in the output buffer. */ (void) ocrypto_curve_p256_scalarmult_base(&public_key, &mod_le); ocrypto_curve_p256_to32bytes(out, &public_key); return 0;
1.3 FMDN设备(配件)应用所涉及的密钥- Account key: 账户密钥是Google fast pair过程中Seeker传给Provider的16字节的密钥。
- Owner account key:所有者账户密钥是从Account key list中选出来的一个account key。对于原本设计就是FMDN设备的情况,设备不支持Subsequent pairing,所以它只拥有一个account key,那么这个account key也是Owner account key。对于原本设计不是FMDN设备,且做过Google fast pair,拥有多个account key的情况,通过升级具有了FMDN能力,那么选择第一个account key作为Owner account key。
- Ephemeral identity key:临时身份密钥是Seeker做FMDN provisioning(配置)过程中,产生的一个32字节随机数。Seeker通过Beacon Actions Characteristic write方式,将EIK用owner account key做AES-ECB-128加密后,发送给Provider的。Provider使用owner account key解密EIK。 如果EIK被设备清除了,那么设备需要做工厂复位(factory reset)。EIK有两个用途:1. 参与SHA256计算,用于身份认证;2. 参与生成EID的计算。EID相当于椭圆曲线算法计算出来的一个公钥,是配件的FMND广播包数据的一部分。获得并存储了EIK的配件设备是provisioned设备。如果没有EIK,或是EIK被删除了,那么就是unprovision设备,不具备寻物网络功能。
- Recovery key:恢复临时身份密钥,对 “Ephemeral identity key ||(拼接) 0x01” 进行 SHA256 哈希运算,然后截取前 8 个字节。该密钥存储在配件上,并且在用户通过按下配件上的按钮表示同意的情况下,Seeker(所有者设备)可以使用带有它生成的安全凭证的命令来读取临时身份密钥 。
- Ring key:响铃密钥,对 “Ephemeral identity key || 0x02” 进行 SHA256 哈希运算,然后截取前 8 个字节。该密钥存储在配件上,Seeker只能使用带有它生成的安全凭证的命令来让配件发出响铃(响铃操作)。
- Unwanted tracking protection key:防止不必要跟踪密钥,对 “Ephemeral identity key || 0x03” 进行 SHA256 哈希运算,然后截取前 8 个字节。该密钥存储在配件上,Seeker只能使用带有它生成的安全凭证的命令来激活防止不必要跟踪模式(unwanted tracking protection mode )。
- One-time Authentication Key:一次性身份验证密钥,可以理解为一个安全凭证。Seeker发送不同命令的时候携带不同的One-time Authentication Key