Merge "msm: msm7630(nand): Add secure boot support to appsbl"
diff --git a/target/msm7630_surf/tools/makefile b/target/msm7630_surf/tools/makefile
index db458e6..4822edd 100644
--- a/target/msm7630_surf/tools/makefile
+++ b/target/msm7630_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
 
diff --git a/target/msm7630_surf/tools/mkheader.c b/target/msm7630_surf/tools/mkheader.c
index c7ad742..1e9f2b6 100644
--- a/target/msm7630_surf/tools/mkheader.c
+++ b/target/msm7630_surf/tools/mkheader.c
@@ -1,12 +1,77 @@
-/* Copyright 2007, Google Inc. */
+/*
+ * Copyright (c) 2007, Google Inc.
+ * All rights reserved.
+ *
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of Google, Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 #include <stdio.h>
 #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;
@@ -16,17 +81,40 @@
 	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;
+		return print_usage();
 	}
 
 	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 (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(stat(argv[1], &s)) {
@@ -50,15 +138,15 @@
 #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;
+	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;
 
 	if (unified_boot == 1)
 	{
@@ -87,5 +175,129 @@
 	}
 	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;
+		}
+
+		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;
+		}
+
+		//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;
+		}
+
+		//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);
+	}
+
 	return 0;
 }