Signed-off-by: Vitaly Chekryzhev <13hakta@gmail.com> [moved to firmware-utils package] [dropped the compiled binary] Signed-off-by: Mathias Kresin <dev@kresin.me>
		
			
				
	
	
		
			149 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2014 Soul Trace <S-trace@list.ru>
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of the GNU General Public License version 2 as published
 | 
						|
 * by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#define _POSIX_SOURCE
 | 
						|
#define _POSIX_C_SOURCE 199309L /* getopt */
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#define szbuf 32768
 | 
						|
 | 
						|
u_int32_t crc_tab[256];
 | 
						|
 | 
						|
u_int32_t chksum_crc32 (FILE *f)
 | 
						|
{
 | 
						|
  register unsigned long crc;
 | 
						|
  unsigned long i, j;
 | 
						|
  char *buffer = malloc(szbuf);
 | 
						|
  char *buf;
 | 
						|
 | 
						|
  crc = 0xFFFFFFFF;
 | 
						|
  while (!feof(f))
 | 
						|
  {
 | 
						|
    j = fread(buffer, 1, szbuf, f);
 | 
						|
    buf = buffer;
 | 
						|
    for (i = 0; i < j; i++)
 | 
						|
      crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *buf++) & 0xFF];
 | 
						|
  }
 | 
						|
  free(buffer);
 | 
						|
  return crc;
 | 
						|
}
 | 
						|
 | 
						|
void chksum_crc32gentab ()
 | 
						|
{
 | 
						|
  unsigned long crc, poly;
 | 
						|
  int i, j;
 | 
						|
 | 
						|
  poly = 0xEDB88320L;
 | 
						|
  for (i = 0; i < 256; i++)
 | 
						|
  {
 | 
						|
    crc = i;
 | 
						|
    for (j = 8; j > 0; j--)
 | 
						|
    {
 | 
						|
      if (crc & 1)
 | 
						|
        crc = (crc >> 1) ^ poly;
 | 
						|
      else
 | 
						|
        crc >>= 1;
 | 
						|
    }
 | 
						|
    crc_tab[i] = crc;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void usage(char *progname)
 | 
						|
{
 | 
						|
  printf("Usage: %s [ -v Version ] [ -d Device_ID ] <input file>\n", progname);
 | 
						|
  exit(1);
 | 
						|
}
 | 
						|
 | 
						|
int main(int argc, char *argv[]) {
 | 
						|
  struct signature
 | 
						|
  {
 | 
						|
    const char magic[4];
 | 
						|
    unsigned int device_id;
 | 
						|
    char firmware_version[48];
 | 
						|
    unsigned int crc32;
 | 
						|
  }
 | 
						|
  sign =
 | 
						|
  {
 | 
						|
    { 'Z', 'N', 'B', 'G' },
 | 
						|
    1,
 | 
						|
    { "V.1.0.0(1.0.0)" },
 | 
						|
    0
 | 
						|
  };
 | 
						|
  FILE *f;
 | 
						|
  struct signature oldsign;
 | 
						|
  char *filename;
 | 
						|
  static const char *optString;
 | 
						|
  int opt;
 | 
						|
 | 
						|
  if (argc < 1)
 | 
						|
    usage(argv[0]);
 | 
						|
 | 
						|
  optString = "v:d:h";
 | 
						|
  opt = getopt( argc, argv, optString );
 | 
						|
  while( opt != -1 ) {
 | 
						|
    switch( opt ) {
 | 
						|
      case 'v':
 | 
						|
        if (optarg == NULL)
 | 
						|
          usage(argv[0]);
 | 
						|
        strncpy(sign.firmware_version, optarg, sizeof(sign.firmware_version)-1);
 | 
						|
       sign.firmware_version[sizeof(sign.firmware_version)-1]='\0'; /* Make sure that string is terminated correctly */
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'd':
 | 
						|
        sign.device_id = atoi(optarg);
 | 
						|
        if (sign.device_id == 0)
 | 
						|
          sign.device_id = (int)strtol(optarg, NULL, 16);
 | 
						|
        break;
 | 
						|
 | 
						|
      case '?':
 | 
						|
      case 'h':
 | 
						|
        usage(argv[0]);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    opt = getopt( argc, argv, optString );
 | 
						|
  }
 | 
						|
 | 
						|
  chksum_crc32gentab();
 | 
						|
 | 
						|
  filename=argv[optind];
 | 
						|
  if (access(filename, W_OK) || access(filename, R_OK))
 | 
						|
  {
 | 
						|
    printf("Not open input file %s\n", filename);
 | 
						|
    exit(1);
 | 
						|
  }
 | 
						|
  f = fopen(argv[optind], "r+");
 | 
						|
  if (f != NULL)
 | 
						|
  {
 | 
						|
    fseek(f, sizeof(sign)*-1, SEEK_END);
 | 
						|
    fread(&oldsign, sizeof(oldsign), 1, f);
 | 
						|
 | 
						|
    if (strncmp(oldsign.magic,"ZNBG", sizeof(oldsign.magic)) == 0 )
 | 
						|
    {
 | 
						|
      printf("Image is already signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", oldsign.device_id, oldsign.firmware_version, oldsign.crc32);
 | 
						|
      exit(0);
 | 
						|
    }
 | 
						|
 | 
						|
    fseek(f, 0, SEEK_SET);
 | 
						|
    sign.crc32 = chksum_crc32(f);
 | 
						|
    fwrite(&sign, sizeof(sign), 1, f);
 | 
						|
    fclose(f);
 | 
						|
 | 
						|
    printf("Image signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", sign.device_id, sign.firmware_version, sign.crc32);
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 |