SDK准备
编译
- 将TA源代码放在\ ta/customer\ 目录中。
- 打开位于\ ta/customer\ 目录中的\ Makefile\ 。
- 在\ Makefile\ 文件中将新建的目录名添加到TA_SUBDIRS变量中。
- 检查\ build.sh\ 文件中环境变量CROSS_COMPILE是否为当前编译工具链所在路径,确保路径正确。
- 执行\ ./build.sh all\ 编译TA。
- 编译完成后,在\ hobot_tee_devkit/out/ta/customer\ 目录中可以看到与TA源代码同名目录,里面就是对应的TA程序,以.ta为后缀的二进制文件。
- 如果您需要清理构建并重新开始,您可以切换到\ hobot_tee_devkit\ 目录使用以下命令:\ ./build.sh clean\ 。
- 将编译完成的TA程序放置到板端\ /lib/optee_armtz\ 或\ /usr/hobot/lib/optee_armtz\ 目录中,在CA中通过uuid可以调用到此TA。
调试方法
错误码
出现异常时,通过查看错误码可以知道错误类型,OP-TEE常见错误码如下:
#define TEE_ERROR_CORRUPT_OBJECT 0xF0100001
#define TEE_ERROR_CORRUPT_OBJECT_2 0xF0100002
#define TEE_ERROR_STORAGE_NOT_AVAILABLE 0xF0100003
#define TEE_ERROR_STORAGE_NOT_AVAILABLE_2 0xF0100004
#define TEE_ERROR_CIPHERTEXT_INVALID 0xF0100006
#define TEE_ERROR_GENERIC 0xFFFF0000
#define TEE_ERROR_ACCESS_DENIED 0xFFFF0001
#define TEE_ERROR_CANCEL 0xFFFF0002
#define TEE_ERROR_ACCESS_CONFLICT 0xFFFF0003
#define TEE_ERROR_EXCESS_DATA 0xFFFF0004
#define TEE_ERROR_BAD_FORMAT 0xFFFF0005
#define TEE_ERROR_BAD_PARAMETERS 0xFFFF0006
#define TEE_ERROR_BAD_STATE 0xFFFF0007
#define TEE_ERROR_ITEM_NOT_FOUND 0xFFFF0008
#define TEE_ERROR_NOT_IMPLEMENTED 0xFFFF0009
#define TEE_ERROR_NOT_SUPPORTED 0xFFFF000A
#define TEE_ERROR_NO_DATA 0xFFFF000B
#define TEE_ERROR_OUT_OF_MEMORY 0xFFFF000C
#define TEE_ERROR_BUSY 0xFFFF000D
#define TEE_ERROR_COMMUNICATION 0xFFFF000E
#define TEE_ERROR_SECURITY 0xFFFF000F
#define TEE_ERROR_SHORT_BUFFER 0xFFFF0010
#define TEE_ERROR_EXTERNAL_CANCEL 0xFFFF0011
#define TEE_ERROR_OVERFLOW 0xFFFF300F
#define TEE_ERROR_TARGET_DEAD 0xFFFF3024
#define TEE_ERROR_STORAGE_NO_SPACE 0xFFFF3041
#define TEE_ERROR_MAC_INVALID 0xFFFF3071
#define TEE_ERROR_SIGNATURE_INVALID 0xFFFF3072
#define TEE_ERROR_TIME_NOT_SET 0xFFFF5000
#define TEE_ERROR_TIME_NEEDS_RESET 0xFFFF5001
调用栈
使用步骤如下:
板端出现panic信息,例如:
E/TC:? 0
E/TC:? 0 TA panicked with code 0xffff0006
E/LD: Status of TA e5cbaf39-f1a3-4761-ac0f-02a3f1cd3304
E/LD: arch: aarch64
E/LD: region 0: va 0x40004000 pa 0xa2600000 size 0x002000 flags rw-s (ldelf)
E/LD: region 1: va 0x40006000 pa 0xa2602000 size 0x011000 flags r-xs (ldelf)
E/LD: region 2: va 0x40017000 pa 0xa2613000 size 0x001000 flags rw-s (ldelf)
E/LD: region 3: va 0x40018000 pa 0xa2614000 size 0x004000 flags rw-s (ldelf)
E/LD: region 4: va 0x4001c000 pa 0xa2618000 size 0x001000 flags r--s
E/LD: region 5: va 0x4001d000 pa 0xa2646000 size 0x001000 flags rw-s (stack)
E/LD: region 6: va 0x4001e000 pa 0xa5e30000 size 0x001000 flags rw-- (param)
E/LD: region 7: va 0x4001f000 pa 0xa5e40000 size 0x001000 flags rw-- (param)
E/LD: region 8: va 0x40028000 pa 0x00001000 size 0x021000 flags r-xs [0]
E/LD: region 9: va 0x40049000 pa 0x00022000 size 0x00c000 flags rw-s [0]
E/LD: [0] e5cbaf39-f1a3-4761-ac0f-02a3f1cd3304 @ 0x40028000
E/LD: Call stack:
E/LD: 0x40034518
E/LD: 0x40029030
E/LD: 0x40028510
E/LD: 0x40028644
E/LD: 0x40035c78
E/LD: 0x40035d2c
E/LD: 0x4002910c在编译环境下执行脚本,其中-d参数后面跟二进制文件的路径,分为两种:TEE core panic时为tee.elf的路径;TA panic时为对应TA elf的路径:
core: {sdk_dir}/optee/scripts/symbolize.py -d path/to/tee.elf
或
TA: {sdk_dir}/optee/scripts/symbolize.py -d path/to/ta.elf将panic信息复制到脚本终端下,得到调用栈:
:~/root$ {sdk_dir}/optee/scripts/symbolize.py -d path/to/ta.elf
E/TC:? 0
E/TC:? 0 TA panicked with code 0xffff0006 (TEE_ERROR_BAD_PARAMETERS)
E/LD: Status of TA e5cbaf39-f1a3-4761-ac0f-02a3f1cd3304
E/LD: arch: aarch64
E/LD: region 0: va 0x40004000 pa 0xa2600000 size 0x002000 flags rw-s (ldelf)
E/LD: region 1: va 0x40006000 pa 0xa2602000 size 0x011000 flags r-xs (ldelf)
E/LD: region 2: va 0x40017000 pa 0xa2613000 size 0x001000 flags rw-s (ldelf)
E/LD: region 3: va 0x40018000 pa 0xa2614000 size 0x004000 flags rw-s (ldelf)
E/LD: region 4: va 0x4001c000 pa 0xa2618000 size 0x001000 flags r--s
E/LD: region 5: va 0x4001d000 pa 0xa2646000 size 0x001000 flags rw-s (stack)
E/LD: region 6: va 0x4001e000 pa 0xa5e30000 size 0x001000 flags rw-- (param)
E/LD: region 7: va 0x4001f000 pa 0xa5e40000 size 0x001000 flags rw-- (param)
E/LD: region 8: va 0x40028000 pa 0x00001000 size 0x021000 flags r-xs [0] .ta_head .text .rodata .gnu.hash .dynsym .dynstr .hash .rela.dyn
E/LD: region 9: va 0x40049000 pa 0x00022000 size 0x00c000 flags rw-s [0] .dynamic .got .rela.got .data .bss
E/LD: [0] e5cbaf39-f1a3-4761-ac0f-02a3f1cd3304 @ 0x40028000 (bin/debug/ta/e5cbaf39-f1a3-4761-ac0f-02a3f1cd3304.elf)
E/LD: Call stack:
E/LD: 0x40034518 TEE_Panic at optee/lib/libutee/tee_api_panic.c:24
E/LD: 0x40029030 crypto_skcipher_update at optee/ta/skcipher/skcipher_ta_api.c:322
E/LD: 0x40028510 TA_skcipher_update at optee/ta/skcipher/skcipher_ta.c:300
E/LD: 0x40028644 TA_InvokeCommandEntryPoint at optee/ta/skcipher/skcipher_ta.c:384
E/LD: 0x40035c78 entry_invoke_command at optee/lib/libutee/arch/arm/user_ta_entry.c:370
E/LD: 0x40035d2c __utee_entry at optee/lib/libutee/arch/arm/user_ta_entry.c:390
Hobot TA
如果用户需要在TEE使用基于HSM实现的密码学算法,建议直接使用地平线提供的TA。如果用户需要自研基于HSM加解密的TA,GP接口的使用方式必须按地平线定义的规则进行使用,使用示例可参考地平线提供的TA(见Hobot TA)的实现方式。
Hobot TA:
| TA | description |
+=================+===============================================+
| aead | 认证加密算法TA,支持算法:ccm、gcm |
+-------------------+-------------------------------------------------+
| akcipher | 非对称算法TA, |
| | 包含签名验签、加解密,支持算法:rsa、ecdsa、sm2 |
+-------------------+-------------------------------------------------+
| hb_secure_save | 安全存储TA,提供密钥管理功能 |
+-------------------+-------------------------------------------------+
| hb_secure_storage | 安全存储TA,提供REE FS和RPMB的读写功能 |
+-------------------+-------------------------------------------------+
| kpp | 密钥协商TA,支持算法:ecdh、x25519、x448、sm2 |
+-------------------+-------------------------------------------------+
| md | 摘要算法TA,支持算法:HASH、hmac、cmac |
+-------------------+-------------------------------------------------+
| skcipher | 对称加密算法TA,支持算法:aes、sm4 |
+-------------------+-------------------------------------------------+
Pkcs11 TA
TEE底层加解密算法有2种实现方式:一种是基于HSM实现,如Hobot TA中使用的密码学算法;另一种是基于Optee OS内部算法库实现,即本节介绍的Pkcs11 TA中使用的密码学算法。
TEE基于Optee Os算法库实现的TA,支持的算法类型包括:AES/RSA/ECDSA/SHA224/SHA256/SHA384/SHA512/HMAC。
TEE基于Optee Os算法库实现的TA,GP接口的使用方式符合GP标准。
用户使用Pkcs11 TA,需要在REE侧自研(或移植)上层用户库,地平线不提供上层库的支持。
- 移植开源pkcs11_tool工具,作为Pkcs11 TA的调试Sample,客户可以使用该工具进行功能调试,且其使用方式遵循开源标准。使用示例如下:\ /app/sample/S83_Sample/S83E08_Crypto/optee_pkcs11_sample/bin/pkcs11-tool --module /usr/lib/aarch64-linux-gnu/libckteec.so --slot-index 0 --init-token --label softtoken0 --so-pin 123456 --init-pin --pin 654321\ 。
如果有服务需要访问OP-TEE,比如使用加解密、安全存储等,需要在tee-supplicant之后启动。
具体可参考hobot-log-hsm.service,增加After=tee-supplicant.service,文件路径:\ {sdk_dir}/hbre/boot-utils/hb-init-scripts/lib/systemd/system/hobot-log-hsm.service\ 。当设备要休眠时,需要确保调用OP-TEE的功能已经全部处理完成,且不会再有新的OP-TEE调用。可参考地平线提供的解决方案。
- 保证这些服务需要在休眠的\ suspend-action.sh\ 执行前停止对OP-TEE的访问,在唤醒的\ resume-action.sh\ 执行后重新开始对OP-TEE的访问。
- 具体可以在\ suspend_resume.sh\ 当中的\ bash suspend-action.sh\ 前关闭服务,在\ bash resume-action.sh\ 后重新启动服务。
当设备要进行Acore下电(Acore Reset)时,需要确保Acore侧发出的对HSM的请求,已经被HSM全部处理完成。可参考地平线提供的解决方案。
这部分功能在地平线提供的电源管理方案中,已经默认支持,不需要客户进行适配。该场景下,如果客户有自己的定制化方案,需要特别关注。
对于使用HSM做密钥协商的用户需要注意。
在休眠前,如果用户程序使用HSM协商出来了密钥,经过唤醒后,该密钥不可再次使用,需要重新协商密钥。
客户如果未使用HSM做密钥协商,例如使用openssl软件做密钥协商,可以忽略此项休眠唤醒的影响。