264 lines
6.5 KiB
C
264 lines
6.5 KiB
C
#include <inttypes.h>
|
|
#include "operations.h"
|
|
#include "key_pair.h"
|
|
|
|
static char* storeNext(
|
|
TEE_ObjectHandle kp,
|
|
uint32_t attribute_id,
|
|
char *curr, const char * const end)
|
|
{
|
|
TEE_Result res;
|
|
uint32_t attribute_sz;
|
|
|
|
if (curr == NULL)
|
|
return NULL;
|
|
|
|
TEE_GetObjectBufferAttribute(kp, attribute_id, NULL, &attribute_sz);
|
|
if (curr + sizeof(uint32_t) + attribute_sz > end)
|
|
return NULL;
|
|
|
|
EMSG("[INFO] -->> attr_size %u\n", attribute_sz);
|
|
|
|
// store attribute size
|
|
curr[0] = attribute_sz & 0xFF;
|
|
curr[1] = attribute_sz >> 8 & 0xFF;
|
|
curr[2] = attribute_sz >> 16 & 0xFF;
|
|
curr[3] = attribute_sz >> 24 & 0xFF;
|
|
|
|
curr += sizeof(uint32_t); // move pointer
|
|
|
|
res = TEE_GetObjectBufferAttribute(kp, attribute_id, curr, &attribute_sz);
|
|
if (res != TEE_SUCCESS)
|
|
return NULL;
|
|
|
|
return curr + attribute_sz;
|
|
}
|
|
|
|
static char* readNext(
|
|
TEE_Attribute *key_attr,
|
|
uint32_t attribute_id,
|
|
char *curr, const char * const end)
|
|
{
|
|
if (curr > end || curr == NULL)
|
|
return NULL;
|
|
|
|
uint32_t attribute_sz = curr[3] <<24 | curr[2] <<16 | curr[1] <<8 | curr[0];
|
|
EMSG("[INFO] <<-- attr_size %u\n", attribute_sz);
|
|
curr += sizeof(uint32_t); // move pointer
|
|
|
|
TEE_InitRefAttribute(key_attr, attribute_id, curr, attribute_sz);
|
|
|
|
return curr + attribute_sz;
|
|
}
|
|
|
|
TEE_Result kp_create(
|
|
TEE_ObjectHandle *kp)
|
|
{
|
|
const uint32_t key_type = TEE_TYPE_RSA_KEYPAIR;
|
|
const uint32_t key_size = 1024; // fast calculations
|
|
|
|
TEE_Result res;
|
|
TEE_ObjectHandle key = NULL;
|
|
|
|
res = TEE_AllocateTransientObject(
|
|
key_type, key_size,
|
|
&key);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_create: TEE_AllocateTransientObject(%#" PRIx32 ", %" PRId32 "): %#" PRIx32, key_type, key_size, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_GenerateKey(
|
|
key, key_size,
|
|
NULL, 0);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_create: TEE_GenerateKey(%" PRId32 "): %#" PRIx32, key_size, res);
|
|
goto exit;
|
|
}
|
|
|
|
*kp = key;
|
|
key = NULL;
|
|
|
|
exit:
|
|
if (key)
|
|
TEE_FreeTransientObject(key);
|
|
|
|
return res;
|
|
}
|
|
|
|
TEE_Result kp_serialize(
|
|
TEE_ObjectHandle kp,
|
|
char *serilized, uint32_t *serilized_sz)
|
|
{
|
|
char *curr = serilized;
|
|
char *end = serilized + *serilized_sz;
|
|
|
|
curr = storeNext(kp, TEE_ATTR_RSA_MODULUS , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_PUBLIC_EXPONENT , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_PRIVATE_EXPONENT, curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_PRIME1 , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_PRIME2 , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_EXPONENT1 , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_EXPONENT2 , curr, end);
|
|
curr = storeNext(kp, TEE_ATTR_RSA_COEFFICIENT , curr, end);
|
|
|
|
if (curr == NULL)
|
|
return TEE_ERROR_OVERFLOW;
|
|
|
|
*serilized_sz = curr - serilized;
|
|
|
|
return TEE_SUCCESS;
|
|
}
|
|
|
|
TEE_Result kp_deserialize(
|
|
char *serilized, uint32_t serilized_sz,
|
|
TEE_ObjectHandle *kp)
|
|
{
|
|
TEE_Result res;
|
|
TEE_Attribute key_attr[8];
|
|
uint32_t key_attr_count = 8;
|
|
|
|
TEE_ObjectHandle transient_kp = NULL;
|
|
const uint32_t key_type = TEE_TYPE_RSA_KEYPAIR;
|
|
const uint32_t key_size = 1024; // fast calculations
|
|
|
|
char *curr = serilized;
|
|
char *curr_end = serilized + serilized_sz;
|
|
|
|
curr = readNext(&key_attr[0], TEE_ATTR_RSA_MODULUS , curr, curr_end);
|
|
curr = readNext(&key_attr[1], TEE_ATTR_RSA_PUBLIC_EXPONENT , curr, curr_end);
|
|
curr = readNext(&key_attr[2], TEE_ATTR_RSA_PRIVATE_EXPONENT, curr, curr_end);
|
|
curr = readNext(&key_attr[3], TEE_ATTR_RSA_PRIME1 , curr, curr_end);
|
|
curr = readNext(&key_attr[4], TEE_ATTR_RSA_PRIME2 , curr, curr_end);
|
|
curr = readNext(&key_attr[5], TEE_ATTR_RSA_EXPONENT1 , curr, curr_end);
|
|
curr = readNext(&key_attr[6], TEE_ATTR_RSA_EXPONENT2 , curr, curr_end);
|
|
curr = readNext(&key_attr[7], TEE_ATTR_RSA_COEFFICIENT , curr, curr_end);
|
|
|
|
if (curr == NULL) {
|
|
res = TEE_ERROR_OVERFLOW;
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_AllocateTransientObject(
|
|
key_type, key_size,
|
|
&transient_kp);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_deserialize(): TEE_AllocateTransientObject(%#" PRIx32 ", %" PRId32 "): %#" PRIx32, key_type, key_size, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_PopulateTransientObject(
|
|
transient_kp,
|
|
key_attr, key_attr_count);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR]: kp_deserialize(): TEE_PopulateTransientObject: 0x%x", res);
|
|
goto exit;
|
|
}
|
|
|
|
*kp = transient_kp;
|
|
transient_kp = NULL;
|
|
|
|
exit:
|
|
if (transient_kp)
|
|
TEE_FreeTransientObject(transient_kp);
|
|
return res;
|
|
}
|
|
|
|
TEE_Result kp_encrypt(
|
|
TEE_ObjectHandle kp,
|
|
void *inbuf, uint32_t inbuf_sz,
|
|
void *outbuf, uint32_t *outbuf_sz)
|
|
{
|
|
const uint32_t alg = TEE_ALG_RSAES_PKCS1_V1_5;
|
|
|
|
TEE_Result res;
|
|
TEE_OperationHandle op = NULL;
|
|
TEE_ObjectInfo key_info;
|
|
|
|
res = TEE_GetObjectInfo1(kp, &key_info);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_GetObjectInfo1: %#" PRIx32, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_AllocateOperation(
|
|
&op,
|
|
alg, TEE_MODE_ENCRYPT,
|
|
key_info.keySize);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_AllocateOperation(TEE_MODE_ENCRYPT, %#" PRIx32 ", %" PRId32 "): %#" PRIx32, alg, key_info.keySize, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_SetOperationKey(op, kp);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_SetOperationKey: %#" PRIx32, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_AsymmetricEncrypt(
|
|
op,
|
|
NULL, 0,
|
|
inbuf, inbuf_sz,
|
|
outbuf, outbuf_sz);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_AsymmetricEncrypt(%u, %u): 0x%x", inbuf_sz, *outbuf_sz, res);
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
if (op)
|
|
TEE_FreeOperation(op);
|
|
|
|
return res;
|
|
}
|
|
|
|
TEE_Result kp_decrypt(
|
|
TEE_ObjectHandle kp,
|
|
void *inbuf, uint32_t inbuf_sz,
|
|
void *outbuf, uint32_t *outbuf_sz)
|
|
{
|
|
const uint32_t alg = TEE_ALG_RSAES_PKCS1_V1_5;
|
|
|
|
TEE_Result res;
|
|
TEE_OperationHandle op = NULL;
|
|
TEE_ObjectInfo key_info;
|
|
|
|
res = TEE_GetObjectInfo1(kp, &key_info);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_GetObjectInfo1: %#" PRIx32, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_AllocateOperation(
|
|
&op,
|
|
alg, TEE_MODE_DECRYPT,
|
|
key_info.keySize);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_AllocateOperation(TEE_MODE_DECRYPT, %#" PRIx32 ", %" PRId32 "): %#" PRIx32, alg, key_info.keySize, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_SetOperationKey(op, kp);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_SetOperationKey: %#" PRIx32, res);
|
|
goto exit;
|
|
}
|
|
|
|
res = TEE_AsymmetricDecrypt(
|
|
op,
|
|
NULL, 0,
|
|
inbuf, inbuf_sz,
|
|
outbuf, outbuf_sz);
|
|
if (res != TEE_SUCCESS) {
|
|
EMSG("[ERR] kp_encrypt: TEE_AsymmetricEncrypt(%u, %u): 0x%x", inbuf_sz, *outbuf_sz, res);
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
if (op)
|
|
TEE_FreeOperation(op);
|
|
|
|
return res;
|
|
}
|