CHDK_DE Vorschauversion  Trunk Rev. 5766
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
fi2enc.c-Dateireferenz
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>
#include "zlib.h"
#include "aes128.h"
+ Include-Abhängigkeitsdiagramm für fi2enc.c:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  fi2_rec_s
 
struct  fi2_header_s
 

Typdefinitionen

typedef struct fi2_header_s fi2_hdr_t
 
typedef struct fi2_header_spfi2_hdr_t
 

Funktionen

char * _strlwr (char *moep)
 
static uint32_t read32_be (const void *src_buffer)
 
static void store32_be (void *dst_buffer, uint32_t value)
 
static uint32_t align128 (uint32_t value)
 
static int get_hexstring (void *dst, const char *str, int len)
 
static int fi2rec_size (uint32_t dryos_ver)
 
static int fi2enc (char *infname, char *outfname, uint32_t *key, uint32_t *iv, uint32_t pid, uint32_t dryos_ver, int32_t cs_words)
 
int main (int argc, char **argv)
 

Variablen

static const char * g_str_err_malloc = "memory allocation error (requested %d bytes)\n"
 
static const char * g_str_shorthelp
 
struct fi2_rec_s fi2_rec_s
 

Dokumentation der benutzerdefinierten Typen

typedef struct fi2_header_s fi2_hdr_t
typedef struct fi2_header_s * pfi2_hdr_t

Dokumentation der Funktionen

char* _strlwr ( char *  moep)

Definiert in Zeile 19 der Datei fi2enc.c.

19  {
20  char *tmp = moep;
21  while((*tmp = tolower(*tmp))) tmp++;
22  return moep;
23 }
static uint32_t align128 ( uint32_t  value)
static

Definiert in Zeile 66 der Datei fi2enc.c.

67 {
68  return ( (value + 16 - 1) & 0xFFFFFFF0ul );
69 }
static int fi2enc ( char *  infname,
char *  outfname,
uint32_t key,
uint32_t iv,
uint32_t  pid,
uint32_t  dryos_ver,
int32_t  cs_words 
)
static

Definiert in Zeile 117 der Datei fi2enc.c.

