-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libptateec: manufacturing protection PTA #352
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
project(ptateec | ||
VERSION 0.1.0 | ||
LANGUAGES C) | ||
|
||
################################################################################ | ||
# Packages | ||
################################################################################ | ||
find_package(Threads REQUIRED) | ||
if(NOT THREADS_FOUND) | ||
message(FATAL_ERROR "Threads not found") | ||
endif() | ||
|
||
include(GNUInstallDirs) | ||
|
||
################################################################################ | ||
# Source files | ||
################################################################################ | ||
set (SRC | ||
src/pta.c | ||
src/pta_imx_manufacturing_protection.c | ||
) | ||
|
||
################################################################################ | ||
# Built library | ||
################################################################################ | ||
add_library (ptateec ${SRC}) | ||
|
||
set_target_properties (ptateec PROPERTIES | ||
VERSION ${PROJECT_VERSION} | ||
SOVERSION ${PROJECT_VERSION_MAJOR} | ||
) | ||
|
||
################################################################################ | ||
# Flags always set | ||
################################################################################ | ||
target_compile_definitions (ptateec | ||
PRIVATE -D_GNU_SOURCE | ||
PRIVATE -DBINARY_PREFIX="LT" | ||
) | ||
|
||
################################################################################ | ||
# Optional flags | ||
################################################################################ | ||
|
||
################################################################################ | ||
# Public and private header and library dependencies | ||
################################################################################ | ||
target_include_directories(ptateec | ||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
$<INSTALL_INTERFACE:include> | ||
PRIVATE src | ||
) | ||
|
||
target_link_libraries (ptateec | ||
PRIVATE pthread | ||
PRIVATE teec | ||
) | ||
|
||
################################################################################ | ||
# Install targets | ||
################################################################################ | ||
install (TARGETS ptateec | ||
DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
) | ||
|
||
add_subdirectory(include) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
include ../flags.mk | ||
include ../config.mk | ||
|
||
OUT_DIR := $(OO)/libptateec | ||
|
||
.PHONY: all libptateec clean | ||
|
||
all: libptateec | ||
install: libptateec | ||
|
||
LIB_NAME := libptateec | ||
MAJOR_VERSION := 0 | ||
MINOR_VERSION := 1 | ||
PATCH_VERSION := 0 | ||
|
||
LIB_MAJOR := $(LIB_NAME).so.$(MAJOR_VERSION) | ||
LIB_MAJ_MIN := $(LIB_NAME).so.$(MAJOR_VERSION).$(MINOR_VERSION) | ||
LIB_MAJ_MIN_PAT := $(LIB_NAME).so.$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION) | ||
LIBPTATEEC_SO_LIBRARY := $(LIB_MAJ_MIN_PAT) | ||
LIBPTATEEC_AR_LIBRARY := $(LIB_NAME).a | ||
|
||
LIBPTATEEC_SRC_DIR := src | ||
|
||
LIBPTATEEC_SRCS = pta.c \ | ||
pta_imx_manufacturing_protection.c | ||
|
||
LIBPTATEEC_INCLUDES = ${CURDIR}/include | ||
LIBPTATEEC_INCLUDES += ${CURDIR}/../public | ||
|
||
LIBPTATEEC_CFLAGS := $(addprefix -I, $(LIBPTATEEC_INCLUDES)) \ | ||
$(CFLAGS) -D_GNU_SOURCE -fPIC | ||
|
||
LIBPTATEEC_LFLAGS := $(LDFLAGS) -L$(OUT_DIR)/../libteec -lteec -lpthread | ||
|
||
LIBPTATEEC_OBJ_DIR := $(OUT_DIR) | ||
LIBPTATEEC_OBJS := $(patsubst %.c,$(LIBPTATEEC_OBJ_DIR)/%.o, $(LIBPTATEEC_SRCS)) | ||
|
||
$(LIBPTATEEC_OBJ_DIR)/%.o: ${LIBPTATEEC_SRC_DIR}/%.c | ||
$(VPREFIX)mkdir -p $(LIBPTATEEC_OBJ_DIR) | ||
@echo " CC $<" | ||
$(VPREFIX)$(CC) $(LIBPTATEEC_CFLAGS) -c $< -o $@ | ||
|
||
libptateec: $(OUT_DIR)/$(LIBPTATEEC_SO_LIBRARY) | ||
|
||
$(OUT_DIR)/$(LIBPTATEEC_SO_LIBRARY): $(LIBPTATEEC_OBJS) | ||
@echo " LINK $@" | ||
$(VPREFIX)$(CC) -shared -Wl,-soname,$(LIB_MAJOR) -o $@ $+ $(LIBPTATEEC_LFLAGS) | ||
@echo "" | ||
|
||
libptateec: $(OUT_DIR)/$(LIBPTATEEC_AR_LIBRARY) | ||
|
||
$(OUT_DIR)/$(LIBPTATEEC_AR_LIBRARY): $(LIBPTATEEC_OBJS) | ||
@echo " AR $@" | ||
$(VPREFIX)$(AR) rcs $@ $+ | ||
|
||
libptateec: | ||
$(VPREFIX)ln -sf $(LIB_MAJ_MIN_PAT) $(OUT_DIR)/$(LIB_MAJ_MIN) | ||
$(VPREFIX)ln -sf $(LIB_MAJ_MIN) $(OUT_DIR)/$(LIB_MAJOR) | ||
$(VPREFIX)ln -sf $(LIB_MAJOR) $(OUT_DIR)/$(LIB_NAME).so | ||
|
||
################################################################################ | ||
# Cleaning up configuration | ||
################################################################################ | ||
clean: | ||
$(RM) $(LIBPTATEEC_OBJS) | ||
$(RM) $(OUT_DIR)/$(LIB_MAJ_MIN_PAT) | ||
$(RM) $(OUT_DIR)/$(LIB_MAJ_MIN) | ||
$(RM) $(OUT_DIR)/$(LIB_MAJOR) | ||
$(RM) $(OUT_DIR)/$(LIBPTATEEC_SO_LIBRARY) | ||
$(RM) $(OUT_DIR)/$(LIBPTATEEC_AR_LIBRARY) | ||
$(call rmdir,$(OUT_DIR)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
project (libptateec-headers C) | ||
|
||
FILE(GLOB INSTALL_HEADERS "*.h") | ||
|
||
add_library(${PROJECT_NAME} INTERFACE) | ||
|
||
install (FILES ${INSTALL_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* SPDX-License-Identifier: BSD-2-Clause */ | ||
/* | ||
* Copyright (c) 2023, Foundries.io | ||
*/ | ||
|
||
#ifndef PTA_TEE_H | ||
#define PTA_TEE_H | ||
|
||
#include <tee_client_api.h> | ||
#include <unistd.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* pta_imx_mprotect_get_key() - Retrieves the iMX CAAM Manufacturing Protection | ||
* EC public key. The components x,y are retrieved in RAW format and should | ||
* be converted to DER or PEM as required. | ||
* | ||
* For the 256 bit curve, this will generate two 32 byte components therefore | ||
* requiring at least a 64 byte buffer. | ||
* | ||
* @key: [out] Public key in RAW format. | ||
* @len: [in/out] Key length in bytes. | ||
* | ||
* @return TEEC_ERROR_BAD_PARAMETERS Invalid parameters provided on input. | ||
* @return TEEC_ERROR_ACCESS_DENIED Error opening the TEE session. | ||
* @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. | ||
* @return TEEC_ERROR_GENERIC Error unspecified. | ||
* @return TEEC_ERROR_SHORT_BUFFER Error small buffer provided. | ||
* @return TEEC_ERROR_COMMUNICATION Some other thread closed the connection. | ||
* @return TEEC_SUCCESS On success. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe add |
||
* | ||
*/ | ||
TEEC_Result pta_imx_mprotect_get_key(char *key, size_t *len); | ||
|
||
/** | ||
* pta_imx_mprotect_sign() - Signs a message using the Manufacturing Protection | ||
* EC private key. | ||
* | ||
* This function takes message data as input and outputs a signature over a | ||
* message composed of the content of the MPMR, followed by the input-data | ||
* message. | ||
* | ||
* @message: [in] Message to sign. | ||
* @mlen: [in] Message length in bytes. | ||
* @signature: [out] Generated signature. | ||
* @slen: [in/out] Signature length in bytes. | ||
* @mpmr: [out] MPMR data. | ||
* @len: [in/out] MPMR length in bytes. | ||
* | ||
* @return TEEC_ERROR_BAD_PARAMETERS Invalid parameters provided on input. | ||
* @return TEEC_ERROR_ACCESS_DENIED Error opening the TEE session. | ||
* @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. | ||
* @return TEEC_ERROR_GENERIC Error unspecified. | ||
* @return TEEC_ERROR_COMMUNICATION Some other thread closed the connection. | ||
* @return TEEC_ERROR_SHORT_BUFFER Error small buffer provided. | ||
* @return TEEC_SUCCESS On success. | ||
* | ||
*/ | ||
TEEC_Result pta_imx_mprotect_sign(char *message, size_t mlen, char *signature, | ||
size_t *slen, char *mpmr, size_t *len); | ||
|
||
/** | ||
* pta_imx_mprotect_final() - Closes the OP-TEE session | ||
* | ||
* This function may fail with TEEC_ERROR_BUSY if there are unfulfilled calls | ||
* pending. | ||
* | ||
* @return TEEC_ERROR_BUSY PTA is still in use. | ||
* @return TEEC_SUCCESS On success. | ||
* | ||
*/ | ||
TEEC_Result pta_imx_mprotect_final(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /*PTA_TEE_H*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// SPDX-License-Identifier: BSD-2-Clause | ||
/* | ||
* Copyright (c) 2023, Foundries.io Ltd | ||
*/ | ||
|
||
#ifndef BINARY_PREFIX | ||
#define BINARY_PREFIX "ptateec" | ||
#endif | ||
|
||
#include "pta.h" | ||
|
||
TEEC_Result pta_open_session(struct pta_context *ctx) | ||
{ | ||
TEEC_Result ret = TEEC_SUCCESS; | ||
|
||
pthread_mutex_lock(&ctx->lock); | ||
if (!ctx->open) { | ||
ret = TEEC_InitializeContext(NULL, &ctx->context); | ||
if (!ret) { | ||
ret = TEEC_OpenSession(&ctx->context, &ctx->session, | ||
&ctx->uuid, TEEC_LOGIN_PUBLIC, | ||
NULL, NULL, NULL); | ||
if (!ret) | ||
ctx->open = true; | ||
} | ||
} | ||
if (ctx->open) | ||
atomic_fetch_add(&ctx->count, 1); | ||
pthread_mutex_unlock(&ctx->lock); | ||
|
||
return ret; | ||
} | ||
|
||
TEEC_Result pta_invoke_cmd(struct pta_context *ctx, uint32_t cmd_id, | ||
TEEC_Operation *op, uint32_t *error_origin) | ||
{ | ||
TEEC_Result ret = TEEC_SUCCESS; | ||
|
||
pthread_mutex_lock(&ctx->lock); | ||
if (!ctx->open) { | ||
atomic_store(&ctx->count, 0); | ||
pthread_mutex_unlock(&ctx->lock); | ||
|
||
return TEEC_ERROR_COMMUNICATION; | ||
} | ||
pthread_mutex_unlock(&ctx->lock); | ||
ret = TEEC_InvokeCommand(&ctx->session, cmd_id, op, error_origin); | ||
atomic_fetch_sub(&ctx->count, 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This means 1 call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If so, I think there is no need to have 2 functions. A single call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I think it's a bit weird that a generic PTA invocation API requires each call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this session handling is a bit more complicated than needed with mutex and reference counter. Couldn't we skip it all and rely on the normal TEE Client primitives? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO being capable of rejecting a close request coming from some separate thread because an invoke is about to follow is a nice feature to have (it really only costs the mutex and reference counter and it has no impact on performance). But sure I can remove it if you think it adds too much maintenance noise. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove it then. |
||
|
||
return ret; | ||
} | ||
|
||
TEEC_Result pta_final(struct pta_context *ctx) | ||
{ | ||
TEEC_Result ret = TEEC_SUCCESS; | ||
|
||
pthread_mutex_lock(&ctx->lock); | ||
if (!ctx->open) { | ||
pthread_mutex_unlock(&ctx->lock); | ||
return TEEC_SUCCESS; | ||
} | ||
|
||
if (atomic_load(&ctx->count)) { | ||
ret = TEEC_ERROR_BUSY; | ||
} else { | ||
TEEC_CloseSession(&ctx->session); | ||
TEEC_FinalizeContext(&ctx->context); | ||
ctx->open = false; | ||
} | ||
pthread_mutex_unlock(&ctx->lock); | ||
|
||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you describe the arguments?