Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / sbchk_base.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/crypto.h>
4 #include <linux/scatterlist.h>
5 #include <linux/gfp.h>
6 #include <linux/err.h>
7 #include <linux/syscalls.h>
8 #include <linux/slab.h>
9 #include <linux/delay.h>
10 #include <linux/sched.h>
11
12 #include <asm/mach/arch.h>
13 #include <asm/mach/time.h>
14 #include <asm/mach/map.h>
15 #include <asm/mach-types.h>
16
17 #include <mach/mt_typedefs.h>
18 #include <mach/sbchk_base.h>
19
20 /**************************************************************************
21 * MODULE DEFINITION
22 **************************************************************************/
23 #define MOD "SBCHK_BASE"
24 #define KER_SHA1_TEST (0)
25
26 /**************************************************************************
27 * MODULE MACRO
28 **************************************************************************/
29 #ifndef ASSERT
30 #define ASSERT(expr) BUG_ON(!(expr))
31 #endif
32
33 /**************************************************************************
34 * GLOBAL VARIABLES
35 **************************************************************************/
36 bool bIsChecked = FALSE;
37
38 /**************************************************************************
39 * UTILITIES
40 **************************************************************************/
41 void sbchk_dump(unsigned char* buf, unsigned int len)
42 {
43 unsigned int i = 1;
44
45 for (i =1; i <len+1; i++)
46 {
47 printk("%02x",buf[i-1]);
48 }
49
50 printk("\n");
51 }
52
53 void sbchk_hex_string(unsigned char* buf, unsigned int len)
54 {
55 unsigned int i = 1;
56
57 for (i =1; i <len+1; i++)
58 {
59 printk("%c",buf[i-1]);
60 }
61
62 printk("\n");
63 }
64
65 /**************************************************************************
66 * KERNEL SHA1 FUNCTION
67 **************************************************************************/
68 unsigned int sbchk_sha1(char * code, unsigned int code_len, char* result)
69 {
70 unsigned int ret = SEC_OK;
71 struct scatterlist sg[1];
72 struct crypto_hash *tfm = NULL;
73 struct hash_desc desc;
74
75 tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
76 if(IS_ERR(tfm))
77 {
78 ret = SBCHK_BASE_HASH_INIT_FAIL;
79 goto _exit;
80 }
81
82 /* sg_init_one(&sg[0], plaintext, length); */
83 sg_set_buf(&sg[0], code, code_len);
84
85 desc.tfm = tfm;
86 desc.flags = 0;
87 memset(result, 0, 20); /* SHA1 returns 20 bytes */
88 if (crypto_hash_digest(&desc, sg, code_len, result))
89 {
90 ret = SBCHK_BASE_HASH_DATA_FAIL;
91 goto _exit;
92 }
93
94 crypto_free_hash(tfm);
95
96 _exit:
97
98 return ret;
99 }
100
101 /**************************************************************************
102 * KERNEL SHA1 TEST
103 **************************************************************************/
104 void sbchk_test(void)
105 {
106 char * code1 = "2ew34123132513451345";
107 char * code2 = "234123132513451345";
108 char * code3 = "2ew34123132513451345";
109 char *hash_rs1,*hash_rs2,*hash_rs3;
110
111 hash_rs1 = (char *)kmalloc(HASH_OUTPUT_LEN,GFP_KERNEL);
112 hash_rs2 = (char *)kmalloc(HASH_OUTPUT_LEN,GFP_KERNEL);
113 hash_rs3 = (char *)kmalloc(HASH_OUTPUT_LEN,GFP_KERNEL);
114
115 sbchk_sha1(code1,strlen(code1),hash_rs1);
116 sbchk_sha1(code2,strlen(code2),hash_rs2);
117 sbchk_sha1(code3,strlen(code3),hash_rs3);
118
119 printk("[%s] dump result 1:\n",MOD);
120 sbchk_dump(hash_rs1,HASH_OUTPUT_LEN);
121 printk("[%s] dump result 2:\n",MOD);
122 sbchk_dump(hash_rs2,HASH_OUTPUT_LEN);
123 printk("[%s] dump result 3:\n",MOD);
124 sbchk_dump(hash_rs3,HASH_OUTPUT_LEN);
125
126 if(memcmp(hash_rs1,hash_rs2,HASH_OUTPUT_LEN) != 0)
127 {
128 printk("[%s] <1>code1 != code2. TEST PASS\n",MOD);
129 }
130 else
131 {
132 printk("[%s] <1>code1 == code2. TEST FAIL (KERNEL SHA1 FAIL)\n",MOD);
133 ASSERT(0);
134 }
135
136 if(memcmp(hash_rs1,hash_rs3,HASH_OUTPUT_LEN) != 0)
137 {
138 printk("[%s] <1>code1 != code3. TEST FAIL (KERNEL SHA1 FAIL)\n",MOD);
139 ASSERT(0);
140 }
141 else
142 {
143 printk("[%s] <1>code1 == code3. TEST PASS\n",MOD);
144 }
145
146 kfree(hash_rs1);
147 kfree(hash_rs2);
148 kfree(hash_rs3);
149 }
150
151 /**************************************************************************
152 * CHECK FILE HASH
153 **************************************************************************/
154 unsigned int sbchk_verify(char* file_path, char* hash_val)
155 {
156 struct file *fd;
157 unsigned int ret = SEC_OK;
158 unsigned int file_size = 0;
159 char *hash_rs = NULL;
160 char *buf = NULL;
161 bool bBufAllocated = FALSE;
162 struct inode *inode;
163
164 /* save current file system type */
165 mm_segment_t fs = get_fs();
166
167 /* ----------------------- */
168 /* open security file */
169 /* ----------------------- */
170 /* open engine */
171 fd = filp_open(file_path, O_RDONLY, 0);
172 if (fd < 0)
173 {
174 printk("[%s] Open '%s' fail\n",MOD,file_path);
175 ret = SBCHK_BASE_OPEN_FAIL;
176 goto _end;
177 }
178
179 /* ----------------------- */
180 /* configure file system */
181 /* ----------------------- */
182 set_fs(KERNEL_DS);
183
184 /* ----------------------- */
185 /* allocate buffer */
186 /* ----------------------- */
187 inode=fd->f_dentry->d_inode;
188 file_size=inode->i_size;
189 printk("[%s] '%s' exists ('%d' byets)\n",MOD,file_path,file_size);
190 buf = (char *)kmalloc(file_size,GFP_KERNEL);
191 hash_rs = (char *)kmalloc(HASH_OUTPUT_LEN,GFP_KERNEL);
192 bBufAllocated = TRUE;
193
194 /* ----------------------- */
195 /* read security file */
196 /* ----------------------- */
197 /* read image to input buffer */
198 if(0 >= (file_size = fd->f_op->read(fd,buf,file_size,&fd->f_pos)))
199 {
200 ret = SBCHK_BASE_READ_FAIL;
201 printk("[%s] Read '%s' '%d' byets fail\n",MOD,file_path,file_size);
202 goto _end;
203 }
204
205 printk("[%s] Read '%s' '%d' byets\n",MOD,file_path,file_size);
206
207 /* ----------------------- */
208 /* calculate hash */
209 /* ----------------------- */
210 sbchk_sha1(buf,file_size,hash_rs);
211 printk("[%s] Calculate the hash value of '%s' = \n",MOD,file_path);
212 sbchk_dump(hash_rs,HASH_OUTPUT_LEN);
213
214
215 /* ----------------------- */
216 /* verify hash */
217 /* ----------------------- */
218 #if SBCHK_BASE_HASH_CHECK
219 {
220 unsigned int i = 0;
221 char hash_rsn[HASH_OUTPUT_LEN*2+1] = {0};
222 char *hash_prsn = hash_rsn;
223
224
225 /* convert hash value to 'hex' string */
226 for(i=0;i<HASH_OUTPUT_LEN;i++)
227 {
228 sprintf(hash_prsn, "%02x", hash_rs[i]);
229 hash_prsn += 2;
230 }
231
232
233 /* compare hash value */
234 if(memcmp(hash_rsn,hash_val,HASH_OUTPUT_LEN) != 0)
235 {
236 printk("[%s] Hash check fail. The value should be \n",MOD);
237 sbchk_hex_string(hash_val,HASH_OUTPUT_LEN*2);
238 ret = SBCHK_BASE_HASH_CHECK_FAIL;
239 goto _end;
240 }
241 else
242 {
243 printk("[%s] Hash check pass\n",MOD);
244 sbchk_hex_string(hash_val,HASH_OUTPUT_LEN*2);
245 }
246 }
247 #endif
248
249
250 _end:
251
252 set_fs(fs);
253 if(TRUE == bBufAllocated)
254 {
255 kfree(hash_rs);
256 kfree(buf);
257 }
258 return ret;
259 }
260
261 /**************************************************************************
262 * KERNEL SBCHK
263 **************************************************************************/
264 void sbchk_base(void)
265 {
266
267 #ifdef CONFIG_SBCHK_BASE_ENABLE
268
269 unsigned int ret = SEC_OK;
270
271 /* --------------------------------- */
272 /* verify security file */
273 /* --------------------------------- */
274 if(FALSE == bIsChecked)
275 {
276 bIsChecked = TRUE;
277 printk("[%s] Enter\n",MOD);
278
279 /* --------------------------------- */
280 /* test sbchk_sha1 */
281 /* --------------------------------- */
282 #if KER_SHA1_TEST
283 sbchk_test();
284 #endif
285
286 /* --------------------------------- */
287 /* verify user space security engine */
288 /* --------------------------------- */
289 if(SEC_OK != (ret = sbchk_verify(SBCHK_ENGINE_PATH,SBCHK_ENGINE_HASH)))
290 {
291 msleep(20000);
292 printk("[%s] Verify '%s' fail. ret '%x'\n",MOD,SBCHK_ENGINE_PATH,ret);
293 /* punishment can be customized */
294 ASSERT(0);
295 }
296
297 /* --------------------------------- */
298 /* verify kernel security module */
299 /* --------------------------------- */
300 if(SEC_OK != (ret = sbchk_verify(SBCHK_MODULE_PATH,SBCHK_MODULE_HASH)))
301 {
302 msleep(20000);
303 printk("[%s] Verify '%s' fail. ret '%x'\n",MOD,SBCHK_MODULE_PATH,ret);
304 /* punishment can be customized */
305 ASSERT(0);
306 }
307
308 /* --------------------------------- */
309 /* verify kernel core modem module */
310 /* --------------------------------- */
311 if(SEC_OK != (ret = sbchk_verify(MODEM_CORE_MODULE_PATH,MODEM_CORE_MODULE_HASH)))
312 {
313 msleep(20000);
314 printk("[%s] Verify '%s' fail. ret '%x'\n",MOD,MODEM_CORE_MODULE_PATH,ret);
315 /* punishment can be customized */
316 ASSERT(0);
317 }
318
319 /* --------------------------------- */
320 /* verify kernel plat modem module */
321 /* --------------------------------- */
322 if(SEC_OK != (ret = sbchk_verify(MODEM_PLAT_MODULE_PATH,MODEM_PLAT_MODULE_HASH)))
323 {
324 msleep(20000);
325 printk("[%s] Verify '%s' fail. ret '%x'\n",MOD,MODEM_PLAT_MODULE_PATH,ret);
326 /* punishment can be customized */
327 ASSERT(0);
328 }
329
330 #if 0
331 /* --------------------------------- */
332 /* verify init rc */
333 /* --------------------------------- */
334 if(SEC_OK != (ret = sbchk_verify(INIT_RC_PATH,INIT_RC_HASH)))
335 {
336 msleep(20000);
337 printk("[%s] Verify '%s' fail. ret '%x'\n",MOD,INIT_RC_PATH,ret);
338 /* punishment can be customized */
339 ASSERT(0);
340 }
341 #endif
342 }
343
344 #endif
345
346 }
347
348 /**************************************************************************
349 * GET devinfo info with index
350 **************************************************************************/
351 u32 get_devinfo_with_index(u32 index)
352 {
353 int size = (sizeof(g_devinfo_data)/sizeof(u32));
354 if ((index >= 0) && (index < size)){
355 return g_devinfo_data[index];
356 }else{
357 printk("devinfo data index out of range:%d\n", index);
358 printk("devinfo data size:%d\n", size);
359 return SBCHK_BASE_INDEX_OUT_OF_RANGE;
360 }
361 }
362
363