msm: msm7630/8660(emmc): Add secure boot support to appsbl

mkheader contains additional functionality to combine header+raw
appsbl(unsecure appsbl) or header+raw+signature+certificates
(secure appsbl).

Change-Id: I0acda1c57a64f653a51669a711ccb0301392e802
diff --git a/target/msm7630_surf/tools/makefile b/target/msm7630_surf/tools/makefile
index 4822edd..94f47ca 100644
--- a/target/msm7630_surf/tools/makefile
+++ b/target/msm7630_surf/tools/makefile
@@ -31,6 +31,7 @@
 	$(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn
 
 EMMCBOOT.MBN: emmc_appsboothd.mbn $(OUTBIN)
+	cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.raw
 	cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN
 	cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn
 	rm -f $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn
@@ -40,4 +41,5 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
+	cp $(SRC_DIR)/mkheader $(APPSBOOTHEADER_DIR)/mkheader
 
diff --git a/target/msm7630_surf/tools/mkheader.c b/target/msm7630_surf/tools/mkheader.c
index 1e9f2b6..29b0e18 100644
--- a/target/msm7630_surf/tools/mkheader.c
+++ b/target/msm7630_surf/tools/mkheader.c
@@ -137,6 +137,8 @@
 	base = 0;
 #endif
 
+	printf("Image Destination Pointer: 0x%x\n", base);
+
 	magic[0] = 0x00000005; /* appsbl */
 	magic[1] = 0x00000003; //Flash_partition_version /* nand */
 	magic[2] = 0x00000000; //image source pointer
@@ -175,7 +177,6 @@
 	}
 	close(fd);
 
-
 	if (secure_boot && argc > 6){
 		FILE * input_file;
 		FILE * output_file;
@@ -190,6 +191,7 @@
 			perror("ERROR: Occured during fopen");
 			return -1;
 		}
+		printf("Certificate Chain Output File: %s\n", argv[6]);
 
 		for (i = 8; i < argc; i++){
 			if((input_file = fopen(argv[i], "rb"))==NULL){
@@ -223,6 +225,7 @@
 			perror("ERROR: Occured during fopen");
 			return -1;
 		}
+		printf("Image Output File: %s\n", argv[4]);
 
 		//Header
 		if((input_file = fopen(argv[2], "rb"))==NULL){
@@ -276,6 +279,7 @@
 			perror("ERROR: Occured during fopen");
 			return -1;
 		}
+		printf("Image Output File: %s\n", argv[4]);
 
 		//Header
 		if((input_file = fopen(argv[2], "rb"))==NULL){
@@ -299,5 +303,7 @@
 		fclose(output_file);
 	}
 
+	printf("Done execution\n");
+
 	return 0;
 }
diff --git a/target/msm8660_surf/tools/makefile b/target/msm8660_surf/tools/makefile
index db458e6..7da7c6d 100755
--- a/target/msm8660_surf/tools/makefile
+++ b/target/msm8660_surf/tools/makefile
@@ -23,6 +23,7 @@
 
 
 appsboot.mbn: appsboothd.mbn $(OUTBIN)
+	cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboot.raw
 	cat $(APPSBOOTHEADER_DIR)/appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/appsboot.mbn
 	rm -f $(APPSBOOTHEADER_DIR)/appsboothd.mbn
 
@@ -30,6 +31,7 @@
 	$(SRC_DIR)/mkheader $(OUTBIN) $(APPSBOOTHEADER_DIR)/appsboothd.mbn
 
 EMMCBOOT.MBN: emmc_appsboothd.mbn $(OUTBIN)
+	cp $(OUTBIN) $(APPSBOOTHEADER_DIR)/emmc_appsboot.raw
 	cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/EMMCBOOT.MBN
 	cat $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn $(OUTBIN) > $(APPSBOOTHEADER_DIR)/emmc_appsboot.mbn
 	rm -f $(APPSBOOTHEADER_DIR)/emmc_appsboothd.mbn
