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;
}
|