Просмотр исходного кода

change: ota升级文件的校验改为校验md5 https://gitee.com/openLuat/LuatOS/issues/I4XGKY

Wendal Chen 3 лет назад
Родитель
Сommit
0301eb3600
4 измененных файлов с 354 добавлено и 134 удалено
  1. 27 0
      luat/include/luat_md5.h
  2. 239 0
      luat/modules/luat_md5.c
  3. 88 2
      luat/modules/luat_ota.c
  4. 0 132
      luat/vfs/luat_fs_luadb.c

+ 27 - 0
luat/include/luat_md5.h

@@ -0,0 +1,27 @@
+// code from https://github.com/galenguyer/md5 licensed under the Unlicense
+
+
+#define MD5_HASH_SIZE 16
+
+struct md5_context {
+    // state
+    unsigned int a;
+    unsigned int b;
+    unsigned int c;
+    unsigned int d;
+    // number of bits, modulo 2^64 (lsb first)
+    unsigned int count[2];
+    // input buffer
+    unsigned char input[64];
+    // current block
+    unsigned int block[16];
+};
+
+struct md5_digest {
+    unsigned char bytes[MD5_HASH_SIZE];
+};
+
+void luat_md5_init(struct md5_context *ctx);
+void luat_md5_update(struct md5_context* ctx, const void* buffer, uint32_t buffer_size);
+void luat_md5_finalize(struct md5_context* ctx, struct md5_digest* digest);
+//char* md5(const char* input);

+ 239 - 0
luat/modules/luat_md5.c

