pc1crypt: make decrypt/encrypt functions take void * as argument
[project/firmware-utils.git] / src / hcsmakeimage.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <stdio.h>
5 #include <inttypes.h>
6 #include <string.h>
7 #include <getopt.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <time.h>
11 #include <sys/stat.h>
12 #include <libgen.h>
13 #include "bcmalgo.h"
14
15
16 int flag_print_version;
17 int flag_print_help;
18 int flag_compress;
19
20 uint16_t sa2100_magic = 0x2100;
21 uint16_t sa3349_magic = 0x3349;
22 uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away....
23 uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image
24
25 static void print_help ( const char* ename )
26 {
27 printf ( "Firmware image packer and calculator for broadcom-based modems.\n" );
28 printf ( "Part of bcm-utils package.\n" );
29 printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" );
30 printf ( "usage: %s [options]\n", ename );
31 printf ( "Valid options are:\n" );
32 printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" );
33 printf ( "\t\t\t these can be sa2100 (for DPC2100 modem),\n\t\t\t sa3349 (haxorware guys use this one for some reason),\n\t\t\t or a custom hex value e.g. 0xFFFF\n" );
34 printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" );
35 printf ( "--rev_maj=value\t\t - major revision number. default 0\n" );
36 printf ( "--rev_min=value\t\t - minor revision number default 0\n" );
37 printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" );
38 printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" );
39 printf ( "--input_file=value\t - What file are we packing?\n" );
40 printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" );
41 #ifdef _HAX0RSTYLE
42 printf ( "--credz\t - Give some credz!\n" );
43 #endif
44 printf ( "\n" );
45 }
46
47 static time_t source_date_epoch = -1;
48 static void set_source_date_epoch() {
49 char *env = getenv("SOURCE_DATE_EPOCH");
50 char *endptr = env;
51 errno = 0;
52 if (env && *env) {
53 source_date_epoch = strtoull(env, &endptr, 10);
54 if (errno || (endptr && *endptr != '\0')) {
55 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
56 exit(1);
57 }
58 }
59 }
60
61 int main ( int argc, char** argv )
62 {
63 if ( argc<2 )
64 {
65 print_help ( argv[0] );
66 }
67
68 static struct option long_options[] =
69 {
70 {"magic_bytes", required_argument, 0, 'm'},
71 {"rev_maj", required_argument, 0, 'j'},
72 {"rev_min", required_argument, 0, 'n'},
73 {"ldaddress", required_argument, 0, 'l'},
74 {"filename", required_argument, 0, 'f'},
75 {"input_file", required_argument, 0, 'i'},
76 {"output_file", required_argument, 0, 'o'},
77 {"compress", no_argument, &flag_compress, 'c'},
78 {"version", no_argument, &flag_print_version, 'v'},
79 {"help", no_argument, &flag_print_help, 'h'},
80 {0, 0, 0, 0}
81 };
82 int option_index = 0;
83 int opt_result=0;
84 char* filename=NULL;
85 char* input=NULL;
86 char* magic=NULL;
87 char* major=NULL;
88 char* minor=NULL;
89 char* ldaddr=NULL;
90 char* output=NULL;
91
92 while ( opt_result>=0 )
93 {
94 opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index );
95 switch ( opt_result )
96 {
97 case 0:
98 printf ( "o!\n" );
99 break;
100 case 'h':
101 print_help ( argv[0] );
102 break;
103 case 'l':
104 ldaddr=optarg;
105 break;
106 case 'f':
107 filename=optarg;
108 break;
109 case 'i':
110 input=optarg;
111 break;
112 case 'o':
113 output=optarg;
114 break;
115 case 'm':
116 magic=optarg;
117 break;
118 case 'j':
119 major=optarg;
120 break;
121 case 'n':
122 minor=optarg;
123 break;
124 }
125 }
126 if ( input==NULL )
127 {
128 printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" );
129 exit ( 1 );
130 }
131 if ( access ( input,R_OK ) !=0 )
132 {
133 printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input );
134 exit ( 1 );
135 }
136 uint32_t magicnum=sa2100_magic;
137
138 if ( magic )
139 {
140 if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else
141 if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else
142 {
143 sscanf ( magic, "0x%04X", &magicnum );
144 }
145 }
146 unsigned int majrev=0;
147 if ( major )
148 {
149 sscanf ( major, "%d", &majrev );
150 }
151 unsigned int minrev=0;
152 if ( minor )
153 {
154 sscanf ( minor, "%d", &minrev );
155 }
156 uint32_t ldaddress = default_load_address;
157 if ( ldaddr )
158 {
159 sscanf ( ldaddr, "0x%08X", &ldaddress );
160 }
161 char* dupe = strdup(input);
162 char* fname = basename ( dupe );
163 if ( filename )
164 {
165 fname = filename;
166 }
167
168 time_t t = -1;
169 set_source_date_epoch();
170 if (source_date_epoch != -1) {
171 t = source_date_epoch;
172 } else if ((time(&t) == (time_t)(-1))) {
173 fprintf(stderr, "time call failed\n");
174 return EXIT_FAILURE;
175 }
176
177 struct stat buf;
178 stat ( input,&buf );
179 ldr_header_t* head = construct_header ( magicnum, (uint16_t) majrev, (uint16_t) minrev, ( uint32_t ) t, ( uint32_t ) buf.st_size, ldaddress, fname, get_file_crc ( input ) );
180 free(dupe);
181 //uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc
182 //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r");
183 //fread(head,sizeof(ldr_header_t),1,fd);
184 char* filebuffer = malloc ( buf.st_size+10 );
185 FILE* fd = fopen ( input,"r" );
186 fread ( filebuffer, 1, buf.st_size,fd );
187 fclose (fd);
188 if (!output)
189 {
190 output = malloc(strlen(input+5));
191 strcpy(output,input);
192 strcat(output,".bin");
193 }
194 dump_header ( head );
195 FILE* fd_out = fopen ( output,"w+" );
196 if (!fd_out)
197 {
198 fprintf(stderr, "Failed to open output file: %s\n", output);
199 free(filebuffer);
200 exit(1);
201 }
202 fwrite ( head,1,sizeof ( ldr_header_t ),fd_out );
203 fwrite ( filebuffer,1,buf.st_size,fd_out );
204 printf("Firmware image %s is ready\n", output);
205 free(filebuffer);
206 fclose(fd_out);
207 return 0;
208 }