rust-libteec 0.4.5

Rust implementation of TEE Client API for secure communication with Trusted Applications.
Documentation
CC := gcc

TASIGN_TOOL ?= $(shell which tasign-tool 2>/dev/null || echo "~/.cargo/bin/tasign-tool")
SIGN_ALGORITHM ?= sm2-sm3
LEAF_CERT ?= TEST
INTERMEDIATE_CERT ?= TEST
INTERMEDIATE_COUNT ?= 1
LEAF_KEY ?= TEST
LEAF_KEY_PASS ?= TEST
SIGN_OUTPUT_DIR ?= signed

DEBUG ?= 0

# Android cross-compilation configuration (ANDROID_API_LEVEL, ANDROID_TARGET inherited from parent Makefile)
ANDROID_CC := $(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/linux-x86_64/bin/$(ANDROID_TARGET)$(ANDROID_API_LEVEL)-clang
ANDROID_OBJCOPY := $(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy
ANDROID_LIB_DIR := $(CURDIR)/../target/$(ANDROID_TARGET)/release
ANDROID_SIGN_OUTPUT_DIR := signed-android

CC_TEEC_TARGET := cc-teec
TARGETS := $(CC_TEEC_TARGET)

TEE_CLIENT_SRC := tee_client.c
CC_TEEC_SRCS := cc-teec.c $(TEE_CLIENT_SRC)
ALL_SRCS := $(CC_TEEC_SRCS)

INC_DIR := include

BASE_CFLAGS := \
	-I$(INC_DIR) \
	-D_GNU_SOURCE \
	-DBINARY_PREFIX=\"TEEC\" \
	-std=gnu11

# 安全编译选项
SECURITY_CFLAGS := \
	-Wall \
	-Werror \
	-Wextra \
	-Wformat-security \
	-Wstrict-prototypes \
	-Wshadow \
	-Wunused \
	-Wcast-align \
	-Wpointer-arith
	#-Wmissing-prototypes
	#-Wmissing-declarations

# 安全链接选项
SECURITY_LDFLAGS := \
	-Wl,--as-needed \
	-Wl,-z,relro \
	-Wl,-z,now \
	-Wl,-z,noexecstack \
	-Wl,--no-undefined \
	-Wl,--fatal-warnings

# 位置无关代码
PIE_CFLAGS := -fPIE -fpie
PIE_LDFLAGS := -pie

# 栈保护
STACK_PROTECTOR := -fstack-protector-strong

# 优化选项
ifeq ($(BUILD_MODE), release)
	OPTIMIZE_CFLAGS := -O2
	OPTIMIZE_LDFLAGS := -s
else
	OPTIMIZE_CFLAGS := -O0 -ggdb3
	OPTIMIZE_LDFLAGS := -g
endif

# 调试选项
ifeq ($(DEBUG), 1)
	DEBUG_CFLAGS := -g3
	DEBUG_LDFLAGS := -g
else
	DEBUG_CFLAGS :=
	DEBUG_LDFLAGS :=
endif

CFLAGS := \
	$(BASE_CFLAGS) \
	$(SECURITY_CFLAGS) \
	$(PIE_CFLAGS) \
	$(STACK_PROTECTOR) \
	$(OPTIMIZE_CFLAGS) \
	$(DEBUG_CFLAGS)

LDFLAGS := \
	$(PIE_LDFLAGS) \
	$(SECURITY_LDFLAGS) \
	$(OPTIMIZE_LDFLAGS) \
	$(DEBUG_LDFLAGS)

LIBS := -l$(RUST_LIB_NAME)

.PHONY: all
all: check-tasign $(TARGETS) sign-all

# 检查 tasign-tool 是否存在
.PHONY: check-tasign
check-tasign:
	@if [ ! -x "$(TASIGN_TOOL)" ]; then \
		echo "Error: tasign-tool not found at $(TASIGN_TOOL)"; \
		echo "Please install tasign-tool:"; \
		echo "  cargo install tasign --force"; \
		echo "Or set TASIGN_TOOL environment variable to the correct path"; \
		exit 1; \
	fi
	@echo "Using tasign-tool: $(TASIGN_TOOL)"

# 编译所有目标
$(CC_TEEC_TARGET): $(CC_TEEC_SRCS) $(RUST_TARGET_BUILD_DIR)/$(RUST_LIB_FILE)
	@RUST_LIB_PATH=$$(find $(RUST_TARGET_BUILD_DIR) -name "$(RUST_LIB_FILE)" 2>/dev/null | sort -r | head -1); \
	if [ -z "$$RUST_LIB_PATH" ]; then \
		echo "Error: Rust library $(RUST_LIB_FILE) not found in $(RUST_TARGET_BUILD_DIR)"; \
		echo "Please build the Rust library first: cd .. && cargo build --release"; \
		exit 1; \
	fi; \
	RUST_LIB_DIR=$$(dirname $$RUST_LIB_PATH); \
	echo "Using Rust library: $$RUST_LIB_PATH"; \
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -L$$RUST_LIB_DIR $(LIBS)

# 对所有目标进行签名
.PHONY: sign-all
sign-all: $(addprefix sign-,$(TARGETS))

# 签名单个目标
.PHONY: sign-%
sign-%: %
	@echo "Signing $<..."
	@# 如果已存在 .ta_signature section,先清理
	@if objdump -h $< | grep -q ".ta_signature"; then \
		echo "Removing existing .ta_signature section..."; \
		objcopy --remove-section .ta_signature $< $<.tmp && mv $<.tmp $<; \
	fi
	@mkdir -p $(SIGN_OUTPUT_DIR)/$<
	@$(TASIGN_TOOL) sign \
		--elf $< \
		--out-dir $(SIGN_OUTPUT_DIR)/$< \
		--leaf-cert $(LEAF_CERT) \
		--intermediate-cert $(INTERMEDIATE_CERT) \
		--intermediate-count $(INTERMEDIATE_COUNT) \
		--algorithm $(SIGN_ALGORITHM) \
		--leaf-key $(LEAF_KEY) \
		--leaf-key-pass $(LEAF_KEY_PASS)
	@$(TASIGN_TOOL) write-elf \
		--input-elf $< \
		--signature-bin $(SIGN_OUTPUT_DIR)/$</signature.bin \
		--output-elf $< \
		--objcopy objcopy
	@$(TASIGN_TOOL) verify-elf --elf $< --ca-cert $(LEAF_CERT) && \
		echo "✓ Successfully signed and verified: $<" || \
		(echo "✗ Signature verification failed for $<"; exit 1)

.PHONY: clean
clean:
	rm -rf $(TARGETS) $(SIGN_OUTPUT_DIR)

# Android cross-compilation targets
android-ndk-check:
	@if [ -z "$(ANDROID_NDK_HOME)" ]; then \
		echo "Error: ANDROID_NDK_HOME is not set. Please export ANDROID_NDK_HOME=/path/to/android-ndk-r29"; \
		exit 1; \
	fi

android: android-ndk-check
	@if [ ! -f "$(ANDROID_CC)" ]; then \
		echo "Error: NDK compiler not found at $(ANDROID_CC)"; \
		echo "Set ANDROID_NDK_HOME to your NDK installation path"; \
		exit 1; \
	fi
	@if [ ! -f "$(ANDROID_LIB_DIR)/$(RUST_LIB_FILE)" ]; then \
		echo "Error: $(RUST_LIB_FILE) not found at $(ANDROID_LIB_DIR)"; \
		echo "Build it first: cd .. && make android"; \
		exit 1; \
	fi
	@echo "Building for Android $(ANDROID_TARGET)..."
	$(ANDROID_CC) $(BASE_CFLAGS) $(SECURITY_CFLAGS) -fstack-protector-strong -fPIE -O2 \
		-I$(INC_DIR) -o $(CC_TEEC_TARGET) $(CC_TEEC_SRCS) \
		-L$(ANDROID_LIB_DIR) -Wl,-rpath,/vendor/lib64 -l$(RUST_LIB_NAME) -ldl
	@echo "Android build completed: $(CC_TEEC_TARGET)"

android-sign: android
	@echo "Signing $(CC_TEEC_TARGET) (Android)..."
	@if $(ANDROID_OBJCOPY) --dump-section .ta_signature=/dev/null $(CC_TEEC_TARGET) 2>/dev/null; then \
		echo "Removing existing .ta_signature section..."; \
		$(ANDROID_OBJCOPY) --remove-section .ta_signature $(CC_TEEC_TARGET) $(CC_TEEC_TARGET).tmp && mv $(CC_TEEC_TARGET).tmp $(CC_TEEC_TARGET); \
	fi
	@mkdir -p $(ANDROID_SIGN_OUTPUT_DIR)/$(CC_TEEC_TARGET)
	@$(TASIGN_TOOL) sign \
		--elf $(CC_TEEC_TARGET) \
		--out-dir $(ANDROID_SIGN_OUTPUT_DIR)/$(CC_TEEC_TARGET) \
		--leaf-cert $(LEAF_CERT) \
		--intermediate-cert $(INTERMEDIATE_CERT) \
		--intermediate-count $(INTERMEDIATE_COUNT) \
		--algorithm $(SIGN_ALGORITHM) \
		--leaf-key $(LEAF_KEY) \
		--leaf-key-pass $(LEAF_KEY_PASS)
	@$(TASIGN_TOOL) write-elf \
		--input-elf $(CC_TEEC_TARGET) \
		--signature-bin $(ANDROID_SIGN_OUTPUT_DIR)/$(CC_TEEC_TARGET)/signature.bin \
		--output-elf $(CC_TEEC_TARGET) \
		--objcopy $(ANDROID_OBJCOPY)
	@$(TASIGN_TOOL) verify-elf --elf $(CC_TEEC_TARGET) --ca-cert $(LEAF_CERT) && \
		echo "✓ Successfully signed and verified: $(CC_TEEC_TARGET) (Android)" || \
		(echo "✗ Signature verification failed for $(CC_TEEC_TARGET) (Android)"; exit 1)

.PHONY: all check-tasign sign-all sign-% clean \
        android-ndk-check android android-sign