BK库使用

2024/06/03 PUF 共 6653 字,约 20 分钟
闷骚的程序员

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.功能介绍

  1. 密钥生成

    • 支持生成设备唯一的对称密钥(128bits、192bits、256bits)。

    • 支持生成设备唯一的椭圆曲线密钥对(192/224/256/384/521bits)。

    • 提供基于设备噪声的随机数生成。

    • 使用ECDH算法生成共享密钥。

  2. 密钥存储与保护

    • 利用SRAM PUF技术,实现对密钥的安全存储,无需在NVM中存储密钥。

    • 提供基于设备唯一包装密钥的安全密钥存储解决方案。

  3. 加密数据

    • 使用椭圆曲线算法对明文进行加密。

3.API

  1. 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);
    
  2. bk_start():使用之前生成的激活代码调用bk_start函数,启动BK。

    //activation_code:存储ac激活码的地址。
    iid_return_t bk_start(const uint8_t * const activation_code);
    
  3. 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);
    
  4. 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);
    
  5. 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
    );
    
  6. 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);
    
  7. 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)

    推测:将所使用的方法和数据写在了头部中。

  8. 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);
    
  9. 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);
    
  10. 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);
    
        
    
  11. 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);
    
  12. 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);
    
  13. 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);
    
  14. 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);
    
  15. 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);
    
  16. 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);
    
  17. 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位单调计数器,用于密码文重放保护,并将在成功函数完成后保存新的计数器值。对于每个不同的发送者-接收者密钥对,都必须使用单独的计数器缓冲区。

  18. 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);
    
  19. 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);
    

文档信息

Search

    Table of Contents