ta trieu rsa
Huongnm
c_cpp
a month ago
7.0 kB
6
Indexable
#include <tee_internal_api.h>
#include <string.h>
#include <stdio.h>
#include "TA.h"
// Biến toàn cục lưu giữ Handle của cặp khóa RSA bên trong TA
static TEE_ObjectHandle rsa_keypair = TEE_HANDLE_NULL;
TEE_Result TA_CreateEntryPoint(void)
{
TEE_Result res;
// 1. Cấp phát một Transient Object cho RSA Keypair
res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, 2048, &rsa_keypair);
if (res != TEE_SUCCESS) return res;
// 2. Tạo ngẫu nhiên cặp khóa RSA-2048
res = TEE_GenerateKey(rsa_keypair, 2048, NULL, 0);
if (res != TEE_SUCCESS) {
TEE_FreeTransientObject(rsa_keypair);
rsa_keypair = TEE_HANDLE_NULL;
}
return res;
}
void TA_DestroyEntryPoint(void)
{
if (rsa_keypair != TEE_HANDLE_NULL) {
TEE_FreeTransientObject(rsa_keypair);
}
}
TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes,
TEE_Param params[4], void **sessionContext)
{
(void) paramTypes;
(void) params;
(void) sessionContext;
return TEE_SUCCESS;
}
void TA_CloseSessionEntryPoint(void *sessionContext)
{
(void) sessionContext;
}
static void create_obj_id(PasswordEntry *e, char *obj_id, size_t *len){
// Ensure buffer is null-terminated
obj_id[0] = '\0';
// Ensure we don't overflow the buffer
size_t package_len = strlen(e->package_name);
size_t user_len = strlen(e->user_id);
size_t max_len = MAX_SIZE * 2 - 1; // Leave room for null terminator
// Truncate if strings are too long to fit with separator
if (package_len + user_len + 2 > max_len) { // +2 for '|' and '\0'
if (package_len > MAX_SIZE - 1) package_len = MAX_SIZE - 1;
if (user_len > MAX_SIZE - 1) user_len = MAX_SIZE - 1;
// Ensure total fits
if (package_len + user_len + 2 > max_len) {
// Reduce the longer one
if (package_len > user_len) {
package_len = max_len - user_len - 2;
} else {
user_len = max_len - package_len - 2;
}
}
}
snprintf(obj_id, MAX_SIZE * 2, "%.*s|%.*s",
(int)package_len, e->package_name,
(int)user_len, e->user_id);
obj_id[MAX_SIZE * 2 - 1] = '\0'; // Ensure null termination
*len = strlen(obj_id);
}
TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext,
uint32_t commandID, uint32_t paramTypes, TEE_Param params[4])
{
(void) sessionContext;
(void) commandID;
if (paramTypes != TEE_PARAM_TYPES(
TEE_PARAM_TYPE_MEMREF_INOUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE)) {
/* Bad parameter types */
return TEE_ERROR_BAD_PARAMETERS;
}
PasswordEntry *entry = (PasswordEntry *)params[0].memref.buffer;
uint32_t entry_size = params[0].memref.size;
TEE_ObjectHandle object;
TEE_Result res;
char obj_id[MAX_SIZE * 2];
size_t obj_id_len;
switch (commandID)
{
case CMD_GET_PUBLIC_KEY:
// Kiểm tra tham số đầu ra (Memref để chứa Modulus N)
if (paramTypes != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)) {
return TEE_ERROR_BAD_PARAMETERS;
}
if (params[0].memref.size < RSA_2048_KEY_SIZE) return TEE_ERROR_SHORT_BUFFER;
// Trích xuất Modulus (N) từ cặp khóa RSA để gửi cho CA
uint32_t exp_size = params[0].memref.size;
res = TEE_GetObjectAttributeBuffer(rsa_keypair, TEE_ATTR_RSA_MODULUS, params[0].memref.buffer, &exp_size);
params[0].memref.size = exp_size;
return res;
case CMD_SAVE_PASSWORD:
if (paramTypes != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)) {
return TEE_ERROR_BAD_PARAMETERS;
}
// Nhận struct đã bị mã hóa từ Shared Memory
EncryptedPasswordEntry *enc_entry = (EncryptedPasswordEntry *)params[0].memref.buffer;
// Tạo một cấu trúc PasswordEntry (Plaintext) trên Stack của TA để chuẩn bị giải mã vào đó
PasswordEntry plain_entry;
memset(&plain_entry, 0, sizeof(PasswordEntry));
memcpy(plain_entry.package_name, enc_entry->package_name, MAX_SIZE);
memcpy(plain_entry.user_id, enc_entry->user_id, MAX_SIZE);
// Tiến hành giải mã RSA dữ liệu password
TEE_OperationHandle op;
res = TEE_AllocateOperation(&op, TEE_ALG_RSAES_PKCS1_V1_5, TEE_MODE_DECRYPT, 2048);
if (res != TEE_SUCCESS) return res;
res = TEE_SetOperationKey(op, rsa_keypair);
if (res != TEE_SUCCESS) { TEE_FreeOperation(op); return res; }
size_t decrypted_len = MAX_SIZE - 1;
res = TEE_AsymmetricDecrypt(op, NULL, 0,
enc_entry->encrypted_password, RSA_2048_KEY_SIZE,
plain_entry.password, &decrypted_len);
TEE_FreeOperation(op);
if (res != TEE_SUCCESS) {
printf("TA Decryption failed: 0x%x\n", res);
return res;
}
plain_entry.password[decrypted_len] = '\0'; // Đảm bảo null-terminated
// Tạo Object ID dựa trên dữ liệu đã giải mã
create_obj_id(&plain_entry, obj_id, &obj_id_len);
// Lưu bản rõ (plain_entry) vào Secure Storage của TEE
res = TEE_CreatePersistentObject(
TEE_STORAGE_PRIVATE,
obj_id, obj_id_len,
TEE_DATA_FLAG_ACCESS_WRITE | TEE_DATA_FLAG_OVERWRITE,
TEE_HANDLE_NULL,
&plain_entry, sizeof(PasswordEntry),
&object
);
if (res == TEE_SUCCESS) {
TEE_CloseObject(object);
}
return res;
case CMD_CALL_PASSWORD:
create_obj_id(entry, obj_id, &obj_id_len);
/**
TEE_Result TEE_OpenPersistentObject(
uint32_t storageID,
[in(objectIDLength)] void* objectID, size_t objectIDLen,
uint32_t flags,
[out] TEE_ObjectHandle* object);
**/
res = TEE_OpenPersistentObject(
TEE_STORAGE_PRIVATE,
obj_id, obj_id_len,
TEE_DATA_FLAG_ACCESS_READ,
&object
);
if(res != TEE_SUCCESS){
printf("open persistent object fail\n");
return res;
} else {
printf("open persistent object success\n");
}
// Use stack buffer instead of struct to avoid memory access issues
char buffer[MAX_SIZE * 3]; // Enough space for the PasswordEntry struct
if (entry_size > sizeof(buffer)) {
TEE_CloseObject(object);
return TEE_ERROR_OVERFLOW;
}
size_t count;
/**
TEE_Result TEE_ReadObjectData(
TEE_ObjectHandle object,
[out] void* buffer,
size_t size,
[out] size_t* count
**/
res = TEE_ReadObjectData(object, buffer, entry_size, &count);
if(res != TEE_SUCCESS) {
printf("read object data fail: 0x%x\n", res);
} else {
printf("read object data success\n");
// Copy data back to entry struct
memcpy(entry, buffer, count);
}
TEE_CloseObject(object);
return res;
default:
return TEE_ERROR_NOT_SUPPORTED;
}
}
Editor is loading...
Leave a Comment