Ticket #5970: webupgrade.builder.v20.patch

File webupgrade.builder.v20.patch, 65.9 KB (added by Maddes <maddes_trac@…>, 8 years ago)

the "wrt350nv2-builder" tool itself

  • tools/wrt350nv2-builder/src/wrt350nv2-builder.c

     
     1/* 
     2 
     3        WRT350Nv2-Builder 2.0 (previously called buildimg) 
     4        Copyright (C) 2008-2009 Dirk Teurlings <info@upexia.nl> 
     5        Copyright (C) 2009      Matthias Buecher (http://www.maddes.net/) 
     6 
     7        This program is free software; you can redistribute it and/or modify 
     8        it under the terms of the GNU General Public License as published by 
     9        the Free Software Foundation; either version 2 of the License, or 
     10        (at your option) any later version. 
     11 
     12        This program is distributed in the hope that it will be useful, 
     13        but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     15        GNU General Public License for more details. 
     16 
     17        You should have received a copy of the GNU General Public License 
     18        along with this program; if not, write to the Free Software 
     19        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     20 
     21        A lot of thanks to Kaloz and juhosg from OpenWRT and Lennert Buytenhek from 
     22        marvell for helping me figure this one out. This code is based on bash 
     23        scripts wrote by Peter van Valderen so the real credit should go to him. 
     24 
     25        This program reads the provided parameter file and creates an image which can 
     26        be used to flash a Linksys WRT350N v2 from stock firmware. 
     27        The trick is to fill unused space in the bin file with random, so that the 
     28        resulting zip file passes the size check of the stock firmware. 
     29 
     30        The parameter file layout for an original Linksys firmware: 
     31                :kernel 0x001A0000      /path/to/uImage 
     32                :rootfs 0       /path/to/root.squashfs 
     33                :u-boot 0       /path/to/u-boot.bin 
     34 
     35        args: 
     36                1       wrt350nv2.par           parameter file describing the image layout 
     37                2       wrt350nv2.img           output file for linksys style image 
     38 
     39        An u-boot image inside the bin file is not necessary. 
     40        The version is not important. 
     41        The name of the bin file is not important. 
     42 
     43        Linksys assumes that no mtd will be used to its maximum, so the last 16 bytes 
     44        of the mtd are abused to define the length of the next mtd content (4 bytes for 
     45        size + 12 pad bytes). 
     46 
     47        At the end of "rootfs" additional 16 bytes are abused for some data and an 
     48        highly important eRcOmM identifier, so the last 32 bytes of "rootfs" are abused. 
     49 
     50        At the end of "u-boot" 128 bytes are abused for some data, a checksum and an 
     51        highly important sErCoMm identifier. 
     52 
     53 
     54        This program uses a special GNU scanf modifier to allocate 
     55        sufficient memory for a strings with unknown length. 
     56        See http://www.kernel.org/doc/man-pages/online/pages/man3/scanf.3.html#NOTES 
     57 
     58 
     59        To extract everything from a Linksys style firmware image see 
     60        https://forum.openwrt.org/viewtopic.php?pid=92928#p92928 
     61 
     62*/ 
     63 
     64// ToDo: 
     65// * Has NODE to be added to bin file *after* creating checksum byte? 
     66 
     67// includes 
     68#define _GNU_SOURCE     // for GNU's basename() 
     69#include <assert.h> 
     70#include <errno.h>      // errno 
     71#include <stdarg.h> 
     72#include <stdio.h>      // fopen(), fread(), fclose(), etc. 
     73#include <stdlib.h>     // system(), etc. 
     74#include <string.h>     // basename(), strerror(), strdup(), etc. 
     75#include <unistd.h>     // optopt(), access(), etc. 
     76#include <sys/wait.h>   // WEXITSTATUS, etc. 
     77 
     78// custom includes 
     79#include "md5.h"        // MD5 routines 
     80#include "upgrade.h"    // Linksys definitions from firmware 2.0.19 
     81 
     82 
     83// version info 
     84#define VERSION "2.0" 
     85char program_info[] = "WRT350Nv2-Builder v%s by Dirk Teurlings <info@upexia.nl> and Matthias Buecher (http://www.maddes.net/)\n"; 
     86 
     87// verbosity 
     88#define DEBUG 1 
     89#define DEBUG_LVL2 2 
     90int verbosity = 0; 
     91 
     92// mtd info 
     93typedef struct { 
     94        char *name; 
     95        int offset; 
     96        int size; 
     97        char *filename; 
     98        long int filesize; 
     99        unsigned char magic[2]; 
     100} mtd_info; 
     101 
     102mtd_info mtd_kernel = { "kernel", 0, 0, NULL, 0L, { 0, 0 } }; 
     103mtd_info mtd_rootfs = { "rootfs", 0, 0, NULL, 0L, { 0, 0 } }; 
     104mtd_info mtd_uboot = { "u-boot", 0, 0, NULL, 0L, { 0, 0 } }; 
     105 
     106#define ROOTFS_END_OFFSET       0x00760000 
     107#define ROOTFS_MIN_OFFSET       0x00700000      // should be filled up to here, to make sure that the zip file is big enough to pass the size check of the stock firmware 
     108 
     109// rootfs statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0x0075FFE0 -n 16 "wrt350n.bin" ; echo -en "\n" 
     110unsigned char product_id[] = { 0x00, 0x03 };    // seems to be a fixed value 
     111unsigned char protocol_id[] = { 0x00, 0x00 };   // seems to be a fixed value 
     112unsigned char fw_version[] = { 0x20, 0x19 }; 
     113unsigned char rootfs_unknown[] = { 0x90, 0xF7 };        // seems to be a fixed value 
     114unsigned char sign[] = { 0x65, 0x52, 0x63, 0x4F, 0x6D, 0x4D, 0x00, 0x00 };      // eRcOmM 
     115 
     116// u-boot statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0x007FFF80 -n 128 "wrt350n.bin" ; echo -en "\n" 
     117//unsigned char sn[]   = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };       // (12) seems to be an unused value 
     118//unsigned char pin[]  = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };       // (8) seems to be an unused value 
     119//unsigned char node[] = {      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (25) seems to be an unused value 
     120//                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
     121//unsigned char checksum[] = { 0xE9 };  // (1) is calculated, does it belong to node? 
     122unsigned char pid[] = { 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x01, 0x00, 0x00, 0x59, 0x42, 0x50, 0x00, 0x01, // (70) seems to be a fixed value, except for fw version 
     123                                0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     124                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // protocol id? 
     125                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,   // protocol id? 
     126                                0x12, 0x34,     // firmware version, same as in rootfs 
     127                                0x00, 0x00, 0x00, 0x04, 
     128                                0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D };     // sErCoMm 
     129 
     130// img statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0 -n 512 "WRT350N-EU-ETSI-2.00.19.img" ; echo -en "\n" 
     131unsigned char img_hdr[] = {     0x00, 0x01, 0x00, 0x00, 0x59, 0x42, 0x50, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     132                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     133                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
     134                                0x00, 0x00, 
     135                                0x12, 0x34,     // firmware version, same as in rootfs 
     136                                0x00, 0x00, 0x00, 0x04, 0x61, 0x44, 0x6D, 0x42, 0x6C, 0x4B, 0x3D, 0x00, 
     137                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     138                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     139                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     140                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     141                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     142                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     143                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     144                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     145                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     146                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     147                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     148                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     149                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     150                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     151                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     152                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     153                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     154                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     155                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     156                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     157                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     158                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     159                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     160                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     161                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     162                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     163                                0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // md5 checksum 
     164                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
     165 
     166unsigned char img_eof[] = {     0xFF }; 
     167 
     168 
     169void lprintf(int outputlevel, char *fmt, ...) { 
     170        va_list argp; 
     171        if (outputlevel <= verbosity) { 
     172                va_start(argp, fmt); 
     173                vprintf(fmt, argp); 
     174                va_end(argp); 
     175        } 
     176} 
     177 
     178 
     179int parse_par_file(FILE *f_par) { 
     180        int exitcode = 0; 
     181 
     182        char *buffer; 
     183        size_t buffer_size; 
     184        char *line; 
     185 
     186        int lineno; 
     187        int count; 
     188 
     189        char *string1; 
     190        char *string2; 
     191        int value; 
     192 
     193        mtd_info *mtd; 
     194        FILE *f_in; 
     195        int f_exitcode = 0; 
     196 
     197        // read all lines 
     198        buffer_size = 1000; 
     199        buffer = NULL; 
     200        lineno = 0; 
     201        while (!feof(f_par)) { 
     202                // read next line into memory 
     203                do { 
     204                        // allocate memory for input line 
     205                        if (buffer == NULL) { 
     206                                buffer = malloc(buffer_size); 
     207                        } 
     208                        if (buffer == NULL) { 
     209                                exitcode = 1; 
     210                                printf("parse_par_file: can not allocate %i bytes\n", buffer_size); 
     211                                break; 
     212                        } 
     213 
     214                        line = fgets(buffer, buffer_size, f_par); 
     215                        if (line == NULL) { 
     216                                exitcode = ferror(f_par); 
     217                                if (exitcode) { 
     218                                        printf("parse_par_file: %s\n", strerror(exitcode)); 
     219                                } 
     220                                break; 
     221                        } 
     222 
     223                        // if buffer was not completely filled, then assume that line is complete 
     224                        count = strlen(buffer) + 1; 
     225                        if (count-- < buffer_size) { 
     226                                break; 
     227                        } 
     228 
     229                        // otherwise.... 
     230 
     231                        // reset file position to line start 
     232                        value = fseek(f_par, -count, SEEK_CUR); 
     233                        if (value == -1) { 
     234                                exitcode = errno; 
     235                                printf("parse_par_file: %s\n", strerror(exitcode)); 
     236                                break; 
     237                        } 
     238 
     239                        // double buffer size 
     240                        free(buffer); 
     241                        buffer = NULL; 
     242                        buffer_size *= 2; 
     243                        lprintf(DEBUG_LVL2, " extending buffer to %i bytes\n", buffer_size); 
     244                } while (1); 
     245                if (line == NULL || exitcode) { 
     246                        break; 
     247                } 
     248 
     249                lineno++;       // increase line number 
     250 
     251                lprintf(DEBUG_LVL2, " line %i (%i) %s", lineno, count, line); 
     252 
     253                string1 = NULL; 
     254                string2 = NULL; 
     255                value = 0; 
     256                mtd = NULL; 
     257 
     258                // split line if starting with a colon 
     259                switch (line[0]) { 
     260                        case ':': 
     261                                count = sscanf(line, ":%ms %i %ms", &string1, &value, &string2); 
     262                                if (count != 3) { 
     263                                        printf("line %i does not meet defined format (:<mtdname> <mtdsize> <file>)\n", lineno); 
     264                                } else { 
     265                                        // populate mtd_info if supported mtd names 
     266                                        if (strcmp(string1, mtd_kernel.name) == 0) { 
     267                                                mtd = &mtd_kernel; 
     268                                        } else if (strcmp(string1, mtd_rootfs.name) == 0) { 
     269                                                mtd = &mtd_rootfs; 
     270                                        } else if (strcmp(string1, mtd_uboot.name) == 0) { 
     271                                                mtd = &mtd_uboot; 
     272                                        } 
     273 
     274                                        if (mtd == NULL) { 
     275                                                printf("unknown mtd %s in line %i\n", string1, lineno); 
     276                                        } else if (mtd->filename != NULL) { 
     277                                                f_exitcode = 1; 
     278                                                printf("mtd %s in line %i multiple definitions\n", string1, lineno); 
     279                                        } else { 
     280                                                mtd->size = value; 
     281                                                mtd->filename = string2; 
     282                                                string2 = NULL; // do not free 
     283 
     284                                                // Get file size 
     285                                                f_in = fopen(mtd->filename, "rb"); 
     286                                                if (f_in == NULL) { 
     287                                                        f_exitcode = errno; 
     288                                                        printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode)); 
     289                                                } else { 
     290                                                        value = fread(&mtd->magic, 1, 2, f_in); 
     291                                                        if (value < 2) { 
     292                                                                if (ferror(f_in)) { 
     293                                                                        f_exitcode = ferror(f_in); 
     294                                                                        printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode)); 
     295                                                                } else { 
     296                                                                        f_exitcode = 1; 
     297                                                                        printf("input file %s: smaller than two bytes, no magic code\n", mtd->filename); 
     298                                                                } 
     299                                                        } 
     300 
     301                                                        value = fseek(f_in, 0, SEEK_END); 
     302                                                        if (value == -1) { 
     303                                                                f_exitcode = errno; 
     304                                                                printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode)); 
     305                                                        } else { 
     306                                                                mtd->filesize = ftell(f_in); 
     307                                                                if (mtd->filesize == -1) { 
     308                                                                        f_exitcode = errno; 
     309                                                                        printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode)); 
     310                                                                } 
     311                                                        } 
     312 
     313                                                        fclose(f_in); 
     314                                                } 
     315 
     316                                                lprintf(DEBUG, "mtd %s in line %i: size=0x%08X, filesize=0x%08lX, magic=0x%02X%02X, file=%s\n", mtd->name, lineno, mtd->size, mtd->filesize, mtd->magic[0], mtd->magic[1], mtd->filename); 
     317                                        } 
     318                                } 
     319                                break; 
     320                        case '#':       // integer values 
     321                                count = sscanf(line, "#%ms %i", &string1, &value); 
     322                                if (count != 2) { 
     323                                        printf("line %i does not meet defined format (:<variable name> <integer>\n", lineno); 
     324                                } else { 
     325                                        if (strcmp(string1, "version") == 0) { 
     326                                                // changing version 
     327                                                fw_version[0] = 0x000000FF & ( value >> 8 ); 
     328                                                fw_version[1] = 0x000000FF &   value; 
     329                                        } else { 
     330                                                printf("unknown integer variable %s in line %i\n", string1, lineno); 
     331                                        } 
     332 
     333                                        lprintf(DEBUG, "integer variable %s in line %i: 0x%08X\n", string1, lineno, value); 
     334                                } 
     335                                break; 
     336                        case '$':       // strings 
     337                                count = sscanf(line, "$%ms %ms", &string1, &string2); 
     338                                if (count != 2) { 
     339                                        printf("line %i does not meet defined format (:<mtdname> <mtdsize> <file>)\n", lineno); 
     340                                } else { 
     341/* 
     342                                        if (strcmp(string1, "something") == 0) { 
     343                                                something = string2; 
     344                                                string2 = NULL; // do not free 
     345                                        } else { 
     346*/ 
     347                                                printf("unknown string variable %s in line %i\n", string1, lineno); 
     348//                                      } 
     349                                        lprintf(DEBUG, "string variable %s in line %i: %s\n", string1, lineno, string2); 
     350                                } 
     351                                break; 
     352                        default: 
     353                                break; 
     354                } 
     355 
     356                if (string1) { 
     357                        free(string1); 
     358                } 
     359                if (string2) { 
     360                        free(string2); 
     361                } 
     362        } 
     363        free(buffer); 
     364 
     365        if (!exitcode) { 
     366                exitcode = f_exitcode; 
     367        } 
     368 
     369        return exitcode; 
     370} 
     371 
     372 
     373int create_bin_file(char *bin_filename) { 
     374        int exitcode = 0; 
     375 
     376        unsigned char *buffer; 
     377 
     378        int i; 
     379        mtd_info *mtd; 
     380        int addsize; 
     381        int padsize; 
     382 
     383        char *rand_filename = "/dev/urandom"; 
     384        FILE *f_in; 
     385        int size; 
     386 
     387        unsigned long int csum; 
     388        unsigned char checksum; 
     389 
     390        FILE *f_out; 
     391 
     392        // allocate memory for bin file 
     393        buffer = malloc(KERNEL_CODE_OFFSET + FLASH_SIZE); 
     394        if (buffer == NULL) { 
     395                exitcode = 1; 
     396                printf("create_bin_file: can not allocate %i bytes\n", FLASH_SIZE); 
     397        } else { 
     398                // initialize with zero 
     399                memset(buffer, 0, KERNEL_CODE_OFFSET + FLASH_SIZE); 
     400        } 
     401 
     402        // add files 
     403        if (!exitcode) { 
     404                for (i = 1; i <= 3; i++) { 
     405                        addsize = 0; 
     406                        padsize = 0; 
     407 
     408                        switch (i) { 
     409                                case 1: 
     410                                        mtd = &mtd_kernel; 
     411                                        break; 
     412                                case 2: 
     413                                        mtd = &mtd_rootfs; 
     414                                        addsize = mtd->filesize; 
     415                                        padsize = ROOTFS_MIN_OFFSET - mtd_kernel.size - mtd->filesize; 
     416                                        break; 
     417                                case 3: 
     418                                        mtd = &mtd_uboot; 
     419                                        addsize = mtd->filesize; 
     420                                        break; 
     421                                default: 
     422                                        mtd = NULL; 
     423                                        exitcode = 1; 
     424                                        printf("create_bin_file: unknown mtd %i\n", i); 
     425                                        break; 
     426                        } 
     427                        if (mtd == NULL) { 
     428                                break; 
     429                        } 
     430                        if (mtd->filename == NULL) { 
     431                                continue; 
     432                        } 
     433 
     434                        lprintf(DEBUG, "adding mtd %s file %s\n", mtd->name, mtd->filename); 
     435 
     436                        // adding file size 
     437                        if (addsize) { 
     438                                buffer[KERNEL_CODE_OFFSET + mtd->offset - 16] = 0x000000FFL & ( addsize >> 24 ); 
     439                                buffer[KERNEL_CODE_OFFSET + mtd->offset - 15] = 0x000000FFL & ( addsize >> 16 ); 
     440                                buffer[KERNEL_CODE_OFFSET + mtd->offset - 14] = 0x000000FFL & ( addsize >> 8  ); 
     441                                buffer[KERNEL_CODE_OFFSET + mtd->offset - 13] = 0x000000FFL &   addsize; 
     442                        } 
     443 
     444                        // adding file content 
     445                        f_in = fopen(mtd->filename, "rb"); 
     446                        if (f_in == NULL) { 
     447                                exitcode = errno; 
     448                                printf("input file %s: %s\n", mtd->filename, strerror(exitcode)); 
     449                        } else { 
     450                                size = fread(&buffer[KERNEL_CODE_OFFSET + mtd->offset], mtd->filesize, 1, f_in); 
     451                                if (size < 1) { 
     452                                        if (ferror(f_in)) { 
     453                                                exitcode = ferror(f_in); 
     454                                                printf("input file %s: %s\n", mtd->filename, strerror(exitcode)); 
     455                                        } else { 
     456                                                exitcode = 1; 
     457                                                printf("input file %s: smaller than before *doh*\n", mtd->filename); 
     458                                        } 
     459                                } 
     460                                fclose(f_in); 
     461                        } 
     462 
     463                        // padding 
     464                        if (padsize > 0) { 
     465                                printf("mtd %s input file %s is too small (0x%08lX), adding 0x%08X random bytes\n", mtd->name, mtd->filename, mtd->filesize, padsize); 
     466 
     467                                addsize = padsize & 0x0000FFFF; // start on next 64KB border 
     468                                padsize -= addsize; 
     469                                addsize += KERNEL_CODE_OFFSET + mtd->offset + mtd->filesize;    // get offset 
     470                                lprintf(DEBUG, " padding offset 0x%08X length 0x%08X\n", addsize, padsize); 
     471 
     472                                f_in = fopen(rand_filename, "rb"); 
     473                                if (f_in == NULL) { 
     474                                        exitcode = errno; 
     475                                        printf("input file %s: %s\n", rand_filename, strerror(exitcode)); 
     476                                } else { 
     477                                        size = fread(&buffer[addsize], padsize, 1, f_in); 
     478                                        if (size < 1) { 
     479                                                if (ferror(f_in)) { 
     480                                                        exitcode = ferror(f_in); 
     481                                                        printf("input file %s: %s\n", rand_filename, strerror(exitcode)); 
     482                                                } else { 
     483                                                        exitcode = 1; 
     484                                                        printf("input file %s: smaller than before *doh*\n", rand_filename); 
     485                                                } 
     486                                        } 
     487                                } 
     488                                fclose(f_in); 
     489                        } 
     490                } 
     491        } 
     492 
     493        // add special contents 
     494        if (!exitcode) { 
     495                lprintf(DEBUG, "adding rootfs special data\n"); 
     496                memcpy(&buffer[KERNEL_CODE_OFFSET + PRODUCT_ID_OFFSET], product_id, 2); 
     497                memcpy(&buffer[KERNEL_CODE_OFFSET + PROTOCOL_ID_OFFSET], protocol_id, 2); 
     498                memcpy(&buffer[KERNEL_CODE_OFFSET + FW_VERSION_OFFSET], fw_version, 2); 
     499                memcpy(&buffer[KERNEL_CODE_OFFSET + FW_VERSION_OFFSET + 2], rootfs_unknown, 2); 
     500                memcpy(&buffer[KERNEL_CODE_OFFSET + SIGN_OFFSET], sign, 8);     // eRcOmM 
     501 
     502                lprintf(DEBUG, "adding u-boot special data 1/2\n");     // ToDo: or after creating the checksum byte? 
     503//              memcpy(&buffer[KERNEL_CODE_OFFSET + SN_OFF], sn, 12);   // ToDo: find out what's this for? 
     504//              memcpy(&buffer[KERNEL_CODE_OFFSET + PIN_OFF], pin, 8);  // ToDo: find out what's this for? 
     505//              memcpy(&buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF], node, 25);  // ToDo: find out what's this for? 
     506 
     507                lprintf(DEBUG, "adding checksum byte\n"); 
     508                csum = 0; 
     509                for (i = 0; i < KERNEL_CODE_OFFSET + FLASH_SIZE; i++) { 
     510                        csum += buffer[i]; 
     511                } 
     512                lprintf(DEBUG_LVL2, " checksum 0x%016lX (%li)\n", csum, csum); 
     513 
     514                buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25] = ~(csum+108)+1; 
     515                lprintf(DEBUG, " byte 0x%02X\n", buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25]); 
     516 
     517                lprintf(DEBUG, "adding u-boot special data 2/2\n"); 
     518                memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET], pid, 70); // sErCoMm 
     519                memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET + 57], fw_version, 2); 
     520        } 
     521 
     522        // write bin file 
     523        if (!exitcode) { 
     524                lprintf(DEBUG, "writing file %s\n", bin_filename); 
     525                f_out = fopen(bin_filename, "wb"); 
     526                if (f_out == NULL) { 
     527                        exitcode = errno; 
     528                        printf("output file %s: %s\n", bin_filename, strerror(exitcode)); 
     529                } else { 
     530                        size = fwrite(buffer, KERNEL_CODE_OFFSET + FLASH_SIZE, 1, f_out); 
     531                        if (size < 1) { 
     532                                if (ferror(f_out)) { 
     533                                        exitcode = ferror(f_out); 
     534                                        printf("output file %s: %s\n", bin_filename, strerror(exitcode)); 
     535                                } else { 
     536                                        exitcode = 1; 
     537                                        printf("output file %s: unspecified write error\n", bin_filename); 
     538                                } 
     539                        } 
     540                        fclose(f_out); 
     541                } 
     542        } 
     543 
     544        return exitcode; 
     545} 
     546 
     547 
     548int create_zip_file(char *zip_filename, char *bin_filename) { 
     549        int exitcode = 0; 
     550 
     551        char *buffer; 
     552        size_t buffer_size; 
     553        int count; 
     554 
     555        buffer_size = 1000; 
     556        buffer = NULL; 
     557        do { 
     558                // allocate memory for command line 
     559                if (buffer == NULL) { 
     560                        buffer = malloc(buffer_size); 
     561                } 
     562                if (buffer == NULL) { 
     563                        exitcode = 1; 
     564                        printf("create_zip_file: can not allocate %i bytes\n", buffer_size); 
     565                        break; 
     566                } 
     567 
     568                // if buffer was not completely filled, then line fit in completely 
     569                count = snprintf(buffer, buffer_size, "zip %s %s", zip_filename, bin_filename); 
     570                if (count > -1 && count < buffer_size) { 
     571                        break; 
     572                } 
     573 
     574                // otherwise try again with more space 
     575                if (count > -1) {       // glibc 2.1 
     576                        buffer_size = count + 1;        // precisely what is needed 
     577                } else {        // glibc 2.0 
     578                        buffer_size *= 2;       // twice the old size 
     579                } 
     580                free(buffer); 
     581                buffer = NULL; 
     582                lprintf(DEBUG_LVL2, " extending buffer to %i bytes\n", buffer_size); 
     583        } while (1); 
     584 
     585        if (!exitcode) { 
     586                // zipping binfile 
     587                lprintf(DEBUG, "%s\n", buffer); 
     588                count = system(buffer); 
     589                if (count < 0 || WEXITSTATUS(count)) { 
     590                        exitcode = 1; 
     591                        printf("create_zip_file: can not execute %s bytes\n", buffer); 
     592                } 
     593        } 
     594 
     595        return exitcode; 
     596} 
     597 
     598 
     599int create_img_file(FILE *f_out, char *out_filename, char *zip_filename) { 
     600        int exitcode = 0; 
     601 
     602        md5_state_t state; 
     603        md5_byte_t digest[16]; 
     604 
     605        int i; 
     606        int size; 
     607 
     608        FILE *f_in; 
     609        unsigned char buffer[1]; 
     610 
     611        // copy firmware version 
     612        memcpy(&img_hdr[50], fw_version, 2); 
     613 
     614        // clear md5 checksum 
     615        memset(&img_hdr[480], 0, 16); 
     616 
     617        // prepare md5 checksum calculation 
     618        md5_init(&state); 
     619 
     620        // add img header 
     621        lprintf(DEBUG_LVL2, " adding img header\n"); 
     622        for (i = 0; i < 512; i++) { 
     623                size = fputc(img_hdr[i], f_out); 
     624                if (size == EOF) { 
     625                        exitcode = ferror(f_out); 
     626                        printf("output file %s: %s\n", out_filename, strerror(exitcode)); 
     627                        break; 
     628                } 
     629                md5_append(&state, (const md5_byte_t *)&img_hdr[i], 1); 
     630        } 
     631 
     632        // adding zip file 
     633        if (!exitcode) { 
     634                lprintf(DEBUG_LVL2, " adding zip file\n"); 
     635                f_in = fopen(zip_filename, "rb"); 
     636                if (f_in == NULL) { 
     637                        exitcode = errno; 
     638                        printf("input file %s: %s\n", zip_filename, strerror(exitcode)); 
     639                } else { 
     640                        while ((size = fgetc(f_in)) != EOF) { 
     641                                buffer[0] = size; 
     642 
     643                                size = fputc(buffer[0], f_out); 
     644                                if (size == EOF) { 
     645                                        exitcode = ferror(f_out); 
     646                                        printf("output file %s: %s\n", out_filename, strerror(exitcode)); 
     647                                        break; 
     648                                } 
     649                                md5_append(&state, (const md5_byte_t *)buffer, 1); 
     650                        } 
     651                        if (ferror(f_in)) { 
     652                                exitcode = ferror(f_in); 
     653                                printf("input file %s: %s\n", zip_filename, strerror(exitcode)); 
     654                        } 
     655                } 
     656 
     657        } 
     658 
     659        // add end byte 
     660        if (!exitcode) { 
     661                lprintf(DEBUG_LVL2, " adding img eof byte\n"); 
     662                size = fputc(img_eof[0], f_out); 
     663                if (size == EOF) { 
     664                        exitcode = ferror(f_out); 
     665                        printf("output file %s: %s\n", out_filename, strerror(exitcode)); 
     666                } 
     667                md5_append(&state, (const md5_byte_t *)img_eof, 1); 
     668        } 
     669 
     670        // append salt to md5 checksum 
     671        md5_append(&state, (const md5_byte_t *)"A^gU*<>?RFY@#DR&Z", 17); 
     672 
     673        // finish md5 checksum calculation 
     674        md5_finish(&state, digest); 
     675 
     676        // write md5 checksum into img header 
     677        if (!exitcode) { 
     678                lprintf(DEBUG_LVL2, " writing md5 checksum into img header of file\n"); 
     679 
     680                size = fseek(f_out, 480, SEEK_SET); 
     681                if (size == -1) { 
     682                        exitcode = errno; 
     683                        printf("output file %s: %s\n", out_filename, strerror(exitcode)); 
     684                } else { 
     685                        size = fwrite(digest, 16, 1, f_out); 
     686                        if (size < 1) { 
     687                                if (ferror(f_out)) { 
     688                                        exitcode = ferror(f_out); 
     689                                        printf("output file %s: %s\n", out_filename, strerror(exitcode)); 
     690                                } else { 
     691                                        exitcode = 1; 
     692                                        printf("output file %s: unspecified write error\n", out_filename); 
     693                                } 
     694                        } 
     695                } 
     696 
     697                fclose(f_in); 
     698        } 
     699 
     700        return exitcode; 
     701} 
     702 
     703 
     704int main(int argc, char *argv[]) { 
     705        int exitcode = 0; 
     706 
     707        int help; 
     708        int havezip; 
     709        char option; 
     710        char *par_filename = NULL; 
     711        char *out_filename = NULL; 
     712        char *base_filename = NULL; 
     713        char *bin_filename = NULL; 
     714        char *zip_filename = NULL; 
     715 
     716        FILE *f_par; 
     717        FILE *f_out; 
     718 
     719        int i; 
     720        mtd_info *mtd; 
     721        int mandatory; 
     722        int noupdate; 
     723        int sizecheck; 
     724        unsigned char magic[2]; 
     725 
     726 
     727// display program header 
     728        printf(program_info, VERSION); 
     729 
     730 
     731// command line processing 
     732        // options 
     733        help = 0; 
     734        havezip = 0; 
     735        while ((option = getopt(argc, argv, ":hzf:v")) != -1) { 
     736                switch(option) { 
     737                        case 'h': 
     738                                help = 1; 
     739                                break; 
     740                        case 'z': 
     741                                havezip = 1; 
     742                                break; 
     743                        case 'f': 
     744                                sizecheck = sscanf(optarg, "%i", &i); 
     745                                if (sizecheck != 1) { 
     746                                        printf("firmware version of -f option not a valid integer\n"); 
     747                                        exitcode = 1; 
     748                                } else { 
     749                                        fw_version[0] = 0x000000FF & ( i >> 8 ); 
     750                                        fw_version[1] = 0x000000FF &   i; 
     751                                } 
     752                                break; 
     753                        case 'v': 
     754                                verbosity++; 
     755                                break; 
     756                        case ':':       // option with missing operand 
     757                                printf("Option -%c requires an operand\n", optopt); 
     758                                exitcode = 1; 
     759                                break; 
     760                        case '?': 
     761                                printf("Unrecognized option: -%c\n", optopt); 
     762                                exitcode = 1; 
     763                                break; 
     764                } 
     765        } 
     766 
     767        // files 
     768        for ( ; optind < argc; optind++) { 
     769                if (par_filename == NULL) { 
     770                        par_filename = argv[optind]; 
     771 
     772                        if (access(par_filename, R_OK)) { 
     773                                if (havezip) { 
     774                                        printf("No read access to zip file %s\n", par_filename); 
     775                                } else { 
     776                                        printf("No read access to parameter or zip file %s\n", par_filename); 
     777                                } 
     778                                exitcode = 1; 
     779                        } 
     780 
     781                        continue; 
     782                } 
     783 
     784                if (out_filename == NULL) { 
     785                        out_filename = argv[optind]; 
     786 
     787                        if (!access(out_filename, F_OK)) {      // if file already exists then check write access 
     788                                if (access(out_filename, W_OK)) { 
     789                                        printf("No write access to output file %s\n", out_filename); 
     790                                        exitcode = 1; 
     791                                } 
     792                        } 
     793 
     794                        continue; 
     795                } 
     796 
     797                printf("Too many files stated\n"); 
     798                exitcode = 1; 
     799                break; 
     800        } 
     801 
     802        // file name checks 
     803        if (par_filename == NULL) { 
     804                if (havezip) { 
     805                        printf("Zip file not stated\n"); 
     806                } else { 
     807                        printf("Parameter file not stated\n"); 
     808                } 
     809                exitcode = 1; 
     810        } else { 
     811                base_filename = basename(par_filename); 
     812                if (base_filename == NULL) { 
     813                        if (havezip) { 
     814                                printf("Zip file is a directory\n"); 
     815                        } else { 
     816                                printf("Parameter file is a directory\n"); 
     817                        } 
     818                        exitcode = 1; 
     819                } 
     820        } 
     821 
     822        if (out_filename == NULL) { 
     823                printf("Output file not stated\n"); 
     824                exitcode = 1; 
     825        } else { 
     826                base_filename = basename(out_filename); 
     827                if (base_filename == NULL) { 
     828                        printf("Output file is a directory\n"); 
     829                        exitcode = 1; 
     830                } else { 
     831                        base_filename = strdup(base_filename); 
     832                        zip_filename = strrchr(base_filename, '.'); 
     833                        if (zip_filename != NULL) { 
     834                                zip_filename[0] = 0; 
     835                                zip_filename = NULL;    // clean up 
     836                        } 
     837                } 
     838        } 
     839 
     840        // react on parameter problems or help request, and exit 
     841        if ((exitcode != 0) || help) { 
     842                if (help) { 
     843                        printf("This program creates Linksys style images for the WRT350Nv2 router.\n"); 
     844                } 
     845                printf("  Usage:\n\ 
     846  %s [-h] [-z] [-f <version>] [-v] <parameter or zip file> <output file>\n\n\ 
     847  Options:\n\ 
     848  -h            -  Show this help\n\ 
     849  -z            -  Have zip file, the img file will be directly created from it\n\ 
     850  -f <version>  -  Wanted firmware version to use with -z\n\ 
     851                   Default firmware version is 0x2019 = 2.00.19.\n\ 
     852                   Note: version from parameter file will supersede this\n\ 
     853  -v            -  Increase debug verbosity level\n\n\ 
     854  Example:\n\ 
     855  %s wrt350nv2.par wrt350nv2.img\n\n", argv[0], argv[0]); 
     856                return exitcode; 
     857        } 
     858 
     859        // handle special case when zipfile is stated 
     860        if (havezip) { 
     861                zip_filename = par_filename; 
     862                par_filename = NULL; 
     863        } 
     864 
     865        lprintf(DEBUG_LVL2, " verbosity: %i\n", verbosity); 
     866        lprintf(DEBUG_LVL2, " program: %s\n", argv[0]); 
     867 
     868        lprintf(DEBUG, "Parameter file: %s\n", par_filename); 
     869        lprintf(DEBUG, "Output file: %s\n", out_filename); 
     870        lprintf(DEBUG_LVL2, " basename: %s (%i)\n", base_filename, strlen(base_filename)); 
     871 
     872 
     873// open files from command line 
     874        // parameter file 
     875        if (par_filename != NULL) { 
     876                f_par = fopen(par_filename, "r"); 
     877                if (f_par == NULL) { 
     878                        exitcode = errno; 
     879                        printf("input file %s: %s\n", par_filename, strerror(exitcode)); 
     880                } 
     881        } 
     882 
     883        // output file 
     884        f_out = fopen(out_filename, "w"); 
     885        if (f_out == NULL) { 
     886                exitcode = errno; 
     887                printf("Output file %s: %s\n", out_filename, strerror(exitcode)); 
     888        } 
     889 
     890        if (exitcode) { 
     891                return exitcode; 
     892        } 
     893 
     894 
     895// parameter file processing 
     896        if (!exitcode && par_filename != NULL) { 
     897                lprintf(DEBUG, "parsing parameter file...\n"); 
     898 
     899                exitcode = parse_par_file(f_par); 
     900 
     901                lprintf(DEBUG, "...done parsing file\n"); 
     902        } 
     903        if (par_filename != NULL) { 
     904                fclose(f_par); 
     905        } 
     906 
     907 
     908// check all input data 
     909        if (!exitcode && par_filename != NULL) { 
     910                lprintf(DEBUG, "checking mtd data...\n"); 
     911 
     912                for (i = 1; i <= 3; i++) { 
     913                        mandatory = 0; 
     914                        noupdate = 0; 
     915                        sizecheck = 0; 
     916                        magic[0] = 0; 
     917                        magic[1] = 0; 
     918 
     919                        switch (i) { 
     920                                case 1: 
     921                                        mtd = &mtd_kernel; 
     922                                        mandatory = 1; 
     923                                        sizecheck = mtd_kernel.size - 16; 
     924                                        magic[0] = 0x27; 
     925                                        magic[1] = 0x05; 
     926                                        break; 
     927                                case 2: 
     928                                        mtd = &mtd_rootfs; 
     929                                        mtd->offset = mtd_kernel.size; 
     930                                        mtd->size = ROOTFS_END_OFFSET - mtd_kernel.size; 
     931                                        mandatory = 1; 
     932                                        sizecheck = PRODUCT_ID_OFFSET - mtd_kernel.size; 
     933                                        magic[0] = 0x68; 
     934                                        magic[1] = 0x73; 
     935                                        break; 
     936                                case 3: 
     937                                        mtd = &mtd_uboot; 
     938                                        mtd->offset = BOOT_ADDR_BASE_OFF; 
     939                                        noupdate = 1; 
     940                                        sizecheck = SN_OFF - BOOT_ADDR_BASE_OFF; 
     941                                        break; 
     942                                default: 
     943                                        mtd = NULL; 
     944                                        exitcode = 1; 
     945                                        printf("unknown mtd check %i\n", i); 
     946                                        break; 
     947                        } 
     948                        if (mtd == NULL) { 
     949                                break; 
     950                        } 
     951 
     952                        lprintf(DEBUG_LVL2, " checking mtd %s\n", mtd->name); 
     953 
     954                        // general checks 
     955                        if (mandatory && mtd->filename == NULL) { 
     956                                exitcode = 1; 
     957                                printf("mtd %s not specified correctly or at all in parameter file\n", mtd->name); 
     958                        } 
     959 
     960                        // end checks if no file data present 
     961                        if (mtd->filename == NULL) { 
     962                                continue; 
     963                        } 
     964 
     965                        // not updated by stock firmware 
     966                        if (noupdate) { 
     967                                printf("mtd %s is specified, but will not be updated as of Linksys firmware 2.0.19\n", mtd->name); 
     968                        } 
     969 
     970                        // general magic number check 
     971                        if (magic[0]) { 
     972                                if (mtd->magic[0] != magic[0] || mtd->magic[1] != magic[1]) { 
     973                                        exitcode = 1; 
     974                                        printf("mtd %s input file %s has wrong magic number (0x%02X%02X)\n", mtd->name, mtd->filename, mtd->magic[0], mtd->magic[1]); 
     975                                } 
     976                        } 
     977 
     978                        // mtd specific size check 
     979                        if (mtd == &mtd_kernel) { 
     980                                if (mtd->filesize < 0x00050000) { 
     981                                        exitcode = 1; 
     982                                        printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filesize); 
     983                                } 
     984                        } 
     985 
     986                        // general size check 
     987                        if (sizecheck) { 
     988                                if (sizecheck <= 0) { 
     989                                        exitcode = 1; 
     990                                        printf("mtd %s bad file size check (%i) due to input data\n", mtd->name, sizecheck); 
     991                                } else { 
     992                                        if (mtd->filesize > sizecheck) { 
     993                                                exitcode = 1; 
     994                                                printf("mtd %s input file %s too big (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize); 
     995                                        } 
     996                                } 
     997                        } 
     998                } 
     999                lprintf(DEBUG, "...done checking mtd data\n"); 
     1000        } 
     1001 
     1002 
     1003// bin creation in memory 
     1004        if (!exitcode && par_filename != NULL) { 
     1005                // create bin name from basename 
     1006                bin_filename = malloc(strlen(base_filename)+10); 
     1007                sprintf(bin_filename, "%s.bin", base_filename); 
     1008 
     1009                lprintf(DEBUG, "creating bin file %s...\n", bin_filename); 
     1010 
     1011                exitcode = create_bin_file(bin_filename); 
     1012 
     1013                lprintf(DEBUG, "...done creating bin file\n"); 
     1014        } 
     1015 
     1016 
     1017// zip file creation 
     1018        if (!exitcode && zip_filename == NULL) { 
     1019                // create zip name from basename 
     1020                zip_filename = malloc(strlen(base_filename)+10); 
     1021                sprintf(zip_filename, "%s.zip", base_filename); 
     1022 
     1023                lprintf(DEBUG, "creating zip file %s...\n", zip_filename); 
     1024 
     1025                exitcode = create_zip_file(zip_filename, bin_filename); 
     1026 
     1027                lprintf(DEBUG, "...done creating zip file\n"); 
     1028        } 
     1029 
     1030 
     1031// img file creation 
     1032        if (!exitcode) { 
     1033                lprintf(DEBUG, "creating img file...\n"); 
     1034 
     1035                exitcode = create_img_file(f_out, out_filename, zip_filename); 
     1036 
     1037                lprintf(DEBUG, "...done creating img file\n"); 
     1038        } 
     1039        fclose(f_out); 
     1040 
     1041 
     1042// end program 
     1043        return exitcode; 
     1044} 
  • tools/wrt350nv2-builder/src/ioapi.c

     
     1/* ioapi.c -- IO base function header for compress/uncompress .zip 
     2   files using zlib + zip or unzip API 
     3 
     4   Version 1.01e, February 12th, 2005 
     5 
     6   Copyright (C) 1998-2005 Gilles Vollant 
     7*/ 
     8 
     9#include <stdio.h> 
     10#include <stdlib.h> 
     11#include <string.h> 
     12 
     13#include "zlib.h" 
     14#include "ioapi.h" 
     15 
     16 
     17 
     18/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 
     19 
     20#ifndef SEEK_CUR 
     21#define SEEK_CUR    1 
     22#endif 
     23 
     24#ifndef SEEK_END 
     25#define SEEK_END    2 
     26#endif 
     27 
     28#ifndef SEEK_SET 
     29#define SEEK_SET    0 
     30#endif 
     31 
     32voidpf ZCALLBACK fopen_file_func OF(( 
     33   voidpf opaque, 
     34   const char* filename, 
     35   int mode)); 
     36 
     37uLong ZCALLBACK fread_file_func OF(( 
     38   voidpf opaque, 
     39   voidpf stream, 
     40   void* buf, 
     41   uLong size)); 
     42 
     43uLong ZCALLBACK fwrite_file_func OF(( 
     44   voidpf opaque, 
     45   voidpf stream, 
     46   const void* buf, 
     47   uLong size)); 
     48 
     49long ZCALLBACK ftell_file_func OF(( 
     50   voidpf opaque, 
     51   voidpf stream)); 
     52 
     53long ZCALLBACK fseek_file_func OF(( 
     54   voidpf opaque, 
     55   voidpf stream, 
     56   uLong offset, 
     57   int origin)); 
     58 
     59int ZCALLBACK fclose_file_func OF(( 
     60   voidpf opaque, 
     61   voidpf stream)); 
     62 
     63int ZCALLBACK ferror_file_func OF(( 
     64   voidpf opaque, 
     65   voidpf stream)); 
     66 
     67 
     68voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) 
     69   voidpf opaque; 
     70   const char* filename; 
     71   int mode; 
     72{ 
     73    FILE* file = NULL; 
     74    const char* mode_fopen = NULL; 
     75    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 
     76        mode_fopen = "rb"; 
     77    else 
     78    if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 
     79        mode_fopen = "r+b"; 
     80    else 
     81    if (mode & ZLIB_FILEFUNC_MODE_CREATE) 
     82        mode_fopen = "wb"; 
     83 
     84    if ((filename!=NULL) && (mode_fopen != NULL)) 
     85        file = fopen(filename, mode_fopen); 
     86    return file; 
     87} 
     88 
     89 
     90uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) 
     91   voidpf opaque; 
     92   voidpf stream; 
     93   void* buf; 
     94   uLong size; 
     95{ 
     96    uLong ret; 
     97    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); 
     98    return ret; 
     99} 
     100 
     101 
     102uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) 
     103   voidpf opaque; 
     104   voidpf stream; 
     105   const void* buf; 
     106   uLong size; 
     107{ 
     108    uLong ret; 
     109    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); 
     110    return ret; 
     111} 
     112 
     113long ZCALLBACK ftell_file_func (opaque, stream) 
     114   voidpf opaque; 
     115   voidpf stream; 
     116{ 
     117    long ret; 
     118    ret = ftell((FILE *)stream); 
     119    return ret; 
     120} 
     121 
     122long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) 
     123   voidpf opaque; 
     124   voidpf stream; 
     125   uLong offset; 
     126   int origin; 
     127{ 
     128    int fseek_origin=0; 
     129    long ret; 
     130    switch (origin) 
     131    { 
     132    case ZLIB_FILEFUNC_SEEK_CUR : 
     133        fseek_origin = SEEK_CUR; 
     134        break; 
     135    case ZLIB_FILEFUNC_SEEK_END : 
     136        fseek_origin = SEEK_END; 
     137        break; 
     138    case ZLIB_FILEFUNC_SEEK_SET : 
     139        fseek_origin = SEEK_SET; 
     140        break; 
     141    default: return -1; 
     142    } 
     143    ret = 0; 
     144    fseek((FILE *)stream, offset, fseek_origin); 
     145    return ret; 
     146} 
     147 
     148int ZCALLBACK fclose_file_func (opaque, stream) 
     149   voidpf opaque; 
     150   voidpf stream; 
     151{ 
     152    int ret; 
     153    ret = fclose((FILE *)stream); 
     154    return ret; 
     155} 
     156 
     157int ZCALLBACK ferror_file_func (opaque, stream) 
     158   voidpf opaque; 
     159   voidpf stream; 
     160{ 
     161    int ret; 
     162    ret = ferror((FILE *)stream); 
     163    return ret; 
     164} 
     165 
     166void fill_fopen_filefunc (pzlib_filefunc_def) 
     167  zlib_filefunc_def* pzlib_filefunc_def; 
     168{ 
     169    pzlib_filefunc_def->zopen_file = fopen_file_func; 
     170    pzlib_filefunc_def->zread_file = fread_file_func; 
     171    pzlib_filefunc_def->zwrite_file = fwrite_file_func; 
     172    pzlib_filefunc_def->ztell_file = ftell_file_func; 
     173    pzlib_filefunc_def->zseek_file = fseek_file_func; 
     174    pzlib_filefunc_def->zclose_file = fclose_file_func; 
     175    pzlib_filefunc_def->zerror_file = ferror_file_func; 
     176    pzlib_filefunc_def->opaque = NULL; 
     177} 
  • tools/wrt350nv2-builder/src/md5.c

     
     1/* 
     2  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved. 
     3 
     4  This software is provided 'as-is', without any express or implied 
     5  warranty.  In no event will the authors be held liable for any damages 
     6  arising from the use of this software. 
     7 
     8  Permission is granted to anyone to use this software for any purpose, 
     9  including commercial applications, and to alter it and redistribute it 
     10  freely, subject to the following restrictions: 
     11 
     12  1. The origin of this software must not be misrepresented; you must not 
     13     claim that you wrote the original software. If you use this software 
     14     in a product, an acknowledgment in the product documentation would be 
     15     appreciated but is not required. 
     16  2. Altered source versions must be plainly marked as such, and must not be 
     17     misrepresented as being the original software. 
     18  3. This notice may not be removed or altered from any source distribution. 
     19 
     20  L. Peter Deutsch 
     21  ghost@aladdin.com 
     22 
     23 */ 
     24/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ 
     25/* 
     26  Independent implementation of MD5 (RFC 1321). 
     27 
     28  This code implements the MD5 Algorithm defined in RFC 1321, whose 
     29  text is available at 
     30        http://www.ietf.org/rfc/rfc1321.txt 
     31  The code is derived from the text of the RFC, including the test suite 
     32  (section A.5) but excluding the rest of Appendix A.  It does not include 
     33  any code or documentation that is identified in the RFC as being 
     34  copyrighted. 
     35 
     36  The original and principal author of md5.c is L. Peter Deutsch 
     37  <ghost@aladdin.com>.  Other authors are noted in the change history 
     38  that follows (in reverse chronological order): 
     39 
     40  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 
     41        either statically or dynamically; added missing #include <string.h> 
     42        in library. 
     43  2002-03-11 lpd Corrected argument list for main(), and added int return 
     44        type, in test program and T value program. 
     45  2002-02-21 lpd Added missing #include <stdio.h> in test program. 
     46  2000-07-03 lpd Patched to eliminate warnings about "constant is 
     47        unsigned in ANSI C, signed in traditional"; made test program 
     48        self-checking. 
     49  1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 
     50  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 
     51  1999-05-03 lpd Original version. 
     52 */ 
     53 
     54#include "md5.h" 
     55#include <string.h> 
     56 
     57#undef BYTE_ORDER       /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 
     58#ifdef ARCH_IS_BIG_ENDIAN 
     59#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 
     60#else 
     61#  define BYTE_ORDER 0 
     62#endif 
     63 
     64#define T_MASK ((md5_word_t)~0) 
     65#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 
     66#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 
     67#define T3    0x242070db 
     68#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 
     69#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 
     70#define T6    0x4787c62a 
     71#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 
     72#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 
     73#define T9    0x698098d8 
     74#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 
     75#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 
     76#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 
     77#define T13    0x6b901122 
     78#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 
     79#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 
     80#define T16    0x49b40821 
     81#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 
     82#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 
     83#define T19    0x265e5a51 
     84#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 
     85#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 
     86#define T22    0x02441453 
     87#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 
     88#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 
     89#define T25    0x21e1cde6 
     90#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 
     91#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 
     92#define T28    0x455a14ed 
     93#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 
     94#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 
     95#define T31    0x676f02d9 
     96#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 
     97#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 
     98#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 
     99#define T35    0x6d9d6122 
     100#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 
     101#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 
     102#define T38    0x4bdecfa9 
     103#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 
     104#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 
     105#define T41    0x289b7ec6 
     106#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 
     107#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 
     108#define T44    0x04881d05 
     109#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 
     110#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 
     111#define T47    0x1fa27cf8 
     112#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 
     113#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 
     114#define T50    0x432aff97 
     115#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 
     116#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 
     117#define T53    0x655b59c3 
     118#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 
     119#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 
     120#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 
     121#define T57    0x6fa87e4f 
     122#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 
     123#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 
     124#define T60    0x4e0811a1 
     125#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 
     126#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 
     127#define T63    0x2ad7d2bb 
     128#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 
     129 
     130 
     131static void 
     132md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 
     133{ 
     134    md5_word_t 
     135        a = pms->abcd[0], b = pms->abcd[1], 
     136        c = pms->abcd[2], d = pms->abcd[3]; 
     137    md5_word_t t; 
     138#if BYTE_ORDER > 0 
     139    /* Define storage only for big-endian CPUs. */ 
     140    md5_word_t X[16]; 
     141#else 
     142    /* Define storage for little-endian or both types of CPUs. */ 
     143    md5_word_t xbuf[16]; 
     144    const md5_word_t *X; 
     145#endif 
     146 
     147    { 
     148#if BYTE_ORDER == 0 
     149        /* 
     150         * Determine dynamically whether this is a big-endian or 
     151         * little-endian machine, since we can use a more efficient 
     152         * algorithm on the latter. 
     153         */ 
     154        static const int w = 1; 
     155 
     156        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 
     157#endif 
     158#if BYTE_ORDER <= 0             /* little-endian */ 
     159        { 
     160            /* 
     161             * On little-endian machines, we can process properly aligned 
     162             * data without copying it. 
     163             */ 
     164            if (!((data - (const md5_byte_t *)0) & 3)) { 
     165                /* data are properly aligned */ 
     166                X = (const md5_word_t *)data; 
     167            } else { 
     168                /* not aligned */ 
     169                memcpy(xbuf, data, 64); 
     170                X = xbuf; 
     171            } 
     172        } 
     173#endif 
     174#if BYTE_ORDER == 0 
     175        else                    /* dynamic big-endian */ 
     176#endif 
     177#if BYTE_ORDER >= 0             /* big-endian */ 
     178        { 
     179            /* 
     180             * On big-endian machines, we must arrange the bytes in the 
     181             * right order. 
     182             */ 
     183            const md5_byte_t *xp = data; 
     184            int i; 
     185 
     186#  if BYTE_ORDER == 0 
     187            X = xbuf;           /* (dynamic only) */ 
     188#  else 
     189#    define xbuf X              /* (static only) */ 
     190#  endif 
     191            for (i = 0; i < 16; ++i, xp += 4) 
     192                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 
     193        } 
     194#endif 
     195    } 
     196 
     197#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 
     198 
     199    /* Round 1. */ 
     200    /* Let [abcd k s i] denote the operation 
     201       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 
     202#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 
     203#define SET(a, b, c, d, k, s, Ti)\ 
     204  t = a + F(b,c,d) + X[k] + Ti;\ 
     205  a = ROTATE_LEFT(t, s) + b 
     206    /* Do the following 16 operations. */ 
     207    SET(a, b, c, d,  0,  7,  T1); 
     208    SET(d, a, b, c,  1, 12,  T2); 
     209    SET(c, d, a, b,  2, 17,  T3); 
     210    SET(b, c, d, a,  3, 22,  T4); 
     211    SET(a, b, c, d,  4,  7,  T5); 
     212    SET(d, a, b, c,  5, 12,  T6); 
     213    SET(c, d, a, b,  6, 17,  T7); 
     214    SET(b, c, d, a,  7, 22,  T8); 
     215    SET(a, b, c, d,  8,  7,  T9); 
     216    SET(d, a, b, c,  9, 12, T10); 
     217    SET(c, d, a, b, 10, 17, T11); 
     218    SET(b, c, d, a, 11, 22, T12); 
     219    SET(a, b, c, d, 12,  7, T13); 
     220    SET(d, a, b, c, 13, 12, T14); 
     221    SET(c, d, a, b, 14, 17, T15); 
     222    SET(b, c, d, a, 15, 22, T16); 
     223#undef SET 
     224 
     225     /* Round 2. */ 
     226     /* Let [abcd k s i] denote the operation 
     227          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 
     228#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 
     229#define SET(a, b, c, d, k, s, Ti)\ 
     230  t = a + G(b,c,d) + X[k] + Ti;\ 
     231  a = ROTATE_LEFT(t, s) + b 
     232     /* Do the following 16 operations. */ 
     233    SET(a, b, c, d,  1,  5, T17); 
     234    SET(d, a, b, c,  6,  9, T18); 
     235    SET(c, d, a, b, 11, 14, T19); 
     236    SET(b, c, d, a,  0, 20, T20); 
     237    SET(a, b, c, d,  5,  5, T21); 
     238    SET(d, a, b, c, 10,  9, T22); 
     239    SET(c, d, a, b, 15, 14, T23); 
     240    SET(b, c, d, a,  4, 20, T24); 
     241    SET(a, b, c, d,  9,  5, T25); 
     242    SET(d, a, b, c, 14,  9, T26); 
     243    SET(c, d, a, b,  3, 14, T27); 
     244    SET(b, c, d, a,  8, 20, T28); 
     245    SET(a, b, c, d, 13,  5, T29); 
     246    SET(d, a, b, c,  2,  9, T30); 
     247    SET(c, d, a, b,  7, 14, T31); 
     248    SET(b, c, d, a, 12, 20, T32); 
     249#undef SET 
     250 
     251     /* Round 3. */ 
     252     /* Let [abcd k s t] denote the operation 
     253          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 
     254#define H(x, y, z) ((x) ^ (y) ^ (z)) 
     255#define SET(a, b, c, d, k, s, Ti)\ 
     256  t = a + H(b,c,d) + X[k] + Ti;\ 
     257  a = ROTATE_LEFT(t, s) + b 
     258     /* Do the following 16 operations. */ 
     259    SET(a, b, c, d,  5,  4, T33); 
     260    SET(d, a, b, c,  8, 11, T34); 
     261    SET(c, d, a, b, 11, 16, T35); 
     262    SET(b, c, d, a, 14, 23, T36); 
     263    SET(a, b, c, d,  1,  4, T37); 
     264    SET(d, a, b, c,  4, 11, T38); 
     265    SET(c, d, a, b,  7, 16, T39); 
     266    SET(b, c, d, a, 10, 23, T40); 
     267    SET(a, b, c, d, 13,  4, T41); 
     268    SET(d, a, b, c,  0, 11, T42); 
     269    SET(c, d, a, b,  3, 16, T43); 
     270    SET(b, c, d, a,  6, 23, T44); 
     271    SET(a, b, c, d,  9,  4, T45); 
     272    SET(d, a, b, c, 12, 11, T46); 
     273    SET(c, d, a, b, 15, 16, T47); 
     274    SET(b, c, d, a,  2, 23, T48); 
     275#undef SET 
     276 
     277     /* Round 4. */ 
     278     /* Let [abcd k s t] denote the operation 
     279          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 
     280#define I(x, y, z) ((y) ^ ((x) | ~(z))) 
     281#define SET(a, b, c, d, k, s, Ti)\ 
     282  t = a + I(b,c,d) + X[k] + Ti;\ 
     283  a = ROTATE_LEFT(t, s) + b 
     284     /* Do the following 16 operations. */ 
     285    SET(a, b, c, d,  0,  6, T49); 
     286    SET(d, a, b, c,  7, 10, T50); 
     287    SET(c, d, a, b, 14, 15, T51); 
     288    SET(b, c, d, a,  5, 21, T52); 
     289    SET(a, b, c, d, 12,  6, T53); 
     290    SET(d, a, b, c,  3, 10, T54); 
     291    SET(c, d, a, b, 10, 15, T55); 
     292    SET(b, c, d, a,  1, 21, T56); 
     293    SET(a, b, c, d,  8,  6, T57); 
     294    SET(d, a, b, c, 15, 10, T58); 
     295    SET(c, d, a, b,  6, 15, T59); 
     296    SET(b, c, d, a, 13, 21, T60); 
     297    SET(a, b, c, d,  4,  6, T61); 
     298    SET(d, a, b, c, 11, 10, T62); 
     299    SET(c, d, a, b,  2, 15, T63); 
     300    SET(b, c, d, a,  9, 21, T64); 
     301#undef SET 
     302 
     303     /* Then perform the following additions. (That is increment each 
     304        of the four registers by the value it had before this block 
     305        was started.) */ 
     306    pms->abcd[0] += a; 
     307    pms->abcd[1] += b; 
     308    pms->abcd[2] += c; 
     309    pms->abcd[3] += d; 
     310} 
     311 
     312void 
     313md5_init(md5_state_t *pms) 
     314{ 
     315    pms->count[0] = pms->count[1] = 0; 
     316    pms->abcd[0] = 0x67452301; 
     317    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 
     318    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 
     319    pms->abcd[3] = 0x10325476; 
     320} 
     321 
     322void 
     323md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 
     324{ 
     325    const md5_byte_t *p = data; 
     326    int left = nbytes; 
     327    int offset = (pms->count[0] >> 3) & 63; 
     328    md5_word_t nbits = (md5_word_t)(nbytes << 3); 
     329 
     330    if (nbytes <= 0) 
     331        return; 
     332 
     333    /* Update the message length. */ 
     334    pms->count[1] += nbytes >> 29; 
     335    pms->count[0] += nbits; 
     336    if (pms->count[0] < nbits) 
     337        pms->count[1]++; 
     338 
     339    /* Process an initial partial block. */ 
     340    if (offset) { 
     341        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 
     342 
     343        memcpy(pms->buf + offset, p, copy); 
     344        if (offset + copy < 64) 
     345            return; 
     346        p += copy; 
     347        left -= copy; 
     348        md5_process(pms, pms->buf); 
     349    } 
     350 
     351    /* Process full blocks. */ 
     352    for (; left >= 64; p += 64, left -= 64) 
     353        md5_process(pms, p); 
     354 
     355    /* Process a final partial block. */ 
     356    if (left) 
     357        memcpy(pms->buf, p, left); 
     358} 
     359 
     360void 
     361md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 
     362{ 
     363    static const md5_byte_t pad[64] = { 
     364        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     365        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     366        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     367        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
     368    }; 
     369    md5_byte_t data[8]; 
     370    int i; 
     371 
     372    /* Save the length before padding. */ 
     373    for (i = 0; i < 8; ++i) 
     374        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 
     375    /* Pad to 56 bytes mod 64. */ 
     376    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 
     377    /* Append the length. */ 
     378    md5_append(pms, data, 8); 
     379    for (i = 0; i < 16; ++i) 
     380        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 
     381} 
  • tools/wrt350nv2-builder/src/crypt.h

     
     1/* crypt.h -- base code for crypt/uncrypt ZIPfile 
     2 
     3 
     4   Version 1.01e, February 12th, 2005 
     5 
     6   Copyright (C) 1998-2005 Gilles Vollant 
     7 
     8   This code is a modified version of crypting code in Infozip distribution 
     9 
     10   The encryption/decryption parts of this source code (as opposed to the 
     11   non-echoing password parts) were originally written in Europe.  The 
     12   whole source package can be freely distributed, including from the USA. 
     13   (Prior to January 2000, re-export from the US was a violation of US law.) 
     14 
     15   This encryption code is a direct transcription of the algorithm from 
     16   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This 
     17   file (appnote.txt) is distributed with the PKZIP program (even in the 
     18   version without encryption capabilities). 
     19 
     20   If you don't need crypting in your application, just define symbols 
     21   NOCRYPT and NOUNCRYPT. 
     22 
     23   This code support the "Traditional PKWARE Encryption". 
     24 
     25   The new AES encryption added on Zip format by Winzip (see the page 
     26   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong 
     27   Encryption is not supported. 
     28*/ 
     29 
     30#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 
     31 
     32/*********************************************************************** 
     33 * Return the next byte in the pseudo-random sequence 
     34 */ 
     35static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) 
     36{ 
     37    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an 
     38                     * unpredictable manner on 16-bit systems; not a problem 
     39                     * with any known compiler so far, though */ 
     40 
     41    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; 
     42    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 
     43} 
     44 
     45/*********************************************************************** 
     46 * Update the encryption keys with the next byte of plain text 
     47 */ 
     48static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) 
     49{ 
     50    (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 
     51    (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 
     52    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 
     53    { 
     54      register int keyshift = (int)((*(pkeys+1)) >> 24); 
     55      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 
     56    } 
     57    return c; 
     58} 
     59 
     60 
     61/*********************************************************************** 
     62 * Initialize the encryption keys and the random header according to 
     63 * the given password. 
     64 */ 
     65static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) 
     66{ 
     67    *(pkeys+0) = 305419896L; 
     68    *(pkeys+1) = 591751049L; 
     69    *(pkeys+2) = 878082192L; 
     70    while (*passwd != '\0') { 
     71        update_keys(pkeys,pcrc_32_tab,(int)*passwd); 
     72        passwd++; 
     73    } 
     74} 
     75 
     76#define zdecode(pkeys,pcrc_32_tab,c) \ 
     77    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) 
     78 
     79#define zencode(pkeys,pcrc_32_tab,c,t) \ 
     80    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) 
     81 
     82#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 
     83 
     84#define RAND_HEAD_LEN  12 
     85   /* "last resort" source for second part of crypt seed pattern */ 
     86#  ifndef ZCR_SEED2 
     87#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */ 
     88#  endif 
     89 
     90static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) 
     91    const char *passwd;         /* password string */ 
     92    unsigned char *buf;         /* where to write header */ 
     93    int bufSize; 
     94    unsigned long* pkeys; 
     95    const unsigned long* pcrc_32_tab; 
     96    unsigned long crcForCrypting; 
     97{ 
     98    int n;                       /* index in random header */ 
     99    int t;                       /* temporary */ 
     100    int c;                       /* random byte */ 
     101    unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 
     102    static unsigned calls = 0;   /* ensure different random header each time */ 
     103 
     104    if (bufSize<RAND_HEAD_LEN) 
     105      return 0; 
     106 
     107    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the 
     108     * output of rand() to get less predictability, since rand() is 
     109     * often poorly implemented. 
     110     */ 
     111    if (++calls == 1) 
     112    { 
     113        srand((unsigned)(time(NULL) ^ ZCR_SEED2)); 
     114    } 
     115    init_keys(passwd, pkeys, pcrc_32_tab); 
     116    for (n = 0; n < RAND_HEAD_LEN-2; n++) 
     117    { 
     118        c = (rand() >> 7) & 0xff; 
     119        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 
     120    } 
     121    /* Encrypt random header (last two bytes is high word of crc) */ 
     122    init_keys(passwd, pkeys, pcrc_32_tab); 
     123    for (n = 0; n < RAND_HEAD_LEN-2; n++) 
     124    { 
     125        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 
     126    } 
     127    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 
     128    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 
     129    return n; 
     130} 
     131 
     132#endif 
  • tools/wrt350nv2-builder/src/ioapi.h

     
     1/* ioapi.h -- IO base function header for compress/uncompress .zip 
     2   files using zlib + zip or unzip API 
     3 
     4   Version 1.01e, February 12th, 2005 
     5 
     6   Copyright (C) 1998-2005 Gilles Vollant 
     7*/ 
     8 
     9#ifndef _ZLIBIOAPI_H 
     10#define _ZLIBIOAPI_H 
     11 
     12 
     13#define ZLIB_FILEFUNC_SEEK_CUR (1) 
     14#define ZLIB_FILEFUNC_SEEK_END (2) 
     15#define ZLIB_FILEFUNC_SEEK_SET (0) 
     16 
     17#define ZLIB_FILEFUNC_MODE_READ      (1) 
     18#define ZLIB_FILEFUNC_MODE_WRITE     (2) 
     19#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 
     20 
     21#define ZLIB_FILEFUNC_MODE_EXISTING (4) 
     22#define ZLIB_FILEFUNC_MODE_CREATE   (8) 
     23 
     24 
     25#ifndef ZCALLBACK 
     26 
     27#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 
     28#define ZCALLBACK CALLBACK 
     29#else 
     30#define ZCALLBACK 
     31#endif 
     32#endif 
     33 
     34#ifdef __cplusplus 
     35extern "C" { 
     36#endif 
     37 
     38typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 
     39typedef uLong  (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 
     40typedef uLong  (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 
     41typedef long   (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 
     42typedef long   (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 
     43typedef int    (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 
     44typedef int    (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 
     45 
     46typedef struct zlib_filefunc_def_s 
     47{ 
     48    open_file_func      zopen_file; 
     49    read_file_func      zread_file; 
     50    write_file_func     zwrite_file; 
     51    tell_file_func      ztell_file; 
     52    seek_file_func      zseek_file; 
     53    close_file_func     zclose_file; 
     54    testerror_file_func zerror_file; 
     55    voidpf              opaque; 
     56} zlib_filefunc_def; 
     57 
     58 
     59 
     60void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 
     61 
     62#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) 
     63#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) 
     64#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) 
     65#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) 
     66#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) 
     67#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) 
     68 
     69 
     70#ifdef __cplusplus 
     71} 
     72#endif 
     73 
     74#endif 
     75 
  • tools/wrt350nv2-builder/src/md5.h

     
     1/* 
     2  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved. 
     3 
     4  This software is provided 'as-is', without any express or implied 
     5  warranty.  In no event will the authors be held liable for any damages 
     6  arising from the use of this software. 
     7 
     8  Permission is granted to anyone to use this software for any purpose, 
     9  including commercial applications, and to alter it and redistribute it 
     10  freely, subject to the following restrictions: 
     11 
     12  1. The origin of this software must not be misrepresented; you must not 
     13     claim that you wrote the original software. If you use this software 
     14     in a product, an acknowledgment in the product documentation would be 
     15     appreciated but is not required. 
     16  2. Altered source versions must be plainly marked as such, and must not be 
     17     misrepresented as being the original software. 
     18  3. This notice may not be removed or altered from any source distribution. 
     19 
     20  L. Peter Deutsch 
     21  ghost@aladdin.com 
     22 
     23 */ 
     24/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ 
     25/* 
     26  Independent implementation of MD5 (RFC 1321). 
     27 
     28  This code implements the MD5 Algorithm defined in RFC 1321, whose 
     29  text is available at 
     30        http://www.ietf.org/rfc/rfc1321.txt 
     31  The code is derived from the text of the RFC, including the test suite 
     32  (section A.5) but excluding the rest of Appendix A.  It does not include 
     33  any code or documentation that is identified in the RFC as being 
     34  copyrighted. 
     35 
     36  The original and principal author of md5.h is L. Peter Deutsch 
     37  <ghost@aladdin.com>.  Other authors are noted in the change history 
     38  that follows (in reverse chronological order): 
     39 
     40  2002-04-13 lpd Removed support for non-ANSI compilers; removed 
     41        references to Ghostscript; clarified derivation from RFC 1321; 
     42        now handles byte order either statically or dynamically. 
     43  1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 
     44  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); 
     45        added conditionalization for C++ compilation from Martin 
     46        Purschke <purschke@bnl.gov>. 
     47  1999-05-03 lpd Original version. 
     48 */ 
     49 
     50#ifndef md5_INCLUDED 
     51#  define md5_INCLUDED 
     52 
     53/* 
     54 * This package supports both compile-time and run-time determination of CPU 
     55 * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be 
     56 * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is 
     57 * defined as non-zero, the code will be compiled to run only on big-endian 
     58 * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to 
     59 * run on either big- or little-endian CPUs, but will run slightly less 
     60 * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. 
     61 */ 
     62 
     63typedef unsigned char md5_byte_t; /* 8-bit byte */ 
     64typedef unsigned int md5_word_t; /* 32-bit word */ 
     65 
     66/* Define the state of the MD5 Algorithm. */ 
     67typedef struct md5_state_s { 
     68    md5_word_t count[2];        /* message length in bits, lsw first */ 
     69    md5_word_t abcd[4];         /* digest buffer */ 
     70    md5_byte_t buf[64];         /* accumulate block */ 
     71} md5_state_t; 
     72 
     73#ifdef __cplusplus 
     74extern "C"  
     75{ 
     76#endif 
     77 
     78/* Initialize the algorithm. */ 
     79void md5_init(md5_state_t *pms); 
     80 
     81/* Append a string to the message. */ 
     82void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); 
     83 
     84/* Finish the message and return the digest. */ 
     85void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); 
     86 
     87#ifdef __cplusplus 
     88}  /* end extern "C" */ 
     89#endif 
     90 
     91#endif /* md5_INCLUDED */ 
  • tools/wrt350nv2-builder/src/upgrade.h

     
     1#ifndef _UPGRADE_H_ 
     2#define _UPGRADE_H_ 
     3 
     4#define FLASH_END_ADDR       0xffffffff  
     5#define FLASH_ADDR_BASE      0xff800000 
     6#define BOOT_ADDR_BASE                   0xfffc0000 
     7#define BOOT_ADDR_BASE_OFF   0x7c0000 
     8#define FLASH_SIZE           0x800000 
     9#define BOOT_SIZE            0x40000 
     10//NVRAM in boot area 
     11//#define NVRAM_ADDR_BASE      0xfff90000 
     12//#define NVRAM_ADDR_BASE_OFF  0x790000 
     13//#define NVRAM_SIZE           0x10000 
     14 
     15#define PID_OFFSET         (BOOT_SIZE- 0x46) 
     16#define NODE_ADDRESS       (BOOT_SIZE-0x60) 
     17#define NODE_BASE_OFF   (FLASH_SIZE-0x60) 
     18#define PIN_ADDRESS         (BOOT_SIZE-0x70)//WPS PIN,8bytes 
     19#define PIN_OFF                                 (FLASH_SIZE-0x70) 
     20#define KERNEL_CODE_OFFSET      0          
     21#define SN_ADDRESS (BOOT_SIZE-0x80) //12bytes 
     22#define SN_OFF (FLASH_SIZE-0x80) 
     23 
     24 
     25#define UPGRADE_START_OFFSET  0 
     26#define UPGRADE_END_OFFSET    0x7A0000 
     27#define PRODUCT_ID_OFFSET     0x75ffe0//(UPGRADE_END_OFFSET  - 0x10) 
     28#define PROTOCOL_ID_OFFSET   (PRODUCT_ID_OFFSET + 0x02) 
     29#define FW_VERSION_OFFSET    (PRODUCT_ID_OFFSET + 0x04) 
     30#define SIGN_OFFSET          (PRODUCT_ID_OFFSET + 0x08)   /* eRcOmM */ 
     31 
     32//#define LANG_UPGRADE 
     33#ifdef LANG_UPGRADE 
     34#define LANGBUF_BEGIN   0x1300000 
     35#define LANGBUF_END     0x1f00000 
     36#define LANGBUF_LENTH   (LANGBUF_END - LANGBUF_BEGIN) 
     37#endif 
     38#ifndef ERROR 
     39#define ERROR -1 
     40#endif 
     41 
     42#ifndef OK 
     43#define OK 0 
     44#endif 
     45 
     46#ifndef NULL 
     47#define NULL 0 
     48#endif 
     49 
     50 
     51void do_boot(void); 
     52void Download(void); 
     53void Assign(void); 
     54 
     55void gpio_init(void); 
     56void Led_Power(int value); 
     57void Led_security(int value); 
     58int PushButton(void); 
     59 
     60static unsigned short xchg ( unsigned short dwData); 
     61int FlashDriver(unsigned long dlAddress,unsigned char *dbData,unsigned long dlLength,unsigned long dlFlag); 
     62int ProgramChip(unsigned long dlAddress,unsigned char * dbData,unsigned long dlLength); 
     63int dl_Initialize(void); 
     64void dl_GetAddr(unsigned char *node); 
     65int dl_Receive(void); 
     66int dl_Transmit(char *buf,int len); 
     67void reset(void); 
     68void AssignHWAddress(unsigned char *psBuffer); 
     69int ResetChip(unsigned long ulRomDstAddr); 
     70int GetFlashType(void); 
     71 
     72#ifdef LANG_UPGRADE 
     73int save_lang_buf(unsigned long flash_addr, char *mem_addr,unsigned long length); 
     74int LangDriver(unsigned long flash_addr, char *mem_addr,unsigned long length, unsigned long dlFlag); 
     75#endif  
     76#endif 
     77 
  • tools/wrt350nv2-builder/Makefile

     
     1#  
     2# Copyright (C) 2006-2009 OpenWrt.org 
     3# 
     4# This is free software, licensed under the GNU General Public License v2. 
     5# See /LICENSE for more information. 
     6# 
     7 
     8include $(TOPDIR)/rules.mk 
     9 
     10PKG_NAME:=wrt350nv2-builder 
     11PKG_VERSION:=2.0 
     12 
     13HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}-$(PKG_VERSION) 
     14 
     15include $(INCLUDE_DIR)/host-build.mk 
     16 
     17define Host/Compile 
     18        $(HOSTCC) $(HOST_CFLAGS) -c src/md5.c -o $(HOST_BUILD_DIR)/md5.o 
     19        $(HOSTCC) $(HOST_CFLAGS) -c src/ioapi.c -o $(HOST_BUILD_DIR)/ioapi.o 
     20        $(HOSTCC) $(HOST_CFLAGS) -c src/wrt350nv2-builder.c -o $(HOST_BUILD_DIR)/wrt350nv2-builder.o 
     21        $(HOSTCC) $(HOST_CFLAGS) -o $(HOST_BUILD_DIR)/wrt350nv2-builder $(HOST_BUILD_DIR)/wrt350nv2-builder.o $(HOST_BUILD_DIR)/md5.o $(HOST_BUILD_DIR)/ioapi.o 
     22endef 
     23 
     24define Host/Install 
     25        $(INSTALL_BIN) $(HOST_BUILD_DIR)/wrt350nv2-builder $(STAGING_DIR_HOST)/bin/ 
     26        # optionally the builder can add an u-boot binary from the user who builds this (does not belong into the trunk) 
     27        ( [ -f "src/wrt350nv2-u-boot.bin" ] && $(CP) src/wrt350nv2-u-boot.bin $(STAGING_DIR_HOST)/bin/; ) || ( exit 0; ) 
     28endef 
     29 
     30define Host/Clean 
     31        rm -f $(STAGING_DIR_HOST)/bin/wrt350nv2-builder 
     32        # optional files 
     33        ( [ -f "$(STAGING_DIR_HOST)/bin/wrt350nv2-u-boot.bin" ] && rm -f $(STAGING_DIR_HOST)/bin/wrt350nv2-u-boot.bin; ) || ( exit 0; ) 
     34endef 
     35 
     36$(eval $(call HostBuild))