2022-07-03 10:26:20 +00:00
|
|
|
// Procedures for digital signature processing
|
2017-06-22 15:01:05 +00:00
|
|
|
|
2016-11-04 17:42:26 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifndef WIN32
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <strings.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#else
|
|
|
|
#include <windows.h>
|
|
|
|
#include "getopt.h"
|
|
|
|
#include "printf.h"
|
|
|
|
#include "buildno.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "hdlcio.h"
|
|
|
|
#include "ptable.h"
|
|
|
|
#include "flasher.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "zlib.h"
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// table of key parameters -g
|
2016-11-04 17:42:26 +00:00
|
|
|
struct {
|
|
|
|
uint8_t type;
|
|
|
|
uint32_t len;
|
|
|
|
char* descr;
|
|
|
|
} signbase[] = {
|
2022-07-03 10:26:20 +00:00
|
|
|
{1,2958,"Basic Firmware"},
|
|
|
|
{1,2694,"E3372s-Stick Firmware"},
|
|
|
|
{2,1110,"Web-Interface + ISO for HiLink-Modem"},
|
|
|
|
{6,1110,"Web-Interface + ISO for HiLink-Modem"},
|
|
|
|
{2,846,"ISO (Dashboard) for Stick-Modem"},
|
|
|
|
{7,3750,"Firmware + ISO + Web-Interface"},
|
2016-11-04 17:42:26 +00:00
|
|
|
};
|
|
|
|
|
2017-06-22 15:01:05 +00:00
|
|
|
#define signbaselen 6
|
2016-11-04 17:42:26 +00:00
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// table of signature types
|
2017-06-22 15:01:05 +00:00
|
|
|
char* fwtypes[]={
|
|
|
|
"UNKNOWN", // 0
|
|
|
|
"ONLY_FW", // 1
|
|
|
|
"ONLY_ISO", // 2
|
|
|
|
"FW_ISO", // 3
|
|
|
|
"ONLY_WEBUI", // 4
|
|
|
|
"FW_WEBUI", // 5
|
|
|
|
"ISO_WEBUI", // 6
|
|
|
|
"FW_ISO_WEBUI" // 7
|
2022-07-03 10:26:20 +00:00
|
|
|
};
|
2016-11-04 17:42:26 +00:00
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// result string ^signver-command
|
2016-11-05 05:13:53 +00:00
|
|
|
uint8_t signver[200];
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// digital type signature flag
|
2016-11-04 17:42:26 +00:00
|
|
|
extern int gflag;
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// firmware type flag
|
2017-06-23 08:01:13 +00:00
|
|
|
extern int dflag;
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// parameters of the current digital signature
|
|
|
|
uint32_t signtype; // firmware type
|
|
|
|
uint32_t signlen; // signature length
|
2017-06-23 07:40:18 +00:00
|
|
|
|
|
|
|
int32_t serach_sign();
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
// public key hash for ^signver
|
2017-09-06 17:02:25 +00:00
|
|
|
char signver_hash[100]="778A8D175E602B7B779D9E05C330B5279B0661BF2EED99A20445B366D63DD697";
|
|
|
|
|
2016-11-04 17:42:26 +00:00
|
|
|
//****************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Receiving of firmware type description by code
|
2016-11-04 17:42:26 +00:00
|
|
|
//****************************************************
|
|
|
|
char* fw_description(uint8_t code) {
|
2022-07-03 10:26:20 +00:00
|
|
|
return fwtypes[code&0x7];
|
2016-11-04 17:42:26 +00:00
|
|
|
}
|
|
|
|
|
2017-06-23 08:01:13 +00:00
|
|
|
//****************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Receiving of firmware type list
|
2017-06-23 08:01:13 +00:00
|
|
|
//****************************************************
|
|
|
|
void dlist() {
|
|
|
|
int i;
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n # Description\n--------------------------------------");
|
2017-06-23 08:01:13 +00:00
|
|
|
for(i=1;i<8;i++) {
|
|
|
|
printf("\n %i %s",i,fw_description(i));
|
|
|
|
}
|
|
|
|
printf("\n\n");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//***************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Processing of key parameters -d
|
2017-06-23 08:01:13 +00:00
|
|
|
//***************************************************
|
|
|
|
void dparm(char* sparm) {
|
2022-07-03 10:26:20 +00:00
|
|
|
|
2017-06-23 08:01:13 +00:00
|
|
|
if (dflag != 0) {
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Duplicate option -d\n\n");
|
2017-06-23 08:01:13 +00:00
|
|
|
exit(-1);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2017-06-23 08:01:13 +00:00
|
|
|
|
|
|
|
if (sparm[0] == 'l') {
|
|
|
|
dlist();
|
|
|
|
exit(0);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2017-06-23 08:01:13 +00:00
|
|
|
sscanf(sparm,"%x",&dload_id);
|
|
|
|
if ((dload_id == 0) || (dload_id >7)) {
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Incorrect value for option -d\n\n");
|
2017-06-23 08:01:13 +00:00
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
dflag=1;
|
|
|
|
}
|
|
|
|
|
2016-11-04 17:42:26 +00:00
|
|
|
//****************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Get a list of -g key parameters
|
2016-11-04 17:42:26 +00:00
|
|
|
//****************************************************
|
|
|
|
void glist() {
|
|
|
|
int i;
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n # Length Type Description \n--------------------------------------");
|
2016-11-04 17:42:26 +00:00
|
|
|
for (i=0; i<signbaselen; i++) {
|
|
|
|
printf("\n%1i %5i %2i %s",i,signbase[i].len,signbase[i].type,signbase[i].descr);
|
|
|
|
}
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n\n You can also specify arbitrary signature parameters in the format:\n -g *,type,len\n\n");
|
2016-11-04 17:42:26 +00:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//***************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Processing -g option parameters
|
2016-11-04 17:42:26 +00:00
|
|
|
//***************************************************
|
|
|
|
void gparm(char* sparm) {
|
2022-07-03 10:26:20 +00:00
|
|
|
|
|
|
|
int index;
|
2016-11-04 17:42:26 +00:00
|
|
|
char* sptr;
|
|
|
|
char parm[100];
|
|
|
|
|
|
|
|
|
|
|
|
if (gflag != 0) {
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Duplicate option -g\n\n");
|
2017-05-06 04:01:58 +00:00
|
|
|
exit(-1);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2016-11-04 17:42:26 +00:00
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
strcpy(parm,sparm); // local copy of parameters
|
2016-11-04 17:42:26 +00:00
|
|
|
|
|
|
|
if (parm[0] == 'l') {
|
|
|
|
glist();
|
|
|
|
exit(0);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2016-11-04 17:42:26 +00:00
|
|
|
|
2017-06-23 07:40:18 +00:00
|
|
|
if (parm[0] == 'd') {
|
2022-07-03 10:26:20 +00:00
|
|
|
// disable signature auto-detection
|
2017-06-23 07:40:18 +00:00
|
|
|
gflag = -1;
|
|
|
|
return;
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2017-06-23 07:40:18 +00:00
|
|
|
|
2016-11-04 17:42:26 +00:00
|
|
|
if (strncmp(parm,"*,",2) == 0) {
|
2022-07-03 10:26:20 +00:00
|
|
|
// arbitrary parameters
|
|
|
|
// select length
|
2016-11-04 17:42:26 +00:00
|
|
|
sptr=strrchr(parm,',');
|
|
|
|
if (sptr == 0) goto perror;
|
|
|
|
signlen=atoi(sptr+1);
|
|
|
|
*sptr=0;
|
2022-07-03 10:26:20 +00:00
|
|
|
// select partition type
|
2016-11-04 17:42:26 +00:00
|
|
|
sptr=strrchr(parm,',');
|
|
|
|
if (sptr == 0) goto perror;
|
|
|
|
signtype=atoi(sptr+1);
|
|
|
|
if (fw_description(signtype) == 0) {
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Option -g: Unknown firmware type - %i\n",signtype);
|
2017-05-06 04:01:58 +00:00
|
|
|
exit(-1);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2016-11-04 17:42:26 +00:00
|
|
|
}
|
2022-07-03 10:26:20 +00:00
|
|
|
else {
|
2016-11-04 17:42:26 +00:00
|
|
|
index=atoi(parm);
|
|
|
|
if (index >= signbaselen) goto perror;
|
|
|
|
signlen=signbase[index].len;
|
|
|
|
signtype=signbase[index].type;
|
|
|
|
}
|
|
|
|
|
|
|
|
gflag=1;
|
|
|
|
// printf("\nstr - %s",signver);
|
|
|
|
return;
|
|
|
|
|
|
|
|
perror:
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Incorrect value in option -g\n");
|
2017-05-06 04:01:58 +00:00
|
|
|
exit(-1);
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|
2016-11-05 05:13:53 +00:00
|
|
|
|
|
|
|
//***************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Sending digital signature
|
2016-11-05 05:13:53 +00:00
|
|
|
//***************************************************
|
|
|
|
void send_signver() {
|
2022-07-03 10:26:20 +00:00
|
|
|
|
2016-11-05 05:13:53 +00:00
|
|
|
uint32_t res;
|
2022-07-03 10:26:20 +00:00
|
|
|
// response to ^signver
|
2016-11-05 05:13:53 +00:00
|
|
|
unsigned char SVrsp[]={0x0d, 0x0a, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, 0x4f, 0x4b, 0x0d, 0x0a};
|
|
|
|
uint8_t replybuf[200];
|
2022-07-03 10:26:20 +00:00
|
|
|
|
|
|
|
if (gflag == 0) {
|
|
|
|
// auto-detect digital signature
|
2017-06-24 02:28:58 +00:00
|
|
|
signtype=dload_id&0x7;
|
2017-06-23 07:40:18 +00:00
|
|
|
signlen=serach_sign();
|
2022-07-03 10:26:20 +00:00
|
|
|
if (signlen == -1) return; // no signature found in the file
|
2017-06-23 07:40:18 +00:00
|
|
|
}
|
|
|
|
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n Digital Signature Type: %s (%i bytes)",fw_description(signtype),signlen);
|
2017-09-06 17:02:25 +00:00
|
|
|
sprintf(signver,"^SIGNVER=%i,0,%s,%i",signtype,signver_hash,signlen);
|
2016-11-05 05:13:53 +00:00
|
|
|
res=atcmd(signver,replybuf);
|
|
|
|
if ( (res<sizeof(SVrsp)) || (memcmp(replybuf,SVrsp,sizeof(SVrsp)) != 0) ) {
|
2022-07-03 10:26:20 +00:00
|
|
|
printf("\n ! Error checking digital signature - %02x\n",replybuf[2]);
|
2017-05-06 04:01:58 +00:00
|
|
|
exit(-2);
|
2016-11-05 05:13:53 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-22 15:01:05 +00:00
|
|
|
|
|
|
|
//***************************************************
|
2022-07-03 10:26:20 +00:00
|
|
|
//* Search for digital signature in firmware
|
2017-06-22 15:01:05 +00:00
|
|
|
//***************************************************
|
|
|
|
int32_t serach_sign() {
|
|
|
|
|
2017-09-06 17:02:25 +00:00
|
|
|
int i,j;
|
2017-06-22 15:01:05 +00:00
|
|
|
uint32_t pt;
|
|
|
|
uint32_t signsize;
|
|
|
|
|
|
|
|
for (i=0;i<2;i++) {
|
2018-02-10 15:51:17 +00:00
|
|
|
if (i == npart) break;
|
2017-06-22 15:01:05 +00:00
|
|
|
pt=*((uint32_t*)&ptable[i].pimage[ptable[i].hd.psize-4]);
|
2022-07-03 10:26:20 +00:00
|
|
|
if (pt == 0xffaaaffa) {
|
|
|
|
// signature found
|
2017-06-22 15:01:05 +00:00
|
|
|
signsize=*((uint32_t*)&ptable[i].pimage[ptable[i].hd.psize-12]);
|
2022-07-03 10:26:20 +00:00
|
|
|
// select public key hash
|
2017-09-06 17:02:25 +00:00
|
|
|
for(j=0;j<32;j++) {
|
2017-09-09 18:47:24 +00:00
|
|
|
sprintf(signver_hash+2*j,"%02X",ptable[i].pimage[ptable[i].hd.psize-signsize+6+j]);
|
2017-09-06 17:02:25 +00:00
|
|
|
}
|
2017-06-22 15:01:05 +00:00
|
|
|
return signsize;
|
|
|
|
}
|
|
|
|
}
|
2022-07-03 10:26:20 +00:00
|
|
|
// not found
|
2017-06-22 15:01:05 +00:00
|
|
|
return -1;
|
2022-07-03 10:26:20 +00:00
|
|
|
}
|