--- /dev/null
+#ifndef __SECRET_KEY_H_
+#define __SECRET_KEY_H_
+#define SECRET_KEY "THIS/STRING/MUST/BE/REPLACED/IN/REAL/DEVICE="
+#endif
%define ta_name %{unified_ta_devkit_get_ta_name 00000000000000000000666666555555}
+%define attach_product_key OFF
+%define attach_test_key OFF
+
+%define secret_ta_key_enable OFF
+
+%if %{attach_product_key} == ON && %{attach_test_key} == ON
+ %{error: You cannot attach product key and test key in one build}
+%endif
+
+%if %{attach_product_key} == ON
+ %if 0%{!?secret_ta_key_delivery_method:1}
+ %{error: You must define macro secret_ta_key_delivery_method}
+ %endif
+ %define secret_ta_key_enable ON
+%endif
+
+%if %{attach_test_key} == ON
+ %define secret_ta_key_enable ON
+ %define secret_ta_key_delivery_method "cp data/secret_key.h ta/include/"
+%endif
+
Name: key-manager-ta
Summary: Central Key Manager Trusted Application
Version: 0.1.24
cp -a %{SOURCE2} .
%build
+
+%if 0%{?secret_ta_key_delivery_method:1}
+ /bin/bash -c %{secret_ta_key_delivery_method}
+%endif
+
%{unified_ta_devkit_export}
%ifarch %{arm} aarch64
%{?asan:%gcc_unforce_options}
-DTASTORE_DIR=%{_tastoredir} \
-DINCLUDE_DIR=%{include_dir} \
-DLIB_DIR=%{lib_dir} \
- -DTA_NAME=%{ta_name}
+ -DTA_NAME=%{ta_name} \
+ -DSECRET_KEY_ENABLE=%{secret_ta_key_enable}
make %{?jobs:-j%jobs}
%install
${KEY_MANAGER_TA_PATH}/src/internal.c
${KEY_MANAGER_TA_PATH}/src/log.c
${KEY_MANAGER_TA_PATH}/src/km_ta.c
+ ${KEY_MANAGER_TA_PATH}/src/base64.c
${KEY_MANAGER_TA_SERIALIZATION_PATH}/src/km_serialization.c
)
${KEY_MANAGER_TA_SOURCES}
)
+IF(SECRET_KEY_ENABLE)
+ TARGET_COMPILE_OPTIONS(${TARGET_KEY_MANAGER_TA} PRIVATE -DSECRET_KEY_ENABLE)
+ENDIF(SECRET_KEY_ENABLE)
+
TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_TA}
${KEY_MANAGER_TA_DEPS_LIBRARIES}
${KEY_MANAGER_TA_DEPS_STATIC_LIBRARIES}
--- /dev/null
+/*
+ * Copyright (c) 2014, STMicroelectronics International N.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef BASE64_H
+#define BASE64_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+bool base64_enc(const void *data, size_t size, char *buf, size_t *blen);
+bool base64_dec(const char *data, size_t size, void *buf, size_t *blen);
+size_t base64_enc_len(size_t size);
+
+#endif /* BASE64_H */
TEE_Result KM_EncryptKey(TEE_ObjectHandle keyHndl, KM_PwdData *pwd, TEE_ObjectHandle *encKeyHndl,
void *tag, uint32_t *tag_size);
+TEE_Result KM_DecryptImportedData(KM_BinaryData *iv, KM_BinaryData *tag,
+ KM_BinaryData *input, KM_BinaryData *output);
+
TEE_Result KM_DecryptDataWithPwd(KM_PwdData* pwd, void *in, size_t in_size,
void *out, uint32_t *out_size);
///< KM_BinaryData with binary data or symetric key
///< uint32_t binary data size in bits
///< KM_BinaryData IV for decryption with built-in key
+ ///< KM_BinaryData tag for data verificaiton after gcm decryption
///< uint32_t boolean value - true if password is provided
///< KM_PwdData with password (optional)
///< Output:
--- /dev/null
+/*
+ * Copyright (c) 2014, STMicroelectronics International N.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "base64.h"
+
+static const char base64_table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+size_t base64_enc_len(size_t size)
+{
+ return 4 * ((size + 2) / 3) + 1;
+}
+
+bool base64_enc(const void *data, size_t dlen, char *buf, size_t *blen)
+{
+ size_t n;
+ size_t boffs = 0;
+ const char *d = data;
+
+ n = base64_enc_len(dlen);
+ if (*blen < n) {
+ *blen = n;
+ return false;
+ }
+
+ for (n = 0; n < dlen; n += 3) {
+ uint32_t igrp;
+
+ igrp = d[n];
+ igrp <<= 8;
+
+ if ((n + 1) < dlen)
+ igrp |= d[n + 1];
+ igrp <<= 8;
+
+ if ((n + 2) < dlen)
+ igrp |= d[n + 2];
+
+ buf[boffs] = base64_table[(igrp >> 18) & 0x3f];
+ buf[boffs + 1] = base64_table[(igrp >> 12) & 0x3f];
+ if ((n + 1) < dlen)
+ buf[boffs + 2] = base64_table[(igrp >> 6) & 0x3f];
+ else
+ buf[boffs + 2] = '=';
+ if ((n + 2) < dlen)
+ buf[boffs + 3] = base64_table[igrp & 0x3f];
+ else
+ buf[boffs + 3] = '=';
+
+ boffs += 4;
+ }
+ buf[boffs++] = '\0';
+
+ *blen = boffs;
+ return true;
+}
+
+static bool get_idx(char ch, uint8_t *idx)
+{
+ size_t n;
+
+ for (n = 0; base64_table[n] != '\0'; n++) {
+ if (ch == base64_table[n]) {
+ *idx = n;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool base64_dec(const char *data, size_t size, void *buf, size_t *blen)
+{
+ size_t n;
+ uint8_t idx;
+ uint8_t *b = buf;
+ size_t m = 0;
+ size_t s = 0;
+
+ for (n = 0; n < size && data[n] != '\0'; n++) {
+ if (data[n] == '=')
+ break; /* Reached pad characters, we're done */
+
+ if (!get_idx(data[n], &idx))
+ continue;
+
+ if (m > *blen)
+ b = NULL;
+
+ switch (s) {
+ case 0:
+ if (b)
+ b[m] = idx << 2;
+ s++;
+ break;
+ case 1:
+ if (b)
+ b[m] |= idx >> 4;
+ m++;
+ if (m > *blen)
+ b = NULL;
+ if (b)
+ b[m] = (idx & 0xf) << 4;
+ s++;
+ break;
+ case 2:
+ if (b)
+ b[m] |= idx >> 2;
+ m++;
+ if (m > *blen)
+ b = NULL;
+ if (b)
+ b[m] = (idx & 0x3) << 6;
+ s++;
+ break;
+ case 3:
+ if (b)
+ b[m] |= idx;
+ m++;
+ s = 0;
+ break;
+ default:
+ return false; /* "Can't happen" */
+ }
+ }
+ /* We don't detect if input was bad, but that's OK with the spec. */
+ *blen = m;
+ if (b)
+ return true;
+ else
+ return false;
+}
TEE_ObjectHandle key = TEE_HANDLE_NULL;
TEE_ObjectHandle oldKey = TEE_HANDLE_NULL;
KM_BinaryData dataToSave;
- KM_BinaryData dataEncIV; // IV used to decrypt dataToSave with built-in key
- KM_BinaryData encData; // Used during encyption with password
+ KM_BinaryData dataEncIV; // IV used to decrypt dataToSave with build-in key
+ KM_BinaryData dataEncTag; // TAG used to data verfication after gcm decryption
KM_BinaryData objId; // Random ID of object
KM_BinaryData tag;
KM_PwdData pwdData;
uint32_t dataSizeBits_flag;
uint32_t dataTypeFlag; // representation of tz_data_type
+ KM_BinaryData plainData; // Used during decryption with build-in key
+ KM_BinaryData encData; // Used during encyption with password
+
void *in_buffer = param[1].memref.buffer;
void *out_buffer = param[2].memref.buffer;
uint32_t in_size_guard = param[1].memref.size;
uint32_t out_size_guard = param[2].memref.size;
- encData.data = objId.data = tag.data = NULL;
+ plainData.data = encData.data = objId.data = tag.data = NULL;
if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &dataTypeFlag)) {
LOG("Error in deserialization");
goto clean;
}
+ if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &dataEncTag)) {
+ LOG("Error in deserialization");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
+
if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &with_pwd)) {
LOG("Error in deserialization");
ret = TEE_ERROR_BAD_PARAMETERS;
// ObjectID generation
TEE_GenerateRandom(objId.data, objId.data_size);
+ // Decryption
+ if (dataEncIV.data_size) {
+ plainData.data_size = (dataToSave.data_size * 32 + 31)/32;
+ plainData.data = malloc(plainData.data_size);
+ if (plainData.data == NULL) {
+ LOG("Failed to allocate object buffer for decryption data");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ ret = KM_DecryptImportedData(&dataEncIV, &dataEncTag, &dataToSave, &plainData);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to decrypt initial values");
+ goto clean;
+ }
+
+ dataToSave = plainData;
+ }
+
+ // Let's save data
if (dataTypeFlag == TYPE_GENERIC_SECRET) {
- // TODO support for decryption with dataEncIV
if (with_pwd) {
tag.data_size = pwdData.tag_len_bits / 8;
tag.data = malloc(tag.data_size);
LOG("Failed to save data to storage");
}
} else if (dataTypeFlag == TYPE_SKEY) {
- // TODO support for decryption with dataEncIV
if (!KM_CheckAlgoKeySize(TEE_TYPE_AES, dataSizeBits_flag)) {
LOG("Unsupported key size provided: %u", dataSizeBits_flag);
ret = TEE_ERROR_BAD_PARAMETERS;
clean:
TEE_CloseObject(oldKey);
TEE_CloseObject(key);
+ free(plainData.data);
free(objId.data);
free(encData.data);
free(tag.data);
#include <crypto_symmetric.h>
#include <crypto_auth.h>
+#ifdef SECRET_KEY_ENABLE
+#include <base64.h>
+#include <secret_key.h>
+#endif
+
#ifndef TEE_DATA_FLAG_OVERWRITE
#define TEE_DATA_FLAG_OVERWRITE TEE_DATA_FLAG_EXCLUSIVE
#endif
return ret;
}
+#ifdef SECRET_KEY_ENABLE
+TEE_Result KM_DecryptImportedData(
+ KM_BinaryData *iv,
+ KM_BinaryData *tag,
+ KM_BinaryData *input,
+ KM_BinaryData *output)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_OperationHandle op = TEE_HANDLE_NULL;
+
+ const char base64key[] = SECRET_KEY;
+ char buff[40];
+ size_t buff_size = sizeof(buff);
+
+ if (!base64_dec(base64key, sizeof(base64key), buff, &buff_size)) {
+ LOG("Failed to decode built-in key");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ ret = KM_CreateKey(TEE_TYPE_AES, buff_size*8, buff, &key);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create built-in key");
+ goto out;
+ }
+
+ ret = KM_CreateOperation(key, TEE_ALG_AES_GCM, TEE_MODE_DECRYPT, &op);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create operation: %x", ret);
+ goto out;
+ }
+
+ ret = KM_AuthDecrypt(
+ op,
+ iv->data,
+ iv->data_size,
+ tag->data_size*8,
+ 0,
+ input->data,
+ input->data_size,
+ NULL,
+ 0,
+ tag->data,
+ tag->data_size,
+ output->data,
+ &(output->data_size));
+
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to decrypt key: %x", ret);
+ goto out;
+ }
+
+out:
+ if (op != TEE_HANDLE_NULL) TEE_FreeOperation(op);
+ TEE_FreeTransientObject(key);
+ return ret;
+}
+#else
+TEE_Result KM_DecryptImportedData(
+ KM_BinaryData *iv,
+ KM_BinaryData *tag,
+ KM_BinaryData *input,
+ KM_BinaryData *output)
+{
+ LOG("This version of key-manager-ta application does not support import of encrypted values.");
+ return TEE_ERROR_NOT_SUPPORTED;
+}
+#endif
+
TEE_Result KM_DecryptDataWithPwd(KM_PwdData* pwd, void *in, size_t in_size,
void *out, uint32_t *out_size)
{