/* Handle s case. */
int p_handler(va_list args)
{
        unsigned long int addr;
        addr = va_arg(args, unsigned long int);
        print_str("0x");
        return convert_hex(addr);
}
Beispiel #2
0
static char *
convert_escape (struct type *type, const char *dest_charset,
		char *p, char *limit, struct obstack *output)
{
  /* Skip the backslash.  */
  ADVANCE;

  switch (*p)
    {
    case '\\':
      obstack_1grow (output, '\\');
      ++p;
      break;

    case 'x':
      ADVANCE;
      if (!isxdigit (*p))
	error (_("\\x used with no following hex digits."));
      p = convert_hex (type, p, limit, output);
      break;

    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      p = convert_octal (type, p, limit, output);
      break;

    case 'u':
    case 'U':
      {
	int length = *p == 'u' ? 4 : 8;

	ADVANCE;
	if (!isxdigit (*p))
	  error (_("\\u used with no following hex digits"));
	p = convert_ucn (p, limit, dest_charset, output, length);
      }
    }

  return p;
}
Beispiel #3
0
int main(int argc, char *argv[]) {
  FILE *in, *out;
  cencrypted_v1_header v1header;
  cencrypted_v2_pwheader v2header;

  uint8_t hmacsha1_key[20], aes_key[16], inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE];
  uint32_t chunk_no;
  int hdr_version, c,i, optError = 0;
  char inFile[512], outFile[512], passphrase[512];
  int iflag = 0, oflag = 0, pflag = 0, kflag = 0, verbose = 0;
  extern char *optarg;
  extern int optind, optopt;

  memset(inFile, 0, 512);
  memset(outFile, 0, 512);
  memset(passphrase, 0, 512);

  while((c = getopt(argc, argv, "hvi:o:p:k:")) != -1) {
    switch(c) {
    case 'h':
      usage("Help is on the way. Stay calm.");
      break;
    case 'v':
      verbose++;
      break;
    case 'i':
      if(optarg) strncpy(inFile, optarg, sizeof(inFile)-1);
      iflag = 1;
      break;
    case 'o':
      if (optarg) strncpy(outFile, optarg, sizeof(outFile)-1);
      oflag = 1;
      break;
    case 'p':
      if (optarg) strncpy(passphrase, optarg, sizeof(passphrase)-1);
      pflag = 1;
      break;
    case 'k':
      convert_hex(optarg, aes_key, 16);
      convert_hex(optarg+32, hmacsha1_key, 20);
      kflag=1;
      break;
    case '?':
      fprintf(stderr, "Unknown option: -%c\n", optopt);
      optError++;
      break;
    }
  }

  /* check to see if our user gave incorrect options */
  if (optError) usage("Incorrect arguments.");

  if (strlen(inFile) == 0) {
    in = stdin;
  } else {
    if ((in = fopen(inFile, "rb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", inFile);
      exit(1);
    }
  }

  if (strlen(outFile) == 0) {
    out = stdout;
  } else {
    if ((out = fopen(outFile, "wb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", outFile);
      exit(1);
    }
  }

  if (!pflag && !kflag) {
    fprintf(stderr, "No Passphrase given.\n");
    exit(1);
  }

  hdr_version = determine_header_version(in);

  if (verbose >= 1) {
    if (hdr_version > 0) {
      fprintf(stderr, "v%d header detected.\n", hdr_version);
    } else {
      fprintf(stderr, "unknown format.\n");
      exit(1);
    }
  }

  if (hdr_version == 1) {
    fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END);
    if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v1_header_byteorder(&v1header);
    if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key);
  }

  if (hdr_version == 2) {
    fseek(in, 0L, SEEK_SET);
    if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v2_header_byteorder(&v2header);
    dump_v2_header(&v2header);
    if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key);
    CHUNK_SIZE = v2header.blocksize;
  }

  HMAC_CTX_init(&hmacsha1_ctx);
  HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL);
  AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key);

  if (verbose >= 1) {
    fprintf(stderr, "AES Key: \n");
    print_hex(aes_key, 16);
    fprintf(stderr, "SHA1 seed: \n");
    print_hex(hmacsha1_key, 20);
  }

  if (hdr_version == 2) fseek(in, v2header.dataoffset, SEEK_SET);
  else fseek(in, 0L, SEEK_SET);

  chunk_no = 0;
  while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) {
    decrypt_chunk(inbuf, outbuf, chunk_no);
    chunk_no++;
    if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) {
      fwrite(outbuf, v2header.datasize - ftell(out), 1, out);
      break;
    }
    fwrite(outbuf, CHUNK_SIZE, 1, out);
  }

  if (verbose)  fprintf(stderr, "%d chunks written\n", chunk_no);
  return(0);
}
/* Handle x case. */
int x_handler(va_list args)
{
        int d;
        d = va_arg(args, int);
        return convert_hex(d);
}
Beispiel #5
0
int decrypt_root_fs(const char *crypt, const char *decrypt, char *key) {
  FILE *in, *out;
  cencrypted_v1_header v1header;
  cencrypted_v2_pwheader v2header;

  uint8_t hmacsha1_key[20], aes_key[16], inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE];
  uint32_t chunk_no;
  int hdr_version, c,i, optError = 0;
  char inFile[512], outFile[512], passphrase[512];
  int iflag = 0, oflag = 0, pflag = 0, kflag = 0, verbose = 0;
  extern char *optarg;
  extern int optind, optopt;

  memset(inFile, 0, 512);
  memset(outFile, 0, 512);
  memset(passphrase, 0, 512);

      verbose++;
      optarg=(char *)crypt;
      if(optarg) strncpy(inFile, optarg, sizeof(inFile)-1);
      iflag=1;
      optarg=(char *)decrypt;
      if (optarg) strncpy(outFile, optarg, sizeof(outFile)-1);
      oflag=1;
      optarg=key;
      convert_hex(optarg, aes_key, 16);
      convert_hex(optarg+32, hmacsha1_key, 20);
      kflag=1;

  if (strlen(inFile) == 0) {
    in = stdin;
  } else {
    if ((in = fopen(inFile, "rb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", inFile);
      exit(1);
    }
  }

  if (strlen(outFile) == 0) {
    out = stdout;
  } else {
    if ((out = fopen(outFile, "wb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", outFile);
      exit(1);
    }
  }

  hdr_version = determine_header_version(in);

  if (verbose >= 1) {
    if (hdr_version > 0) {
      fprintf(stderr, "v%d header detected.\n", hdr_version);
    } else {
      fprintf(stderr, "unknown format.\n");
      exit(1);
    }
  }

  if (hdr_version == 1) {
    fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END);
    if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v1_header_byteorder(&v1header);
    if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key);
  }

  if (hdr_version == 2) {
    fseek(in, 0L, SEEK_SET);
    if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v2_header_byteorder(&v2header);
    dump_v2_header(&v2header);
    if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key);
    CHUNK_SIZE = v2header.blocksize;
  }

  HMAC_CTX_init(&hmacsha1_ctx);
  HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL);
  AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key);

  if (verbose >= 1) {
    fprintf(stderr, "AES Key: \n");
    print_hex(aes_key, 16);
    fprintf(stderr, "SHA1 seed: \n");
    print_hex(hmacsha1_key, 20);
  }

  if (hdr_version == 2) fseek(in, v2header.dataoffset, SEEK_SET);
  else fseek(in, 0L, SEEK_SET);

  chunk_no = 0;
  while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) {
    decrypt_chunk(inbuf, outbuf, chunk_no);
    chunk_no++;
    if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) {
      fwrite(outbuf, v2header.datasize - ftell(out), 1, out);
      break;
    }
    fwrite(outbuf, CHUNK_SIZE, 1, out);
  }

  if (verbose)  fprintf(stderr, "%d chunks written\n", chunk_no);
  return 0;

	return 0;
}
Beispiel #6
0
/*
 *uart_printf(char*)
 *Converts and formats values to be sent via char UART. Works similar to normal printf function.
 *INPUT: Char* EX: uart_printf("DATA: %i\r\n", datvar);
 *RETURN: None
 */