@@ -0,0 +1,239 @@
+// code from https://github.com/galenguyer/md5 licensed under the Unlicense
+
+#pragma GCC diagnostic ignored "-Wshift-count-overflow"
+#pragma GCC diagnostic ignored "-Wshift-count-negative"
+
+// #include <memory.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "string.h"
+#include "luat_md5.h"
+
+#define F(x, y, z) (z ^ (x & (y ^ z)))
+#define G(x, y, z) (y ^ (z & (x ^ y)))
+#define H(x, y, z) (x ^ y ^ z)
+#define I(x, y, z) (y ^ (x | ~z))
+
+#define ROTATE_LEFT(x, s) (x<<s | x>>(32-s))
+
+#define STEP(f, a, b, c, d, x, t, s) ( \
+    a += f(b, c, d) + x + t, \
+    a = ROTATE_LEFT(a, s), \
+    a += b \
+)
+
+void luat_md5_init(struct md5_context* ctx) {
+    ctx->a = 0x67452301;
+    ctx->b = 0xefcdab89;
+    ctx->c = 0x98badcfe;
+    ctx->d = 0x10325476;
+
+    ctx->count[0] = 0;
+    ctx->count[1] = 0;
+}
+
+static uint8_t* md5_transform(struct md5_context* ctx, const void* data, uintmax_t size) {
+    uint8_t* ptr = (uint8_t*) data;
+    uint32_t a, b, c, d, aa, bb, cc, dd;
+
+    #define GET(n) (ctx->block[(n)])
+    #define SET(n) (ctx->block[(n)] =        \
+          ((uint32_t)ptr[(n)*4 + 0] << 0 )   \
+        | ((uint32_t)ptr[(n)*4 + 1] << 8 )   \
+        | ((uint32_t)ptr[(n)*4 + 2] << 16)   \
+        | ((uint32_t)ptr[(n)*4 + 3] << 24) )
+
+    a = ctx->a;
+    b = ctx->b;
+    c = ctx->c;
+    d = ctx->d;
+
+    do {
+        aa = a;
+        bb = b;
+        cc = c; 
+        dd = d;
+
+        STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7);
+        STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12);
+        STEP(F, c, d, a, b, SET(2), 0x242070db, 17);
+        STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22);
+        STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7);
+        STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12);
+        STEP(F, c, d, a, b, SET(6), 0xa8304613, 17);
+        STEP(F, b, c, d, a, SET(7), 0xfd469501, 22);
+        STEP(F, a, b, c, d, SET(8), 0x698098d8, 7);
+        STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12);
+        STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17);
+        STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22);
+        STEP(F, a, b, c, d, SET(12), 0x6b901122, 7);
+        STEP(F, d, a, b, c, SET(13), 0xfd987193, 12);
+        STEP(F, c, d, a, b, SET(14), 0xa679438e, 17);
+        STEP(F, b, c, d, a, SET(15), 0x49b40821, 22);
+
+        STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5);
+        STEP(G, d, a, b, c, GET(6), 0xc040b340, 9);
+        STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14);
+        STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20);
+        STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5);
+        STEP(G, d, a, b, c, GET(10), 0x02441453, 9);
+        STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14);
+        STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20);
+        STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5);
+        STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9);
+        STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14);
+        STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20);
+        STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5);
+        STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9);
+        STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14);
+        STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20);
+
+        STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4);
+        STEP(H, d, a, b, c, GET(8), 0x8771f681, 11);
+        STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16);
+        STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23);
+        STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4);
+        STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11);
+        STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16);
+        STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23);
+        STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4);
+        STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11);
+        STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16);
+        STEP(H, b, c, d, a, GET(6), 0x04881d05, 23);
+        STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4);
+        STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11);
+        STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16);
+        STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23);
+
+        STEP(I, a, b, c, d, GET(0), 0xf4292244, 6);
+        STEP(I, d, a, b, c, GET(7), 0x432aff97, 10);
+        STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15);
+        STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21);
+        STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6);
+        STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10);
+        STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15);
+        STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21);
+        STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6);
+        STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10);
+        STEP(I, c, d, a, b, GET(6), 0xa3014314, 15);
+        STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21);
+        STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6);
+        STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10);
+        STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15);
+        STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21);
+
+        a += aa;
+        b += bb;
+        c += cc;
+        d += dd;
+
+        ptr += 64;
+    } while (size -= 64);
+
+    ctx->a = a;
+    ctx->b = b;
+    ctx->c = c;
+    ctx->d = d;
+
+    #undef GET
+    #undef SET
+
+    return ptr;
+}
+
+void luat_md5_update(struct md5_context* ctx, const void* buffer, uint32_t buffer_size) {
+    uint32_t saved_low = ctx->count[0];
+    uint32_t used;
+    uint32_t free;
+
+    if ((ctx->count[0] = ((saved_low+buffer_size) & 0x1fffffff)) < saved_low) {
+        ctx->count[1]++;
+    }
+    ctx->count[1] += (uint32_t)(buffer_size>>29);
+
+    used = saved_low & 0x3f;
+
+    if (used) {
+        free = 64 - used;
+
+        if (buffer_size < free) {
+            memcpy(&ctx->input[used], buffer, buffer_size);
+            return;
+        }
+
+        memcpy(&ctx->input[used], buffer, free);
+        buffer = (uint8_t*) buffer + free;
+        buffer_size -= free;
+        md5_transform(ctx, ctx->input, 64);
+    }
+
+    if (buffer_size >= 64) {
+        buffer = md5_transform(ctx, buffer, buffer_size & ~(unsigned long)0x3f);
+    }
+
+    memcpy(ctx->input, buffer, buffer_size);
+}
+
+void luat_md5_finalize(struct md5_context* ctx, struct md5_digest* digest) {
+    uint32_t used = ctx->count[0] & 0x3f;
+    ctx->input[used++] = 0x80;
+    uint32_t free = 64 - used;
+
+    if (free < 8) {
+        memset(&ctx->input[used], 0, free);
+        md5_transform(ctx, ctx->input, 64);
+        used = 0;
+        free = 64;
+    }
+
+    memset(&ctx->input[used], 0, free - 8);
+
+    ctx->count[0] <<= 3;
+    ctx->input[56] = (uint8_t)(ctx->count[0]);
+    ctx->input[57] = (uint8_t)(ctx->count[0] >> 8);
+    ctx->input[58] = (uint8_t)(ctx->count[0] >> 16);
+    ctx->input[59] = (uint8_t)(ctx->count[0] >> 24);
+    ctx->input[60] = (uint8_t)(ctx->count[1]);
+    ctx->input[61] = (uint8_t)(ctx->count[1] >> 8);
+    ctx->input[62] = (uint8_t)(ctx->count[1] >> 16);
+    ctx->input[63] = (uint8_t)(ctx->count[1] >> 24);
+
+    md5_transform(ctx, ctx->input, 64);
+
+    digest->bytes[0]  = (uint8_t)(ctx->a);
+    digest->bytes[1]  = (uint8_t)(ctx->a >> 8);
+    digest->bytes[2]  = (uint8_t)(ctx->a >> 16);
+    digest->bytes[3]  = (uint8_t)(ctx->a >> 24);
+    digest->bytes[4]  = (uint8_t)(ctx->b);
+    digest->bytes[5]  = (uint8_t)(ctx->b >> 8);
+    digest->bytes[6]  = (uint8_t)(ctx->b >> 16);
+    digest->bytes[7]  = (uint8_t)(ctx->b >> 24);
+    digest->bytes[8]  = (uint8_t)(ctx->c);
+    digest->bytes[9]  = (uint8_t)(ctx->c >> 8);
+    digest->bytes[10] = (uint8_t)(ctx->c >> 16);
+    digest->bytes[11] = (uint8_t)(ctx->c >> 24);
+    digest->bytes[12] = (uint8_t)(ctx->d);
+    digest->bytes[13] = (uint8_t)(ctx->d >> 8);
+    digest->bytes[14] = (uint8_t)(ctx->d >> 16);
+    digest->bytes[15] = (uint8_t)(ctx->d >> 24);
+}
+
+// char* md5(const char* input) {
+//     struct md5_context context;
+//     struct md5_digest digest;
+
+//     md5_init(&context);
+//     md5_update(&context, input, (unsigned long)strlen(input));
+//     md5_finalize(&context, &digest);
+
+//     char* output = malloc(sizeof(char) * (sizeof(digest)*2 + 1));
+//     output[sizeof(digest)] = '\0';
+
+//     for(int i=0; i<sizeof(digest); i++)
+//     {
+//         sprintf(&output[i*2], "%2.2x", digest.bytes[i]);
+//     }
+
+//     return output;
+// }

