diff options
Diffstat (limited to 'utils/hwpatcher/hwpatcher.c')
-rw-r--r-- | utils/hwpatcher/hwpatcher.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/utils/hwpatcher/hwpatcher.c b/utils/hwpatcher/hwpatcher.c index 60e142bbc1..7153a220c9 100644 --- a/utils/hwpatcher/hwpatcher.c +++ b/utils/hwpatcher/hwpatcher.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include "misc.h" | 47 | #include "misc.h" |
48 | #include "md5.h" | 48 | #include "md5.h" |
49 | 49 | ||
50 | #define ARRAYLEN(arr) (sizeof(arr) / sizeof(arr[0])) | ||
51 | |||
50 | lua_State *g_lua; | 52 | lua_State *g_lua; |
51 | bool g_exit = false; | 53 | bool g_exit = false; |
52 | 54 | ||
@@ -59,6 +61,18 @@ enum fw_type_t | |||
59 | FW_UNK, FW_ELF, FW_SB1, FW_SB2, FW_BIN, FW_EDOC | 61 | FW_UNK, FW_ELF, FW_SB1, FW_SB2, FW_BIN, FW_EDOC |
60 | }; | 62 | }; |
61 | 63 | ||
64 | enum crc_type_t | ||
65 | { | ||
66 | CRC_RKW | ||
67 | }; | ||
68 | |||
69 | struct crc_type_desc_t | ||
70 | { | ||
71 | enum crc_type_t type; | ||
72 | const char *lua_name; | ||
73 | unsigned (*fn)(uint8_t *buf, size_t len); | ||
74 | }; | ||
75 | |||
62 | struct bin_file_t | 76 | struct bin_file_t |
63 | { | 77 | { |
64 | size_t size; | 78 | size_t size; |
@@ -849,6 +863,66 @@ int my_lua_section_info(lua_State *state) | |||
849 | return 1; | 863 | return 1; |
850 | } | 864 | } |
851 | 865 | ||
866 | unsigned crc_rkw(uint8_t *buf, size_t len) | ||
867 | { | ||
868 | /* polynomial 0x04c10db7 */ | ||
869 | static const uint32_t crc32_lookup[16] = | ||
870 | { /* lookup table for 4 bits at a time is affordable */ | ||
871 | 0x00000000, 0x04C10DB7, 0x09821B6E, 0x0D4316D9, | ||
872 | 0x130436DC, 0x17C53B6B, 0x1A862DB2, 0x1E472005, | ||
873 | 0x26086DB8, 0x22C9600F, 0x2F8A76D6, 0x2B4B7B61, | ||
874 | 0x350C5B64, 0x31CD56D3, 0x3C8E400A, 0x384F4DBD | ||
875 | }; | ||
876 | |||
877 | uint32_t crc32 = 0; | ||
878 | unsigned char byte; | ||
879 | uint32_t t; | ||
880 | |||
881 | while (len--) | ||
882 | { | ||
883 | byte = *buf++; /* get one byte of data */ | ||
884 | |||
885 | /* upper nibble of our data */ | ||
886 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
887 | t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */ | ||
888 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
889 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
890 | |||
891 | /* lower nibble of our data */ | ||
892 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
893 | t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */ | ||
894 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
895 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
896 | } | ||
897 | |||
898 | return crc32; | ||
899 | } | ||
900 | |||
901 | struct crc_type_desc_t crc_types[] = | ||
902 | { | ||
903 | {CRC_RKW, "RKW", crc_rkw} | ||
904 | }; | ||
905 | |||
906 | int my_lua_crc_buf(lua_State *state) | ||
907 | { | ||
908 | int n = lua_gettop(state); | ||
909 | if(n != 2) | ||
910 | return luaL_error(state, "crc_buf takes two arguments: a crc type and a buffer"); | ||
911 | unsigned type = lua_tounsigned(state, 1); | ||
912 | size_t len; | ||
913 | void *buf = my_lua_get_buffer(state, 2, &len); | ||
914 | for(int i = 0; i < ARRAYLEN(crc_types); i++) | ||
915 | if(crc_types[i].type == type) | ||
916 | { | ||
917 | lua_pushunsigned(state, crc_types[i].fn(buf, len)); | ||
918 | free(buf); | ||
919 | return 1; | ||
920 | } | ||
921 | free(buf); | ||
922 | luaL_error(state, "crc_buf: unknown crc type"); | ||
923 | return 0; | ||
924 | } | ||
925 | |||
852 | /* compute MD5 sum of a buffer */ | 926 | /* compute MD5 sum of a buffer */ |
853 | static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16]) | 927 | static bool compute_md5sum_buf(void *buf, size_t sz, uint8_t file_md5sum[16]) |
854 | { | 928 | { |
@@ -945,6 +1019,17 @@ static bool init_lua_hwp(void) | |||
945 | lua_pushcfunction(g_lua, my_lua_md5sum); | 1019 | lua_pushcfunction(g_lua, my_lua_md5sum); |
946 | lua_setfield(g_lua, -2, "md5sum"); | 1020 | lua_setfield(g_lua, -2, "md5sum"); |
947 | 1021 | ||
1022 | lua_newtable(g_lua); | ||
1023 | for(int i = 0; i < ARRAYLEN(crc_types); i++) | ||
1024 | { | ||
1025 | lua_pushunsigned(g_lua, crc_types[i].type); | ||
1026 | lua_setfield(g_lua, -2, crc_types[i].lua_name); | ||
1027 | } | ||
1028 | lua_setfield(g_lua, -2, "CRC"); | ||
1029 | |||
1030 | lua_pushcfunction(g_lua, my_lua_crc_buf); | ||
1031 | lua_setfield(g_lua, -2, "crc_buf"); | ||
1032 | |||
948 | return true; | 1033 | return true; |
949 | } | 1034 | } |
950 | 1035 | ||