+++ /dev/null
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
-AR = $(CROSS_COMPILE)ar
-NM = $(CROSS_COMPILE)nm
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
-READELF = $(CROSS_COMPILE)readelf
-
-OBJS = ca_km.o
-
-CFLAGS += -Wall -I/usr/include
-LDADD += -L/usr/lib/ -lkm_serialization -lteec
-
-BINARY = km_ca
-
-all: $(BINARY)
-
-%.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-$(BINARY): $(OBJS)
- $(CC) $(LDADD) $(OBJS) -o $@
-
-clean:
- rm -f $(OBJS) $(BINARY)
+++ /dev/null
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-#include <tee_client_api.h>
-#include "ca_km.h"
-#include "serialization.h"
-//mod
-TEEC_UUID km_uuid = {
- .timeLow = 0x0,
- .timeMid = 0x0,
- .timeHiAndVersion = 0x0,
- .clockSeqAndNode = {0x0, 0x0, 0x66, 0x66, 0x66, 0x55, 0x55, 0x55},
-};
-
-#define LOG(format, arg...) do{ fprintf(stderr,format,##arg); }while(0)
-
-void printhex(const void *buf, unsigned len) {
- unsigned i;
- for (i = 0; i < len; ++i) {
- fprintf(stderr,"%02X", ((const char*)buf)[i]);
- }
- fprintf(stderr,"\n");
-}
-
-#define SHARED_BUFFER_SIZE 512
-
-static int key_generate(TEEC_Context *context, TEEC_Session *session, int algo, uint32_t key_bits,
- uint32_t *key_id, uint32_t* key_id_size)
-{
- SymmetricInput *out = NULL;
- KeyId *keyId = NULL;
- TEEC_Operation operation;
- TEEC_SharedMemory shmem;
- int ret;
-
- shmem.size = SHARED_BUFFER_SIZE;
- shmem.flags = TEEC_MEM_OUTPUT;
- ret = TEEC_AllocateSharedMemory(context, &shmem);
- if (ret != TEEC_SUCCESS) {
- printf("%s: allocateing shared memeory failed with error=%x\n", __func__, ret);
- return ret;
- }
- operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,TEEC_MEMREF_PARTIAL_OUTPUT,TEEC_NONE,TEEC_NONE);
- operation.params[0].value.a = algo;
- operation.params[0].value.b = key_bits;
- operation.params[1].memref.parent = &shmem;
- operation.params[1].memref.offset = 0x0;
- operation.params[1].memref.size = SHARED_BUFFER_SIZE;
-
- ret = TEEC_InvokeCommand(session, CMD_GENERATE_KEY, &operation, NULL);
- if (ret != TEEC_SUCCESS) {
- printf("%s: invoke command failed with error=%x\n", __func__, ret);
- return ret;
- }
-
- if (0 != KM_ParamsDeserializationInit(shmem.buffer, operation.params[1].memref.size, &out)) {
- return -1;
- }
- if (0 != KM_ParamsDeserializeKeyId(out, &keyId)) {
- return -1;
- }
- printf("%s: shmem.size=%d operation.params[1].memref.size=%d\n", __func__, shmem.size, operation.params[1].memref.size);
- if (key_id) {
- *key_id_size = keyId->data_size;
- memcpy(key_id, keyId->data, keyId->data_size);
- } else {
- printf("%s: There's no keyId\n", __func__);
- }
- return ret;
-}
-
-static int send_symmetric_cmd(TEEC_Session *session, uint32_t cmd, uint32_t key_type, uint32_t algo,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o, uint32_t *out_size)
-{
- TEEC_Operation operation;
- int ret;
-
- //operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,TEEC_MEMREF_WHOLE,TEEC_MEMREF_WHOLE,TEEC_NONE);
- operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,TEEC_MEMREF_PARTIAL_INPUT,TEEC_MEMREF_PARTIAL_OUTPUT,TEEC_NONE);
- operation.params[0].value.a = key_type;
- operation.params[0].value.b = algo;
- operation.params[1].memref.parent = message_i;
- operation.params[1].memref.offset = 0;
- operation.params[1].memref.size = message_i->size;
- operation.params[2].memref.parent = message_o;
- operation.params[2].memref.offset = 0;
- operation.params[2].memref.size = message_o->size;
-
- ret = TEEC_InvokeCommand(session, cmd, &operation, NULL);
- if (ret != TEEC_SUCCESS) {
- LOG("TEEC_InvokeCommand failed with ret=%x\n", ret);
- }
- *out_size = operation.params[2].memref.size;
- return ret;
-}
-
-static int symmetric_encrypt(TEEC_Session *session, uint32_t key_type, int algo,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o, uint32_t *out_size) {
- return send_symmetric_cmd(session, CMD_ENCRYPT, key_type, algo, message_i, message_o, out_size);
-}
-
-static int symmetric_decrypt(TEEC_Session *session, uint32_t key_type, int algo,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o, uint32_t *out_size) {
- return send_symmetric_cmd(session, CMD_DECRYPT, key_type, algo, message_i, message_o, out_size);
-}
-
-static int serialize_all(void *buffer, uint32_t buffer_size, void *input, uint32_t input_size,
- void *iv, uint32_t iv_size, void *key_id, uint32_t key_id_size, void *key,
- uint32_t key_size, uint32_t key_bits_size, uint32_t tagLen,
- uint32_t AADLen, uint32_t payloadLen, void *tag, uint32_t tag_size)
-{
- SymmetricInput *out = NULL;
- if (KM_ParamsSerializationInit (buffer, buffer_size, &out) != 0) {
- return -1;
- }
- if (KM_ParamsSerializeInputData (out, input, input_size) != 0) {
- return -1;
- }
- if (iv) {
- if (KM_ParamsSerializeIVData (out, iv, iv_size) != 0) {
- return -1;
- }
- }
- if (tagLen > 0) {
- if (KM_ParamsSerializeAEData (out, tagLen, AADLen, payloadLen, tag, tag_size) != 0) {
- return -1;
- }
- }
- if (key) {
- if (KM_ParamsSerializeKey (out, key, key_size, key_bits_size) != 0) {
- return -1;
- }
- }
- if (key_id) {
- if (KM_ParamsSerializeKeyId (out, key_id, key_id_size) != 0) {
- return -1;
- }
- }
- return 0;
-}
-
-static TEEC_Result symmetric_test(TEEC_Session *session, uint32_t key_type, uint32_t algo,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o,
- void *key_id, uint32_t key_id_size, size_t key_bits_size,
- void *iv, uint32_t iv_size)
-{
- TEEC_Result ret;
- char inbuf[240] = "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decry";
- uint32_t inbuf_size = sizeof(inbuf);
- SymmetricInput *out = NULL;
- OutData *out_data = NULL;
- uint32_t out_size;
-
- if (serialize_all(message_i->buffer, message_i->size, inbuf, inbuf_size, iv, iv_size, key_id,
- key_id_size, NULL, 0, key_bits_size, 0, 0, 0, NULL, 0) == -1) {
- LOG("serialize_all failed.\n");
- return -1;
- }
-
- ret = symmetric_encrypt(session, key_type, algo, message_i, message_o, &out_size);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_encrypt returned %x\n", ret);
- return ret;
- }
- if (KM_ParamsDeserializationInit(message_o->buffer, out_size, &out) != 0
- || KM_ParamsDeserializeOutData(out, &out_data) != 0) {
- return -1;
- }
- LOG("Encrypted test text:\n");
- printhex(out_data->data, out_data->data_size);
- memset(message_i->buffer, 0x00, message_i->size);
-
- if (serialize_all(message_i->buffer, message_i->size, out_data->data, out_data->data_size, iv,
- iv_size, key_id, key_id_size, NULL, 0, key_bits_size, 0, 0, 0, NULL, 0) == -1) {
- LOG("serialize_all failed.\n");
- return -1;
- }
- memset(message_o->buffer, 0x00, message_o->size);
-
- ret = symmetric_decrypt(session, key_type, algo, message_i, message_o, &out_size);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_decrypt returned %x\n", ret);
- return ret;
- }
- if (KM_ParamsDeserializationInit(message_o->buffer, out_size, &out) != 0
- || KM_ParamsDeserializeOutData(out, &out_data) != 0) {
- return -1;
- }
- LOG("Decrypted test text:\n");
- printhex(out_data->data, out_data->data_size);
- memset(message_i->buffer, 0x00, message_i->size);
- memset(message_o->buffer, 0x00, message_o->size);
-
- return ret;
-}
-
-static TEEC_Result symmetric_test_tag(TEEC_Session *session, uint32_t key_type, uint32_t algo,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o,
- void *key_id, uint32_t key_id_size, size_t key_bits_size,
- void *iv, uint32_t iv_size)
-{
- TEEC_Result ret;
- char inbuf[240] = "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decry";
- uint32_t inbuf_size = sizeof(inbuf);
- SymmetricInput *out = NULL;
- OutData *out_data = NULL;
- TagData *tag_data = NULL;
- uint32_t out_size;
-
- if (serialize_all(message_i->buffer, message_i->size, inbuf, inbuf_size, iv, iv_size, key_id,
- key_id_size, NULL, 0, key_bits_size, 96, 0, inbuf_size, NULL, 0) == -1) {
- LOG("serialize_all failed.\n");
- return -1;
- }
-
- ret = symmetric_encrypt(session, key_type, algo, message_i, message_o, &out_size);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_encrypt returned %x\n", ret);
- return ret;
- }
- if (KM_ParamsDeserializationInit(message_o->buffer, out_size, &out) != 0
- || KM_ParamsDeserializeOutData(out, &out_data) != 0
- || KM_ParamsDeserializeTagData(out, &tag_data) != 0) {
- return -1;
- }
- LOG("Encrypted test text:\n");
- printhex(out_data->data, out_data->data_size);
- memset(message_i->buffer, 0x00, message_i->size);
-
- if (serialize_all (message_i->buffer, message_i->size, out_data->data, out_data->data_size, iv,
- iv_size, key_id, key_id_size, NULL, 0, key_bits_size, 96, 0, inbuf_size,
- tag_data->data, tag_data->data_size) == -1) {
- LOG("serialize_all failed.\n");
- return -1;
- }
- memset(message_o->buffer, 0x00, message_o->size);
-
- ret = symmetric_decrypt(session, key_type, algo, message_i, message_o, &out_size);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_decrypt returned %x\n", ret);
- return ret;
- }
- if (KM_ParamsDeserializationInit(message_o->buffer, out_size, &out) != 0
- || KM_ParamsDeserializeOutData(out, &out_data) != 0) {
- return -1;
- }
- LOG("Decrypted test text:\n");
- printhex(out_data->data, out_data->data_size);
- memset(message_i->buffer, 0x00, message_i->size);
- memset(message_o->buffer, 0x00, message_o->size);
-
- return ret;
-}
-
-static TEEC_Result symmetric_algo_test(TEEC_Session *session, uint32_t key_type,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o,
- void *key_id, uint32_t key_id_size, size_t key_bits_size,
- void *iv, uint32_t iv_size)
-{
- TEEC_Result ret;
- unsigned n = 0;
-
- LOG("Test:%d\n", n);
- ret = symmetric_test(session, key_type, ALGO_ECB_NOPAD, message_i, message_o, key_id, key_id_size,
- key_bits_size, NULL, 0);
- if (ret != TEEC_SUCCESS) {
- LOG("%d symmetric_test returned %x\n", n, ret);
- return ret;
- }
- ++n;
-
- LOG("Test:%d\n", n);
- ret = symmetric_test(session, key_type, ALGO_CBC_NOPAD, message_i, message_o, key_id, key_id_size,
- key_bits_size, iv, iv_size);
- if (ret != TEEC_SUCCESS) {
- LOG("%d symmetric_test returned %x\n", n, ret);
- return ret;
- }
- ++n;
-
- return ret;
-}
-
-static TEEC_Result symmetric_algo_test_tag(TEEC_Session *session, uint32_t key_type,
- TEEC_SharedMemory *message_i, TEEC_SharedMemory *message_o,
- void *key, uint32_t key_size, size_t key_bits_size, void * iv,
- uint32_t iv_size)
-{
- TEEC_Result ret;
-
- LOG("Test GCM\n");
- ret = symmetric_test_tag(session, key_type, ALGO_GCM, message_i, message_o, key, key_size,
- key_bits_size, iv, iv_size);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_test returned %x\n", ret);
- return ret;
- }
-
- LOG("Test CCM\n");
- ret = symmetric_test_tag(session, key_type, ALGO_CCM, message_i, message_o, key, key_size,
- key_bits_size, iv, 8);
- if (ret != TEEC_SUCCESS) {
- LOG("symmetric_test returned %x\n", ret);
- return ret;
- }
-
- return ret;
-}
-
-static TEEC_Result all_symmetric_test(TEEC_Context *context)
-{
- TEEC_Result ret = 0;
- TEEC_Session session;
- TEEC_SharedMemory message_i;
- TEEC_SharedMemory message_o;
- uint32_t origin;
- uint32_t key_id[1024];
- uint32_t key_id_size = 0;
- char inbuf[240] = "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decrypt"
- "TO jest TEKST TestoWY, 1234567890, w celu sprawdzenia funkcji encrypt i decry";
- uint32_t inbuf_size = sizeof(inbuf);
- char iv[16] = "1234567887654321";
-
- LOG("TEEC_OpenSession\n");
- ret = TEEC_OpenSession(context, &session, &km_uuid, 0, NULL, NULL, &origin);
- LOG("TEEC_OpenSession returned %x from %x\n", ret, origin);
- if (ret != TEEC_SUCCESS) {
- return ret;
- }
-
- message_i.size = sizeof(SymmetricInput) + sizeof(InputData) + sizeof(IVData) + sizeof(Key) + 1536;
- message_i.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
- ret = TEEC_AllocateSharedMemory(context, &message_i);
- if (ret != TEEC_SUCCESS) {
- LOG("AllocateSharedMemory failed with ret=%x\n", ret);
- goto close;
- }
- LOG("TEEC_AllocateSharedMemory: buffer:%p\n", message_i.buffer);
-
- message_o.size = message_i.size;
- message_o.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
- ret = TEEC_AllocateSharedMemory(context, &message_o);
- if (ret != TEEC_SUCCESS) {
- LOG("AllocateSharedMemory2 failed with ret=%x\n", ret);
- goto close;
- }
- memset(message_o.buffer, 0x00, message_o.size);
-
- LOG("Original test text:\n");
- printhex(inbuf, inbuf_size);
- do {
- ret = key_generate(context, &session, KEY_TYPE_DES, 56, key_id, &key_id_size);
- if (ret != TEEC_SUCCESS) {
- break;
- }
-
- ret = symmetric_algo_test(&session, KEY_TYPE_DES, &message_i, &message_o, key_id,
- key_id_size, 56, iv, 8);
- if (ret != TEEC_SUCCESS) {
- break;
- }
-
- ret = key_generate(context, &session, KEY_TYPE_DES3, 112, key_id, &key_id_size);
- if (ret != TEEC_SUCCESS) {
- break;
- }
-
- ret = symmetric_algo_test(&session, KEY_TYPE_DES3, &message_i, &message_o, key_id,
- key_id_size, 112, iv, 8);
- if (ret != TEEC_SUCCESS) {
- break;
- }
-
- ret = key_generate(context, &session, KEY_TYPE_AES, 128, key_id, &key_id_size);
- if (ret != TEEC_SUCCESS) {
- break;
- }
-
- ret = symmetric_algo_test(&session, KEY_TYPE_AES, &message_i, &message_o, key_id,
- key_id_size, 128, iv, 16);
- if (ret != TEEC_SUCCESS) {
- break;
- }
- ret = symmetric_algo_test_tag(&session, KEY_TYPE_AES, &message_i, &message_o,
- key_id, key_id_size, 128, iv, 16);
- if (ret != TEEC_SUCCESS) {
- break;
- }
- } while (0);
-
- TEEC_ReleaseSharedMemory(&message_i);
- TEEC_ReleaseSharedMemory(&message_o);
-
-close:
- LOG("TEEC_CloseSession\n");
- TEEC_CloseSession(&session);
-
- return ret;
-}
-
-int main(void)
-{
- TEEC_Context context;
- TEEC_Result ret;
-
- LOG("TEEC_InitializeContext\n");
- ret = TEEC_InitializeContext(NULL, &context);
- if (ret != TEEC_SUCCESS) {
- LOG("InitializeContext failed: %x\n", ret);
- goto out;
- }
-
- LOG("all_symmetric_test\n");
- ret = all_symmetric_test(&context);
- LOG("all_symmetric_test failed:%d\n", ret);
-
- LOG("TEEC_FinalizeContext;\n");
- TEEC_FinalizeContext(&context);
- out: return (ret != TEEC_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 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
- */
-/*
- * @file ca_km.h
- * @author RafaĆ Tyminski (r.tyminski@partner.samsung.com)
- * @version 1.0
- * @brief
- */
-#ifndef __REE_CA_KM_H__
-#define __REE_CA_KM_H__
-
-typedef enum {
- CMD_NOP = 0,
- CMD_GENERATE_KEY,
- CMD_IMPORT_KEY,
- CMD_IMPORT_ENCRYPTED_KEY,
- CMD_ENCRYPT,
- CMD_DECRYPT,
- CMD_SIGN,
- CMD_VERIFY,
- CMD_GENERATE_IV,
- CMD_GENERATE_KEY_PWD,
-} tz_command;
-
-typedef enum {
- ALGO_NONE = 0,
- ALGO_AES_CTR,
- ALGO_AES_CBC,
- ALGO_AES_GCM,
- ALGO_AES_CFB, // TODO to implement
- ALGO_RSA_OAEP,
- ALGO_AES_GEN,
- ALGO_RSA_GEN,
-} tz_algo_type;
-
-#endif //__REE_CA_KM_H__
+++ /dev/null
-<manifest>
- <assign>
- <filesystem path="/usr/bin/km_ca" exec_label="_" />
- </assign>
- <request>
- <domain name="_" />
- </request>
-</manifest>
+++ /dev/null
-%define ta_dev_kit_dir /opt/optee/export-ta_arm%{__isa_bits}
-
-Name: key-manager-ca
-Summary: Central Key Manager Trusted Application
-Version: 0.1.24
-Release: 1
-Group: Security/Secure Storage
-License: Apache-2.0 and BSL-1.0 and BSD-3-Clause
-Source0: %{name}-%{version}.tar.gz
-Source1: %{name}.manifest
-
-Provides: %{name}
-
-BuildRequires: python
-BuildRequires: openssl
-BuildRequires: key-manager-ta-serialization
-BuildRequires: optee-client
-
-%description
-Key Manager Trusted Application working in the ARMÂź TrustZoneÂź environment.
-
-%prep
-%setup -q
-
-%build
-make -C host CROSS_COMPILE=""
-
-%install
-mkdir -p %{buildroot}/%{_bindir}/
-cp -rf host/km_ca %{buildroot}/%{_bindir}/
-
-%clean
-rm -rf %{buildroot}
-
-%files
-%defattr(-, root, root, -)
-%manifest packaging/%{name}.manifest
-%{_bindir}/km_ca
#include <stdint.h>
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
typedef enum KM_ParamsMagic {
PSMagic_SymmetricInput = 0x542345,
PSMagic_InputData = 0x575445,
typedef struct Data_ TagData;
typedef struct AEData_ {
- Data tag;
+ Data aad;
uint32_t tagLen;
uint32_t AADLen;
uint32_t payloadLen;
int KM_ParamsDeserializeKeyId(SymmetricInput *self, KeyId **out);
int KM_ParamsSerializationInit(void *buffer, size_t buffer_size, SymmetricInput **out);
-int KM_ParamsSerializeInputData(SymmetricInput *self, void *data, uint32_t data_size);
-int KM_ParamsSerializeIVData(SymmetricInput *self, void *data, uint32_t data_size);
+int KM_ParamsSerializeInputData(SymmetricInput *self, const void *data, size_t data_size);
+int KM_ParamsSerializeIVData(SymmetricInput *self, const void *data, size_t data_size);
int KM_ParamsSerializeAEData(SymmetricInput *self, uint32_t tagLen, uint32_t AADLen,
- uint32_t payloadLen, void *tag, uint32_t tag_size);
-int KM_ParamsSerializeOutData(SymmetricInput *self, void *data, size_t data_size);
+ uint32_t payloadLen, const void *aad, size_t aad_size);
+int KM_ParamsSerializeOutData(SymmetricInput *self, const void *data, size_t data_size);
+
+int KM_ParamsSerializeTagData(SymmetricInput *self, const void *data, size_t data_size);
-int KM_ParamsSerializeTagData(SymmetricInput *self, void *data, size_t data_size);
+int KM_ParamsSerializeKey(SymmetricInput *self, const void *data, size_t data_size,
+ uint32_t bits_size);
-int KM_ParamsSerializeKey(SymmetricInput *self, void *data, size_t data_size,
- size_t bits_size);
+int KM_ParamsSerializeKeyId(SymmetricInput *self, const void *data, size_t data_size);
-int KM_ParamsSerializeKeyId(SymmetricInput *self, void *data, size_t data_size);
+#ifdef __cplusplus
+}
+#endif
#endif //__PARAMS_SERIALIZATION_H__
#include <string.h>
#include "serialization.h"
-#define LOG printf
-
-#define LOG_ERR(...) LOG("%s:", __func__); LOG(__VA_ARGS__); LOG(" \n")
+#define LOG(...) printf(__VA_ARGS__);
static size_t addAlignment(size_t size)
{
uint32_t curr_ptr = 0;
Data *ptr = NULL;
if (NULL == self || NULL == out) {
- LOG_ERR("Invalid input.");
+ LOG("Invalid input.");
return -1;
}
ptr = (Data *) curr_ptr;
if (magic != ptr->magic) {
- LOG_ERR("Invalid magic.");
+ LOG("Invalid magic.");
return -1;
}
return 0;
}
-static int KM_ParamsSerializeData(SymmetricInput *self, void *data, size_t data_size,
+static int KM_ParamsSerializeData(SymmetricInput *self, const void *data, size_t data_size,
uint32_t size, uint32_t magic, Data **ptr)
{
uint32_t curr_ptr = 0;
Data *tmp = NULL;
- if (NULL == self || self->buffer_size < self->global_offset + size + data_size) {
- LOG_ERR("Invalid parameters. (self=%p|"
- "self->buffer_size < self->global_offset + size + data_size=%d < %d",
- (void *) self, self->buffer_size, self->global_offset + size + data_size);
+ if (self == NULL) {
+ LOG("Provided NULL serialization pointer");
+ return -1;
+ }
+
+ if (self->buffer_size < self->global_offset + size + data_size) {
+ LOG("Invalid parameters. ("
+ "self->buffer_size < self->global_offset + size + data_size=%d < %d",
+ self->buffer_size, self->global_offset + size + data_size);
return -1;
}
curr_ptr = ((uint32_t) self) + self->global_offset;
TagData *tag_data)
{
if (input) {
- LOG_ERR("buffer_size=%d key_data_offset=%d key_id_data_offset=%d input_data_offset=%d "
+ LOG("buffer_size=%d key_data_offset=%d key_id_data_offset=%d input_data_offset=%d "
"iv_data_offset=%d ae_data_offset=%d out_data_offset=%d tag_data_offset=%d| "
"global_offset=%d", input->buffer_size, input->key_data_offset,
input->key_id_data_offset, input->input_data_offset, input->iv_data_offset,
input->global_offset);
}
if (key_data) {
- LOG_ERR("Key=%p, key_size=%d, key_bits_size=%d", key_data->key.data, key_data->key.data_size,
+ LOG("Key=%p, key_size=%d, key_bits_size=%d", key_data->key.data, key_data->key.data_size,
key_data->key_bits_size);
}
if (key_id_data) {
- LOG_ERR("Key_id=%p, key_id_size=%d", key_id_data->data, key_id_data->data_size);
+ LOG("Key_id=%p, key_id_size=%d", key_id_data->data, key_id_data->data_size);
}
if (iv_data) {
- LOG_ERR("IV=%p, iv_size=%d", iv_data->data, iv_data->data_size);
+ LOG("IV=%p, iv_size=%d", iv_data->data, iv_data->data_size);
}
if (input_data) {
- LOG_ERR("Input=%p, input_size=%d", input_data->data, input_data->data_size);
+ LOG("Input=%p, input_size=%d", input_data->data, input_data->data_size);
}
if (ae_data) {
- LOG_ERR("Tag=%p, tag_size=%d, tagLen=%d, AADLen=%d, payloadLen=%d", ae_data->tag.data,
- ae_data->tag.data_size, ae_data->tagLen, ae_data->AADLen, ae_data->payloadLen);
+ LOG("aad.data=%p, aad.size=%d, tagLen=%d, AADLen=%d, payloadLen=%d", ae_data->aad.data,
+ ae_data->aad.data_size, ae_data->tagLen, ae_data->AADLen, ae_data->payloadLen);
}
if (out_data) {
- LOG_ERR("Out=%p, out_size=%d", out_data->data, out_data->data_size);
+ LOG("Out=%p, out_size=%d", out_data->data, out_data->data_size);
}
if (tag_data) {
- LOG_ERR("Tag=%p, tag_size=%d", tag_data->data, tag_data->data_size);
+ LOG("Tag=%p, tag_size=%d", tag_data->data, tag_data->data_size);
}
}
int KM_ParamsDeserializationInit(void *buffer, size_t buffer_size, SymmetricInput **out)
{
SymmetricInput *self = (SymmetricInput *) buffer;
- if (NULL == buffer || sizeof(SymmetricInput) > buffer_size) {
- LOG_ERR("Invalid input");
+ if (buffer == NULL) {
+ LOG("Invalid input buffer");
+ return -1;
+ }
+ if (sizeof(SymmetricInput) > buffer_size) {
+ LOG("Serialization buffer not big enough.");
return -1;
}
if (PSMagic_SymmetricInput != self->magic) {
- LOG_ERR("Invalid magic.");
+ LOG("Invalid magic.");
return -1;
}
if (self->buffer_size > buffer_size) {
- LOG_ERR("Serialized object was bigger then input buffer.");
+ LOG("Serialized object was bigger than input buffer.");
return -1;
}
int KM_ParamsSerializationInit(void *buffer, size_t buffer_size, SymmetricInput **out)
{
SymmetricInput *self = (SymmetricInput *) buffer;
- if (NULL == buffer || sizeof(SymmetricInput) > buffer_size) {
- LOG_ERR("Invalid input.");
+ if (buffer == NULL) {
+ LOG("Invalid input buffer");
+ return -1;
+ }
+ if (sizeof(SymmetricInput) > buffer_size) {
+ LOG("Serialization buffer not big enough");
return -1;
}
+
memset(self, 0, sizeof(SymmetricInput));
self->magic = PSMagic_SymmetricInput;
self->buffer_size = buffer_size;
return 0;
}
-int KM_ParamsSerializeInputData(SymmetricInput *self, void *data, size_t data_size)
+int KM_ParamsSerializeInputData(SymmetricInput *self, const void *data, size_t data_size)
{
Data *ptr = NULL;
uint32_t ret = 0;
if (0 != self->input_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->input_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->input_data_offset=%d",
data, data_size, self->input_data_offset);
return -1;
}
return 0;
}
-int KM_ParamsSerializeIVData(SymmetricInput *self, void *data, size_t data_size)
+int KM_ParamsSerializeIVData(SymmetricInput *self, const void *data, size_t data_size)
{
Data *ptr = NULL;
uint32_t ret = 0;
if (0 != self->iv_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->iv_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->iv_data_offset=%d",
data, data_size, self->iv_data_offset);
return -1;
}
}
int KM_ParamsSerializeAEData(SymmetricInput *self, uint32_t tagLen, uint32_t AADLen,
- uint32_t payloadLen, void *tag, uint32_t tag_size)
+ uint32_t payloadLen, const void *aad, size_t aad_size)
{
AEData *ptr = NULL;
uint32_t ret = 0;
if (0 != self->ae_data_offset) {
- LOG_ERR("Invalid parameters. (self->ae_data_offset=%d", self->ae_data_offset);
+ LOG("Invalid parameters. (self->ae_data_offset=%d", self->ae_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, tag, tag_size, sizeof(AEData), PSMagic_AEData,
+ ret = KM_ParamsSerializeData(self, aad, aad_size, sizeof(AEData), PSMagic_AEData,
(Data **) &ptr);
if (ret != 0) {
return ret;
ptr->payloadLen = payloadLen;
self->ae_data_offset = self->global_offset;
- self->global_offset += sizeof(AEData) + addAlignment(tag_size);
+ self->global_offset += sizeof(AEData) + addAlignment(aad_size);
return 0;
}
-int KM_ParamsSerializeOutData(SymmetricInput *self, void *data, uint32_t data_size)
+int KM_ParamsSerializeOutData(SymmetricInput *self, const void *data, size_t data_size)
{
Data *ptr = NULL;
uint32_t ret = 0;
if (0 != self->out_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->out_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->out_data_offset=%d",
data, data_size, self->out_data_offset);
return -1;
}
return 0;
}
-int KM_ParamsSerializeTagData(SymmetricInput *self, void *data, uint32_t data_size)
+int KM_ParamsSerializeTagData(SymmetricInput *self, const void *data, size_t data_size)
{
Data *ptr = NULL;
uint32_t ret = 0;
if (0 != self->tag_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->tag_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->tag_data_offset=%d",
data, data_size, self->tag_data_offset);
return -1;
}
return 0;
}
-int KM_ParamsSerializeKey(SymmetricInput *self, void *data, size_t data_size,
- size_t bits_size)
+int KM_ParamsSerializeKey(SymmetricInput *self, const void *data, size_t data_size,
+ uint32_t bits_size)
{
Key *ptr = NULL;
uint32_t ret = 0;
if (0 != self->key_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
data, data_size, self->key_data_offset);
return -1;
}
return 0;
}
-int KM_ParamsSerializeKeyId(SymmetricInput *self, void *data, size_t data_size)
+int KM_ParamsSerializeKeyId(SymmetricInput *self, const void *data, size_t data_size)
{
KeyId *ptr = NULL;
uint32_t ret = 0;
if (0 != self->key_id_data_offset) {
- LOG_ERR("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
+ LOG("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
data, data_size, self->key_id_data_offset);
return -1;
}
ALGO_RSA_GEN,
} tz_algo_type;
+// TODO this must be somehow confronted with TEE_OBJECT_ID_MAX_LEN
+#define KM_KEY_ID_SIZE 64
+
+// Errors
+#define KM_TA_SUCCESS 0
+#define KM_TA_ERROR_GENERIC 1
+#define KM_TA_ERROR_AUTH_FAILED 2
+
#endif //__REE_CA_KM_H__
TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
uint32_t AADLen, uint32_t payloadLen, void *data, uint32_t data_size,
- void *out, uint32_t *out_size, void *tag, uint32_t tag_size);
+ void *tag, uint32_t tag_size, void *out, uint32_t *out_size);
#endif // __CRYPTO_AUTH_H__
--- /dev/null
+/*
+ * Copyright (c) 2017 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
+ */
+/*
+ * @file crypto_hash.h
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version 1.0
+ * @brief Implementation of Global Platform Internal API usage (hashing)
+ */
+#ifndef __CRYPTO_HASH_H__
+#define __CRYPTO_HASH_H__
+
+#include <tee_internal_api.h>
+
+TEE_Result KM_DeriveKey(TEE_OperationHandle op, void *salt, uint32_t salt_size,
+ uint32_t key_bits_size, TEE_ObjectHandle* out_key);
+
+#endif // __CRYPTO_AUTH_H__
+++ /dev/null
-/*
- * Copyright (c) 2017 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
- */
-/*
- * @file crypto_hash.h
- * @author Lukasz Kostyra (l.kostyra@samsung.com)
- * @version 1.0
- * @brief Implementation of Global Platform Internal API usage (hashing)
- */
-#ifndef __CRYPTO_HASH_H__
-#define __CRYPTO_HASH_H__
-
-#include <tee_internal_api.h>
-
-TEE_Result KM_Hash(TEE_OperationHandle hndl, void *iv, uint32_t iv_size,
- void *data, uint32_t data_size, void *out, uint32_t *out_size);
-
-#endif // __CRYPTO_AUTH_H__
#include <tee_internal_api.h>
-#define AES_BLOCK_SIZE 16
+// separate function for AES CFB - not supported by pure GP API
+TEE_Result KM_SymmetricCrypt_AES_CFB(void *key_id, uint32_t key_id_size, uint32_t mode,
+ void *iv, uint32_t iv_size, void *input, uint32_t input_size,
+ void *output, uint32_t *output_size);
TEE_Result KM_SymmetricCrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, void *input,
- uint32_t input_size, void *output, uint32_t *output_size);
+ uint32_t input_size, void *output, uint32_t *output_size);
#endif // __CRYPTO_SYMMETRIC_H__
TEE_Result KM_CreateRandomKey(uint32_t tee_key_type, uint32_t key_bits_size, TEE_ObjectHandle *hndl);
-TEE_Result KM_CreateOperation(TEE_ObjectHandle obj_hndl, uint32_t algo, uint32_t mode,
+TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo, uint32_t mode,
uint32_t key_bits_size, TEE_OperationHandle *hndl);
TEE_Result KM_CreateOperationWithKey(void *key, uint32_t key_size, uint32_t type, uint32_t mode,
TEE_Result KM_CreateOperationWithKeyId(void *key_id, uint32_t key_id_size, uint32_t mode,
uint32_t algo, TEE_OperationHandle *oper_hndl);
+// saves the key inside persistent object
TEE_Result KM_SaveKey(void *data, size_t data_size, TEE_ObjectHandle key, void *objId,
size_t objId_size);
+// extracts key from generic object, creates temporarily new object with given type
+// and saves the key to persistent object for further use
+TEE_Result KM_SaveDerivedKey(TEE_ObjectHandle key, uint32_t type, uint32_t keyBitsSize,
+ void *objId, size_t objId_size);
+
TEE_Result KM_OpenKey(void *objId, size_t objId_size, uint32_t *key_bits_size,
TEE_ObjectHandle *hndl);
#include <stdlib.h>
#include <tee_internal_api.h>
+#include <tee_internal_api_extensions.h>
#include <ca_km.h>
#include <internal.h>
#include <crypto_symmetric.h>
#include <crypto_auth.h>
-#include <crypto_hash.h>
+#include <crypto_derive.h>
#include <serialization.h>
#include <cmd_exec.h>
#include <log.h>
// random value to mark unsupported algorithm
#define KM_TA_ALG_AES_CFB 0x50005050
+const uint32_t AES_BLOCK_SIZE = 16; // in bytes
+
+
static uint32_t KM_AlgoType2TeeType(int algo)
{
switch (algo) {
uint32_t type = KM_AlgoType2TeeType(param[0].value.a);
uint32_t key_bits_size = param[0].value.b;
- uint32_t objId_size = TEE_OBJECT_ID_MAX_LEN;
+
+ uint32_t objId_size = KM_KEY_ID_SIZE;
uint32_t *objId = (uint32_t*)malloc(objId_size);
if (objId == NULL) {
- return TEE_ERROR_OUT_OF_MEMORY;
+ LOG("Failed to allocate object ID buffer");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
}
ret = KM_CreateRandomKey(type, key_bits_size, &hndl);
if (TEE_SUCCESS != ret) {
+ LOG("Failed to randomize new key");
goto clean;
}
ret = KM_SaveKey(NULL, 0, hndl, objId, objId_size);
if (TEE_SUCCESS != ret) {
+ LOG("Failed to save generated key");
goto clean;
}
if (0 != KM_ParamsSerializationInit(param[1].memref.buffer, param[1].memref.size,
&input) || 0 != KM_ParamsSerializeKeyId(input, objId, objId_size)) {
+ LOG("Failed to serialize key to output buffer");
ret = TEE_ERROR_BAD_PARAMETERS;
}
TEE_Result KM_ExecCmdGenerateKeyPwd(TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
- TEE_ObjectHandle hndl = TEE_HANDLE_NULL;
+ TEE_ObjectHandle derivedKey = TEE_HANDLE_NULL;
TEE_OperationHandle op = TEE_HANDLE_NULL;
SymmetricInput *input = NULL;
InputData *input_data = NULL;
IVData *iv_data = NULL;
- void *hashed = NULL;
- size_t hashed_size = 0;
- uint32_t type = KM_AlgoType2TeeType(param[0].value.a);
uint32_t key_bits_size = param[0].value.b;
uint32_t objId_size = TEE_OBJECT_ID_MAX_LEN;
uint32_t *objId = (uint32_t*)malloc(objId_size);
if (objId == NULL) {
+ LOG("Failed to allocate object ID buffer");
ret = TEE_ERROR_OUT_OF_MEMORY;
goto clean;
}
if (KM_ParamsDeserializationInit(param[1].memref.buffer, param[1].memref.size, &input) != 0
|| KM_ParamsDeserializeInputData(input, &input_data) != 0
|| KM_ParamsDeserializeIVData(input, &iv_data) != 0) {
+ LOG("Failed to deserialize input data");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
- hashed_size = input_data->data_size + AES_BLOCK_SIZE;
- hashed = malloc(hashed_size);
- if (hashed == NULL) {
- ret = TEE_ERROR_OUT_OF_MEMORY;
- goto clean;
- }
-
- ret = TEE_AllocateOperation(&op, TEE_ALG_HMAC_SHA1, TEE_MODE_MAC, key_bits_size);
+ ret = KM_CreateOperationWithKey(input_data->data, input_data->data_size, TEE_TYPE_PBKDF2_PASSWORD,
+ TEE_MODE_DERIVE, TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY,
+ key_bits_size, &op);
if (TEE_SUCCESS != ret) {
- LOG("Failed to allocate HMAC operation");
+ LOG("Failed to create derive operation: %x", ret);
goto clean;
}
- ret = KM_Hash(op, iv_data->data, iv_data->data_size, input_data->data,
- input_data->data_size, hashed, &hashed_size);
- TEE_FreeOperation(op);
-
+ ret = KM_DeriveKey(op, iv_data->data, iv_data->data_size, key_bits_size, &derivedKey);
if (TEE_SUCCESS != ret) {
- LOG("Failed to hash key");
+ LOG("Failed to hash key: %x", ret);
goto clean;
}
- ret = KM_CreateKey(type, key_bits_size, 0, 0, &hndl);
- if (TEE_SUCCESS != ret) {
- LOG("Failed to create new key");
- goto clean;
- }
- ret = KM_SaveKey(hashed, hashed_size, hndl, objId, objId_size);
+ ret = KM_SaveDerivedKey(derivedKey, TEE_TYPE_AES, key_bits_size, objId, objId_size);
if (TEE_SUCCESS != ret) {
- LOG("Failed to save new key");
+ LOG("Failed to save new key: %x", ret);
goto clean;
}
if (0 != KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size,
&input) || 0 != KM_ParamsSerializeKeyId(input, objId, objId_size)) {
+ LOG("Failed to serialize output data");
ret = TEE_ERROR_BAD_PARAMETERS;
}
clean:
- free(hashed);
+ TEE_FreeTransientObject(derivedKey);
+ if (op != TEE_HANDLE_NULL) TEE_FreeOperation(op);
free(objId);
return ret;
}
TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
- TEE_OperationHandle hndl = TEE_HANDLE_NULL;
+ TEE_OperationHandle operation = TEE_HANDLE_NULL;
SymmetricInput *input = NULL;
InputData *input_data = NULL;
IVData *iv_data = NULL;
KeyId *key_id_data = NULL;
Key *key_data = NULL;
+ char ownIVFlag = 0;
uint32_t *iv = NULL;
uint32_t iv_size = 0;
return TEE_ERROR_BAD_PARAMETERS;
}
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo,
- &hndl);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type, mode,
- algo, key_data->key_bits_size, &hndl);
- }
-
- if (TEE_SUCCESS != ret) {
- return ret;
- }
-
- // LKTODO check for padding and raise error if NOPAD is in effect
out_size_pad = AES_BLOCK_SIZE - (input_data->data_size % AES_BLOCK_SIZE);
if (out_size_pad == AES_BLOCK_SIZE)
out_size_pad = 0;
ret = TEE_ERROR_OUT_OF_MEMORY;
goto clean;
}
+
if (iv_data) {
iv = iv_data->data;
iv_size = iv_data->data_size;
+ } else {
+ // create empty (zeroed) IV based on AES block size
+ ownIVFlag = 1;
+ iv_size = AES_BLOCK_SIZE;
+ iv = malloc(iv_size);
+ if (iv == NULL) {
+ LOG("Failed to allocate IV buffer");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+ memset(iv, 0x00, iv_size);
+ }
+
+ if (algo == KM_TA_ALG_AES_CFB) {
+ ret = KM_SymmetricCrypt_AES_CFB(key_id_data->data, key_id_data->data_size, mode, iv, iv_size,
+ input_data->data, input_data->data_size, out, &out_size);
+ } else {
+ if (key_id_data) {
+ ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo, &operation);
+ } else if (key_data) {
+ type = KM_AlgoType2TeeType(param[0].value.a);
+ ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type, mode,
+ algo, key_data->key_bits_size, &operation);
+ }
+
+ if (TEE_SUCCESS != ret) {
+ goto clean;
+ }
+
+ ret = KM_SymmetricCrypt(operation, iv, iv_size, input_data->data, input_data->data_size, out, &out_size);
}
- ret = KM_SymmetricCrypt(hndl, iv, iv_size, input_data->data, input_data->data_size, out, &out_size);
if (TEE_SUCCESS != ret) {
goto clean;
}
out_size -= out_size_pad;
- LOGD("out_size = %u", out_size);
+ LOGD("LKDEBUG out_size = %u", out_size);
if (0 != KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size, &input)
|| 0 != KM_ParamsSerializeOutData(input, out, out_size)) {
}
clean:
- if (out) free(out);
- TEE_FreeOperation(hndl);
+ free(out);
+ if (ownIVFlag) free(iv);
+ if (operation != TEE_HANDLE_NULL) TEE_FreeOperation(operation);
return ret;
}
KeyId *key_id_data = NULL;
Key *key_data = NULL;
AEData *ae_data = NULL;
+ TagData *tag_data = NULL;
void *out = NULL;
uint32_t out_size = 0;
uint32_t mode = KM_Cmd2TeeMode(commandID);
if (ALGO_AES_GCM != param[0].value.a) {
- LOG("Invalid key type=:%d.", param[0].value.a);
+ LOG("Invalid key type: %d.", param[0].value.a);
return TEE_ERROR_BAD_PARAMETERS;
}
|| 0 != KM_ParamsDeserializeIVData(input, &iv_data)
|| 0 != KM_ParamsDeserializeKey(input, &key_data)
|| 0 != KM_ParamsDeserializeKeyId(input, &key_id_data)
- || 0 != KM_ParamsDeserializeAEData(input, &ae_data)) {
+ || 0 != KM_ParamsDeserializeAEData(input, &ae_data)
+ || 0 != KM_ParamsDeserializeTagData(input, &tag_data)) {
return TEE_ERROR_BAD_PARAMETERS;
}
if (!ae_data || !input_data) {
LOG("There need to be AEData or InputData!");
return TEE_ERROR_BAD_PARAMETERS;
}
- if (KM_CheckAESMode(algo, ae_data->tagLen)) {
- LOG("Tag has invalid length. (tagLen=%d)", ae_data->tagLen);
+
+ if (commandID == CMD_DECRYPT && !tag_data) {
+ LOG("Tag data is needed for verification");
return TEE_ERROR_BAD_PARAMETERS;
}
- KM_ParamsDump(input, input_data, iv_data, key_data, NULL, ae_data, NULL, NULL);
+ KM_ParamsDump(input, input_data, iv_data, key_data, NULL, ae_data, NULL, tag_data);
if ((NULL != key_data && NULL != key_id_data) || (NULL == key_data && NULL == key_id_data)) {
LOG("You need to specify key or keyId. At least one and only one.");
return TEE_ERROR_BAD_PARAMETERS;
}
+ if (KM_CheckAESMode(algo, ae_data->tagLen)) {
+ LOG("Tag has invalid length. (tagLen=%d)", ae_data->tagLen);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
if (key_id_data) {
ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo,
&hndl);
if (TEE_SUCCESS != ret) {
return ret;
}
- out = malloc(input_data->data_size);
- out_size = input_data->data_size;
+
+ out_size = input_data->data_size + AES_BLOCK_SIZE;
+ out = malloc(out_size);
+ if (out == NULL) {
+ LOG("Failed to allocate output buffer");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
if (CMD_ENCRYPT == commandID) {
- tag = malloc(ae_data->tagLen);
- tag_size = ae_data->tagLen;
+ tag_size = ae_data->tagLen / 8; // convert tag size to bytes
+ tag = malloc(tag_size);
+ if (tag == NULL) {
+ LOG("Failed to allocate tag buffer");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
ret = KM_AuthEncrypt(hndl, iv_data->data, iv_data->data_size, ae_data->tagLen,
- ae_data->AADLen, ae_data->payloadLen, input_data->data,
- input_data->data_size, out, &out_size, tag, &tag_size);
+ ae_data->AADLen, ae_data->payloadLen, input_data->data,
+ input_data->data_size, out, &out_size, tag, &tag_size);
} else {
ret = KM_AuthDecrypt(hndl, iv_data->data, iv_data->data_size, ae_data->tagLen,
- ae_data->AADLen, ae_data->payloadLen, input_data->data,
- input_data->data_size, out, &out_size, ae_data->tag.data,
- ae_data->tag.data_size);
+ ae_data->AADLen, ae_data->payloadLen, input_data->data,
+ input_data->data_size, tag_data->data, tag_data->data_size,
+ out, &out_size);
}
+
if (TEE_SUCCESS != ret) {
goto clean;
}
+
if (0 != KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size, &input)
|| 0 != KM_ParamsSerializeOutData(input, out, out_size)) {
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
+
if (tag) {
if (0 != KM_ParamsSerializeTagData(input, tag, tag_size)) {
ret = TEE_ERROR_BAD_PARAMETERS;
}
}
+
clean:
free(out);
- TEE_FreeOperation(hndl);
+ free(tag);
+ if (hndl != TEE_HANDLE_NULL) TEE_FreeOperation(hndl);
return ret;
}
{
TEE_Result ret = TEE_SUCCESS;
+ LOG("Tag length: %u", tagLen);
ret = TEE_AEInit(hndl, iv, (size_t) iv_size, tagLen, AADLen, payloadLen);
if (TEE_SUCCESS != ret) {
- LOG("KM_AuthCryptoInit failed with error=%x.", ret);
+ LOG("TEE_AEInit failed with error=%x.", ret);
return ret;
}
+
+ LOG("out_size %u tag_size %u", *out_size, *tag_size);
ret = TEE_AEEncryptFinal(hndl, data, data_size, out, out_size, tag, tag_size);
if (TEE_SUCCESS != ret) {
LOG("TEE_AEEncryptFinal failed with error=%x.", ret);
}
+ LOG("out_size %u tag_size %u", *out_size, *tag_size);
+
return ret;
}
TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
uint32_t AADLen, uint32_t payloadLen, void *data, uint32_t data_size,
- void *out, uint32_t *out_size, void *tag, uint32_t tag_size)
+ void *tag, uint32_t tag_size, void *out, uint32_t *out_size)
{
TEE_Result ret = TEE_SUCCESS;
ret = TEE_AEInit(hndl, iv, (size_t) iv_size, tagLen, AADLen, payloadLen);
if (TEE_SUCCESS != ret) {
- LOG("KM_AuthCryptoInit failed with error=%x.", ret);
+ LOG("TEE_AEInit failed with error=%x.", ret);
return ret;
}
ret = TEE_AEDecryptFinal(hndl, data, data_size, out, out_size, tag, tag_size);
--- /dev/null
+/*
+ * Copyright (c) 2017 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
+ */
+/*
+ * @file crypto_hash.c
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version 1.0
+ * @brief Implementation of Global Platform Internal API usage (hashing)
+ */
+
+#include <crypto_derive.h>
+#include <tee_internal_api_extensions.h>
+#include <log.h>
+
+const uint32_t ITERATION_COUNT = 1024;
+
+TEE_Result KM_DeriveKey(TEE_OperationHandle op, void *salt, uint32_t salt_size,
+ uint32_t key_bits_size, TEE_ObjectHandle* out_key)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ const uint32_t ATTRIBUTE_COUNT = 3;
+ TEE_Attribute attrs[ATTRIBUTE_COUNT];
+ TEE_ObjectHandle derived_key = TEE_HANDLE_NULL;
+
+ LOG("LKDEBUG key_bits %u", key_bits_size);
+ ret = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, key_bits_size, &derived_key);
+ if (TEE_SUCCESS != ret) {
+ LOG("TEE_AllocateTransientObject has failed with=%x. %x %u", ret, TEE_TYPE_AES, key_bits_size);
+ return ret;
+ }
+
+ uint32_t key_bytes = key_bits_size / 8;
+ TEE_InitValueAttribute(&attrs[0], TEE_ATTR_PBKDF2_ITERATION_COUNT, ITERATION_COUNT, 0);
+ TEE_InitValueAttribute(&attrs[1], TEE_ATTR_PBKDF2_DKM_LENGTH, key_bytes, 0);
+ TEE_InitRefAttribute(&attrs[2], TEE_ATTR_PBKDF2_SALT, salt, salt_size);
+
+ TEE_DeriveKey(op, attrs, ATTRIBUTE_COUNT, derived_key);
+ *out_key = derived_key;
+
+ return ret;
+}
+++ /dev/null
-/*
- * Copyright (c) 2017 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
- */
-/*
- * @file crypto_hash.c
- * @author Lukasz Kostyra (l.kostyra@samsung.com)
- * @version 1.0
- * @brief Implementation of Global Platform Internal API usage (hashing)
- */
-
-#include <crypto_hash.h>
-#include <log.h>
-
-TEE_Result KM_Hash(TEE_OperationHandle hndl, void *iv, uint32_t iv_size,
- void *data, uint32_t data_size, void *out, uint32_t *out_size)
-{
- TEE_Result ret = TEE_SUCCESS;
-
- TEE_MACInit(hndl, iv, iv_size);
-
- ret = TEE_MACComputeFinal(hndl, data, data_size, out, out_size);
- if (ret != TEE_SUCCESS) {
- LOG("Failed to compute MAC: %x", ret);
- }
-
- return ret;
-}
#include <crypto_symmetric.h>
#include <log.h>
+#include <internal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-TEE_Result KM_SymmetricCrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, void *input,
- uint32_t input_size, void *output, uint32_t *output_size)
+extern const uint32_t AES_BLOCK_SIZE;
+
+
+TEE_Result KM_SymmetricCrypt_AES_CFB(void *key_id, uint32_t key_id_size, uint32_t mode,
+ void *iv, uint32_t iv_size, void *input, uint32_t input_size,
+ void *output, uint32_t *output_size)
{
+ TEE_OperationHandle op = TEE_HANDLE_NULL;
TEE_Result ret = TEE_SUCCESS;
- uint32_t emptyIVFlag = 0;
-
- if (iv == NULL) {
- // Create empty initialization vector
- emptyIVFlag = 1;
- iv_size = AES_BLOCK_SIZE; // TODO for all algs
- iv = malloc(iv_size);
- if (iv == NULL) {
- return TEE_ERROR_OUT_OF_MEMORY;
- }
- memset(iv, 0x00, iv_size);
- }
- TEE_CipherInit(hndl, iv, iv_size);
+ uint32_t input_index = 0;
+ uint32_t ecb_input[AES_BLOCK_SIZE];
+ uint32_t ecb_output[AES_BLOCK_SIZE];
+ uint32_t* input_buf = (uint32_t*)input;
+ uint32_t* output_buf = (uint32_t*)output;
+ uint32_t ecb_index = 0;
+ uint32_t ecb_out_size = AES_BLOCK_SIZE;
+ if (output_size)
+ *output_size = 0;
- ret = TEE_CipherDoFinal(hndl, input, input_size, output, output_size);
- if (TEE_SUCCESS != ret) {
- LOG("TEE_CipherDoFinal has failed with=%x.", ret);
- if (emptyIVFlag)
- free(iv);
- return ret;
+ // below code assumes AES CFB mode - 128/192/256 bit key
+
+ if (input_size % AES_BLOCK_SIZE != 0) {
+ LOG("Data not padded to block size (missing %u bytes)", AES_BLOCK_SIZE - (input_size % AES_BLOCK_SIZE));
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
}
- if (emptyIVFlag) {
- free(iv);
- iv = NULL;
+ // CFB always uses AES in encryption mode
+ ret = KM_CreateOperationWithKeyId(key_id, key_id_size, TEE_MODE_ENCRYPT, TEE_ALG_AES_ECB_NOPAD, &op);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create AES CFB operation: %x", ret);
+ goto clean;
}
+ // copy IV as our starting data
+ memcpy(ecb_input, iv, AES_BLOCK_SIZE);
+
+ for (input_index = 0; input_index < input_size / sizeof(uint32_t); input_index += (AES_BLOCK_SIZE / sizeof(uint32_t))) {
+ // pass IV/previous ciphertext through cipher block
+ ret = KM_SymmetricCrypt(op, iv, iv_size, ecb_input, AES_BLOCK_SIZE, ecb_output, &ecb_out_size);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to pass data through cipher: %x", ret);
+ goto clean;
+ }
+
+ if (ecb_out_size != AES_BLOCK_SIZE) {
+ LOG("Mismatched expected output and result from ECB cipher: ECB result is %u", ecb_out_size);
+ ret = TEE_ERROR_GENERIC;
+ goto clean;
+ }
+
+ // result of this is now XORed with input (plaintext/ciphertext)
+ for (ecb_index = 0; ecb_index < AES_BLOCK_SIZE / sizeof(uint32_t); ++ecb_index) {
+ output_buf[input_index + ecb_index] = ecb_output[ecb_index] ^ input_buf[input_index + ecb_index];
+ }
+
+ if (mode == TEE_MODE_ENCRYPT) {
+ // the result of XOR is our encryption result and new ecb_input
+ memcpy(ecb_input, &output_buf[input_index], AES_BLOCK_SIZE);
+ } else {
+ // input ciphertext is our new ecb_input
+ memcpy(ecb_input, &input_buf[input_index], AES_BLOCK_SIZE);
+ }
+
+ if (output_size)
+ *output_size += AES_BLOCK_SIZE;
+ }
+
+clean:
+ if (op != TEE_HANDLE_NULL) TEE_FreeOperation(op);
return ret;
}
-/*
-TEE_Result KM_SymmetricAE(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, void *input,
- uint32_t input_size, void *output, uint32_t *output_size)
+
+TEE_Result KM_SymmetricCrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, void *input,
+ uint32_t input_size, void *output, uint32_t *output_size)
{
TEE_Result ret = TEE_SUCCESS;
+ TEE_CipherInit(hndl, iv, iv_size);
+
+ ret = TEE_CipherDoFinal(hndl, input, input_size, output, output_size);
+ if (TEE_SUCCESS != ret) {
+ LOG("TEE_CipherDoFinal has failed with=%x.", ret);
+ return ret;
+ }
return ret;
-}*/
\ No newline at end of file
+}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <tee_internal_api.h>
-#include <trace.h>
-#include <string.h>
-
-static uint32_t HMAC_password(void *psswrd, int passwrd_size)
-{
- TEE_Result ret;
- TEE_ObjectHandle hmac_key = (TEE_ObjectHandle) NULL;
- TEE_OperationHandle hmac_handle = (TEE_OperationHandle) NULL;
- uint32_t alg = TEE_ALG_HMAC_SHA1;
- uint32_t fn_ret = 1; /* Initialized error return */
-
- ret = TEE_AllocateTransientObject(TEE_TYPE_HMAC_SHA1, passwrd_size, &hmac_key);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("Failed to alloc transient object handle : 0x%x", ret);
- goto err;
- }
-
- ret = TEE_GenerateKey(hmac_key, key_size, (TEE_Attribute *)NULL, 0);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("Generate key failure : 0x%x", ret);
- goto err;
- }
-
- ret = TEE_AllocateOperation(&hmac_handle, alg, TEE_MODE_MAC, passwrd_size);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("Cant alloc first handler");
- goto err;
- }
-
- ret = TEE_SetOperationKey(hmac_handle, hmac_key);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("Failed to set first operation key : 0x%x", ret);
- goto err;
- }
-
- TEE_MACInit(hmac_handle, NULL, 0);
-
- TEE_MACUpdate(hmac_handle, msg, msg_len);
-
- ret = TEE_MACComputeFinal(hmac_handle, NULL, 0, mac, &mac_len);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("First final failed : 0x%x", ret);
- goto err;
- }
-
- TEE_MACInit(hmac_handle2, NULL, 0);
-
- ret = TEE_MACCompareFinal(hmac_handle2, msg, msg_len, mac, mac_len);
- if (ret != TEE_SUCCESS) {
- PRI_FAIL("MAC Invalid");
- goto err;
- }
-
- fn_ret = 0; /* OK */
-err:
- TEE_FreeTransientObject(hmac_key);
- TEE_FreeOperation(hmac_handle);
- TEE_FreeOperation(hmac_handle2);
- TEE_Free(mac);
- TEE_Free(msg);
-
- if (fn_ret == 0)
- PRI_OK("-");
-
- return fn_ret;
-}
#include <internal.h>
#include <log.h>
+#include <tee_internal_api_extensions.h>
+#include <stdlib.h>
#ifndef TEE_DATA_FLAG_OVERWRITE
#define TEE_DATA_FLAG_OVERWRITE TEE_DATA_FLAG_EXCLUSIVE
TEE_Attribute attr;
TEE_Result ret = TEE_SUCCESS;
- TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_size);
+ if (tee_key_type == TEE_TYPE_PBKDF2_PASSWORD)
+ TEE_InitRefAttribute(&attr, TEE_ATTR_PBKDF2_PASSWORD, key, key_size);
+ else
+ TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_size);
+
ret = TEE_AllocateTransientObject(tee_key_type, key_bits_size, hndl);
if (TEE_SUCCESS != ret) {
LOG("TEE_AllocateTransientObject has failed with=%x. Arguments=(tee_key_type=%X, "
return ret;
}
-TEE_Result KM_CreateOperation(TEE_ObjectHandle obj_hndl, uint32_t algo, uint32_t mode,
+TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo, uint32_t mode,
uint32_t key_bits_size, TEE_OperationHandle *hndl)
{
TEE_Result ret = TEE_SUCCESS;
return ret;
}
- ret = TEE_SetOperationKey(*hndl, obj_hndl);
+ LOG("OpKey: %p %p", (void*)*hndl, (void*)op_key_hndl);
+ ret = TEE_SetOperationKey(*hndl, op_key_hndl);
if (TEE_SUCCESS != ret) {
LOG("TEE_SetOperationKey has failed with=%x.", ret);
TEE_FreeOperation(*hndl);
ret = KM_CreateKey(type, key_bits_size, key, key_size, &hndl);
if (TEE_SUCCESS != ret) {
+ LOG("Failed to create key: %x", ret);
return ret;
}
+
ret = KM_CreateOperation(hndl, algo, mode, key_bits_size, oper_hndl);
+ TEE_FreeTransientObject(hndl);
+
if (TEE_SUCCESS != ret) {
LOG("Failed to create operation: %x", ret);
- return ret;
}
- TEE_FreeTransientObject(hndl);
return ret;
}
uint32_t algo, TEE_OperationHandle *oper_hndl)
{
TEE_Result ret = TEE_SUCCESS;
- TEE_ObjectHandle hndl = TEE_HANDLE_NULL;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_ObjectInfo keyInfo;
uint32_t ks = 0;
- ret = KM_OpenKey(key_id, key_id_size, &ks, &hndl);
+ ret = KM_OpenKey(key_id, key_id_size, &ks, &key);
if (TEE_SUCCESS != ret) {
+ LOG("Failed to open key: %x", ret);
return ret;
}
- ret = KM_CreateOperation(hndl, algo, mode, ks, oper_hndl);
+ TEE_GetObjectInfo(key, &keyInfo);
+
+ ret = KM_CreateOperation(key, algo, mode, keyInfo.keySize, oper_hndl);
+ TEE_CloseObject(key);
+
if (TEE_SUCCESS != ret) {
LOG("Failed to create operation with key id: %x", ret);
- return ret;
}
- TEE_CloseObject(hndl);
return ret;
}
ret = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size, flags, key, data,
data_size, &pers_handl);
+ TEE_CloseObject(pers_handl);
+
if (TEE_SUCCESS != ret) {
LOG("TEE_CreatePersistentObject has failed with=%x.", ret);
}
+ return ret;
+}
- TEE_CloseObject(pers_handl);
+TEE_Result KM_SaveDerivedKey(TEE_ObjectHandle key, uint32_t type, uint32_t keyBitsSize,
+ void * objId, size_t objId_size)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_Attribute attr;
+ TEE_ObjectInfo info;
+ TEE_ObjectHandle tempKey = TEE_HANDLE_NULL;
+ void* buffer = NULL;
+ uint32_t bufferSize = 0;
+
+ // extract object's attributes
+ TEE_GetObjectInfo(key, &info);
+
+ LOGD("LKDEBUG Key info:");
+ LOGD(" objType: %x", info.objectType);
+ LOGD(" keySize: %x", info.keySize);
+ LOGD(" maxKeySize: %x", info.maxKeySize);
+ LOGD(" objectUsage: %x", info.objectUsage);
+ LOGD(" dataSize: %x", info.dataSize);
+ LOGD(" dataPosition: %x", info.dataPosition);
+ LOGD(" handleFlags: %x", info.handleFlags);
+
+ if (info.objectType != TEE_TYPE_GENERIC_SECRET) {
+ LOG("Failed to save derived key - provided object is not a derived generic secret");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ // convert key bits size to get key buffer size in bytes
+ bufferSize = keyBitsSize / 8;
+ buffer = malloc(bufferSize);
+ if (buffer == NULL) {
+ LOG("Failed to allocate buffer for key data");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ ret = TEE_GetObjectBufferAttribute(key, TEE_ATTR_SECRET_VALUE, buffer, &bufferSize);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to acquire key from object: %x", ret);
+ goto clean;
+ }
+
+ // create new transient object to keep the key of wanted type
+ ret = TEE_AllocateTransientObject(type, keyBitsSize, &tempKey);
+ if (TEE_SUCCESS != ret) {
+ LOG("TEE_AllocateTransientObject has failed with=%x. Arguments=(type=%X, "
+ "key_bits_size=%d.", ret, type, keyBitsSize);
+ goto clean;
+ }
+
+ TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, buffer, bufferSize);
+
+ ret = TEE_PopulateTransientObject(tempKey, &attr, 1);
+ if (TEE_SUCCESS != ret) {
+ LOG("TEE_PopulateTransientObject has failed with=%x.", ret);
+ goto clean;
+ }
+
+ ret = KM_SaveKey(NULL, 0, tempKey, objId, objId_size);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to save derived key: %x", ret);
+ goto clean;
+ }
+
+clean:
+ TEE_FreeTransientObject(tempKey);
+ free(buffer);
return ret;
}
}
TEE_GetObjectInfo(*hndl, &info);
- *key_bits_size = info.maxObjectSize;
+ *key_bits_size = info.objectSize;
return ret;
}
return TEE_ERROR_BAD_PARAMETERS;
}
- switch (tee_key_type)
- {
- case TEE_TYPE_DES:
- case TEE_TYPE_DES3:
- case TEE_TYPE_AES:
- ret = TEE_GetObjectBufferAttribute(hndl, TEE_ATTR_SECRET_VALUE, buffer, buffer_size);
- break;
- case TEE_TYPE_RSA_KEYPAIR:
- LOG("Copy generated key for RSA.");
- break;
- default:
- LOG("Can't generate key. Unknown key type=%d.", tee_key_type);
- ret = TEE_ERROR_BAD_PARAMETERS;
+ switch (tee_key_type) {
+ case TEE_TYPE_DES:
+ case TEE_TYPE_DES3:
+ case TEE_TYPE_AES:
+ ret = TEE_GetObjectBufferAttribute(hndl, TEE_ATTR_SECRET_VALUE, buffer, buffer_size);
+ break;
+ case TEE_TYPE_RSA_KEYPAIR:
+ // TODO copy generated key for RSA
+ default:
+ LOG("Can't generate key. Unknown key type=%d.", tee_key_type);
+ ret = TEE_ERROR_BAD_PARAMETERS;
}
if (TEE_SUCCESS != ret) {
LOG("Getting object has failed with=%x for type=%d", ret, tee_key_type);
void KM_GenerateIV(void *iv, size_t iv_size)
{
- LOGD("iv: %p iv_size: %u", iv, iv_size);
+ LOGD("LKDEBUG iv: %p iv_size: %u", iv, iv_size);
TEE_GenerateRandom(iv, iv_size);
}
#include "log.h"
+#include <stdio.h>
#include <stdarg.h>
void log_msg(const char* type, const char* location, int line, const char* func,
srcs-y += ta_km.c
srcs-y += crypto_symmetric.c
+srcs-y += crypto_derive.c
srcs-y += crypto_auth.c
srcs-y += internal.c
-srcs-y += cmd_exec.c
\ No newline at end of file
+srcs-y += log.c
+srcs-y += cmd_exec.c
*/
#include <tee_internal_api.h>
+#include <tee_internal_api_extensions.h>
#include <ca_km.h>
#include <cmd_exec.h>
#include <log.h>
#include <internal.h>
+#ifdef S_VAR_NOT_USED
#undef S_VAR_NOT_USED
+#endif // S_VAR_NOT_USED
+
#define S_VAR_NOT_USED(variable) do { (void)(variable); } while (0);
TEE_Result TA_CreateEntryPoint(void)
break;
case CMD_GENERATE_IV:
LOGD("!!! Generate IV !!!");
- KM_GenerateIV(param[0].memref.buffer, param[0].memref.size);
+ KM_GenerateIV(param[1].memref.buffer, param[1].memref.size);
break;
case CMD_GENERATE_KEY_PWD:
- LOGD("!!! Generate key from PWD !!!");
+ LOGD("!!! Generate PWD !!!");
ret = KM_ExecCmdGenerateKeyPwd(param);
break;
case CMD_ENCRYPT:
ret = TEE_ERROR_BAD_PARAMETERS;
break;
}
- if (ALGO_AES_GCM == param[0].value.b) {
+ if (ALGO_AES_GCM == param[0].value.a) {
ret = KM_ExecCmdAuth(commandID, param);
} else {
ret = KM_ExecCmdSymmetric(commandID, param);
default:
LOG("Unknown commandID=%d.", commandID);
ret = TEE_ERROR_BAD_PARAMETERS;
- break;
+ }
+
+ // inform about successful operation, or about an error in authorization
+ // TEEC API has less return codes than TEE, so about some exceptional
+ // situations (like authorization failure) we must inform user in other ways
+ LOGD("Return value: %x", ret);
+ param[0].value.a = KM_TA_SUCCESS;
+ if (ret != TEE_SUCCESS) {
+ switch (ret) {
+ case TEE_ERROR_MAC_INVALID:
+ // error during auth cipher - revert return to success because
+ // TEE Client API does not support this error code and inform
+ // about it thorugh our own TA-specific return value
+ ret = TEE_SUCCESS;
+ param[0].value.a = KM_TA_ERROR_AUTH_FAILED;
+ break;
+ default:
+ // other errors can be added here as we need
+ param[0].value.a = KM_TA_ERROR_GENERIC;
+ break;
+ }
}
return ret;
+++ /dev/null
-/*
- * Copyright (c) 2017 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
- */
-/*
- * @file crypto_auth.c
- * @author RafaĆ Tyminski (r.tyminski@partner.samsung.com)
- * @version 1.0
- * @brief Implementation of Global Platform Internal API usage (authentication encryption)
- */
-
-#include <internal.h>
-#include <auth.h>
-
-#define PERSISTENT_ID_SIZE 64
-#define PERSISTENT_ID_SIZE 64
-#define MAX_IV_SIZE 16
-
-TEE_Result
-psswrd_crypt(char *passwrd, uint32_t algo, uint32_t mode, uint32_t key_bits_size, char *data, uint32_t data_size)
-{
- TEE_Result ret;
- TEE_ObjectHandle handl;
- TEE_ObjectHandle IVhandl;
- char iv[MAX_IV_SIZE];
- char objId[PERSISTENT_ID_SIZE];
-
- if (mode == TEE_MODE_ENCRYPT) {
- ret = generateIV(&IVhndl, &iv[0], sizeof(iv));
- if (TEE_SUCCESS != ret) {
- LOG("generateIV has failed with=%x.", ret);
- return ret;
- }
- }
-
- ret = auth_crypt_init(&hndl, TEE_TYPE_AES, key_bits_size, uint32_t key, uint32_t key_size, algo, mode, &iv[0],
- sizeof(iv), uint32_t tagLen, uint32_t AADLen, uint32_t payloadLen);
- if (mode == TEE_MODE_ENCRYPT) {
- ret = auth_encrypt_final(hndl, data, data_size, void *out, size_t *out_size, void *tag, size_t *tag_size);
- } else if (mode == TEE_MODE_DECRYPT) {
- ret = auth_encrypt_final(hndl, data, data_size, void *out, size_t *out_size, void *tag, size_t *tag_size);
- } else {
- LOG("Invalid mode=%x.", mode);
- }
- ret = saveKey(out, out_size, ivhndl, (void *) &objId[0], sizeof(objId));
- return 0;
-}