2 * Copyright (C) 2016 Raptor Engineering, LLC
3 * Copyright (C) 2018 Opengear, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #if defined(HAVE_CONFIG_H)
30 #include <sys/types.h>
33 #include <file/file.h>
34 #include <talloc/talloc.h>
36 #include <util/util.h>
37 #include <i18n/i18n.h>
41 struct pb_url * get_signature_url(void *ctx, struct pb_url *base_file)
43 struct pb_url *signature_file = NULL;
45 signature_file = pb_url_copy(ctx, base_file);
46 talloc_free(signature_file->file);
47 signature_file->file = talloc_asprintf(signature_file,
48 "%s.sig", base_file->file);
49 talloc_free(signature_file->path);
50 signature_file->path = talloc_asprintf(signature_file,
51 "%s.sig", base_file->path);
53 return signature_file;
56 int validate_boot_files(struct boot_task *boot_task) {
58 char *kernel_filename = NULL;
59 char *initrd_filename = NULL;
60 char *dtb_filename = NULL;
62 FILE *authorized_signatures_handle = NULL;
64 char cmdline_template[] = "/tmp/petitbootXXXXXX";
65 int cmdline_fd = mkstemp(cmdline_template);
66 FILE *cmdline_handle = NULL;
68 const char* local_initrd_signature = (boot_task->verify_signature) ?
69 boot_task->local_initrd_signature : NULL;
70 const char* local_dtb_signature = (boot_task->verify_signature) ?
71 boot_task->local_dtb_signature : NULL;
72 const char* local_image_signature = (boot_task->verify_signature) ?
73 boot_task->local_image_signature : NULL;
74 const char* local_cmdline_signature =
75 (boot_task->verify_signature || boot_task->decrypt_files) ?
76 boot_task->local_cmdline_signature : NULL;
78 if ((!boot_task->verify_signature) && (!boot_task->decrypt_files))
81 /* Load authorized signatures file */
82 authorized_signatures_handle = fopen(LOCKDOWN_FILE, "r");
83 if (!authorized_signatures_handle) {
84 pb_log("%s: unable to read lockdown file\n", __func__);
85 return KEXEC_LOAD_SIG_SETUP_INVALID;
88 /* Copy files to temporary directory for verification / boot */
89 result = copy_file_secure_dest(boot_task,
90 boot_task->local_image,
93 pb_log("%s: image copy failed: (%d)\n",
97 if (boot_task->local_initrd) {
98 result = copy_file_secure_dest(boot_task,
99 boot_task->local_initrd,
102 pb_log("%s: initrd copy failed: (%d)\n",
107 if (boot_task->local_dtb) {
108 result = copy_file_secure_dest(boot_task,
109 boot_task->local_dtb,
112 pb_log("%s: dtb copy failed: (%d)\n",
117 boot_task->local_image_override = talloc_strdup(boot_task,
119 if (boot_task->local_initrd)
120 boot_task->local_initrd_override = talloc_strdup(boot_task,
122 if (boot_task->local_dtb)
123 boot_task->local_dtb_override = talloc_strdup(boot_task,
126 /* Write command line to temporary file for verification */
127 if (cmdline_fd < 0) {
129 pb_log("%s: failed: unable to create command line"
130 " temporary file for verification\n",
135 cmdline_handle = fdopen(cmdline_fd, "w");
137 if (!cmdline_handle) {
138 /* Failed to open file */
139 pb_log("%s: failed: unable to write command line"
140 " temporary file for verification\n",
145 fwrite(boot_task->args, sizeof(char),
146 strlen(boot_task->args), cmdline_handle);
147 fflush(cmdline_handle);
150 if (boot_task->verify_signature) {
151 /* Check signatures */
152 if (verify_file_signature(kernel_filename,
153 local_image_signature,
154 authorized_signatures_handle,
156 result = KEXEC_LOAD_SIGNATURE_FAILURE;
157 if (verify_file_signature(cmdline_template,
158 local_cmdline_signature,
159 authorized_signatures_handle,
161 result = KEXEC_LOAD_SIGNATURE_FAILURE;
163 if (boot_task->local_initrd_signature)
164 if (verify_file_signature(initrd_filename,
165 local_initrd_signature,
166 authorized_signatures_handle,
168 result = KEXEC_LOAD_SIGNATURE_FAILURE;
169 if (boot_task->local_dtb_signature)
170 if (verify_file_signature(dtb_filename,
172 authorized_signatures_handle,
174 result = KEXEC_LOAD_SIGNATURE_FAILURE;
177 if (cmdline_handle) {
178 fclose(cmdline_handle);
179 unlink(cmdline_template);
181 fclose(authorized_signatures_handle);
182 } else if (boot_task->decrypt_files) {
184 if (decrypt_file(kernel_filename,
185 authorized_signatures_handle,
187 result = KEXEC_LOAD_DECRYPTION_FALURE;
188 if (verify_file_signature(cmdline_template,
189 local_cmdline_signature,
190 authorized_signatures_handle,
192 result = KEXEC_LOAD_SIGNATURE_FAILURE;
193 if (boot_task->local_initrd)
194 if (decrypt_file(initrd_filename,
195 authorized_signatures_handle,
197 result = KEXEC_LOAD_DECRYPTION_FALURE;
198 if (boot_task->local_dtb)
199 if (decrypt_file(dtb_filename,
200 authorized_signatures_handle,
202 result = KEXEC_LOAD_DECRYPTION_FALURE;
205 if (cmdline_handle) {
206 fclose(cmdline_handle);
207 unlink(cmdline_template);
209 fclose(authorized_signatures_handle);
215 void validate_boot_files_cleanup(struct boot_task *boot_task) {
216 if ((boot_task->verify_signature) || (boot_task->decrypt_files)) {
217 unlink(boot_task->local_image_override);
218 if (boot_task->local_initrd_override)
219 unlink(boot_task->local_initrd_override);
220 if (boot_task->local_dtb_override)
221 unlink(boot_task->local_dtb_override);
223 talloc_free(boot_task->local_image_override);
224 if (boot_task->local_initrd_override)
225 talloc_free(boot_task->local_initrd_override);
226 if (boot_task->local_dtb_override)
227 talloc_free(boot_task->local_dtb_override);