+ 88 - 2
luat/modules/luat_ota.c

@@ -1,4 +1,5 @@
 
+#include "luat_base.h"
 #include "luat_ota.h"
 #include "luat_fs.h"
 #include "luat_timer.h"
@@ -138,8 +139,93 @@ static void luat_bin_exec_rollback(void) {
   luat_os_reboot(0); // 重启
 }
 
+#include "luat_crypto.h"
+#include "luat_md5.h"
+
+void luat_str_fromhex(char* str, size_t len, char* buff);
+void luat_str_tohex(char* str, size_t len, char* buff);
+
+#define OTA_CHECK_BUFF_SIZE (512)
+typedef struct ota_md5
+{
+    uint8_t buff[OTA_CHECK_BUFF_SIZE];
+    struct md5_context context;
+    struct md5_digest digest;
+}ota_md5_t;
+
+
+int luat_ota_checkfile(const char* path) {
+    int ret = 0;
+    
+    FILE * fd = luat_fs_fopen(path, "rb");
+    if (fd == NULL) {
+        LLOGE("no such file");
+        return -1;
+    }
+    size_t binsize = luat_fs_fsize(path);
+    if (binsize < 512 || binsize > 1024*1024) {
+        luat_fs_fclose(fd);
+        LLOGE("%s is too small/big %d", path, binsize);
+        return -1;
+    }
+    ota_md5_t* ota = luat_heap_malloc(sizeof(ota_md5_t));
+    if (ota == NULL) {
+        luat_fs_fclose(fd);
+        LLOGE("out of memory when check ota file md5");
+        return -1;
+    }
+    
+    unsigned int len = 0;
+    int remain = binsize - 16;
+
+    luat_md5_init(&ota->context);
+    while (remain > 0) {
+        if (remain > OTA_CHECK_BUFF_SIZE) {
+            len = luat_fs_fread(ota->buff, OTA_CHECK_BUFF_SIZE, 1, fd);
+        }
+        else {
+            len = luat_fs_fread(ota->buff, remain, 1, fd);
+        }
+        //LLOGD("ota read %d byte", len);
+        if (len == 0) {
+            continue;
+        }
+        if (len < 0 || len > 512) {
+            luat_heap_free(ota);
+            luat_fs_fclose(fd);
+            LLOGE("read file fail");
+            return -1;
+        }
+
+        remain -= len;
+        luat_md5_update(&ota->context, ota->buff, len);
+    }
+    luat_md5_finalize(&ota->context, &ota->digest);
+    // 应该还有16字节的md5
+    //memset(ota->buff, 0, OTA_CHECK_BUFF_SIZE);
+    luat_fs_fread(ota->buff, 16, 1, fd);
+    // 读完就可以关了
+    luat_fs_fclose(fd);
+
+    // 判断一下md5
+    // uint8_t *expect_md5 = ota->buff + 64;
+    // uint8_t *face_md5   = ota->buff + 128;
+
+    if (!memcmp(ota->buff, ota->digest.bytes, 16)) {
+        LLOGD("ota file MD5 ok");
+        ret = 0;
+    }
+    else {
+        LLOGE("ota file MD5 FAIL");
+        ret = -1;
+    }
+
+    luat_heap_free(ota);
+    return ret;
+}
+
+
 #ifdef LUAT_USE_OTA