@@ -39,4 +41,4 @@
 
 mkheader: $(SRC_DIR)/mkheader.c
 	${COMPILER} -DMEMBASE=$(MEMBASE) $(SRC_DIR)/mkheader.c -o $(SRC_DIR)/mkheader
-
+	cp $(SRC_DIR)/mkheader $(APPSBOOTHEADER_DIR)/mkheader
diff --git a/target/msm8660_surf/tools/mkheader.c b/target/msm8660_surf/tools/mkheader.c
index 2eb73e2..29b0e18 100755
--- a/target/msm8660_surf/tools/mkheader.c
+++ b/target/msm8660_surf/tools/mkheader.c
@@ -35,88 +35,275 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <string.h>
 
 #include <sys/stat.h>
 
+int print_usage(){
+	fprintf(stderr,"usage: mkheader <bin> <hdr> <none|unified-boot>\n");
+	fprintf(stderr,"       mkheader <bin> <hdr> <unsecure-boot> <outbin>\n");
+	fprintf(stderr,"       mkheader <bin> <hdr> <secure-boot> <outbin> <maxsize>\n");
+	fprintf(stderr,"       mkheader <bin> <hdr> <secure-boot> <outbin> <maxsize> <certchain> <files...>\n\n");
+	fprintf(stderr,"bin:               Input raw appsbl binary\n");
+	fprintf(stderr,"hdr:               Output of appsbl header location\n");
+	fprintf(stderr,"outbin:            Output of the signed or unsigned apps boot location\n");
+	fprintf(stderr,"maxsize:           Maximum size for certificate chain\n");
+	fprintf(stderr,"certchain:         Output of the certchain location\n");
+	fprintf(stderr,"files:             Input format <bin signature> <certifcate file(s) for certificate chain>...\n");
+	fprintf(stderr,"certificate chain: Files will be concatenated in order to create the certificate chain\n\n");
+	return -1;
+}
+
+int cat(FILE * in, FILE * out, unsigned size, unsigned buff_size){
+	unsigned bytes_left = size;
+	char buf[buff_size];
+	int ret = 0;
+
+	while(bytes_left){
+		fread(buf, sizeof(char), buff_size, in);
+		if(!feof(in)){
+			bytes_left -= fwrite(buf, sizeof(char), buff_size, out);
+		}else
+			bytes_left = 0;
+	}
+	ret = ferror(in) | ferror(out);
+	if(ret)
+		fprintf(stderr, "ERROR: Occured during file concatenation\n");
+	return ret;
+}
+
 int main(int argc, char *argv[])
 {
-    struct stat s;
-    unsigned size, base;
-    int unified_boot = 0;
-    unsigned unified_boot_magic[20];
-    unsigned non_unified_boot_magic[10];
-    unsigned magic_len = 0;
-    unsigned *magic;
-    int fd;
+	struct stat s;
+	unsigned size, base;
+	int unified_boot = 0;
+	unsigned unified_boot_magic[20];
+	unsigned non_unified_boot_magic[10];
+	unsigned magic_len = 0;
+	unsigned *magic;
+	unsigned cert_chain_size = 0;
+	unsigned signature_size = 0;
+	int secure_boot = 0;
+	int fd;
 
-    if(argc < 3) {
-        fprintf(stderr,"usage: mkheader <bin> <hdr>\n");
-        return -1;
-    }
+	if(argc < 3) {
+		return print_usage();
+	}
 
-    if (argc == 4) {
-        if(!strcmp("unified-boot",argv[3])) {
-            unified_boot = 1;
-        }
-    }
+	if (argc == 4) {
+		if(!strcmp("unified-boot",argv[3])) {
+			unified_boot = 1;
+		}else if(!strcmp("secure-boot",argv[3])){
+			fprintf(stderr,
+				"ERROR: Missing arguments: [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n");
+			return print_usage();
+		}
+		else if(!strcmp("unsecure-boot",argv[3])){
+			fprintf(stderr,"ERROR: Missing arguments: outbin directory\n");
+			return print_usage();
+		}
+	}
 
-    if(stat(argv[1], &s)) {
-        perror("cannot stat binary");
-        return -1;
-    }
+	if (argc > 4) {
+		if(!strcmp("secure-boot",argv[3])) {
+			if(argc < 9 && argc != 6){
+				fprintf(stderr,
+					"ERROR: Missing argument(s): [outbin maxsize] | [outbin, maxsize, certchain, signature + certifcate(s)]\n");
+				return print_usage();
+	  		}
+       			secure_boot = 1;
+	  		signature_size = 256; //Support SHA 256
+			cert_chain_size = atoi(argv[5]);
+	  	}
+	}
 
-    if(unified_boot) {
-        magic = unified_boot_magic;
-        magic_len = sizeof(unified_boot_magic);
-    } else {
-        magic = non_unified_boot_magic;
-        magic_len = sizeof(non_unified_boot_magic);
-    }
+	if(stat(argv[1], &s)) {
+		perror("cannot stat binary");
+		return -1;
+	}
 
-    size = s.st_size;
+	if(unified_boot) {
+		magic = unified_boot_magic;
+		magic_len = sizeof(unified_boot_magic);
+	} else {
+		magic = non_unified_boot_magic;
+		magic_len = sizeof(non_unified_boot_magic);
+	}
+
+	size = s.st_size;
 #if MEMBASE
-    base = MEMBASE;
+	base = MEMBASE;
 #else
-    base = 0;
+	base = 0;
 #endif
 
-    magic[0] = 0x00000005; /* appsbl */
-    magic[1] = 0x00000002; /* nand */
-    magic[2] = 0x00000000;
-    magic[3] = base;
-    magic[4] = size;
-    magic[5] = size;
-    magic[6] = size + base;
-    magic[7] = 0x00000000;
-    magic[8] = size + base;
-    magic[9] = 0x00000000;
+	printf("Image Destination Pointer: 0x%x\n", base);
 
-    if (unified_boot == 1)
-    {
-        magic[10] = 0x33836685; /* cookie magic number */
-        magic[11] = 0x00000001; /* cookie version */
-        magic[12] = 0x00000002; /* file formats */
-        magic[13] = 0x00000000;
-        magic[14] = 0x00500000; /* 5M for boot.img */
-        magic[15] = 0x00000000;
-        magic[16] = 0x00000000;
-        magic[17] = 0x00000000;
-        magic[18] = 0x00000000;
-        magic[19] = 0x00000000;
-    }
+	magic[0] = 0x00000005; /* appsbl */
+	magic[1] = 0x00000003; //Flash_partition_version /* nand */
+	magic[2] = 0x00000000; //image source pointer
+	magic[3] = base;       //image destination pointer
+	magic[4] = size + cert_chain_size + signature_size; //image size
+	magic[5] = size;       //code size
+	magic[6] = base + size;
+	magic[7] = signature_size;
+	magic[8] = size + base + signature_size;
+	magic[9] = cert_chain_size;
 
-    fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
-    if(fd < 0) {
-        perror("cannot open header for writing");
-        return -1;
-    }
-    if(write(fd, magic, magic_len) != magic_len) {
-        perror("cannot write header");
-        close(fd);
-        unlink(argv[2]);
-        return -1;
-    }
-    close(fd);
+	if (unified_boot == 1)
+	{
+		magic[10] = 0x33836685; /* cookie magic number */
+		magic[11] = 0x00000001; /* cookie version */
+		magic[12] = 0x00000002; /* file formats */
+		magic[13] = 0x00000000;
+		magic[14] = 0x00000000; /* not setting size for boot.img */
+		magic[15] = 0x00000000;
+		magic[16] = 0x00000000;
+		magic[17] = 0x00000000;
+		magic[18] = 0x00000000;
+		magic[19] = 0x00000000;
+	}
 
-    return 0;
+	fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
+	if(fd < 0) {
+		perror("cannot open header for writing");
+		return -1;
+	}
+	if(write(fd, magic, magic_len) != magic_len) {
+		perror("cannot write header");
+		close(fd);
+		unlink(argv[2]);
+		return -1;
+	}
+	close(fd);
+
+	if (secure_boot && argc > 6){
+		FILE * input_file;
+		FILE * output_file;
+		unsigned buff_size = 1;
+		char buf[buff_size];
+		unsigned bytes_left;
+		unsigned current_cert_chain_size = 0;
+		int padding_size = 0;
+		int i;
+
+		if((output_file = fopen(argv[6], "wb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		printf("Certificate Chain Output File: %s\n", argv[6]);
+
+		for (i = 8; i < argc; i++){
+			if((input_file = fopen(argv[i], "rb"))==NULL){
+				perror("ERROR: Occured during fopen");
+				return -1;
+			}
+			stat(argv[i], &s);
+			bytes_left = s.st_size;
+			current_cert_chain_size += bytes_left;
+			if (cat(input_file, output_file, bytes_left, buff_size))
+				return -1;
+			fclose(input_file);
+		}
+
+		//Pad certifcate chain to the max expected size from input
+		memset(buf, 0xFF, sizeof(buf));
+		padding_size = cert_chain_size - current_cert_chain_size;
+		bytes_left = (padding_size > 0) ? padding_size : 0;
+		while(bytes_left){
+			if(!ferror(output_file))
+				bytes_left -= fwrite(buf, sizeof(buf), buff_size, output_file);
+			else{
+				fprintf(stderr, "ERROR: Occured during certifcate chain padding\n");
+				return -1;
+			}
+		}
+		fclose(output_file);
+
+		//Concat and combine to signed image. Format [HDR][RAW APPSBOOT][PADDED CERT CHAIN]
+		if((output_file = fopen(argv[4], "wb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		printf("Image Output File: %s\n", argv[4]);
+
+		//Header
+		if((input_file = fopen(argv[2], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		stat(argv[2], &s);
+		if (cat(input_file, output_file, s.st_size, buff_size))
+			return -1;
+		fclose(input_file);
+
+		//Raw Appsbl
+		if((input_file = fopen(argv[1], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		stat(argv[1], &s);
+		if(cat(input_file, output_file, s.st_size, buff_size))
+			return -1;
+		fclose(input_file);
+
+		//Signature
+		if((input_file = fopen(argv[7], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		stat(argv[7], &s);
+		if(cat(input_file, output_file, s.st_size, buff_size))
+			return -1;
+		fclose(input_file);
+
+		//Certifcate Chain
+		if((input_file = fopen(argv[6], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		if(cat(input_file, output_file, (current_cert_chain_size + padding_size), buff_size))
+			return -1;
+		fclose(input_file);
+
+		fclose(output_file);
+
+	}else if(argc == 5 || argc == 6){
+		FILE * input_file;
+		FILE * output_file;
+		unsigned buff_size = 1;
+		char buf[buff_size];
+
+		//Concat and combine to unsigned image. Format [HDR][RAW APPSBOOT]
+		if((output_file = fopen(argv[4], "wb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		printf("Image Output File: %s\n", argv[4]);
+
+		//Header
+		if((input_file = fopen(argv[2], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		stat(argv[2], &s);
+		if (cat(input_file, output_file, s.st_size, buff_size))
+			return -1;
+		fclose(input_file);
+
+		//Raw Appsbl
+		if((input_file = fopen(argv[1], "rb"))==NULL){
+			perror("ERROR: Occured during fopen");
+			return -1;
+		}
+		stat(argv[1], &s);
+		if(cat(input_file, output_file, s.st_size, buff_size))
+			return -1;
+		fclose(input_file);
+		fclose(output_file);
+	}
+
+	printf("Done execution\n");
+
+	return 0;
 }