This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM62A7: Optee RPMB

Part Number: AM62A7

Tool/software:

hi, TI optee expert:
In order to support OPTEE RPMB secure storage, I have modified the configuration of optee-os and optee_client:
optee-os:
CFG_REE_FS ?= n
CFG_RPMB_FS ?= y
CFG_RPMB_ TESTKEY?= y
CFG_RPMB_WRITE_KEY ?= y
optee-client
      RPMB_EMU  = OFF
But I have encountered the following problem and I hope to get your help.
Additional explanation:
1.I have rewritten a 'Secure Storage' CA.
2. I wrote a file before, and the emmc rpmb counter has also changed
3. but Occasionally, it can be successful when reading from RPMB()
/*
 * Copyright (c) 2016, Linaro Limited
 * 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 <err.h>
#include <stdio.h>
#include <string.h>

/* OP-TEE TEE client API (built by optee_client) */
#include <tee_client_api.h>

/* For the UUID (found in the TA's h-file(s)) */
#include <hello_world_ta.h>


TEEC_Result res;
TEEC_Context ctx;
TEEC_Session sess;
TEEC_Operation op;

uint32_t err_origin;
void usage(void)
{
	printf("./xx  <action>\n\taction:HELLO_WORLD / OTP / HWRNG /SeWrite /SeRead /SeDelete /HOTP /RSA_encode /AES_encode /AES_decode\n"
		   "\n\tOTP:One Time Program\n"
		   "\tHOTP: HMAC based on One Time Password\n");
}
int HELLO_WORLD(void);
int OTP(void);
int HWRNG(void);
int SeWrite(void);
int SeRead(void);
int SeDelete(void);
int HOTP(void);
int RSA_encode(void);
int AES_encode(void);
int AES_decode(void);
int main(int argc, int **argv)
{

	if( argc != 2 )
	{
		usage();
		return -1;
	}
	/* Initialize a context connecting us to the TEE */
	res = TEEC_InitializeContext(NULL, &ctx);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InitializeContext failed with code 0x%x", res);

	if( strcmp(argv[1], "HELLO_WORLD") == 0) 
	{
		HELLO_WORLD();
	}
	else if (strcmp(argv[1], "OTP") == 0 )
	{
		OTP();
	}
	else if (strcmp(argv[1], "HWRNG") == 0 )
	{
		HWRNG();
	}
	else if (strcmp(argv[1], "SeWrite") == 0 )
	{
		SeWrite();
	}
	else if (strcmp(argv[1], "SeRead") == 0 )
	{
		SeRead();
	}
	else if (strcmp(argv[1], "SeDelete") == 0 )
	{
		SeDelete();
	}
	else if (strcmp(argv[1], "HOTP") == 0 )
	{
		HOTP();
	}
	else if (strcmp(argv[1], "RSA_encode") == 0 )
	{
		RSA_encode();
	}
	
	else if (strcmp(argv[1], "AES_encode") == 0 )
	{
		AES_encode();
	}
	else if (strcmp(argv[1], "AES_decode") == 0 )
	{
		AES_decode();
	}
	else
	{
		usage();
	}
	if( sess.session_id > 0 )
	{
		TEEC_CloseSession(&sess);
	}
	

	TEEC_FinalizeContext(&ctx);

	return 0;
}


int HELLO_WORLD(void)
{
	TEEC_UUID uuid = TA_HELLO_WORLD_UUID;
	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);


	memset(&op, 0, sizeof(op));


	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].value.a = 42;


	printf("##TA_CMD TA to increment %d\n", op.params[0].value.a);
	res = TEEC_InvokeCommand(&sess, TA_HELLO_WORLD_CMD_INC_VALUE, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("TA incremented value to %d\n", op.params[0].value.a);
	return 0;

}