119 {
120  uLongf i;
121  size_t flen;
122  uint32_t cs;
123  FILE *fi, *fo;
124  fi2_hdr_t hdr;
125  struct fi2_rec_s fi2rec;
126  unsigned char *buf = NULL;
127  unsigned char *upkbuf = NULL;
128  unsigned char exkey[176];
129  unsigned char *pblk;
130 
131  if( !infname ){
132  printf("Please supply input file name.\n");
133  return -1;
134  }
135  if( !outfname ){
136  printf("Please supply target file name.\n");
137  return -1;
138  }
139  aes128_expandkey( exkey, key );
140  cs = 0;
141  memset(&hdr, 0, sizeof (hdr));
142  memset(&fi2rec, 0, sizeof (fi2rec));
143  hdr.hwid=pid;
144  hdr.unk1=0x02230000;
145  hdr.id=0x01010000;
146  hdr.ch=0;
147  hdr.unk2=1;
148  fi2rec.addr=0;
149  fi2rec.fboot = 1;
150  if ( !(fi = fopen(infname, "rb")) ){
151  printf( "Can't open data file %s\n", infname );
152  return -1;
153  }
154  fseek( fi, 0, SEEK_END );
155  flen = ftell( fi );
156  fseek( fi, 0, SEEK_SET );
157 
158  if( flen <= 0 || flen > (256 << 20) ){ // file size sanity check (256MB max)
159  printf( "Data file %s have unacceptable file size (%ld)\n", infname, (unsigned long) flen );
160  return -1;
161  }
162  upkbuf = (unsigned char*)malloc( flen ); // allocate buffer for data file
163  if( !upkbuf ){
164  printf( g_str_err_malloc, flen );
165  return -1;
166  }
167  if( flen > fread( upkbuf, 1, flen, fi ) ){
168  printf( "Error reading data file\n" );
169  return -1;
170  }
171  fclose( fi );
172  i = align128( 4 + compressBound( flen ) ); // determine upper bound for compressed block buffer
173  buf = (unsigned char*)malloc( i ); // allocate buffer for compressed block + blocksize
174  if( !buf ){
175  printf( g_str_err_malloc, i );
176  return -1;
177  }
178  memset( buf, 0xFF, i );
179  i -= 4;
180  if( Z_OK != compress( buf + 4, &i, upkbuf, flen ) ){
181  printf( "Data compression error\n" );
182  return -1;
183  }
184  store32_be( buf, i ); // store real compressed block size
185  fi2rec.upklen = flen;
186  fi2rec.offset = 0; // save data block offset
187  fi2rec.len = align128( i + 4 );
188  // encrypt data block
189  aes128_cbc_encrypt( buf, exkey, iv, fi2rec.len );
190  pblk = buf;
191  if (cs_words) {
192  uint32_t *wbuf = (uint32_t*)buf;
193  for( i = 0; i < fi2rec.len/4; i++) cs += wbuf[i]; // update block checksum
194  }
195  else {
196  for( i = 0; i < fi2rec.len; i++) cs += buf[i]; // update block checksum
197  }
198 
199  free( upkbuf ); upkbuf = NULL;
200  // process next block
201  // finalize header
202  i = 32 + fi2rec_size(dryos_ver);
203  i = align128(i); // header needs to be aligned
204  store32_be( &hdr.hlen_be, i - 4 );
205  hdr.nblk = 1;
206  hdr.datacs = cs;
207  buf = (unsigned char*)malloc( i ); // allocate buffer for encrypted header
208  if( !buf ){
209  printf( g_str_err_malloc, i );
210  return -1;
211  }
212  memset( buf, 0, i );
213  memcpy( buf, &hdr, 32 );
214  memcpy( buf+32, &fi2rec, fi2rec_size(dryos_ver));
215  aes128_cbc_encrypt( buf, exkey, iv, i );
216 
217  // ---------------------------- save results ------------------------------
218  // open target file
219  printf( "Saving %s\n", outfname );
220  fo = fopen(outfname,"wb");
221  if(!fo){
222  printf("Can't open file %s for writing\n", outfname);
223  return(-1);
224  }
225  // save header
226  if ( i != fwrite(buf, 1, i, fo ) ){
227  printf("\nError writing header to %s (%ld bytes)\n", outfname, i);
228  return(-1);
229  }
230  free( buf );
231  // save data blocks
232  if (fi2rec.len != fwrite( pblk, 1, fi2rec.len, fo ) ){
233  printf("\nError writing data block to %s (%d bytes)\n", outfname, fi2rec.len);
234  return(-1);
235  }
236  free( pblk );
237  fclose( fo );
238  return 0;
239 }
static int fi2rec_size ( uint32_t  dryos_ver)
static

Definiert in Zeile 100 der Datei fi2enc.c.

101 {
102  // return the correct size to use for the block record
103  if (dryos_ver >= 55)
104  {
105  return sizeof (fi2_rec_s);
106  }
107  else if (dryos_ver >= 50)
108  {
109  return sizeof (fi2_rec_s) - 4; // exclude the new R50 extra value
110  }
111  else
112  {
113  return sizeof (fi2_rec_s) - 8; // exclude the new R55 extra value too
114  }
115 }
static int get_hexstring ( void *  dst,
const char *  str,
int  len 
)
static

Definiert in Zeile 71 der Datei fi2enc.c.

72 {
73  int i;
74  unsigned char c;
75  unsigned char *p = (unsigned char *)dst;
76 
77  if( !str ){
78  printf( "No hex string supplied!\n" );
79  return -1;
80  }
81  if( !p ) return -1;
82  if( strlen( str ) != (size_t)len*2 ){
83  printf( "Hex length mismatch in \"%s\"!\n", str );
84  return -1;
85  }
86  for( i = 0; i < len*2; i++ ){
87  c = str[i];
88  if( c < ('9'+1) && c >= '0' ) c-= 0x30;
89  else if( c < 'G' && c >= 'A' ) c -= ('A' - 0x0A);
90  else if( c < 'g' && c >= 'a' ) c -= ('a' - 0x0A);
91  else {
92  printf("Non-hex character \'%c\' at %d in string %s\n", c, i+1, str );
93  return -1;
94  }
95  p[i/2] = i & 1 ? p[i/2] | c : c << 4;
96  }
97  return 0;
98 }
int main ( int  argc,
char **  argv 
)

