merge with master
[platform/core/security/libcryptsvc.git] / srcs / SecTzSvc.c
1 /*
2  * libTzSvc - encryption and decryption with the TZ-based HW key
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <string.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <dlog.h>
24
25 #include <sys/ioctl.h>
26 #include <sys/time.h>
27 #include <sys/mman.h>
28 #include <sys/stat.h>
29 #include <openssl/sha.h>
30 #include <openssl/evp.h> 
31 #include <openssl/aes.h>
32 #include <openssl/crypto.h> 
33
34 #include "SecTzSvc.h"
35 #include "SecCryptoSvc.h"
36 #include "tlc_tzcrypt.h"
37 #include "tltzcrypt_api.h"
38
39 #define LOG_TAG "tlcTzCrypt"
40 #ifndef CRYPTOSVC_TZ
41 #define SIZE_CHUNK      1024
42 #define SIZE_SECUREOBJECT       1116
43 #define KEY_SIZE 16
44 #endif
45
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)
47 {
48     AES_KEY e_key, d_key;               
49                     
50     AES_set_encrypt_key(aes_key, 128, &e_key);
51     AES_set_decrypt_key(aes_key, 128, &d_key);
52                                             
53     if(mode == 1)
54     {
55                 AES_cbc_encrypt(p_text, c_text, size, &e_key, iv, AES_ENCRYPT);
56                 return c_text;
57         }
58         else
59         {
60             AES_cbc_encrypt(c_text, p_text, size, &d_key, iv, AES_DECRYPT);
61             return p_text;
62         }
63 }
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)
65 {
66
67         TZCRYPT_Result   ret = SEC_CRYPTO_ENCRYPT_ERROR;
68 #ifndef CRYPTOSVC_TZ
69         int outLen = 0;
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 };
73 #endif
74
75 #ifdef CRYPTOSVC_TZ
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);
79                 return ret;
80         }
81 #endif
82
83         LOGI("Start Encryption of TZ Crypt!\n");
84
85 #ifdef CRYPTOSVC_TZ
86         ret = TzCrypt_WrapIdentity(AppInfo, AppInfoLen, WrapAppInfo, WrapAppInfoLen);
87         if (ret) {
88         LOGE("Failed to wrap  AppInfo of TZ [Return Value] = %.8x\n", ret);
89                 return SEC_CRYPTO_WRAPIDENTITY_ERROR;
90         }
91         ret = TzCrypt_Encrypt(Src, SrcLen, Dst, DstLen);
92         if (ret) {
93                 LOGE("Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
94                 return SEC_CRYPTO_ENCRYPT_ERROR;
95     }
96 #else
97         if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
98         {
99                 LOGE("Failed to generate device unique key\n");
100                 return SEC_CRYPTO_ENCRYPT_ERROR;
101         }
102         if(AES_Crypto(Src, Dst, key, iv, 1, SrcLen) == NULL)
103         {
104                 LOGE("Failed to encrypt data \n");
105                 return SEC_CRYPTO_ENCRYPT_ERROR;
106         }
107         *DstLen = SrcLen;
108         EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);
109     *WrapAppInfoLen = outLen;
110         memcpy(WrapAppInfo, hashOut, *WrapAppInfoLen);
111 #endif
112         LOGI("Encryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
113
114         return SEC_CRYPTO_SUCCESS;
115 }
116
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)
118 {
119         TZCRYPT_Result   ret = SEC_CRYPTO_DECRYPT_ERROR;
120 #ifndef CRYPTOSVC_TZ
121     int outLen = 0;
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 };
125 #endif
126 #ifdef CRYPTOSVC_TZ
127         if(SrcLen % SIZE_SECUREOBJECT != 0 ){
128                 LOGE("Ciphertext chunk size :: Test for Encryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
129                 return ret;             
130         }
131
132         if(WrapAppInfoLen != SIZE_WRAPAPPIDENTITY){
133                 LOGE("Wrapped App Identity Size :: failed!!! [Return Value] = %.8x\n", ret);
134                 return ret;
135         }
136         
137         TZCRYPT_UINT8 *unwrapData = NULL;
138         TZCRYPT_UINT32 unwrapDatalen = SIZE_HASHAPPIDENTITY;
139         unwrapData = (TZCRYPT_UINT8 *)malloc(unwrapDatalen);
140
141         ret = TzCrypt_UnwrapIdentity(WrapAppInfo, WrapAppInfoLen, unwrapData, &unwrapDatalen);
142         if (ret) {
143                 LOGE("Test for Unwrap AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
144                 return SEC_CRYPTO_UNWRAPIDENTITY_ERROR;
145         }
146         LOGI("Unwrap AppInfo of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
147
148         TZCRYPT_UINT8 *hashData = NULL;
149         TZCRYPT_UINT32 hashDatalen =  SIZE_HASHAPPIDENTITY;
150         hashData = (TZCRYPT_UINT8 *)malloc(hashDatalen);
151
152         ret = TzCrypt_Hash(AppInfo, AppInfoLen, hashData, &hashDatalen);
153         if (ret) {
154                 LOGE("Test for Hash AppInfo of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
155                 return SEC_CRYPTO_HASH_ERROR;
156     }
157         
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;
161         }
162
163         LOGI("Start Decryption of TZ Crypt!\n");
164     ret = TzCrypt_Decrypt(Src, SrcLen, Dst, DstLen);
165         if (ret) {
166                 LOGE("Test for Decryption of TZ Crypt failed!!! [Return Value] = %.8x\n", ret);
167                 return SEC_CRYPTO_DECRYPT_ERROR;
168     }
169 #else
170         if(!SecFrameGeneratePlatformUniqueKey(KEY_SIZE, key))
171         {
172                 LOGE("Failed to generate device unique key\n");
173                 return SEC_CRYPTO_DECRYPT_ERROR;
174         }
175
176         EVP_Digest(AppInfo, AppInfoLen, hashOut, (unsigned int*)&outLen, EVP_sha1(), NULL);
177
178         if( 0 != memcmp(WrapAppInfo, hashOut, outLen) || outLen != WrapAppInfoLen){
179                 LOGE("AppInfo Identifier Information is wrong\n");
180                 return SEC_CRYPTO_HASH_ERROR;
181         }
182
183         if(AES_Crypto(Dst, Src, key, iv, 0, SrcLen) == NULL)
184         {
185                 LOGE("Failed to decrypt data \n");
186                 return SEC_CRYPTO_DECRYPT_ERROR;
187         }
188         *DstLen = SrcLen;
189
190 #endif
191     LOGI("Test for Decryption of TZ Crypt is Success! [Return Value] = %.8x\n", ret);
192
193         return SEC_CRYPTO_SUCCESS;
194 }
195
196 TZCRYPT_UINT32 SecGetCipherLen(TZCRYPT_UINT32 srclen)
197 {
198 #ifdef CRYPTOSVC_TZ
199         TZCRYPT_UINT32 cipherLength = TzCrypt_GetSOLen(srclen);
200 #else
201         int  cipherLength = (srclen / EVP_aes_128_cbc()->block_size + 1) * EVP_aes_128_cbc()->block_size;
202 #endif
203         return cipherLength;
204 }