-extern int luat_luadb_checkfile(const char* path);
 
 int luat_ota(uint32_t luadb_addr){
     
@@ -179,7 +265,7 @@ _close_decompress:
     //检测是否有升级文件
     if(luat_fs_fexist(UPDATE_BIN_PATH)){
         LLOGI("found update.bin, checking");
-        if (luat_luadb_checkfile(UPDATE_BIN_PATH) == 0) {
+        if (luat_ota_checkfile(UPDATE_BIN_PATH) == 0) {
             LLOGI("update.bin ok, updating...");
             #define UPDATE_BUFF_SIZE 4096
             uint8_t* buff = luat_heap_malloc(UPDATE_BUFF_SIZE);

+ 0 - 132
luat/vfs/luat_fs_luadb.c

@@ -484,135 +484,3 @@ const struct luat_vfs_filesystem vfs_fs_luadb = {
     }
 };
 #endif
-
-#include "luat_crypto.h"
-
-int luat_luadb_checkfile(const char* path) {
-    size_t binsize = luat_fs_fsize(path);
-    if (binsize < 1024 || binsize > 1024*1024) {
-        LLOGD("%s is too small/big %d", path, binsize);
-        return -1;
-    } 
-    uint8_t* binbuff = NULL;
-    FILE * fd = luat_fs_fopen(path, "rb");
-    int res = -1;
-    if (fd) {
-
-        binbuff = (uint8_t*)luat_heap_malloc(binsize * sizeof(uint8_t));
-        if (binbuff == NULL) {
-            LLOGD("update.bin is TOO BIG, not OK");
-            goto _close;
-        }
-        memset(binbuff, 0, binsize);
-
-        luat_fs_fread(binbuff, sizeof(uint8_t), binsize, fd);
-        //做一下校验
-        if (binbuff[0] != 0x01 || binbuff[1] != 0x04 || binbuff[2]+(binbuff[3]<<8) != 0xA55A || binbuff[4]+(binbuff[5]<<8) != 0xA55A){
-            LLOGI("Magic error");
-            goto _close;
-        }
-        LLOGI("Magic OK");
-        if (binbuff[6] != 0x02 || binbuff[7] != 0x02 || binbuff[8] != 0x02 || binbuff[9] != 0x00){
-            LLOGI("Version error");
-            goto _close;
-        }
-        uint16_t version = binbuff[8]+(binbuff[9]<<8);
-        LLOGI("Version:%d",version);
-        if (binbuff[10] != 0x03 || binbuff[11] != 0x04){
-            LLOGI("Header error");
-            goto _close;
-        }
-        uint32_t headsize = binbuff[12]+(binbuff[13]<<8)+(binbuff[14]<<16)+(binbuff[15]<<24);
-        LLOGI("headers:%08x",headsize);
-        if (binbuff[16] != 0x04 || binbuff[17] != 0x02){
-            LLOGI("file count error");
-            goto _close;
-        }
-        uint16_t filecount = binbuff[18]+(binbuff[19]<<8);
-        LLOGI("file count:%d",filecount);
-        if (binbuff[20] != 0xFE || binbuff[21] != 0x02){
-            LLOGI("CRC16 error");
-            goto _close;
-        }
-        uint16_t crc16 = binbuff[22]+(binbuff[23]<<8);
-        int index = 24;
-        uint8_t type = 0;
-        uint32_t len = 0;
-        for (size_t i = 0; i < (int)filecount; i++){
-            LLOGD("LuaDB check files .... %d", i+1);
-            type = binbuff[index++];
-            len = binbuff[index++];
-            if (type != 1 || len != 4) {
-                LLOGD("bad file data 1 : %d %d %d", type, len, index);
-                goto _close;
-            }
-            index += 4;
-            // 2. 然后是名字
-            type = binbuff[index++];
-            len = binbuff[index++];
-            if (type != 2) {
-                LLOGD("bad file data 2 : %d %d %d", type, len, index);
-                goto _close;
-            }
-            // 拷贝文件名
-            LLOGD("LuaDB file name len = %d", len);
-            char test[10];
-            memcpy(test, &(binbuff[index]), len);
-            test[len] = 0x00;
-            index += len;
-            LLOGD("LuaDB file name %s", test);
-            if (strcmp(".airm2m_all_crc#.bin", test)==0){
-                LLOGD(".airm2m_all_crc#.bin");
-                // 3. 文件大小
-                type = binbuff[index++];
-                len = binbuff[index++];
-                if (type != 3 || len != 4) {
-                    LLOGD("bad file data 3 : %d %d %d", type, len, index);
-                    goto _close;
-                }
-                uint32_t fssize = binbuff[index]+(binbuff[index+1]<<8)+(binbuff[index+2]<<16)+(binbuff[index+3]<<24);
-                index+=4;
-                // 0xFE校验码
-                type = binbuff[index++];
-                len = binbuff[index++];
-                if (type != 0xFE || len != 2) {
-                    LLOGD("bad file data 4 : %d %d %d", type, len, index);
-                    goto _close;
-                }
-                index += len;
-                uint8_t md5data[16];
-                luat_crypto_md5_simple((const char*)binbuff, index, md5data);
-                for (size_t i = 0; i < 16; i++){
-                    if (md5data[i]!=binbuff[index++]){
-                        LLOGD("md5data error");
-                        goto _close;
-                    }
-                }
-                res = 0;
-                break;
-            }
-            // 3. 文件大小
-            type = binbuff[index++];
-            len = binbuff[index++];
-            if (type != 3 || len != 4) {
-                LLOGD("bad file data 3 : %d %d %d", type, len, index);
-                goto _close;
-            }
-            uint32_t fssize = binbuff[index]+(binbuff[index+1]<<8)+(binbuff[index+2]<<16)+(binbuff[index+3]<<24);
-            index+=4;
-            // 0xFE校验码
-            type = binbuff[index++];
-            len = binbuff[index++];
-            if (type != 0xFE || len != 2) {
-                LLOGD("bad file data 4 : %d %d %d", type, len, index);
-                goto _close;
-            }
-            index += len;
-            index += fssize;
-        }
-_close:
-        luat_heap_free(binbuff);
-        luat_fs_fclose(fd);
-    }
-    return res;
-}