#include <cmd_exec.h>
#include <cipher_ctx_list.h>
#include <log.h>
+#include <oqs/kem.h>
// random value to mark unsupported algorithm
#define KM_TA_ALG_AES_CFB 0x50005050
const uint32_t PBKDF2_ITERATIONS = 1024;
const PaddingMode PADDING_MODE = KM_PADDING_PKCS7;
+OQS_KEM* createNewKem(const tz_kem kemType)
+{
+ switch (kemType) {
+ case ML_KEM_768: return OQS_KEM_new(OQS_KEM_alg_ml_kem_768);
+ case ML_KEM_1024: return OQS_KEM_new(OQS_KEM_alg_ml_kem_1024);
+ default: return NULL;
+ }
+}
static uint32_t KM_AlgoType2TeeType(int algo)
{
sizeof(ecParams) / sizeof(*ecParams));
}
+TEE_Result KM_ExecCmdGenerateKEMKey(TEE_Param param[4])
+{
+ TEE_Result ret = TEE_SUCCESS;
+
+ void *in_buffer_ptr = param[1].memref.buffer;
+ uint32_t in_buffer_size_guard = param[1].memref.size;
+ void *out_buffer_ptr = param[2].memref.buffer;
+ uint32_t out_buffer_size_guard = param[2].memref.size;
+
+ uint32_t has_pub_pwd = 0, has_priv_pwd = 0;
+ KM_BinaryData pub_key_tag = {0, NULL};
+ KM_BinaryData priv_key_tag = {0, NULL};
+ KM_BinaryData pub_obj_id = {0, NULL};
+ KM_BinaryData priv_obj_id = {0, NULL};
+ KM_BinaryData encrypted_pub = {0, NULL};
+ KM_BinaryData encrypted_priv = {0, NULL};
+ KM_PwdData pub_key_pwd, priv_key_pwd;
+ uint8_t* public_key = NULL;
+ uint8_t* private_key = NULL;
+ OQS_KEM* kem = NULL;
+
+ tz_kem kem_type = param[0].value.b;
+
+ ret = KM_DeserializeFlagAndPw(&in_buffer_ptr, &in_buffer_size_guard, &has_pub_pwd, &pub_key_pwd);
+ if (ret != TEE_SUCCESS) {
+ LOG("Error in deserialization of public flag and password, ret = %x", ret);
+ goto clean;
+ }
+
+ ret = KM_DeserializeFlagAndPw(&in_buffer_ptr, &in_buffer_size_guard, &has_priv_pwd, &priv_key_pwd);
+ if (ret != TEE_SUCCESS) {
+ LOG("Error in deserialization of private flag and password, ret = %x", ret);
+ goto clean;
+ }
+
+ ret = KM_DeserializeBinaryData(&in_buffer_ptr, &in_buffer_size_guard, &priv_obj_id);
+ if (ret != TEE_SUCCESS) {
+ LOG("Error in deserialization of hash(privobjid), ret = %x", ret);
+ goto clean;
+ }
+
+ ret = KM_DeserializeBinaryData(&in_buffer_ptr, &in_buffer_size_guard, &pub_obj_id);
+ if (ret != TEE_SUCCESS) {
+ LOG("Error in deserialization of hash(pubobjid), ret = %x", ret);
+ goto clean;
+ }
+
+ kem = createNewKem(kem_type);
+ if (kem == NULL) {
+ LOG("Invalid OQS algorithm name was provided, or the \
+ requested algorithm was disabled at compile-time.");
+ ret = TEE_ERROR_GENERIC;
+ goto clean;
+ }
+
+ public_key = TEE_Malloc(kem->length_public_key*sizeof(uint8_t), 0);
+ private_key = TEE_Malloc(kem->length_secret_key*sizeof(uint8_t), 0);
+ if (public_key == NULL || private_key == NULL) {
+ LOG("Failed to allocate key buffers");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ OQS_STATUS rc = OQS_KEM_keypair(kem, public_key, private_key);
+ if (rc != OQS_SUCCESS) {
+ LOG("Error in KEM key generation, ret = %x", rc);
+ ret = TEE_ERROR_GENERIC;
+ goto clean;
+ }
+
+ KM_BinaryData pub = {kem->length_public_key, public_key};
+ KM_BinaryData priv = {kem->length_secret_key, private_key};
+
+ // encrypt both keys and serialize tags if needed and save
+ if (has_pub_pwd) {
+ ret = KM_EncryptBinary(&pub_key_pwd, &pub, &encrypted_pub, &pub_key_tag);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to encrypt new key, ret = %x", ret);
+ goto clean;
+ }
+
+ ret = KM_Serialize(&out_buffer_ptr, &out_buffer_size_guard, pub_key_tag.data, pub_key_tag.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+
+ ret = KM_SaveData(encrypted_pub.data, encrypted_pub.data_size, pub_obj_id.data, pub_obj_id.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+
+ } else {
+ ret = KM_SaveData(pub.data, pub.data_size, pub_obj_id.data, pub_obj_id.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+ }
+
+ if (has_priv_pwd) {
+ ret = KM_EncryptBinary(&priv_key_pwd, &priv, &encrypted_priv, &priv_key_tag);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+
+ ret = KM_Serialize(&out_buffer_ptr, &out_buffer_size_guard, priv_key_tag.data, priv_key_tag.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+
+ ret = KM_SaveData(encrypted_priv.data, encrypted_priv.data_size, priv_obj_id.data, priv_obj_id.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+
+ } else {
+ ret = KM_SaveData(priv.data, priv.data_size, priv_obj_id.data, priv_obj_id.data_size);
+ if (ret != TEE_SUCCESS)
+ goto clean;
+ }
+
+ LOGD_ID("Generated KEM public key: ", pub_obj_id.data, pub_obj_id.data_size);
+ LOGD_ID("Generated KEM private key: ", priv_obj_id.data, priv_obj_id.data_size);
+
+clean:
+ TEE_Free(pub_key_tag.data);
+ TEE_Free(priv_key_tag.data);
+ TEE_Free(encrypted_pub.data);
+ TEE_Free(encrypted_priv.data);
+ TEE_Free(public_key);
+ TEE_Free(private_key);
+ OQS_KEM_free(kem);
+
+ return ret;
+}
+
static TEE_Result KM_GetSecretValue(KM_BinaryData *secret_id, KM_BinaryData* secret,
uint32_t with_secret_pwd, KM_PwdData *secret_pwd_data)
{
}
// Let's save data
- if (dataTypeFlag == TYPE_GENERIC_SECRET) {
+ if (dataTypeFlag == TYPE_GENERIC_SECRET ||
+ dataTypeFlag == TYPE_AKEY_PRIVATE_KEM ||
+ dataTypeFlag == TYPE_AKEY_PUBLIC_KEM) {
if (with_pwd) {
ret = KM_EncryptBinary(&pwdData, &dataToSave, &encData, &tag);
if (TEE_SUCCESS != ret) {