本篇文档适合使用Link TEE作为ID²载体的用户。了解Link TEE

适用范围:

  • 使用Link kit SDK v2.3.0 、安全SDK v2.0集成安全功能(包括ID²、iTLS)、使用Link TEE安全存储ID²及相关的机密信息。
  • 通过物联网平台创建的产品,节点类型为:网关类型。网关设备下挂的子设备,通过设备证书(三元组)的方式进行认证。

1. 编译Link kit SDK

1.1 下载Link kit SDK

下载Link Kit SDK v2.3.0,推荐使用v2.3.0版本。

1.2 配置编译选项

通过 make menuconfig进入编译配置,编译选项中,使能 iTLS 和 网关example。

使能iTLS:

使能gateway:

1.3 ubuntu运行平台配置

集成安全SDK库,请参考:《设备端适配:ID²-KM在Link Kit SDK上适配:第2章-集成安全SDK》

将安全SDK的以下库放置于Linkkit SDK的prbuilt/ubuntu/libs目录中。安全SDK发布的库:

libicrypto.a
libid2.a
libitls.a
libkm.a
libls_hal.a
libls_osa.a

将Link TEE发布的库置于Link SDK的prbuilt/ubuntu/libs目录中。

libtee_client.so
libtee_internal.so

修改example/iot.mk,增加对安全SDK及Link TEE相关库的支持。

$(call Append_Conditional, LDFLAGS, \
  -litls \
  -lid2 \
  -lkm \
  -licrypto \
  -lls_osa \
  -lls_hal \
  -ltee_client \
  -ltee_internal \

修改mqtt_example.c中的PRODUCT_KEY,PRODUCT_SECRET为您申请购买后可用的值,DEVICE_NAME, DEVICE_SECRET按照您自己的定义进行命名。

说明 DEVICE_NAME 需要和您在阿里云物联网平台中设定的名称一致,保证名称唯一。
#define PRODUCT_KEY             "a1Oxxxxx"
#define PRODUCT_SECRET          "i11xxxxxxxxxxx"
#define DEVICE_NAME             "test_gateway"
#define DEVICE_SECRET           "i11fxxxxxxxxxxxxxxxxxxxxxx"

修改iotkit-embedded/src/ref-impl/hal/os/$os_name /HAL_Crypt_Linux.c, 适配alicrypto 的接口。 参考代码实现如下:

#include "iot_import.h"
#include "ali_crypto.h"
#define AES_BLOCK_SIZE 16
#define KEY_LEN 16 // aes 128 cbc
#define p_aes128_t p_HAL_Aes128_t
#define PLATFORM_AES_ENCRYPTION HAL_AES_ENCRYPTION
#define PLATFORM_AES_DECRYPTION HAL_AES_DECRYPTION
p_HAL_Aes128_t HAL_Aes128_Init(
           _IN_ const uint8_t *key,
           _IN_ const uint8_t *iv,
           _IN_ AES_DIR_t dir)
{
   ali_crypto_result result;
   void *            aes_ctx;
   size_t            aes_ctx_size, alloc_siz;
   uint8_t *         p;
   bool              is_en = true; // encrypto by default
   if (dir == PLATFORM_AES_DECRYPTION) {
       is_en = false;
   }
   result = ali_aes_get_ctx_size(AES_CBC, &aes_ctx_size);
   if (result != ALI_CRYPTO_SUCCESS) {
       HAL_Printf("get ctx size fail(%08x)", result);
       return NULL;
   }
   alloc_siz = aes_ctx_size + KEY_LEN * 2 + sizeof(bool);
   aes_ctx   = HAL_Malloc(alloc_siz);
   if (aes_ctx == NULL) {
       HAL_Printf("kmalloc(%d) fail", (int)aes_ctx_size);
       return NULL;
   }
   memset(aes_ctx, 0, alloc_siz);
   p = (uint8_t *)aes_ctx + aes_ctx_size;
   memcpy(p, key, KEY_LEN);
   p += KEY_LEN;
   memcpy(p, iv, KEY_LEN);
   p += KEY_LEN;
   *((bool *)p) = is_en;
   return aes_ctx;
}
int HAL_Aes128_Destroy(_IN_ p_HAL_Aes128_t aes)
{
   if (aes) {
       HAL_Free(aes);
   }
   return 0;
}
static int platform_aes128_encrypt_decrypt(p_HAL_Aes128_t aes_ctx,
                                          const void *src, size_t siz,
                                          void *dst, aes_type_t t)
{
   ali_crypto_result result;
   size_t            dlen, in_len = siz, ctx_siz;
   uint8_t *         p, *key, *iv;
   bool              is_en;
   if (aes_ctx == NULL) {
       HAL_Printf("platform_aes128_encrypt_decrypt aes_ctx is NULL");
       return -1;
   }
   result = ali_aes_get_ctx_size(AES_CBC, &ctx_siz);
   if (result != ALI_CRYPTO_SUCCESS) {
       HAL_Printf("get ctx size fail(%08x)", result);
       return 0;
   }
   p   = (uint8_t *)aes_ctx + ctx_siz;
   key = p;
   p += KEY_LEN;
   iv = p;
   p += KEY_LEN;
   is_en = *((uint8_t *)p);
   in_len <<= t == AES_CBC ? 4 : 0;
   dlen = in_len;
   result = ali_aes_init(t, is_en, key, NULL, KEY_LEN, iv, aes_ctx);
   if (result != ALI_CRYPTO_SUCCESS) {
       HAL_Printf("ali_aes_init fail(%08x)", result);
       return 0;
   }
   result = ali_aes_finish(src, in_len, dst, &dlen, SYM_NOPAD, aes_ctx);
   if (result != ALI_CRYPTO_SUCCESS) {
       HAL_Printf("aes_finish fail(%08x)", result);
       return -1;
   }
   return 0;
}
int HAL_Aes128_Cbc_Encrypt(
           _IN_ p_HAL_Aes128_t aes,
           _IN_ const void *src,
           _IN_ size_t blockNum,
           _OU_ void *dst)
{
   return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);
}
int HAL_Aes128_Cbc_Decrypt(
           _IN_ p_HAL_Aes128_t aes,
           _IN_ const void *src,
           _IN_ size_t blockNum,
           _OU_ void *dst)
{
   return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);
}
int HAL_Aes128_Cfb_Encrypt(
           _IN_ p_HAL_Aes128_t aes,
           _IN_ const void *src,
           _IN_ size_t length,
           _OU_ void *dst)
{
   return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);
}
int HAL_Aes128_Cfb_Decrypt(
           _IN_ p_HAL_Aes128_t aes,
           _IN_ const void *src,
           _IN_ size_t length,
           _OU_ void *dst)
{
   return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);
}

1.4 编译,运行make,编译成功后生成linkkit-example-gw。

2. linkkit-example-gw测试验证

在output/release/bin 文件夹下,运行命令:

LD_LIBRARY_PATH=../lib/ ./linkkit-example-gw

出现以下log信息表示已成功切换成itls的链接方式,并使用Link TEE作为安全存储服务。

出现以下log信息表示mqtt测试成功。

3. 阿里云物联网平台验证

登录阿里云物联网平台,在“设备管理”->“设备”列表查看Device Name与(步骤1.3中)gateway example代码中设置的Device Name一致。 如果一致,则该设备已经通过ID²认证并且接入物联网平台,您可以进行后续设备topic订阅与推送等。