#include #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; }