Definiert in Zeile 241 der Datei fi2enc.c.

242 {
243  int i;
244  uint32_t key_buf[4];
245  uint32_t iv_buf[4];
246  uint32_t *key = NULL;
247  uint32_t *iv = NULL;
248  char *fni = NULL, *fno = NULL;
249  uint32_t pid=0;
250  uint32_t dryos_ver=0;
251  char *flags = NULL;
252  int32_t cs_words = 0;
253 
254  // parse command line
255  for( i = 1; i < argc; i++){
256  if( argv[i][0] == '/' || argv[i][0] == '-' ){ // ---- arg is option
257 
258  if( !strcmp( "key", _strlwr(argv[i]+1) ) ){ // opt: key
259  if ( get_hexstring( key_buf, argv[++i], sizeof key_buf ) ) return -1;
260  else key = key_buf;
261  }
262  else if( !strcmp( "iv", _strlwr(argv[i]+1) ) ){ // opt: iv
263  if ( get_hexstring( iv_buf, argv[++i], sizeof iv_buf ) ) return -1;
264  else iv = iv_buf;
265  }
266  else if( !strcmp( "p", _strlwr(argv[i]+1) ) ){ // opt: pid
267  char *err=NULL;
268  pid = strtoul(argv[++i], &err, 0);
269  if (*err) return -1;
270  }
271  else if( !strcmp( "pv", _strlwr(argv[i]+1) ) ){ // opt: dryos_ver
272  char *err=NULL;
273  dryos_ver = strtoul(argv[++i], &err, 0);
274  if (*err) return -1;
275  }
276  else if( !strcmp( "x", _strlwr(argv[i]+1) ) ){ // extra flags, single string without spaces
277  flags = argv[++i];
278  }
279  else {
280  printf("Unexpected option: %s\n", argv[i]);
281  return -1;
282  }
283  } else { // ---- arg is not an option
284  if( !fni ) fni = argv[i]; // 1st non-option is input file name
285  else if( !fno ) fno = argv[i]; // 2nd non-option is output file name
286  else {
287  printf("Unexpected parameter: %s\n", argv[i]);
288  return -1;
289  }
290  }
291  }
292  if( !key || !iv || !pid){
293  fputs( g_str_shorthelp, stdout );
294  return -1;
295  }
296  if (flags) {
297  if ( strstr(flags, "W") ) {
298  cs_words = 1;
299  }
300  }
301  for( i = 0; i < 4; i ++ ) key[i] = read32_be( key+i );
302  i = fi2enc( fni, fno, key, iv , pid, dryos_ver, cs_words);
303  if ( !i ) printf( "Done\n" ); else printf( "Failed!\n" );
304  return i;
305 }
static uint32_t read32_be ( const void *  src_buffer)
static

Definiert in Zeile 51 der Datei fi2enc.c.

52 {
53  unsigned char *b = (unsigned char *)src_buffer;
54  return (b[0]<<24) | (b[1] << 16) | (b[2] << 8) | b[3];
55 }
static void store32_be ( void *  dst_buffer,
uint32_t  value 
)
static

Definiert in Zeile 57 der Datei fi2enc.c.

58 {
59  unsigned char *b = (unsigned char *)dst_buffer;
60  b[0] = ( value >> 24 ) & 0xFF;
61  b[1] = ( value >> 16 ) & 0xFF;
62  b[2] = ( value >> 8 ) & 0xFF;
63  b[3] = ( value >> 0 ) & 0xFF;
64 }

Variablen-Dokumentation

const char* g_str_err_malloc = "memory allocation error (requested %d bytes)\n"
static

Definiert in Zeile 13 der Datei fi2enc.c.

const char* g_str_shorthelp
static
Initialisierung:
= "Usage: fi2encdec [-p PID] [-key KEY -iv IV] [-x FLAGS] in.file out.file\n"
" FLAGS: one or more of the following letters\n"
" W: checksum is word based (on new models)\n"
"\n"

Definiert in Zeile 14 der Datei fi2enc.c.