BK
1.内存形式
MEMORY
{
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x1FC00 /* 127KB */
AC_FLASH (r) : ORIGIN = 0x1FC00, LENGTH = 0x400 /* 1KB */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x1C00 /* 7KB */
PUF (rw) : ORIGIN = 0x20001C00, LENGTH = 0x400 /* 1KB */
}
2.功能介绍
密钥生成
支持生成设备唯一的对称密钥(128bits、192bits、256bits)。
支持生成设备唯一的椭圆曲线密钥对(192/224/256/384/521bits)。
提供基于设备噪声的随机数生成。
使用ECDH算法生成共享密钥。
密钥存储与保护
利用SRAM PUF技术,实现对密钥的安全存储,无需在NVM中存储密钥。
提供基于设备唯一包装密钥的安全密钥存储解决方案。
加密数据
- 使用椭圆曲线算法对明文进行加密。
3.API
bk_init()
:初始化PUF,指向系统保留的SRAM范围,该范围被用作SRAM PUF。//sram_puf:用作SRAM PUF的地址。 //sram_puf_siz:SRAM PUF的内存大小,为1KB。 iid_return_t bk_init(uint8_t * const sram_puf, const uint16_t sram_puf_size);
bk_start()
:使用之前生成的激活代码调用bk_start
函数,启动BK。//activation_code:存储ac激活码的地址。 iid_return_t bk_start(const uint8_t * const activation_code);
bk_generate_random()
:生成基于设备噪声的随机数。//number_of_bytes:随机数的大小。 //data_buffer:随机数保存的位置 iid_return_t bk_generate_random(const uint16_t number_of_bytes, uint8_t * const data_buffer);
bk_get_key()
:生成设备唯一的对称密钥。//BK_SYM_KEY_TYPE_128:密钥大小,可选择128、192、256. //index:密钥索引值,大小为0-255。 //key:存储生成的密钥。 iid_return_t bk_get_key(const bk_sym_key_type_t key_type, const uint8_t index, uint8_t * const key);
bk_get_private_key()
:生成椭圆曲线的私钥。//curve:椭圆曲线的类型,NIST P-192/224/256。 //usage_context:一般为null。 //usage_context_length:0. //key_source:指定私钥来源,可以是PUF派生,随机生成或是用户提供。 iid_return_t bk_get_private_key( const bk_ecc_curve_t curve, const uint8_t *usage_context, const uint32_t usage_context_length, const bk_ecc_key_source_t key_source, uint8_t *private_key );
bk_wrap()
:将用户提供的对称密钥包装成一个设备唯一的密钥代码(key_code)。//index:密钥的索引,大小为0-255. //key:被包装的密钥。 //key_length:密钥大小。 //key_code:存储包装后的密钥代码。 iid_return_t bk_wrap(const uint8_t index, const uint8_t * const key, const uint16_t key_length, uint8_t * const key_code);
bk_unwarp()
:解包密钥。iid_return_t bk_unwrap(const uint8_t * const key_code, uint8_t * const key, uint16_t * const key_length, uint8_t * const index);
不明白,为什么相同的密钥,生成的密钥代码不一样,但是解包之后还是相同的密钥。
用于包装的密钥是:66F477CEBE0E51716A733C92E28FCB0C
10次的key_code为:
F479EC61F0E6D4A8D68E271C08CD3A290000001000000004000000008C791B5524968528E0C0F5A2F2FDF261610A503E02295F518C126EEA95B607F5 47FA7BC0928EE813645C5DF5FF7BE8F40000001000000004000000002E5BA26E07A9D7DE495E23112EA1BC6154BF8B070F41AB8546FF265707D359C5 BD0B0B78D3896E1A249C06C52B4B70A7000000100000000400000000913E5DF3121337795E203B5AC6931B5091E571FE7C8FCF62A6B304953866BA09 90FDF807380B0704EAAFA5B95FB97EB7000000100000000400000000DB9887D108897E7B7AF1C99470280CD6AFAF686E6712A138499767502129BDC3 3758A894E8E7BEC036207909E300BAEA000000100000000400000000C71034375F8131C5F5EF1BE15F1B13E3E4507620458D6EFA01227B8F913AF6A5 F90BACF9A56A2E443893AD428E0EF094000000100000000400000000EE745152A20C8D5A9A6E2C7602684EE6AF3675430D80501DFC507C8440828D2A A3957EEA7DD424D4BF64EBD3C05FC9DB000000100000000400000000FA71E3D2667D1D025F3F327F5BDBEA5EE77CCE813DC0DA8913DCEC02500EBE0F BD03ACEC8689570EF7D3162B83FB87960000001000000004000000001941F9F8126618CD6B5EFD3D0610869A51EA6065C6CCF41A5E99EF0984C12DB0 227E77DBAA06DEDF6D8FF42B74F8002B0000001000000004000000002A836FD15B239172916683F1F93B8FE7120274D82EFF62A0AFB0C9620FF3A880 903CF043FB250AA6DF7CD71E2A9F50820000001000000004000000008AA0F1119A4EABCE3ED538FAC17DA12C97636EDC04994899DEC6DEDB802B235C
发现规律:中间12个字节是一样的,结构为16B+12B+32B。12+32=44,为定义的头部长度。
#define BK_KEY_CODE_HEADER_SIZE_BYTES (44)
推测:将所使用的方法和数据写在了头部中。
bk_derive_public_key
:获取公钥//use_point_compression:是否使用了点压缩技术表示公钥。 iid_return_t bk_derive_public_key(const bool use_point_compression, const bk_ecc_curve_t curve, const uint8_t * const private_key, uint8_t * const public_key);
bk_derive_public_key
:根据私钥密钥代码生成公钥代码。iid_return_t bk_derive_public_key(const bool use_point_compression, const bk_ecc_curve_t curve, const uint8_t * const private_key, uint8_t * const public_key);
bk_create_private_key
:生成椭圆曲线的私钥代码。与5类似的用法。// iid_return_t bk_create_private_key(const bk_ecc_curve_t curve, const bk_ecc_key_purpose_t purpose_flags, const uint8_t * const usage_context, const uint32_t usage_context_length, const bk_ecc_key_source_t key_source, const uint8_t * const private_key, bk_ecc_private_key_code_t * const private_key_code);
bk_compute_public_from_private_key
:根据私钥代码直接计算出公钥代码。iid_return_t bk_compute_public_from_private_key(const bk_ecc_private_key_code_t * const private_key_code, bk_ecc_public_key_code_t * const public_key_code);
bk_import_public_key
:将导入的公钥封装成公钥代码。iid_return_t bk_export_public_key(const bool use_point_compression, const bk_ecc_public_key_code_t * const public_key_code, uint8_t * const public_key, bk_ecc_curve_t * const curve, bk_ecc_key_purpose_t * const purpose_flags);
bk_export_public_key
:导出公钥代码为公钥。// purpose_flags:用来指示公钥的预期用途。 iid_return_t bk_export_public_key(const bool use_point_compression, const bk_ecc_public_key_code_t * const public_key_code, uint8_t * const public_key, bk_ecc_curve_t * const curve, bk_ecc_key_purpose_t * const purpose_flags);
bk_ecdsa_sign
:使用ECDSA算法和椭圆曲线私钥对消息进行签名。//deterministic_signature:指定是否使用确定性或非确定性签名。 //message_is_hash:要进行签名的消息是否为hash过的。 //signature:保存计算出的签名。 iid_return_t bk_ecdsa_sign(const bk_ecc_private_key_code_t * const private_key_code, const bool deterministic_signature, const uint8_t * const message, const uint32_t message_length, const bool message_is_hash, uint8_t * const signature, uint16_t * const signature_length);
bk_ecdsa_verify
:验证使用椭圆曲线公钥签名的消息或消息哈希值的ECDSA签名。iid_return_t bk_ecdsa_verify(const bk_ecc_public_key_code_t * const public_key_code, const uint8_t * const message, const uint32_t message_length, const bool message_is_hash, const uint8_t * const signature, const uint16_t signature_length);
bk_ecdh_shared_secret
:使用 ECDH 算法和提供的私钥和公钥代码来计算共享密钥。ECDH算法还不是很了解//private_key_code:这个私钥代码是通过bk_create_private_key创建的,地址必须对齐到32位。 // iid_return_t bk_ecdh_shared_secret(const bk_ecc_private_key_code_t * const private_key_code, const bk_ecc_public_key_code_t * const public_key_code, uint8_t * const shared_secret);
bk_generate_cryptogram
:将明文进行加密。iid_return_t bk_generate_cryptogram(const bk_ecc_public_key_code_t * const receiver_public_key_code, const bk_ecc_private_key_code_t * const sender_private_key_code, const bk_ecc_cryptogram_type_t cryptogram_type, uint8_t * const counter64, const uint8_t * const plaintext, const uint32_t plaintext_length, uint8_t * const cryptogram, uint32_t * const cryptogram_length);
cryptogram_type
:指定要生成的密码文类型的标志。它必须是有效的标志,属于bk_ecc_cryptogram_type_t
枚举类型。counter64
:指向一个缓冲区的指针,该缓冲区包含当前64位单调计数器,用于密码文重放保护,并将在成功函数完成后保存新的计数器值。对于每个不同的发送者-接收者密钥对,都必须使用单独的计数器缓冲区。bk_process_cryptogram
: 计算出明文。。iid_return_t bk_process_cryptogram(const bk_ecc_private_key_code_t * const receiver_private_key_code, const bk_ecc_public_key_code_t * const sender_public_key_code, bk_ecc_cryptogram_type_t * const cryptogram_type, uint8_t * const counter64, const uint8_t * const cryptogram, const uint32_t cryptogram_length, uint8_t * const plaintext, uint32_t * const plaintext_length);
bk_get_public_key_from_cryptogram
:从密文中导出嵌入的公钥代码。iid_return_t bk_get_public_key_from_cryptogram(const bool use_point_compression, const bk_ecc_curve_t curve, const uint8_t * const cryptogram, const uint32_t cryptogram_length, uint8_t * const public_key);
文档信息
- 本文作者:wangwang
- 本文链接:http://anshichifan.xyz/2024/06/03/BK/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)