zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/os/linux/linux-3.4.x/init/verify_app.c b/ap/os/linux/linux-3.4.x/init/verify_app.c
new file mode 100755
index 0000000..5eccd9c
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/init/verify_app.c
@@ -0,0 +1,130 @@
+/*
+ *  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);
+