void uart_printf(char *format, ...)
{
    char c;
    int i;
    long l;

    va_list list;														//Make the arguement list
    va_start(list, format);

    while(c = *format++)												//run through the input till the end.
    {
        if(c == '%')													//% denotes the variable format character
        {
            switch(c = *format++)
            {
                case 's':                       						// strings
                    uart_puts(va_arg(list, char*));
                    break;

                case 'c':                       						// chars
                    uart_putc(va_arg(list, char));
                    break;

                case 'i':                       						// signed ints
                	i = va_arg(list, int);
                    if(i < 0)
                    {
                    	i = -i;
                     	uart_putc('-');
                    }
                    convert_dec((unsigned)i, divider + 5);
                    break;

                case 'u':                      							// unsigned ints
                    i = va_arg(list, int);
                    convert_dec((unsigned)i, divider + 5);
                    break;

                case 'l':                       						// signed longs
                    l = va_arg(list, long);
                    if(l < 0)
                    {
                    	l = -l;
                    	uart_putc('-');
                    }
                    convert_dec((unsigned long)l, divider);
                    break;

                case 'n':                       						// unsigned longs
                    l = va_arg(list, long);
                    convert_dec((unsigned long)l, divider);
                    break;

                case 'x':                       						// 16bit Hex
                    i = va_arg(list, int);
                    uart_putc(convert_hex(i >> 12));
                    uart_putc(convert_hex(i >> 8));
                    uart_putc(convert_hex(i >> 4));
                    uart_putc(convert_hex(i));
                    break;

                case 0:
                	return;
                default:
                	uart_putc(c);										//can't find formating. just print it.
            }
        }
        else
        {
        	uart_putc(c);
        }
    }
Beispiel #7
0
/**
   \fn int main(int argc, char *argv[])
   
   \brief main routine
   
   \param argc      number of commandline arguments + 1
   \param argv      string array containing commandline arguments (argv[0] contains name of executable)
   
   \return dummy return code (not used)
   
   Main routine for import, programming, and check routines
*/
int main(int argc, char ** argv) {
 
  char      *appname;             // name of application without path
  char      portname[STRLEN];     // name of communication port
  int       baudrate;             // communication baudrate [Baud]
  uint8_t   resetSTM8;            // 0=no reset; 1=HW reset via DTR (RS232/USB) or GPIO18 (Raspi); 2=SW reset by sending 0x55+0xAA
  uint8_t   enableBSL;            // don't enable ROM bootloader after upload (caution!)
  uint8_t   jumpFlash;            // jump to flash after upload
  uint8_t   pauseOnLaunch;        // prompt for <return> prior to upload
  int       flashsize;            // size of flash (kB) for w/e routines
  uint8_t   versBSL;              // BSL version for w/e routines
  char      hexfile[STRLEN];      // name of file to flash
  HANDLE    ptrPort;              // handle to communication port
  char      buf[BUFSIZE];         // buffer for hexfiles
  char      image[BUFSIZE];       // memory image buffer
  uint32_t  imageStart;           // starting address of image
  uint32_t  numBytes;             // number of bytes in image
  char      *ptr=NULL;            // pointer to memory
  int       i, j;                 // generic variables  
  //char      Tx[100], Rx[100];     // debug: buffer for tests
  

  // initialize global variables
  g_pauseOnExit = 1;            // wait for <return> before terminating
  g_UARTmode    = 0;            // 2-wire interface with UART duplex mode
  verbose       = false;        // verbose output when requested only
  
  // initialize default arguments
  portname[0] = '\0';           // no default port name
  baudrate   = 230400;          // default baudrate
  resetSTM8  = 0;               // don't automatically reset STM8
  jumpFlash  = 1;               // jump to flash after uploade
  pauseOnLaunch = 1;            // prompt for return prior to upload
  enableBSL  = 1;               // enable bootloader after upload
  hexfile[0] = '\0';            // no default hexfile
  
  // for debugging only
  //sprintf(portname, "/dev/tty.usbserial-A4009I0O");

  // required for strncpy()
  portname[STRLEN-1]  = '\0';
  hexfile[STRLEN-1]   = '\0';
    
    
  // reset console color (needs to be called once for Win32)      
  setConsoleColor(PRM_COLOR_DEFAULT);


  ////////
  // parse commandline arguments
  ////////
  for (i=1; i<argc; i++) {
    
    // debug: print argument
    //printf("arg %d: '%s'\n", (int) i, argv[i]);
    
    // name of communication port
    if (!strcmp(argv[i], "-p"))
      strncpy(portname, argv[++i], STRLEN-1);

    // communication baudrate
    else if (!strcmp(argv[i], "-b"))
      sscanf(argv[++i],"%d",&baudrate);

    // UART mode: 0=duplex, 1=1-wire reply, 2=2-wire reply (default: duplex)\n");
    else if (!strcmp(argv[i], "-u")) {
      sscanf(argv[++i], "%d", &j);
      g_UARTmode = j;
    }

    // name of hexfile
    else if (!strcmp(argv[i], "-f"))
      strncpy(hexfile, argv[++i], STRLEN-1);

    // HW reset STM8 via DTR line (RS232/USB) or GPIO18 (Raspi only)
    else if (!strcmp(argv[i], "-r")) {
      sscanf(argv[++i], "%d", &j);
      resetSTM8 = j;
    }
    
    // don't enable ROM bootloader after upload (caution!)
    else if (!strcmp(argv[i], "-x"))
      enableBSL = 0;

    // don't jump to address after upload
    else if (!strcmp(argv[i], "-j"))
      jumpFlash = 0;

    // don't prompt for <return> prior to upload
    else if (!strcmp(argv[i], "-Q"))
      pauseOnLaunch = 0;

    // don't prompt for <return> prior to exit
    else if (!strcmp(argv[i], "-q"))
      g_pauseOnExit = 0;

    // verbose output
    else if (!strcmp(argv[i], "-v"))
      verbose = true;

    // else print list of commandline arguments and language commands
    else {
      if (strrchr(argv[0],'\\'))
        appname = strrchr(argv[0],'\\')+1;         // windows
      else if (strrchr(argv[0],'/'))
        appname = strrchr(argv[0],'/')+1;          // Posix
      else
        appname = argv[0];
      printf("\n");
      printf("usage: %s [-h] [-p port] [-b rate] [-u mode] [-f file] [-r ch] [-x] [-j] [-Q] [-q] [-v]\n\n", appname);
      printf("  -h        print this help\n");
      printf("  -p port   name of communication port (default: list all ports and query)\n");
      printf("  -b rate   communication baudrate in Baud (default: 230400)\n");
      printf("  -u mode   UART mode: 0=duplex, 1=1-wire reply, 2=2-wire reply (default: duplex)\n");
      printf("  -f file   name of s19 or intel-hex file to flash (default: none)\n");
      #ifdef __ARMEL__
        printf("  -r ch     reset STM8: 1=DTR line (RS232), 2=send 'Re5eT!' @ 115.2kBaud, 3=GPIO18 pin (Raspi) (default: no reset)\n");
      #else
        printf("  -r ch     reset STM8: 1=DTR line (RS232), 2=send 'Re5eT!' @ 115.2kBaud (default: no reset)\n");
      #endif
      printf("  -x        don't enable ROM bootloader after upload (default: enable)\n");
      printf("  -j        don't jump to flash after upload (default: jump to flash)\n");
      printf("  -Q        don't prompt for <return> prior to upload (default: prompt)\n");
      printf("  -q        don't prompt for <return> prior to exit (default: prompt)\n");
      printf("  -v        verbose output\n");
      printf("\n");
      Exit(0, 0);
    }

  } // process commandline arguments
  
  

  ////////
  // print app name & version, and change console title
  ////////
  get_app_name(argv[0], VERSION, buf);
  printf("\n%s\n", buf);
  setConsoleTitle(buf);  
  
  
  ////////
  // if no port name is given, list all available ports and query
  ////////
  if (strlen(portname) == 0) {
    printf("  enter comm port name ( ");
    list_ports();
    printf(" ): ");
    scanf("%s", portname);
    getchar();
  } // if no comm port name

  // If specified import hexfile - do it early here to be able to report file read errors before others
  if (strlen(hexfile)>0) {
    const char *shortname = strrchr(hexfile, '/');
    if (!shortname)
      shortname = hexfile;

    // convert to memory image, depending on file type
    const char *dot = strrchr (hexfile, '.');
    if (dot && !strcmp(dot, ".s19")) {
      if (verbose)
        printf("  Loading Motorola S-record file %s …\n", shortname);
      load_hexfile(hexfile, buf, BUFSIZE);
      convert_s19(buf, &imageStart, &numBytes, image);
      }
    else if (dot && (!strcmp(dot, ".hex") || !strcmp(dot, ".ihx"))) {
      if (verbose)
        printf("  Loading Intel hex file %s …\n", shortname);
      load_hexfile(hexfile, buf, BUFSIZE);
      convert_hex(buf, &imageStart, &numBytes, image);
    }
    else {
      if (verbose)
        printf("  Loading binary file %s …\n", shortname);
      load_binfile(hexfile, image, &imageStart, &numBytes, BUFSIZE);
    }
  }

  ////////
  // put STM8 into bootloader mode
  ////////
  if (pauseOnLaunch) {
    printf("  activate STM8 bootloader and press <return>");
    fflush(stdout);
    fflush(stdin);
    getchar();
  }

  ////////
  // open port with given properties
  ////////
  printf("  open port '%s' with %gkBaud ... ", portname, (float) baudrate / 1000.0);
  fflush(stdout);
  if (g_UARTmode == 0)
    ptrPort = init_port(portname, baudrate, 1000, 8, 2, 1, 0, 0);   // use even parity
  else
    ptrPort = init_port(portname, baudrate, 1000, 8, 0, 1, 0, 0);   // use no parity
  printf("ok\n");
  fflush(stdout);
  
 
  // debug: communication test (echo+1 test-SW on STM8)
  /*
  printf("open: %d\n", ptrPort);
  for (i=0; i<254; i++) {
    Tx[0] = i;
    send_port(ptrPort, 1, Tx);
    receive_port(ptrPort, 1, Rx);
	printf("%d  %d\n", (int) Tx[0], (int) Rx[0]);
  }
  printf("done\n");
  Exit(1,0);
  */
  

  ////////
  // communicate with STM8 bootloader
  ////////

  // HW reset STM8 using DTR line (USB/RS232)
  if (resetSTM8 == 1) {
    printf("  reset via DTR ... ");
    pulse_DTR(ptrPort, 10);
    printf("done\n");
    SLEEP(5);                       // allow BSL to initialize
  }
  
  // SW reset STM8 via command 'Re5eT!' at 115.2kBaud (requires respective STM8 SW)
  else if (resetSTM8 == 2) {
    set_baudrate(ptrPort, 115200);    // expect STM8 SW to receive at 115.2kBaud
    printf("  reset via UART command ... ");
    sprintf(buf, "Re5eT!");           // reset command (same as in STM8 SW!)
    for (i=0; i<6; i++) {
      send_port(ptrPort, 1, buf+i);   // send reset command bytewise to account for slow handling
      SLEEP(10);
    }
    printf("done\n");
    set_baudrate(ptrPort, baudrate);  // restore specified baudrate
  }
  
  // HW reset STM8 using GPIO18 pin (only Raspberry Pi!)
  #ifdef __ARMEL__
    else if (resetSTM8 == 3) {
      printf("  reset via GPIO18 ... ");
      pulse_GPIO(18, 10);
      printf("done\n");
      SLEEP(5);                       // allow BSL to initialize
    }
  #endif // __ARMEL__
  
  // synchronize baudrate
  bsl_sync(ptrPort);
  
  // get bootloader info for selecting flash w/e routines
  bsl_getInfo(ptrPort, &flashsize, &versBSL);

  // select device dependent flash routines for upload
  if ((flashsize==32) && (versBSL==0x10)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_32K_ver_1_0_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_32K_ver_1_0_s19_len]=0;
  }
  else if ((flashsize==32) && (versBSL==0x12)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_32K_ver_1_2_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_32K_ver_1_2_s19_len]=0;
  }
  else if ((flashsize==32) && (versBSL==0x13)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_32K_ver_1_3_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_32K_ver_1_3_s19_len]=0;
  }
  else if ((flashsize==32) && (versBSL==0x14)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_32K_ver_1_4_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_32K_ver_1_4_s19_len]=0;
  }
  else if ((flashsize==128) && (versBSL==0x20)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_128K_ver_2_0_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_128K_ver_2_0_s19_len]=0;
  }
  else if ((flashsize==128) && (versBSL==0x21)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_128K_ver_2_1_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_128K_ver_2_1_s19_len]=0;
  }
  else if ((flashsize==128) && (versBSL==0x22)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_128K_ver_2_2_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_128K_ver_2_2_s19_len]=0;
  }
  else if ((flashsize==128) && (versBSL==0x24)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_128K_ver_2_4_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_128K_ver_2_4_s19_len]=0;
  }
  else if ((flashsize==256) && (versBSL==0x10)) {
    ptr = (char*) STM8_Routines_E_W_ROUTINEs_256K_ver_1_0_s19;
    ptr[STM8_Routines_E_W_ROUTINEs_256K_ver_1_0_s19_len]=0;
  }
  else {
    setConsoleColor(PRM_COLOR_RED);
    fprintf(stderr, "\n\nerror: unsupported device, exit!\n\n");
    Exit(1, g_pauseOnExit);
  }

  {
    char      ramImage[8192];
    uint32_t  ramImageStart;
    uint32_t  numRamBytes;

    convert_s19(ptr, &ramImageStart, &numRamBytes, ramImage);

    if (verbose)
      printf("Uploading RAM routines\n");
    bsl_memWrite(ptrPort, ramImageStart, numRamBytes, ramImage, 0);
  }

  // if specified upload hexfile
  if (strlen(hexfile)>0)
    bsl_memWrite(ptrPort, imageStart, numBytes, image, 1);
  
  // memory read
  //imageStart = 0x8000;  numBytes = 128*1024;   // complete 128kB flash
  //imageStart = 0x00A0;  numBytes = 352;        // RAM
  //bsl_memRead(ptrPort, imageStart, numBytes, image);
  
  
  // enable ROM bootloader after upload (option bytes always on same address)
  if (enableBSL==1) {
    printf("  activate bootloader ... ");
    bsl_memWrite(ptrPort, 0x487E, 2, (char*)"\x55\xAA", 0);
    printf("done\n");
  }
  
  // jump to flash start address after upload (reset vector always on same address)
  if (jumpFlash)
    bsl_jumpTo(ptrPort, 0x8000);
  
  
  ////////
  // clean up and exit
  ////////
  close_port(&ptrPort);
  if (verbose)
    printf("done with program\n");
  Exit(0, g_pauseOnExit);
  
  // avoid compiler warnings
  return(0);
  
} // main
Beispiel #8
0
int main(int argc, char *argv[])
{
  FILE *in, *out;
  cencrypted_v1_header v1header;
  cencrypted_v2_pwheader v2header;
  char hmacsha1_key_str[20*2+1];
  char aes_key_str[16*2+1];
  uint8_t hmacsha1_key[20];
  uint8_t aes_key[16];
  uint8_t inbuf[CHUNK_SIZE], outbuf[CHUNK_SIZE];
  uint32_t chunk_no;
  int hdr_version;
  
  /* getopts */
  int c;
  int optError;
  char inFile[512] = "";
  char outFile[512] = "";
  char passphrase[512];
  int kflag = 0, iflag = 0, oflag = 0, pflag = 0, mflag = 0;
  int verbose = 0;
  extern char *optarg;
  extern int optind, optopt;

  memset(hmacsha1_key_str, '0', sizeof(hmacsha1_key_str)-1);
  hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0';

  optError = 0;
  while((c = getopt(argc, argv, "hvi:o::p::k:m:")) != -1){
    switch(c) {
    case 'h':      
      usage("Help is on the way. Stay calm.");
      break;
    case 'v':      
      verbose = verbose + 1;
      break;
    case 'i':
      if(optarg) {
	strncpy(inFile, optarg, sizeof(inFile)-1);
      } 
      iflag = 1;
      break;
    case 'o':
      if (optarg) {
	strncpy(outFile, optarg, sizeof(outFile)-1);
      }
      oflag = 1;
      break;
    case 'p':
      if (optarg) {
	strncpy(passphrase, optarg, sizeof(passphrase)-1);
      }
      pflag = 1;
      break;
    case 'k':
      if (optarg) {
	if (strlen(optarg) == 2*(16+20)) {
	  strncpy(aes_key_str, optarg, sizeof(aes_key_str));
	  aes_key_str[sizeof(aes_key_str)-1] = '\0';
	  strncpy(hmacsha1_key_str, optarg+(2*16), sizeof(hmacsha1_key_str));
	  hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0';
	  mflag = 1;
	} else if(strlen(optarg) == 2*16) {
	  strncpy(aes_key_str, optarg, sizeof(aes_key_str));
	  aes_key_str[sizeof(aes_key_str)-1] = '\0';
	} else {
	  usage("you should either specify a aeskey||hmacsha1key or simply aeskey");
	  optError++;
	}
      }
      kflag = 1;
      break;
    case 'm':
      if (mflag) {
	usage("hmacsha1 key has already been specified!");
	optError++;
      }
      if (optarg && strlen(optarg) == 2*20) {
	strncpy(hmacsha1_key_str, optarg, sizeof(hmacsha1_key_str));
	hmacsha1_key_str[sizeof(hmacsha1_key_str)-1] = '\0';
      } else {
        usage("Perhaps you'd like to give us 40 hex bytes of the HMACSHA1 key?");
	optError++;
      }
      mflag = 1;
      break;
    case '?':
      fprintf(stderr, "Unknown option: -%c\n", optopt);
      optError++;
      break;
    }
  }

  /* check to see if our user gave incorrect options */
  if (optError) {
    usage("Incorrect arguments.");
  }

  if (strlen(inFile) == 0) {
    in = stdin; 
  } else {
    if ((in = fopen(inFile, "rb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", inFile);
      exit(1);
    }
  }

  if (strlen(outFile) == 0) {
    out = stdout;
  } else {
    if ((out = fopen(outFile, "wb")) == NULL) {
      fprintf(stderr, "Error: unable to open %s\n", outFile);
      exit(1);
    }
  }

  /* Obviously change this if we implement brute force methods inside vfdecrypt */
  if (!kflag && !pflag) {
    fprintf(stderr, "Neither a passphrase nor a valid key/hmac combo were given.\n");
    exit(1);
  }

  if (kflag && !mflag) {
    fprintf(stderr, "Setting HMAC-SHA1 key to all zeros!\n");
  }

  hdr_version = determine_header_version(in);
 
  if (verbose >= 1) {
    if (hdr_version > 0) {
      fprintf(stderr, "v%d header detected.\n", hdr_version);
    } else {
      fprintf(stderr, "unknown format.\n");
      exit(1);
    }
  }

  if (hdr_version == 1) {
    fseek(in, (long) -sizeof(cencrypted_v1_header), SEEK_END);
    if (fread(&v1header, sizeof(cencrypted_v1_header), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v1_header_byteorder(&v1header);
    if(!kflag) unwrap_v1_header(passphrase, &v1header, aes_key, hmacsha1_key);
  }
  
  if (hdr_version == 2) {
    fseek(in, 0L, SEEK_SET);
    if (fread(&v2header, sizeof(cencrypted_v2_pwheader), 1, in) < 1) {
      fprintf(stderr, "header corrupted?\n"), exit(1);
    }
    adjust_v2_header_byteorder(&v2header);
    if (verbose >= 1) {
      dump_v2_header(&v2header);
    }
    if(!kflag) unwrap_v2_header(passphrase, &v2header, aes_key, hmacsha1_key);
    CHUNK_SIZE = v2header.blocksize;
  }

  if (kflag) {
    convert_hex(aes_key_str, aes_key, 16);
    convert_hex(hmacsha1_key_str, hmacsha1_key, 20);
  }
  
  HMAC_CTX_init(&hmacsha1_ctx);
  HMAC_Init_ex(&hmacsha1_ctx, hmacsha1_key, sizeof(hmacsha1_key), EVP_sha1(), NULL);
  AES_set_decrypt_key(aes_key, CIPHER_KEY_LENGTH * 8, &aes_decrypt_key);

  if (verbose >= 1) {
    fprintf(stderr, "aeskey:\n");
    print_hex(stderr, aes_key, 16);
  }
  if (verbose >= 1) {
    fprintf(stderr, "hmacsha1key:\n");
    print_hex(stderr, hmacsha1_key, 20);
  }
  if (hdr_version == 2) {
    if (verbose >= 1) {
      fprintf(stderr, "data offset : %llu\n", v2header.dataoffset);
      fprintf(stderr, "data size   : %llu\n", v2header.datasize);
    }
    fseek(in, v2header.dataoffset, SEEK_SET);
  } else  {
    fseek(in, 0L, SEEK_SET);
  }

  chunk_no = 0;
  while(fread(inbuf, CHUNK_SIZE, 1, in) > 0) {
    decrypt_chunk(inbuf, outbuf, chunk_no);
    chunk_no++;
    // fix for last chunk
    if(hdr_version == 2 && (v2header.datasize-ftell(out)) < CHUNK_SIZE) {
      fwrite(outbuf, v2header.datasize - ftell(out), 1, out);
      break;
    }
    fwrite(outbuf, CHUNK_SIZE, 1, out);
  }
  if (verbose >= 1) {
    fprintf(stderr, "%d chunks written\n", chunk_no);
  }
  fclose(in);
  fclose(out);
  return(0);
}