summaryrefslogtreecommitdiff
path: root/srcs/SecTzSvc.c
blob: b12fb9f4b47d73b7fb2be70a9a15ec89ea8285c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 * libTzSvc - encryption and decryption with the TZ-based HW key
 *
 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dlog.h>

#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/crypto.h>

#include "SecTzSvc.h"
#include "SecCryptoSvc.h"
#include "tlc_tzcrypt.h"
#include "tltzcrypt_api.h"

#define LOG_TAG "tlcTzCrypt"
#ifndef CRYPTOSVC_TZ
#define	SIZE_CHUNK	1024
#define	SIZE_SECUREOBJECT	1116
#define KEY_SIZE 16
#endif

unsigned char* AES_Crypto(unsigned char* p_text, unsigned char* c_text, unsigned char* aes_key, unsigned char* iv, int mode,  unsigned long size)
{
    AES_KEY e_key, d_key;

    AES_set_encrypt_key(aes_key, 128, &e_key);
    AES_set_decrypt_key(aes_key, 128, &d_key);

    if(mode == 1)
    {
		AES_cbc_encrypt(p_text, c_text, size, &e_key, iv, AES_ENCRYPT);
		return c_text;
	}
	else
	{
	    AES_cbc_encrypt(c_text, p_text, size, &d_key, iv, AES_DECRYPT);
	    return p_text;
	}
}
TZCRYPT_Result SecEncryptTZCrypt(TZCRYPT_UINT8 *Src, TZCRYPT_UINT32 SrcLen, TZCRYPT_UINT8 *Dst, TZCRYPT_UINT32 *DstLen, TZCRYPT_UINT8 *AppInfo, TZCRYPT_UINT32 AppInfoLen, TZCRYPT_UINT8 *WrapAppInfo, TZCRYPT_UINT32 *WrapAppInfoLen)
{

	TZCRYPT_Result   ret = SEC_CRYPTO_ENCRYPT_ERROR;
#ifndef CRYPTOSVC_TZ
	int outLen = 0;
	unsigned char key[KEY_SIZE] = {0,};
	unsigned char hashOut[SHA_DIGEST_LENGTH] = {0,};
	unsigned char iv[] = {0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B };
#endif

#ifdef CRYPTOSVC_TZ
	if(SrcLen % SIZE_CHUNK != 0 || *DstLen % SIZE_SECUREOBJECT != 0){
                LOGE("Plain chunk size :: Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
				LOGE("source length = %d, destination length = %d\n", SrcLen, *DstLen);
                return ret;
	}
#endif

	LOGI("Start Encryption of TZ Crypt!\n");

#ifdef CRYPTOSVC_TZ
	ret = TzCrypt_WrapIdentity(AppInfo, AppInfoLen, WrapAppInfo, WrapAppInfoLen);
	if (ret) {
       	LOGE("Failed to wrap  AppInfo of TZ [Return Value] = %.8x\n", ret);
		return SEC_CRYPTO_WRAPIDENTITY_ERROR;
	}
	ret = TzCrypt_Encrypt(Src, SrcLen, Dst, DstLen);
	if (ret) {
		LOGE("Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
		return SEC_CRYPTO_ENCRYPT_ERROR;
    }
#else
	if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
	{
		LOGE("Failed to generate device unique key\n");
		return SEC_CRYPTO_ENCRYPT_ERROR;
	}
	if(AES_Crypto(Src, Dst, key, iv, 1, SrcLen) == NULL)
	{
		LOGE("Failed to encrypt data \n");
		return SEC_CRYPTO_ENCRYPT_ERROR;
	}
	*DstLen = SrcLen;
	EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);
    *WrapAppInfoLen = outLen;
	memcpy(WrapAppInfo, hashOut, *WrapAppInfoLen);
#endif
	LOGI("Encryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);

	return SEC_CRYPTO_SUCCESS;
}

TZCRYPT_Result SecDecryptTZCrypt(TZCRYPT_UINT8 *Src, TZCRYPT_UINT32 SrcLen, TZCRYPT_UINT8 *Dst, TZCRYPT_UINT32 *DstLen, TZCRYPT_UINT8 *AppInfo, TZCRYPT_UINT32 AppInfoLen, TZCRYPT_UINT8 *WrapAppInfo, TZCRYPT_UINT32 WrapAppInfoLen)
{
	TZCRYPT_Result   ret = SEC_CRYPTO_DECRYPT_ERROR;
#ifndef CRYPTOSVC_TZ
    int outLen = 0;
    unsigned char key[KEY_SIZE] = {0,};
    unsigned char hashOut[SHA_DIGEST_LENGTH] = {0,};
    unsigned char iv[] = {0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B };
#endif
#ifdef CRYPTOSVC_TZ
	if(SrcLen % SIZE_SECUREOBJECT != 0 ){
                LOGE("Ciphertext chunk size :: Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
                return ret;
	}

	if(WrapAppInfoLen != SIZE_WRAPAPPIDENTITY){
		LOGE("Wrapped App Identity Size :: failed!!! [Return Value] = %.8x\n", ret);
		return ret;
	}

	TZCRYPT_UINT8 *unwrapData = NULL;
	TZCRYPT_UINT32 unwrapDatalen = SIZE_HASHAPPIDENTITY;
	unwrapData = (TZCRYPT_UINT8 *)malloc(unwrapDatalen);

	ret = TzCrypt_UnwrapIdentity(WrapAppInfo, WrapAppInfoLen, unwrapData, &unwrapDatalen);
        if (ret) {
                LOGE("Test for Unwrap AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
                return SEC_CRYPTO_UNWRAPIDENTITY_ERROR;
        }
	LOGI("Unwrap AppInfo of TZ Crypt is Success! [Return Value] = %.8x\n", ret);

	TZCRYPT_UINT8 *hashData = NULL;
	TZCRYPT_UINT32 hashDatalen =  SIZE_HASHAPPIDENTITY;
	hashData = (TZCRYPT_UINT8 *)malloc(hashDatalen);

	ret = TzCrypt_Hash(AppInfo, AppInfoLen, hashData, &hashDatalen);
	if (ret) {
		LOGE("Test for Hash AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
		return SEC_CRYPTO_HASH_ERROR;
    }

	if( 0 != memcmp(unwrapData, hashData, hashDatalen) || hashDatalen != unwrapDatalen){
		LOGE("App Info Identity is NOT same as hash Info of a given Identity\n");
		return SEC_CRYPTO_HASH_ERROR;
	}

	LOGI("Start Decryption of TZ Crypt!\n");
    ret = TzCrypt_Decrypt(Src, SrcLen, Dst, DstLen);
	if (ret) {
		LOGE("Test for Decryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
		return SEC_CRYPTO_DECRYPT_ERROR;
    }
#else
	if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
	{
		LOGE("Failed to generate device unique key\n");
		return SEC_CRYPTO_DECRYPT_ERROR;
	}

	EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);

	if( 0 != memcmp(WrapAppInfo, hashOut, outLen) || outLen != WrapAppInfoLen){
		LOGE("AppInfo Identifier Information is wrong\n");
		return SEC_CRYPTO_HASH_ERROR;
	}

	if(AES_Crypto(Dst, Src, key, iv, 0, SrcLen) == NULL)
	{
		LOGE("Failed to decrypt data \n");
		return SEC_CRYPTO_DECRYPT_ERROR;
	}
	*DstLen = SrcLen;

#endif
    LOGI("Test for Decryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);

	return SEC_CRYPTO_SUCCESS;
}

TZCRYPT_UINT32 SecGetCipherLen(TZCRYPT_UINT32 srclen)
{
#ifdef CRYPTOSVC_TZ
	TZCRYPT_UINT32 cipherLength = TzCrypt_GetSOLen(srclen);
#else
	int  cipherLength = (srclen / EVP_aes_128_cbc()->block_size + 1) * EVP_aes_128_cbc()->block_size;
#endif
	return cipherLength;
}