Requires(postun): /sbin/ldconfig
# FIXME
-BuildRequires: key-manager-ta-devel
-BuildRequires: key-manager-ta-serialization-devel
BuildRequires: pkgconfig(tef-libteec)
# Disable hal-rootstrap-checker in order to use key-manager-ta
%define disable_hal_rootstrap_checker 1
PKG_CHECK_MODULES(SECURITY_KEYS_DEPS REQUIRED tef-libteec)
INCLUDE_DIRECTORIES(SYSTEM ${SECURITY_KEYS_DEPS_INCLUDE_DIRS})
LINK_DIRECTORIES(${SECURITY_KEYS_DEPS_LIBRARY_DIRS})
-SET(KM_LINK_EXTRA_DEPS km_serialization)
ADD_LIBRARY(${PROJECT_NAME} SHARED
hal-backend-security-keys-api.cpp
tz-memory.cpp
tz-serializer.cpp
- log.cpp)
+ log.cpp
+ km_serialization.cpp)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ROOTSTRAP_LIBRARIES} -ldlog
- ${SECURITY_KEYS_DEPS_LIBRARIES} ${KM_LINK_EXTRA_DEPS})
+ ${SECURITY_KEYS_DEPS_LIBRARIES})
SET_TARGET_PROPERTIES(${PROJECT_NAME}
PROPERTIES
#include <hal/hal-common-interface.h>
#include <hal/hal-security-keys-interface.h>
#include <hal/hal-security-keys-types.h>
-#include <km_ta_defines.h>
#include <tee_client_api.h>
#include "crypto-params.h"
#include "log.h"
#include "tz-memory.h"
+#include "km_ta_defines.h"
#include "tz-serializer.h"
#define EXPORT __attribute__ ((visibility("default")))
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "log.h"
+#include "km_serialization.h"
+
+int KM_Serialize(void **buffer,
+ uint32_t *size_guard,
+ const void *data_to_serialize,
+ uint32_t size_to_serialize)
+{
+ unsigned char **ptr = (unsigned char **)buffer;
+ if (!buffer || !(*ptr) || !size_guard) {
+ LOGE("Invalid usage of serialization.");
+ return -2;
+ }
+
+ if (*size_guard < size_to_serialize + sizeof(size_to_serialize)) {
+ LOGE("Cannot serialize - buffer too small.");
+ return -1;
+ }
+
+ memcpy(*ptr, &size_to_serialize, sizeof(size_to_serialize));
+ *ptr += sizeof(size_to_serialize);
+ if (data_to_serialize != NULL) {
+ memcpy(*ptr, data_to_serialize, size_to_serialize);
+ }
+ /**
+ * else - its not an error; it will be used to prepare output buffer of given size,
+ * but (on CA side), there will be no content yet
+ */
+ *ptr += size_to_serialize;
+ *size_guard -= size_to_serialize + sizeof(size_to_serialize);
+
+ return 0;
+}
+
+int KM_SerializeFlag(void **buffer,
+ uint32_t *size_guard,
+ uint32_t flag)
+{
+ unsigned char **ptr = (unsigned char **)buffer;
+ if (!buffer || !(*ptr) || !size_guard) {
+ LOGE("Invalid usage of serialization.");
+ return -2;
+ }
+
+ if (*size_guard < sizeof(flag)) {
+ LOGE("Cannot serialize - buffer too small.");
+ return -1;
+ }
+
+ memcpy(*ptr, &flag, sizeof(flag));
+ *ptr += sizeof(flag);
+ *size_guard -= sizeof(flag);
+
+ return 0;
+}
+
+int KM_SerializeBinaryData(void **buffer,
+ uint32_t *size_guard,
+ const KM_BinaryData *data)
+{
+ if (!data) {
+ LOGE("Invalid usage of serialization.");
+ return -1;
+ }
+
+ return KM_Serialize(buffer, size_guard, data->data, data->data_size);
+}
+
+int KM_SerializePwdDataRaw(void **buffer,
+ uint32_t *size_guard,
+ const void *pwd,
+ uint32_t pwd_size,
+ const void *iv,
+ uint32_t iv_size,
+ const void *tag,
+ uint32_t tag_size,
+ uint32_t derive_len_bits,
+ uint32_t it_count,
+ uint32_t tag_len_bits)
+{
+ if (KM_Serialize(buffer, size_guard, pwd, pwd_size))
+ return -2;
+ if (KM_Serialize(buffer, size_guard, iv, iv_size))
+ return -3;
+ if (KM_Serialize(buffer, size_guard, tag, tag_size))
+ return -4;
+ if (KM_SerializeFlag(buffer, size_guard, derive_len_bits))
+ return -5;
+ if (KM_SerializeFlag(buffer, size_guard, it_count))
+ return -6;
+ if (KM_SerializeFlag(buffer, size_guard, tag_len_bits))
+ return -7;
+
+ return 0;
+}
+
+int KM_SerializePwdData(void **buffer,
+ uint32_t *size_guard,
+ const KM_PwdData *data)
+{
+ if (!data) {
+ LOGE("Invalid usage of serialization.");
+ return -1;
+ }
+
+ return KM_SerializePwdDataRaw(buffer, size_guard, data->pwd, data->pwd_size,
+ data->iv, data->iv_size, data->tag, data->tag_size,
+ data->derive_len_bits, data->it_count, data->tag_len_bits);
+}
+
+/**
+ * Doesn't copy memory, just sets destination structure/data pointer properly &
+ * moves 'buffer' accordingly for further deserialization
+ */
+int KM_Deserialize(void **buffer,
+ uint32_t *size_guard,
+ void **destination_location,
+ uint32_t *size_to_deserialize)
+{
+ unsigned char **ptr = (unsigned char **)buffer;
+ unsigned char **ptr_dest = (unsigned char **)destination_location;
+ if (!buffer || !(*ptr)|| !size_guard || !destination_location || !size_to_deserialize) {
+ LOGE("Invalid usage of deserialization.");
+ return -2;
+ }
+
+ if (*size_guard < sizeof(*size_to_deserialize)) {
+ LOGE("Cannot deserialize data, not enough data in the buffer.");
+ return -3;
+ }
+
+ memcpy(size_to_deserialize, *ptr, sizeof(*size_to_deserialize));
+ *size_guard -= sizeof(*size_to_deserialize);
+ if (*size_guard < *size_to_deserialize) {
+ LOGE("Cannot deserialize data, not enough data in the buffer.");
+ return -4;
+ }
+
+ *ptr += sizeof(*size_to_deserialize);
+ *ptr_dest = *ptr;
+ *ptr += *size_to_deserialize;
+ *size_guard -= *size_to_deserialize;
+
+ return 0;
+}
+
+int KM_DeserializeFlag(void **buffer,
+ uint32_t *size_guard,
+ uint32_t *flag)
+{
+ unsigned char **ptr = (unsigned char **)buffer;
+ if (!buffer || !(*ptr)|| !size_guard || !flag) {
+ LOGE("Invalid usage of deserialization.");
+ return -1;
+ }
+
+ if (*size_guard < sizeof(*flag)) {
+ LOGE("Cannot deserialize data, not enough data in the buffer.");
+ return -2;
+ }
+
+ memcpy(flag, *ptr, sizeof(*flag));
+ *ptr += sizeof(*flag);
+ *size_guard -= sizeof(*flag);
+
+ return 0;
+}
+
+int KM_DeserializeBinaryData(void **buffer,
+ uint32_t *size_guard,
+ KM_BinaryData *data)
+{
+ if (!data) {
+ LOGE("Invalid usage of deserialization.");
+ return -1;
+ }
+
+ data->data = NULL;
+ data->data_size = 0;
+
+ return KM_Deserialize(buffer, size_guard, &(data->data), &(data->data_size));
+}
+
+uint32_t KM_SizeOfFlag(void)
+{
+ return sizeof(uint32_t);
+}
+
+uint32_t KM_SizeOfBinaryData(KM_BinaryData* data)
+{
+ if (!data) {
+ LOGE("Invalid usage of serialization KM_SizeOf*.");
+ return 0;
+ }
+
+ return data->data_size + sizeof(data->data_size);
+}
+
+uint32_t KM_SizeOfPwdData(KM_PwdData* data)
+{
+ if (!data) {
+ LOGE("Invalid usage of serialization KM_SizeOf*.");
+ return 0;
+ }
+
+ return data->pwd_size + sizeof(data->pwd_size) +
+ data->iv_size + sizeof(data->iv_size) +
+ data->tag_size + sizeof(data->tag_size) +
+ KM_SizeOfFlag() * 3;
+}
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Structure for storing data necessary to protect data with password.
+ */
+typedef struct {
+ uint32_t pwd_size;
+ uint32_t iv_size;
+ uint32_t tag_size;
+ uint32_t derive_len_bits;
+ uint32_t it_count;
+ uint32_t tag_len_bits;
+ void *pwd;
+ void *iv;
+ void *tag;
+} KM_PwdData;
+
+/**
+ * Structure for storing serialization data & functions for storing arbitrary data.
+ */
+typedef struct {
+ uint32_t data_size;
+ void *data;
+} KM_BinaryData;
+
+/**
+ * Below functions assume 'buffer' is already of proper size & size_guard contains
+ * number of bytes left in the buffer till its end; all functions copy memory to the buffer,
+ * move the 'buffer' pointer forward for further serialization & decrease size_guard if it's possible;
+ * return 0 on success, non-zero on error
+ */
+int KM_Serialize(void **buffer,
+ uint32_t *size_guard,
+ const void *data_to_serialize,
+ uint32_t size_to_serialize);
+
+int KM_SerializeFlag(void **buffer,
+ uint32_t *size_guard,
+ uint32_t flag);
+
+int KM_SerializeBinaryData(void **buffer,
+ uint32_t *size_guard,
+ const KM_BinaryData *data);
+
+int KM_SerializePwdDataRaw(void **buffer,
+ uint32_t *size_guard,
+ const void *pwd,
+ uint32_t pwd_size,
+ const void *iv,
+ uint32_t iv_size,
+ const void *tag,
+ uint32_t tag_size,
+ uint32_t derive_len_bits,
+ uint32_t it_count,
+ uint32_t tag_len_bits);
+
+int KM_SerializePwdData(void **buffer,
+ uint32_t *size_guard,
+ const KM_PwdData *data);
+
+/**
+ * Functions don't copy memory, just set destination structure/data pointer properly,
+ * move 'buffer' accordingly for further deserialization & decrease size_guard;
+ * only deserialization of a flag actually copies some data;
+ * return 0 on success, non-zero on error
+ */
+int KM_Deserialize(void **buffer,
+ uint32_t *size_guard,
+ void **destination_location,
+ uint32_t *size_to_deserialize);
+
+int KM_DeserializeFlag(void **buffer,
+ uint32_t *size_guard,
+ uint32_t *flag);
+
+int KM_DeserializeBinaryData(void **buffer,
+ uint32_t *size_guard,
+ KM_BinaryData *data);
+
+/**
+ * Functions related to size calculations - needed to calculate size of shared memory to be used for communication
+ */
+uint32_t KM_SizeOfFlag(void);
+uint32_t KM_SizeOfBinaryData(KM_BinaryData* data);
+uint32_t KM_SizeOfPwdData(KM_PwdData* data);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#pragma once
+
+/**
+ * Important - below definitions are copied from key-manager-ta and must remain coherent
+ */
+
+/**
+ * Enumeration for commands that can be called from key-manager-ta.
+ */
+typedef enum {
+ CMD_NOP = 0,
+ CMD_GENERATE_KEY, /** Generate random symmetric key */
+ CMD_IMPORT_ENCRYPTED_KEY, /** Key Manager TA import encrypted key from normal world.
+ Not implemented */
+ CMD_ENCRYPT, /** TA encrypt provided data with key.
+ Form of encryption depends on algorithm type */
+ CMD_DECRYPT, /** TA decrypt provided data with key
+ Form of decryption depends on algorithm type */
+ CMD_SIGN, /** TA sign data. Only for ALGO_RSA_SV|ALGO_DSA_SV */
+ CMD_VERIFY, /** TA verify signature. Only for ALGO_RSA_SV|ALGO_DSA_SV */
+ CMD_GENERATE_IV, /** TA generate random IV */
+ CMD_GENERATE_KEY_PWD, /** TA generate random key and encrypt it with password */
+ CMD_DESTROY_KEY, /** TA destroy key from storage */
+ CMD_IMPORT_DATA, /** Key Manager binary data saving to persistent storage
+ TA will encrypt data with password if provided */
+ CMD_GET_DATA, /** Key Manager binary data retrieving from persistent storage
+ TA will decrypt data with password if provided */
+ CMD_GET_DATA_SIZE, /** Key Manager binary data size to be retrieved from persistent storage */
+ CMD_DESTROY_DATA, /** Key Manager binary data removal from persistent storage */
+ CMD_GENERATE_RSA_KEYPAIR, /** Generate random RSA key pair */
+ CMD_GENERATE_DSA_KEYPAIR, /** Generate random DSA key pair */
+ CMD_GENERATE_EC_KEYPAIR, /** Generate random EC key pair */
+ CMD_GENERATE_KEM_KEYPAIR, /** Generate random KEM key pair */
+ CMD_DERIVE, /** Derive secret or key */
+ CMD_DERIVE_HYBRID, /** Hybrid derive secret or key */
+ CMD_IMPORT_WRAPPED_KEY, /** Import a wrapped key */
+ CMD_EXPORT_WRAPPED_KEY, /** Export a key in a wrapped form */
+ CMD_CIPHER_INIT, /** Initialize encryption/decryption context */
+ CMD_CIPHER_INIT_AAD, /** Supply another AAD chunk for the context */
+ CMD_CIPHER_UPDATE, /** Add a chunk of data for encryption/decryption */
+ CMD_CIPHER_FINALIZE, /** Finish the encryption/decryption */
+ CMD_CIPHER_CLEANUP, /** Release resources related to the context in the TA */
+ CMD_GET_MAX_CHUNK_SIZE, /** Get maximum chunk size that can be passed to TA */
+ CMD_WRAP_CONCATENATED_DATA, /** Wrap concatenated key|data with wrapping key and export */
+ CMD_UNWRAP_CONCATENATED_DATA, /** Unwrap concatenated key|data with wrapping key,
+ import key and export data */
+ CMD_ENCAPSULATE_KEY, /** Generate shared secret, encapsulate it and produce a ciphertext */
+ CMD_DECAPSULATE_KEY, /** Decapsulate shared secret from the ciphertext and key */
+} tz_command;
+
+/**
+ * Enumeration for algorithms definitions.
+ * Algorithms with suffix GEN should be used to key generations.
+ * Algorithms with suffix SV should be used to data signing/verification with key.
+ * Algorithms with suffix DRV should be used for key/secret derivation.
+ * Other algorithms should be used to encryption/decrytpion.
+ */
+typedef enum {
+ ALGO_NONE = 0, /** None */
+ ALGO_AES_CTR, /** AES CTR */
+ ALGO_AES_CBC, /** AES CBC */
+ ALGO_AES_GCM, /** AES GCM */
+ ALGO_AES_CFB, /** AES CFB */
+ ALGO_RSA, /** RSA */
+ ALGO_AES_GEN, /** AES GEN */
+ ALGO_RSA_GEN, /** RSA GEN */
+ ALGO_DSA_GEN, /** DSA GEN */
+ ALGO_ECDSA_GEN, /** ECDSA GEN */
+ ALGO_KEM_GEN, /** KEM GEN */
+ ALGO_RSA_SV, /** RSA SV */
+ ALGO_DSA_SV, /** DSA SV */
+ ALGO_ECDSA_SV, /** ECDSA SV */
+ ALGO_ECDH_DRV, /** ECDH DRV */
+ ALGO_KBKDF_DRV, /** KBKDF DRV */
+} tz_algo_type;
+
+/**
+ * Enumeration for hash function type.
+ */
+typedef enum {
+ HASH_SHA1, /** SHA1 */
+ HASH_SHA256, /** SHA256 */
+ HASH_SHA384, /** SHA384 */
+ HASH_SHA512, /** SHA512 */
+} tz_hash_type;
+
+/**
+ * Enumeration for data type, that can be stored on TA side.
+ */
+typedef enum {
+ TYPE_GENERIC_SECRET, /** Generic secret */
+ TYPE_SKEY, /** Symmetric key */
+ TYPE_AKEY_PRIVATE_DSA, /** Private DSA key */
+ TYPE_AKEY_PRIVATE_RSA, /** Private RSA key */
+ TYPE_AKEY_PUBLIC_DSA, /** Public DSA key */
+ TYPE_AKEY_PUBLIC_RSA, /** Public RSA key */
+ TYPE_AKEY_PRIVATE_EC, /** Private EC key */
+ TYPE_AKEY_PUBLIC_EC, /** Public EC key */
+ TYPE_AKEY_PRIVATE_KEM, /** Private KEM key */
+ TYPE_AKEY_PUBLIC_KEM, /** Public KEM key */
+} tz_data_type;
+
+/**
+ * Enumeration for elliptic curve type supported by TA side.
+ */
+typedef enum {
+ EC_NIST_P192, /** P192 */
+ EC_NIST_P256, /** P256 */
+ EC_NIST_P384, /** P384 */
+} tz_ec;
+
+/**
+ * Enumeration for KEM type supported by TA side.
+ */
+typedef enum {
+ ML_KEM_768, /** ML KEM 768 */
+ ML_KEM_1024, /** ML KEM 1024 */
+} tz_kem;
+
+/**
+ * Enumeration for keyed pseudo random function type supported by TA side.
+ */
+typedef enum {
+ PRF_HMAC_SHA256, /** SHA256 */
+ PRF_HMAC_SHA384, /** SHA384 */
+ PRF_HMAC_SHA512, /** SHA512 */
+} tz_prf;
+
+/**
+ * Enumeration for KBKDF pseudo random function type supported by TA side.
+ */
+typedef enum {
+ KBKDF_MODE_COUNTER, /** Counter mode */
+} tz_kbkdf_mode;
+
+/**
+ * Enumeration for counter location type supported by TA side.
+ */
+typedef enum {
+ KBKDF_LOC_BEFORE_FIXED, /** Before fixed */
+ KBKDF_LOC_AFTER_FIXED, /** After fixed */
+ KBKDF_LOC_MIDDLE_FIXED, /** Middle fixed */
+} tz_kbkdf_ctr_loc;
+
+// This must be somehow confronted with TEE_OBJECT_ID_MAX_LEN
+#define KM_KEY_ID_SIZE 64
+
+// Maximum additional size required for encrypted data
+#define KM_ENCRYPTION_OVERHEAD 16
+// Maximum RSA Block Size for encrypted data, in bytes, assumes max RSA key size is 4096 bits
+#define KM_RSA_BLOCK_SIZE 512
+
+// Errors
+#define KM_TA_SUCCESS 0
+#define KM_TA_ERROR_GENERIC 1
+#define KM_TA_ERROR_AUTH_FAILED 2
+#define KM_TA_ERROR_SIGNATURE 3
+
+// UUID
+#define KM_TA_UUID { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x66, 0x66, 0x66, 0x55, 0x55, 0x55} }
+
+// Encryption/decryption flag
+#define CIPHER_ENCRYPT 1
+#define CIPHER_DECRYPT 0
#include <stdexcept>
#include <hal/hal-security-keys-types.h>
-#include <km_serialization.h>
+#include "km_serialization.h"
#include "tz-memory.h"
class TZSerializable {