blob: 5eccd9c8c89951adcbe53c2127febb62ec939bb8 [file] [log] [blame]
/*
* 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);