天天看點

[optee]-TA的簽名和驗簽

TA簽名驗簽

        • 1、TA的簽名
        • 2、TA的驗簽

★★★ 友情連結 : 個人部落格導讀首頁—點選此處 ★★★

1、TA的簽名

在optee或sdk的目錄下,有一個default_ta.pem(RSA2048 priv key)和sign.py簽名腳本. 在編譯TA結束後,會使用這個腳本和key對TA進行簽名…

  • export-ta_arm64/keys/default_ta.pem
  • export-ta_arm64/scripts/sign.py

在編譯TA時,會調用到TA中的link.mk, 在該檔案檔案中可以看到rsakey和簽名腳本sign.py的引用和makefile的依賴關系.

  • xxx.elf 是編譯後的二進制檔案
  • xxx.dump 是dump檔案
  • xxx.stripped.elf 是删除符号表的二進制檔案
  • xxxx.ta 是簽名後的檔案
(export-ta_arm64/mk/link.mk_

SIGN = $(TA_DEV_KIT_DIR)/scripts/sign.py
TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
......
$(link-script-pp): $(link-script) $(MAKEFILE_LIST)
        @$(cmd-echo-silent) '  CPP     $@'
        $(q)mkdir -p $(dir $@)
        $(q)$(CPP$(sm)) -Wp,-P,-MT,$@,-MD,$(link-script-dep) \
                $(link-script-cppflags-$(sm)) $< > $@

$(link-out-dir)/$(binary).elf: $(objs) $(libdeps) $(link-script-pp)
        @$(cmd-echo-silent) '  LD      $@'
        $(q)$(LD$(sm)) $(ldargs-$(binary).elf) -o $@

$(link-out-dir)/$(binary).dmp: $(link-out-dir)/$(binary).elf
        @$(cmd-echo-silent) '  OBJDUMP $@'
        $(q)$(OBJDUMP$(sm)) -l -x -d $< > $@

$(link-out-dir)/$(binary).stripped.elf: $(link-out-dir)/$(binary).elf
        @$(cmd-echo-silent) '  OBJCOPY $@'
        $(q)$(OBJCOPY$(sm)) --strip-unneeded $< $@

$(link-out-dir)/$(binary).ta: $(link-out-dir)/$(binary).stripped.elf \
                                $(TA_SIGN_KEY)
        @echo '  SIGN    $@'
        $(q)$(SIGN) --key $(TA_SIGN_KEY) --uuid $(binary) --version 0 \
           

2、TA的驗簽

在編譯optee_os時,pem_to_pub_c.py腳本中将default_ta.pem中解析出der格式rsa_pub公鑰,放到了ta_pub_key.c檔案的ta_pub_key_modulus數組中

(optee_os/core/sub.mk)
ifeq ($(CFG_WITH_USER_TA),y)
gensrcs-y += ta_pub_key
produce-ta_pub_key = ta_pub_key.c
depends-ta_pub_key = $(TA_SIGN_KEY) scripts/pem_to_pub_c.py
recipe-ta_pub_key = scripts/pem_to_pub_c.py --prefix ta_pub_key \
                --key $(TA_SIGN_KEY) --out $(sub-dir-out)/ta_pub_key.c
cleanfiles += $(sub-dir-out)/ta_pub_key.c
endif
           

ta_pub_key.c檔案是生成在out目錄的,編譯的時候會引用到.

cat ./optee_os/out/arm-plat-xxxx/core/ta_pub_key.c

#include <stdint.h>
#include <stddef.h>

const uint32_t ta_pub_key_exponent = 65537;

const uint8_t ta_pub_key_modulus[] = {
0xa6, 0x5a, 0x18, 0xad, 0xc0, 0xb3, 0xce, 0xe3,
0x0c, 0x90, 0x2b, 0x7d, 0x40, 0x9b, 0xac, 0xbb,
0x5a, 0x49, 0x88, 0x42, 0x0a, 0xb1, 0xe0, 0x92,
0xc0, 0x86, 0x91, 0xe6, 0x9e, 0xef, 0xa0, 0xe1,
0xf1, 0x2f, 0x90, 0xf6, 0x66, 0xdd, 0xea, 0x15,
0x5a, 0xc0, 0x28, 0xb4, 0x9d, 0xdf, 0x52, 0x0c,
0x6e, 0xa5, 0xc6, 0x19, 0x43, 0xac, 0x69, 0xa8,
0xf2, 0x5f, 0xfe, 0x60, 0x00, 0xa5, 0xd2, 0x3a,
0xcc, 0x12, 0x01, 0xf3, 0x5b, 0xba, 0x0c, 0x51,
0x1c, 0x2c, 0xf4, 0xb0, 0x77, 0xb9, 0xd6, 0x72,
0x35, 0x1c, 0x0f, 0x73, 0xcd, 0x2f, 0x16, 0xf9,
0xba, 0x89, 0x84, 0xa0, 0x9b, 0xbf, 0x8b, 0x5b,
0x7f, 0xe8, 0x8b, 0x8b, 0x9f, 0xc8, 0x71, 0xea,
0x1c, 0x6c, 0x1f, 0x00, 0xa0, 0xee, 0xca, 0x3e,
0xbf, 0x18, 0x8e, 0x57, 0x9b, 0x48, 0x66, 0xeb,
0x8b, 0xd4, 0x40, 0x51, 0xae, 0x86, 0xa1, 0x86,
0xf8, 0xd0, 0x0b, 0xfa, 0xb6, 0x2e, 0x25, 0x2e,
0x05, 0xff, 0x76, 0x01, 0x46, 0xd7, 0x3d, 0xeb,
0x1f, 0x7c, 0xfc, 0xdf, 0x1e, 0x82, 0x8b, 0x5e,
0xb0, 0xca, 0xa3, 0xea, 0x16, 0xbe, 0x2d, 0x6e,
0x54, 0x50, 0x9c, 0xb8, 0x41, 0xef, 0x17, 0xc7,
0x7f, 0x60, 0x54, 0xaa, 0xf9, 0x70, 0xa0, 0xf8,
0x98, 0x2e, 0x82, 0xf9, 0x8c, 0x5f, 0xfb, 0x9c,
0x88, 0x8e, 0x77, 0xb0, 0x32, 0x72, 0x99, 0x1a,
0xe0, 0x04, 0x5e, 0xbf, 0x1d, 0xaa, 0xf7, 0xf0,
0x05, 0x3c, 0xb4, 0x95, 0xdd, 0x4d, 0xba, 0x3a,
0x71, 0xa1, 0xf8, 0x72, 0x8e, 0x1d, 0x98, 0xe3,
0x13, 0xba, 0xca, 0xb0, 0x27, 0xbf, 0x87, 0x59,
0x54, 0x27, 0xf8, 0xe8, 0xec, 0xc6, 0x85, 0x37,
0xd2, 0x3a, 0x95, 0xe4, 0xa5, 0x09, 0x9a, 0xd0,
0x1f, 0xa3, 0x86, 0xb0, 0x92, 0xd8, 0x02, 0x1e,
0x33, 0x75, 0xdb, 0x26, 0xbf, 0x27, 0xfc, 0x35,
};
const size_t ta_pub_key_modulus_size = sizeof(ta_pub_key_modulus);
           

在open_ta時,會調用到shdr_verify_signature對TA進行驗簽。我們可以看到在crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size,

key.n)中讀取了公鑰數組,然後調用rsa_verify

TEE_Result shdr_verify_signature(const struct shdr *shdr)
{
	struct rsa_public_key key;
	TEE_Result res;
	uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent);
	size_t hash_size;

	if (shdr->magic != SHDR_MAGIC)
		return TEE_ERROR_SECURITY;

	if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA)
		return TEE_ERROR_SECURITY;

	res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(shdr->algo),
				       &hash_size);
	if (res)
		return TEE_ERROR_SECURITY;
	if (hash_size != shdr->hash_size)
		return TEE_ERROR_SECURITY;

	res = crypto_acipher_alloc_rsa_public_key(&key, shdr->sig_size);
	if (res)
		return TEE_ERROR_SECURITY;

	res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e);
	if (res)
		goto out;
	res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size,
				   key.n);
	if (res)
		goto out;

	res = crypto_acipher_rsassa_verify(shdr->algo, &key, -1,
					   SHDR_GET_HASH(shdr), shdr->hash_size,
					   SHDR_GET_SIG(shdr), shdr->sig_size);
out:
	crypto_acipher_free_rsa_public_key(&key);
	if (res)
		return TEE_ERROR_SECURITY;
	return TEE_SUCCESS;
}
           

繼續閱讀