int OTP(void)
{



	#define PTA_K3_OTP_KEYWRITING_UUID \
       { 0xacc50f40, 0x0613, 0x4abd, \
               { 0x8d, 0xfe, 0xa9, 0x64, 0xcb, 0x74, 0xeb, 0x69} }
	TEEC_UUID uuid = PTA_K3_OTP_KEYWRITING_UUID;
	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);


	memset(&op, 0, sizeof(op));
	int  index = 0;
	printf("## Please Type OTP index:");
	fscanf(stdin, "%d", &index);

	#define TA_OTP_KEYWRITING_CMD_READ_MMR		0
	op.paramTypes =
		TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
				TEEC_VALUE_OUTPUT,
				TEEC_NONE, TEEC_NONE);
	op.params[0].value.a = index;
	res = TEEC_InvokeCommand(&sess, TA_OTP_KEYWRITING_CMD_READ_MMR, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("##OTP READ  index[%d]=%d\n",index, op.params[1].value.a);
	return 0;


}
int HWRNG(void)
{
	#define PTA_RNG_UUID \
		{ 0xab7a617c, 0xb8e7, 0x4d8f, \
				{ 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } }
	TEEC_UUID uuid = PTA_RNG_UUID;
	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);

	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);

	memset(&op, 0, sizeof(op));



	#define PTA_CMD_GET_ENTROPY		0x0
	#define PTA_CMD_GET_RNG_INFO		0x1
	
	op.paramTypes =
		TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
				TEEC_NONE,
				TEEC_NONE, TEEC_NONE);

	res = TEEC_InvokeCommand(&sess, PTA_CMD_GET_RNG_INFO, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("##RNG INFO:  rate:%d quality:%d\n", op.params[0].value.a, op.params[0].value.b);
	
	
	op.paramTypes =
		TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT,
				TEEC_NONE,
				TEEC_NONE, TEEC_NONE);
	char buf[128] = { 0 };
	op.params[0].tmpref.size = sizeof(buf);
	op.params[0].tmpref.buffer = buf;

	res = TEEC_InvokeCommand(&sess, PTA_CMD_GET_ENTROPY, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	for(int i = 0 ;i < 128 ; i +=8  )
	printf("##RNG ENTROPY: %02x %02x %02x %02x %02x %02x %02x %02x\n", \
					buf[i + 0], buf[i + 1], buf[i + 2],buf[i + 3],buf[i + 4],buf[i + 5],buf[i + 6],buf[i + 7] );
	
	return 0;
}
int SeWrite(void)
{
	#define TA_SECURE_STORAGE_CMD_READ_RAW		0
	#define TA_SECURE_STORAGE_CMD_WRITE_RAW		1
	#define TA_SECURE_STORAGE_CMD_DELETE		2
	
	#define TA_SECURE_STORAGE_UUID \
		{ 0xf4e750bb, 0x1437, 0x4fbf, \
			{ 0x87, 0x85, 0x8d, 0x35, 0x80, 0xc3, 0x49, 0x94 } }
	TEEC_UUID uuid = TA_SECURE_STORAGE_UUID;
	char filename [100] = { 0 };
	char data [1024] = { 0 };
	printf("=>Filename(write):");
    fflush(stdout);
	fscanf(stdin, "%s", filename);
	printf("=>data(write):");
    fflush(stdout);
	fscanf(stdin, "%s", data);
	// printf("<%s><%s>\n", filename, data);
	

	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);


	memset(&op, 0, sizeof(op));


	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = filename;
	op.params[0].tmpref.size = strlen(filename);
	op.params[1].tmpref.buffer = data;
	op.params[1].tmpref.size = strlen(data);


	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_WRITE_RAW start\n");
	res = TEEC_InvokeCommand(&sess, TA_SECURE_STORAGE_CMD_WRITE_RAW, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_WRITE_RAW end\n");

	return 0;
}
int SeRead(void)
{
	#define TA_SECURE_STORAGE_CMD_READ_RAW		0
	#define TA_SECURE_STORAGE_CMD_WRITE_RAW		1
	#define TA_SECURE_STORAGE_CMD_DELETE		2
	
	#define TA_SECURE_STORAGE_UUID \
		{ 0xf4e750bb, 0x1437, 0x4fbf, \
			{ 0x87, 0x85, 0x8d, 0x35, 0x80, 0xc3, 0x49, 0x94 } }
	TEEC_UUID uuid = TA_SECURE_STORAGE_UUID;
	char filename [100] = { 0 };
	char data [1024] = { 0 };
	printf("=>Filename(read):");
    fflush(stdout);
	fscanf(stdin, "%s", filename);

	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);


	memset(&op, 0, sizeof(op));


	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = filename;
	op.params[0].tmpref.size = strlen(filename);
	op.params[1].tmpref.buffer = data;
	op.params[1].tmpref.size =  sizeof(data) - 1;


	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_READ_RAW start\n");
	res = TEEC_InvokeCommand(&sess, TA_SECURE_STORAGE_CMD_READ_RAW, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_READ_RAW end\n");
	fprintf(stdout, "=>data(read):<%s>\n", data);
	return 0;
}
int SeDelete(void)
{
	#define TA_SECURE_STORAGE_CMD_READ_RAW		0
	#define TA_SECURE_STORAGE_CMD_WRITE_RAW		1
	#define TA_SECURE_STORAGE_CMD_DELETE		2
	
	#define TA_SECURE_STORAGE_UUID \
		{ 0xf4e750bb, 0x1437, 0x4fbf, \
			{ 0x87, 0x85, 0x8d, 0x35, 0x80, 0xc3, 0x49, 0x94 } }
	TEEC_UUID uuid = TA_SECURE_STORAGE_UUID;
	char filename [100] = { 0 };
	printf("=>Filename(read):");
    fflush(stdout);
	fscanf(stdin, "%s", filename);

	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);


	memset(&op, 0, sizeof(op));


	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = filename;
	op.params[0].tmpref.size = strlen(filename);



	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_DELETE start\n");
	res = TEEC_InvokeCommand(&sess, TA_SECURE_STORAGE_CMD_DELETE, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	printf("##TA_CMD  TA_SECURE_STORAGE_CMD_DELETE end\n");

	return 0;
}
int HOTP(void)
{
	#define TA_HOTP_CMD_REGISTER_SHARED_KEY	0
	#define TA_HOTP_CMD_GET_HOTP		1
	
	#define TA_HOTP_UUID \
	{ 0x484d4143, 0x2d53, 0x4841, \
		{ 0x31, 0x20, 0x4a, 0x6f, 0x63, 0x6b, 0x65, 0x42 } }
	TEEC_UUID uuid = TA_HOTP_UUID;
	uint8_t K[] = {
		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
		0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
		0x37, 0x38, 0x39, 0x30
	};

    // fflush(stdout);
	// fscanf(stdin, "%s", filename);


	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);


	memset(&op, 0, sizeof(op));


	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = K;
	op.params[0].tmpref.size = sizeof(K);



	// printf("##TA_CMD  TA_HOTP_CMD_REGISTER_SHARED_KEY start\n");
	res = TEEC_InvokeCommand(&sess, TA_HOTP_CMD_REGISTER_SHARED_KEY, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	// printf("##TA_CMD  TA_HOTP_CMD_REGISTER_SHARED_KEY end\n");

	while(1)
	{
		char input = 'n';
		printf("## generate One Time Password(y/n)?");
		fscanf(stdin, "%c", &input);
		if(input != 'y')
		{
			printf("## exit ...\n");
			break;
		}
		else
		{
			while ((input = getchar()) != '\n' && input != EOF) {}
		}
		
		memset(&op, 0, sizeof(op));
		op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
		
		// printf("##TA_CMD  TA_HOTP_CMD_GET_HOTP start\n");
		res = TEEC_InvokeCommand(&sess, TA_HOTP_CMD_GET_HOTP, &op,
				 &err_origin);
		if (res != TEEC_SUCCESS)
			errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
		// printf("##TA_CMD  TA_HOTP_CMD_GET_HOTP end\n");
		printf("## one Time Password:%d\n", op.params[0].value.a);
	}
	


	return 0;
}
int get_rsa_args(int *key_size, char * inbuff)
{
    char input = 0;
	printf("## please type keysize(256/512/1024):");


	fscanf(stdin, "%d", key_size);
	while ((input = getchar()) != '\n' && input != EOF) {}
	printf("## please type string( len<=%d):",*key_size / 8 -11);
	fscanf(stdin, "%s", inbuff);
	while ((input = getchar()) != '\n' && input != EOF) {}

	printf("keysize<%d> buff<%s>\n", *key_size, inbuff);
    if( strlen(inbuff) > ( *key_size/8 ) -11 )
    {
        printf("buff len is too big\n");
        return -1;
    }
}
int RSA_encode(void)
{
	#define TA_ACIPHER_CMD_GEN_KEY		0
	#define TA_ACIPHER_CMD_ENCRYPT		1
	
	#define TA_ACIPHER_UUID \
	{ 0xa734eed9, 0xd6a1, 0x4244, { \
		0xaa, 0x50, 0x7c, 0x99, 0x71, 0x9e, 0x7b, 0x7b } }
	TEEC_UUID uuid = TA_ACIPHER_UUID;
	int key_size = 0;
	char inbuff[1024] = { 0 };
	char outbuff[1024] = { 0 };
	get_rsa_args(&key_size, inbuff);


	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);

	/***************************   cmd1-genkey  *********************************/
	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].value.a = key_size;
	res = TEEC_InvokeCommand(&sess, TA_ACIPHER_CMD_GEN_KEY, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);


	/***************************   cmd2-encrypt  *********************************/
	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT,
					TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = inbuff;
	op.params[0].tmpref.size = strlen(inbuff);
	op.params[1].tmpref.buffer = outbuff;
	op.params[1].tmpref.size = sizeof(outbuff);
	res = TEEC_InvokeCommand(&sess, TA_ACIPHER_CMD_ENCRYPT, &op,
				&err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
		res, err_origin);
	/***************************   result  *********************************/
	printf("## Encrypt Result:\n");
	for( int i = 0; i < op.params[1].tmpref.size; i++ )
	{
		printf("%02x ", outbuff[i]);
		if( (i+1) % 8 == 0)
		{
			printf("\n");
		}
	}


	return 0;
}

