blob: 58d4a399898c186e162ba4a4886a0c32ac5e3151 [file] [log] [blame]
Daisuke Nojirie1741c52015-02-09 18:15:17 -08001/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Daisuke Nojirie1741c52015-02-09 18:15:17 -080014#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <unistd.h>
Stefan Reinauer03597d02015-08-06 16:57:48 -070020#include <zlib.h>
Daisuke Nojirie1741c52015-02-09 18:15:17 -080021#include "secimage.h"
22
23#define MIN_SIZE (1024*120)
24
25/*----------------------------------------------------------------------
26 * Name : SBIUsage
27 * Purpose :
28 * Input : none
29 * Output : none
30 *---------------------------------------------------------------------*/
31int SBIUsage(void)
32{
33 printf("\nTo create a Secure Boot Image:\n");
34 printf("secimage: -out <output binary> [-hmac hmac_binary_key] <-config configfile>");
35 printf("\n\t\t[-bl input binary]\n");
36 return 0;
37}
38
39/*----------------------------------------------------------------------
40 * Name : AddImagePayload
41 * Purpose :
42 * Input : none
43 * Output : none
44 *---------------------------------------------------------------------*/
45int AddImagePayload(char *h, char *filename, unsigned int filesize)
46{
47 uint32_t totalLen;
48 int length = filesize;
49 int padlen = 0;
50 int status = 0;
51
52 totalLen = 0x40;
53
54 status = DataRead(filename, (uint8_t *)h + totalLen, &length);
55 printf("\r\n Adding file %s ... \r\n", filename);
56 if (!status) {
57 if (length & 15) {
58 padlen = 16 - (length & 15);
59 memset((uint8_t *)h + totalLen + length, 0, padlen);
60 length += padlen;
61 }
62
63 *(uint32_t *)&h[FIELD5_OFFSET] = length;
64 *(uint32_t *)&h[FIELD6_OFFSET] += length;
65
66 } else
67 printf("Error reading image Payload from %s\n", filename);
68
69 return status;
70}
71
72/*----------------------------------------------------------------------
73 * Name : CreateSecureBootImage
74 * Purpose :
75 * Input : none
76 * Output : none
77 *---------------------------------------------------------------------*/
78int CreateSecureBootImage(int ac, char **av)
79{
80 char *outfile, *configfile, *arg, *privkey = NULL, *bl = NULL;
81 int status = 0;
82 uint32_t sbiLen;
83 struct stat file_stat;
84 uint32_t add_header = 1;
85 outfile = *av;
86 unsigned int filesize;
87 char *buf;
88 --ac; ++av;
89
90 if (ac <= 0)
91 return SBIUsage();
92
93 while (ac) {
94 arg = *av;
95 if (!strcmp(arg, "-bl")) {
96 --ac, ++av;
97 bl = *av;
98 } else if (!strcmp(arg, "-hmac")) {
99 --ac, ++av;
100 privkey = *av;
101 } else if (!strcmp(arg, "-config")) {
102 --ac, ++av;
103 configfile = *av;
104 } else if (!strcmp(arg, "-noheader")) {
105 add_header = 0;
106 } else {
107 return SBIUsage();
108 }
109 --ac, ++av;
110 }
111
112 stat(bl, &file_stat);
113 filesize = file_stat.st_size + MIN_SIZE;
114 buf = calloc(sizeof(uint8_t), filesize);
115
116 if (buf == NULL) {
117 puts("Memory allocation error");
118 status = -1;
119 goto done;
120 }
121
122 *(uint32_t *)&buf[FIELD6_OFFSET] = 0x40;
123 *(uint32_t *)&buf[FIELD9_OFFSET] = 0x45F2D99A;
124 *(uint32_t *)&buf[FIELD3_OFFSET] = 0x900FFFFF;
125 *(uint16_t *)&buf[FIELD1_OFFSET] = 0x40;
126 *(uint32_t *)&buf[FIELD4_OFFSET] = 0x40;
127 *(uint16_t *)&buf[FIELD2_OFFSET] = 0x10;
128 *(uint16_t *)&buf[FIELD8_OFFSET] = 0x20;
129 *(uint16_t *)&buf[FIELD7_OFFSET] = 0x10;
130
131 if (status == 0) {
132
133 if (configfile)
134 FillHeaderFromConfigFile(buf, configfile);
135
136 status = AddImagePayload(buf, bl, filesize);
137 if (status) {
138 status = -1;
139 goto done;
140 }
141
142 sbiLen = *(uint32_t *)&buf[FIELD6_OFFSET];
143
144 printf("HMAC signing %d bytes\n", sbiLen);
145 status = AppendHMACSignature((uint8_t *)buf, sbiLen, privkey,
146 add_header ? 0x10 : 0x40);
147 if (status > 0) {
148 sbiLen += status;
149 status = 0;
150 }
151
152 if (!status) {
153 ((HEADER *)buf)->Length = sbiLen;
Stefan Reinauer03597d02015-08-06 16:57:48 -0700154 ((HEADER *)buf)->crc = crc32(0xFFFFFFFF,
Daisuke Nojirie1741c52015-02-09 18:15:17 -0800155 (uint8_t *)buf, 12);
156
157 printf("Generating Image file %s: %d bytes\n",
158 outfile, sbiLen);
159 if (!add_header)
160 status = DataWrite(outfile, &buf[0x40],
161 sbiLen - 0x40);
162 else
163 status = DataWrite(outfile, buf, sbiLen);
164 }
165 }
166 if (status < 0)
167 printf("Generation error %d\n", status);
168
169done:
170 free(buf);
171 return status;
172}
173
174int main(int argc, char **argv)
175{
176 argc--;
177 argv++;
178 if (argc > 0) {
179 if (!strcmp(*argv, "-out"))
180 return CreateSecureBootImage(--argc, ++argv);
181 }
182 SBIUsage();
183 return 0;
184}