| /* |
| * linux/init/verify_app.c |
| * |
| */ |
| #include <linux/types.h> |
| #include <linux/kernel.h> |
| #include <linux/syscalls.h> |
| #include <linux/string.h> |
| #include <linux/ctype.h> |
| #include <linux/delay.h> |
| #include <linux/init.h> |
| #include <linux/security.h> |
| #include <linux/kthread.h> |
| #include <linux/crypto.h> |
| #include <crypto/hash.h> |
| #include <crypto/sha.h> |
| #include <linux/verify_app.h> |
| #include <linux/soc/zte/efuse/efuse_zx.h> |
| |
| #define VERIFY_TIMEOUT 30000 //ÑÓ³ÙÑéǩʱ¼ä,½¨Òé´óÓÚ2s£» |
| |
| extern void zDrvEfuse_GetSecureMsg(T_ZDrvEfuse_Secure *secure); |
| |
| u8 *bin2hex(const u8 *old, const size_t oldlen) |
| { |
| u8 *result = (u8 *)kmalloc((oldlen * 2 + 1), GFP_KERNEL); |
| size_t i, j; |
| int b = 0; |
| |
| for (i = j = 0; i < oldlen; i++) |
| { |
| b = old[i] >> 4; |
| result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39)); |
| b = old[i] & 0xf; |
| result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39)); |
| } |
| result[j] = '\0'; |
| return result; |
| } |
| |
| static int verify_app_entry(void *p) |
| { |
| int i = 0; |
| int rdlen; |
| char *buff = NULL; |
| size_t size; |
| struct file *fp; |
| int bufflen = 4096; |
| u8 *hashstring; |
| u8 hash[SHA256_DIGEST_SIZE]; |
| struct shash_desc *desc; |
| struct crypto_shash *sha256; |
| T_ZDrvEfuse_Secure secure; |
| |
| msleep(VERIFY_TIMEOUT); |
| |
| zDrvEfuse_GetSecureMsg(&secure); |
| if((secure.secureFlag & 0xFF) != 0xFF) |
| { |
| printk("verify secure boot don't open \n"); |
| return 0; |
| } |
| |
| sha256 = crypto_alloc_shash("sha256", 0, 0); |
| if (IS_ERR(sha256)) { |
| panic("verify sha256 error ! \n"); |
| } |
| size = crypto_shash_descsize(sha256) + sizeof(*desc); |
| desc = kzalloc(size, GFP_KERNEL); |
| BUG_ON(desc == NULL); |
| desc->tfm = sha256; |
| buff = kmalloc(bufflen, GFP_KERNEL); |
| BUG_ON(buff == NULL); |
| for (i = 0; i < g_verify_app_cnt; i++) |
| { |
| fp = filp_open(g_verify_file_array[i], O_RDONLY, 0644); |
| if (IS_ERR(fp)) |
| { |
| printk("app=%s open fail \n",g_verify_file_array[i]); |
| panic("verify open fail"); |
| } |
| else |
| fp->f_pos = 0; |
| crypto_shash_init(desc); |
| while(1) |
| { |
| rdlen = kernel_read(fp, fp->f_pos, buff, bufflen); |
| if (rdlen > 0) |
| { |
| fp->f_pos += rdlen; |
| crypto_shash_update(desc, buff, rdlen); |
| } |
| else if (rdlen == 0) |
| { |
| filp_close((struct file *)fp, NULL); |
| crypto_shash_final(desc, hash); |
| hashstring = bin2hex(hash, SHA256_DIGEST_SIZE); |
| if (memcmp(hashstring, g_verify_hash_array[i], SHA256_DIGEST_SIZE)) |
| { |
| printk("verify app=%s hash=%s \n", g_verify_file_array[i], hashstring); |
| panic("verify hash fail"); |
| } |
| // printk("verify app=%s success \n", g_verify_file_array[i]); |
| kfree(hashstring); |
| break; |
| } |
| else |
| { |
| printk("verify app=%s rdlen=%d \n", g_verify_file_array[i], rdlen); |
| panic("verify read fail"); |
| break; |
| } |
| } |
| } |
| |
| crypto_free_shash(sha256); |
| kfree(desc); |
| kfree(buff); |
| printk("verify app init success \n"); |
| return 0; |
| } |
| |
| static int __init verify_app_init(void) |
| { |
| kthread_run(verify_app_entry, NULL, "verify_app"); |
| return 0; |
| } |
| |
| late_initcall(verify_app_init); |
| |