char char2num(char c)
{
	if( c >= '0' && c <='9')
	{
			return c-'0';
	}
	else if ( c >= 'a' && c <='f')
	{
		return c- 'a' +10;
	}
	else
	{
		return 0xff;
	}

}
	
int AES_common(int mode)
{
	#define TA_AES_UUID \
		{ 0x5dbac793, 0xf574, 0x4871, \
			{ 0x8a, 0xd3, 0x04, 0x33, 0x1e, 0xc1, 0x7f, 0x24 } }
	#define TA_AES_ALGO_ECB			0
	#define TA_AES_ALGO_CBC			1
	#define TA_AES_ALGO_CTR			2

	#define TA_AES_SIZE_128BIT		(128 / 8)
	#define TA_AES_SIZE_256BIT		(256 / 8)

	// #define TA_AES_MODE_ENCODE		1
	// #define TA_AES_MODE_DECODE		0

	#define TA_AES_CMD_PREPARE		0
	#define TA_AES_CMD_SET_KEY		1
	#define TA_AES_CMD_SET_IV		2
	#define TA_AES_CMD_CIPHER		3

	TEEC_UUID uuid = TA_AES_UUID;
	res = TEEC_OpenSession(&ctx, &sess, &uuid,
			       TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x",
			res, err_origin);

	/***************************   cmd1-prepare  *********************************/
	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
					 TEEC_VALUE_INPUT, TEEC_NONE);
	op.params[0].value.a = TA_AES_ALGO_CTR;
	op.params[1].value.a = TA_AES_SIZE_128BIT;

	op.params[2].value.a = mode; // modify

	res = TEEC_InvokeCommand(&sess, TA_AES_CMD_PREPARE, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	
	/***************************   cmd2-setkey  *********************************/
	char key[TA_AES_SIZE_128BIT]= { 0 };
	char iv[TA_AES_SIZE_128BIT] = { 0 };
	int  plain_txt[1024] = { 0 };
	int  result_txt[1024] = { 0 };
	char tmp = 0;


	memset(key, 0x51, sizeof(key));
	
	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = key;
	op.params[0].tmpref.size = sizeof(key);
	res = TEEC_InvokeCommand(&sess, TA_AES_CMD_SET_KEY, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	
	/***************************   cmd3-setiv  *********************************/
	memset(iv, 0x12, sizeof(iv));

	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = iv;
	op.params[0].tmpref.size = sizeof(iv);

	
	res = TEEC_InvokeCommand(&sess, TA_AES_CMD_SET_IV, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);

	/***************************   encode/decode  *********************************/
	printf("## please type text for de/en coding:size data1 data2 data3 ...(note: hex format)\n");
	int input_size= 0;
	fscanf(stdin, "%08x", &input_size);
	for(int i = 0; i < input_size; i++)
	{
		fscanf(stdin, "%08x", &(plain_txt[i]) );
	}
	while ((tmp = getchar()) != '\n' && tmp != EOF) {}
	


	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT,
					 TEEC_NONE, TEEC_NONE);
	op.params[0].tmpref.buffer = plain_txt;
	op.params[0].tmpref.size = input_size*4;
	op.params[1].tmpref.buffer = result_txt;
	op.params[1].tmpref.size = sizeof(result_txt);

	res = TEEC_InvokeCommand(&sess, TA_AES_CMD_CIPHER, &op,
				 &err_origin);
	if (res != TEEC_SUCCESS)
		errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x",
			res, err_origin);
	
	/***************************   result  *********************************/
	printf("## Encode/decode Result: (size:%d bytes)", op.params[1].tmpref.size);
	for( int i = 0; i < op.params[1].tmpref.size / 4 ; i++ )
	{
		printf("%08x ", result_txt[i]);
		if( (i+1) % 8 == 0)
		{
			printf("\n");
		}
	}
	printf("\n");

	return 0;
}

#define TA_AES_MODE_ENCODE		1
#define TA_AES_MODE_DECODE		0
int AES_encode(void)
{
	AES_common(TA_AES_MODE_ENCODE);
}
int AES_decode(void)
{

	AES_common(TA_AES_MODE_DECODE);
}