yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * linux/init/verify_app.c |
| 3 | * |
| 4 | */ |
| 5 | #include <linux/types.h> |
| 6 | #include <linux/kernel.h> |
| 7 | #include <linux/syscalls.h> |
| 8 | #include <linux/string.h> |
| 9 | #include <linux/ctype.h> |
| 10 | #include <linux/delay.h> |
| 11 | #include <linux/init.h> |
| 12 | #include <linux/security.h> |
| 13 | #include <linux/kthread.h> |
| 14 | #include <linux/crypto.h> |
| 15 | #include <crypto/hash.h> |
| 16 | #include <crypto/sha.h> |
| 17 | #include <linux/verify_app.h> |
| 18 | #include <linux/soc/zte/efuse/efuse_zx.h> |
| 19 | |
| 20 | #define VERIFY_TIMEOUT 30000 //ÑÓ³ÙÑéǩʱ¼ä,½¨Òé´óÓÚ2s£» |
| 21 | |
| 22 | extern void zDrvEfuse_GetSecureMsg(T_ZDrvEfuse_Secure *secure); |
| 23 | |
| 24 | u8 *bin2hex(const u8 *old, const size_t oldlen) |
| 25 | { |
| 26 | u8 *result = (u8 *)kmalloc((oldlen * 2 + 1), GFP_KERNEL); |
| 27 | size_t i, j; |
| 28 | int b = 0; |
| 29 | |
| 30 | for (i = j = 0; i < oldlen; i++) |
| 31 | { |
| 32 | b = old[i] >> 4; |
| 33 | result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39)); |
| 34 | b = old[i] & 0xf; |
| 35 | result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39)); |
| 36 | } |
| 37 | result[j] = '\0'; |
| 38 | return result; |
| 39 | } |
| 40 | |
| 41 | static int verify_app_entry(void *p) |
| 42 | { |
| 43 | int i = 0; |
| 44 | int rdlen; |
| 45 | char *buff = NULL; |
| 46 | size_t size; |
| 47 | struct file *fp; |
| 48 | int bufflen = 4096; |
| 49 | u8 *hashstring; |
| 50 | u8 hash[SHA256_DIGEST_SIZE]; |
| 51 | struct shash_desc *desc; |
| 52 | struct crypto_shash *sha256; |
| 53 | T_ZDrvEfuse_Secure secure; |
| 54 | |
| 55 | msleep(VERIFY_TIMEOUT); |
| 56 | |
| 57 | zDrvEfuse_GetSecureMsg(&secure); |
| 58 | if((secure.secureFlag & 0xFF) != 0xFF) |
| 59 | { |
| 60 | printk("verify secure boot don't open \n"); |
| 61 | return 0; |
| 62 | } |
| 63 | |
| 64 | sha256 = crypto_alloc_shash("sha256", 0, 0); |
| 65 | if (IS_ERR(sha256)) { |
| 66 | panic("verify sha256 error ! \n"); |
| 67 | } |
| 68 | size = crypto_shash_descsize(sha256) + sizeof(*desc); |
| 69 | desc = kzalloc(size, GFP_KERNEL); |
| 70 | BUG_ON(desc == NULL); |
| 71 | desc->tfm = sha256; |
| 72 | buff = kmalloc(bufflen, GFP_KERNEL); |
| 73 | BUG_ON(buff == NULL); |
| 74 | for (i = 0; i < g_verify_app_cnt; i++) |
| 75 | { |
| 76 | fp = filp_open(g_verify_file_array[i], O_RDONLY, 0644); |
| 77 | if (IS_ERR(fp)) |
| 78 | { |
| 79 | printk("app=%s open fail \n",g_verify_file_array[i]); |
| 80 | panic("verify open fail"); |
| 81 | } |
| 82 | else |
| 83 | fp->f_pos = 0; |
| 84 | crypto_shash_init(desc); |
| 85 | while(1) |
| 86 | { |
| 87 | rdlen = kernel_read(fp, fp->f_pos, buff, bufflen); |
| 88 | if (rdlen > 0) |
| 89 | { |
| 90 | fp->f_pos += rdlen; |
| 91 | crypto_shash_update(desc, buff, rdlen); |
| 92 | } |
| 93 | else if (rdlen == 0) |
| 94 | { |
| 95 | filp_close((struct file *)fp, NULL); |
| 96 | crypto_shash_final(desc, hash); |
| 97 | hashstring = bin2hex(hash, SHA256_DIGEST_SIZE); |
| 98 | if (memcmp(hashstring, g_verify_hash_array[i], SHA256_DIGEST_SIZE)) |
| 99 | { |
| 100 | printk("verify app=%s hash=%s \n", g_verify_file_array[i], hashstring); |
| 101 | panic("verify hash fail"); |
| 102 | } |
| 103 | // printk("verify app=%s success \n", g_verify_file_array[i]); |
| 104 | kfree(hashstring); |
| 105 | break; |
| 106 | } |
| 107 | else |
| 108 | { |
| 109 | printk("verify app=%s rdlen=%d \n", g_verify_file_array[i], rdlen); |
| 110 | panic("verify read fail"); |
| 111 | break; |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | crypto_free_shash(sha256); |
| 117 | kfree(desc); |
| 118 | kfree(buff); |
| 119 | printk("verify app init success \n"); |
| 120 | return 0; |
| 121 | } |
| 122 | |
| 123 | static int __init verify_app_init(void) |
| 124 | { |
| 125 | kthread_run(verify_app_entry, NULL, "verify_app"); |
| 126 | return 0; |
| 127 | } |
| 128 | |
| 129 | late_initcall(verify_app_init); |
| 130 | |