2 * libTzSvc - encryption and decryption with the TZ-based HW key
4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #include <sys/ioctl.h>
29 #include <openssl/sha.h>
30 #include <openssl/evp.h>
31 #include <openssl/aes.h>
32 #include <openssl/crypto.h>
35 #include "SecCryptoSvc.h"
36 #include "tlc_tzcrypt.h"
37 #include "tltzcrypt_api.h"
39 #define LOG_TAG "tlcTzCrypt"
41 #define SIZE_CHUNK 1024
42 #define SIZE_SECUREOBJECT 1116
46 unsigned char* AES_Crypto(unsigned char* p_text, unsigned char* c_text, unsigned char* aes_key, unsigned char* iv, int mode, unsigned long size)
50 AES_set_encrypt_key(aes_key, 128, &e_key);
51 AES_set_decrypt_key(aes_key, 128, &d_key);
55 AES_cbc_encrypt(p_text, c_text, size, &e_key, iv, AES_ENCRYPT);
60 AES_cbc_encrypt(c_text, p_text, size, &d_key, iv, AES_DECRYPT);
64 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)
67 TZCRYPT_Result ret = SEC_CRYPTO_ENCRYPT_ERROR;
70 unsigned char key[KEY_SIZE] = {0,};
71 unsigned char hashOut[SHA_DIGEST_LENGTH] = {0,};
72 unsigned char iv[] = {0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B };
76 if(SrcLen % SIZE_CHUNK != 0 || *DstLen % SIZE_SECUREOBJECT != 0){
77 LOGE("Plain chunk size :: Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
78 LOGE("source length = %d, destination length = %d\n", SrcLen, *DstLen);
83 LOGI("Start Encryption of TZ Crypt!\n");
86 ret = TzCrypt_WrapIdentity(AppInfo, AppInfoLen, WrapAppInfo, WrapAppInfoLen);
88 LOGE("Failed to wrap AppInfo of TZ [Return Value] = %.8x\n", ret);
89 return SEC_CRYPTO_WRAPIDENTITY_ERROR;
91 ret = TzCrypt_Encrypt(Src, SrcLen, Dst, DstLen);
93 LOGE("Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
94 return SEC_CRYPTO_ENCRYPT_ERROR;
97 if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
99 LOGE("Failed to generate device unique key\n");
100 return SEC_CRYPTO_ENCRYPT_ERROR;
102 if(AES_Crypto(Src, Dst, key, iv, 1, SrcLen) == NULL)
104 LOGE("Failed to encrypt data \n");
105 return SEC_CRYPTO_ENCRYPT_ERROR;
108 EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);
109 *WrapAppInfoLen = outLen;
110 memcpy(WrapAppInfo, hashOut, *WrapAppInfoLen);
112 LOGI("Encryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
114 return SEC_CRYPTO_SUCCESS;
117 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)
119 TZCRYPT_Result ret = SEC_CRYPTO_DECRYPT_ERROR;
122 unsigned char key[KEY_SIZE] = {0,};
123 unsigned char hashOut[SHA_DIGEST_LENGTH] = {0,};
124 unsigned char iv[] = {0x3E, 0xB5, 0x01, 0x45, 0xE4, 0xF8, 0x75, 0x3F, 0x08, 0x9D, 0x9F, 0x57, 0x3B, 0x63, 0xEF, 0x4B };
127 if(SrcLen % SIZE_SECUREOBJECT != 0 ){
128 LOGE("Ciphertext chunk size :: Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
132 if(WrapAppInfoLen != SIZE_WRAPAPPIDENTITY){
133 LOGE("Wrapped App Identity Size :: failed!!! [Return Value] = %.8x\n", ret);
137 TZCRYPT_UINT8 *unwrapData = NULL;
138 TZCRYPT_UINT32 unwrapDatalen = SIZE_HASHAPPIDENTITY;
139 unwrapData = (TZCRYPT_UINT8 *)malloc(unwrapDatalen);
141 ret = TzCrypt_UnwrapIdentity(WrapAppInfo, WrapAppInfoLen, unwrapData, &unwrapDatalen);
143 LOGE("Test for Unwrap AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
144 return SEC_CRYPTO_UNWRAPIDENTITY_ERROR;
146 LOGI("Unwrap AppInfo of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
148 TZCRYPT_UINT8 *hashData = NULL;
149 TZCRYPT_UINT32 hashDatalen = SIZE_HASHAPPIDENTITY;
150 hashData = (TZCRYPT_UINT8 *)malloc(hashDatalen);
152 ret = TzCrypt_Hash(AppInfo, AppInfoLen, hashData, &hashDatalen);
154 LOGE("Test for Hash AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
155 return SEC_CRYPTO_HASH_ERROR;
158 if( 0 != memcmp(unwrapData, hashData, hashDatalen) || hashDatalen != unwrapDatalen){
159 LOGE("App Info Identity is NOT same as hash Info of a given Identity\n");
160 return SEC_CRYPTO_HASH_ERROR;
163 LOGI("Start Decryption of TZ Crypt!\n");
164 ret = TzCrypt_Decrypt(Src, SrcLen, Dst, DstLen);
166 LOGE("Test for Decryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
167 return SEC_CRYPTO_DECRYPT_ERROR;
170 if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
172 LOGE("Failed to generate device unique key\n");
173 return SEC_CRYPTO_DECRYPT_ERROR;
176 EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);
178 if( 0 != memcmp(WrapAppInfo, hashOut, outLen) || outLen != WrapAppInfoLen){
179 LOGE("AppInfo Identifier Information is wrong\n");
180 return SEC_CRYPTO_HASH_ERROR;
183 if(AES_Crypto(Dst, Src, key, iv, 0, SrcLen) == NULL)
185 LOGE("Failed to decrypt data \n");
186 return SEC_CRYPTO_DECRYPT_ERROR;
191 LOGI("Test for Decryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
193 return SEC_CRYPTO_SUCCESS;
196 TZCRYPT_UINT32 SecGetCipherLen(TZCRYPT_UINT32 srclen)
199 TZCRYPT_UINT32 cipherLength = TzCrypt_GetSOLen(srclen);
201 int cipherLength = (srclen / EVP_aes_128_cbc()->block_size + 1) * EVP_aes_128_cbc()->block_size;