blob: 12e1327ec640fe5b328f3537e742de4f7cbfb4f7 [file] [log] [blame]
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <stdint.h>
11#include <stddef.h>
12#include <string.h>
13#include <unistd.h>
14#include <sys/stat.h>
15#include <sys/time.h>
16
17#ifdef CONFIG_MVEBU_SECURE_BOOT
18#include <libconfig.h> /* for parsing config file */
19
Konstantin Porotchkin434e0292018-02-26 16:28:40 +020020/* mbedTLS stuff */
Henrik Nordstrom8eb4efe2023-12-04 10:31:07 +010021#include <mbedtls/version.h>
Konstantin Porotchkin434e0292018-02-26 16:28:40 +020022#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
23 defined(MBEDTLS_SHA256_C) && \
24 defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
25 defined(MBEDTLS_CTR_DRBG_C)
26#include <mbedtls/error.h>
27#include <mbedtls/entropy.h>
28#include <mbedtls/ctr_drbg.h>
29#include <mbedtls/md.h>
30#include <mbedtls/pk.h>
31#include <mbedtls/sha256.h>
32#include <mbedtls/x509.h>
33#else
34#error "Bad mbedTLS configuration!"
35#endif
36#endif /* CONFIG_MVEBU_SECURE_BOOT */
37
38#define MAX_FILENAME 256
39#define CSK_ARR_SZ 16
40#define CSK_ARR_EMPTY_FILE "*"
41#define AES_KEY_BIT_LEN 256
42#define AES_KEY_BYTE_LEN (AES_KEY_BIT_LEN >> 3)
43#define AES_BLOCK_SZ 16
44#define RSA_SIGN_BYTE_LEN 256
45#define MAX_RSA_DER_BYTE_LEN 524
46/* Number of address pairs in control array */
47#define CP_CTRL_EL_ARRAY_SZ 32
48
Konstantin Porotchkina79df342019-05-01 17:08:18 +030049#define VERSION_STRING "Marvell(C) doimage utility version 3.3"
Konstantin Porotchkin434e0292018-02-26 16:28:40 +020050
51/* A8K definitions */
52
53/* Extension header types */
54#define EXT_TYPE_SECURITY 0x1
55#define EXT_TYPE_BINARY 0x2
56
57#define MAIN_HDR_MAGIC 0xB105B002
58
59/* PROLOG alignment considerations:
60 * 128B: To allow supporting XMODEM protocol.
61 * 8KB: To align the boot image to the largest NAND page size, and simplify
62 * the read operations from NAND.
63 * We choose the largest page size, in order to use a single image for all
64 * NAND page sizes.
65 */
66#define PROLOG_ALIGNMENT (8 << 10)
67
68/* UART argument bitfield */
69#define UART_MODE_UNMODIFIED 0x0
70#define UART_MODE_DISABLE 0x1
71#define UART_MODE_UPDATE 0x2
72
73typedef struct _main_header {
74 uint32_t magic; /* 0-3 */
75 uint32_t prolog_size; /* 4-7 */
76 uint32_t prolog_checksum; /* 8-11 */
77 uint32_t boot_image_size; /* 12-15 */
78 uint32_t boot_image_checksum; /* 16-19 */
79 uint32_t rsrvd0; /* 20-23 */
80 uint32_t load_addr; /* 24-27 */
81 uint32_t exec_addr; /* 28-31 */
82 uint8_t uart_cfg; /* 32 */
83 uint8_t baudrate; /* 33 */
84 uint8_t ext_count; /* 34 */
85 uint8_t aux_flags; /* 35 */
86 uint32_t io_arg_0; /* 36-39 */
87 uint32_t io_arg_1; /* 40-43 */
88 uint32_t io_arg_2; /* 43-47 */
89 uint32_t io_arg_3; /* 48-51 */
90 uint32_t rsrvd1; /* 52-55 */
91 uint32_t rsrvd2; /* 56-59 */
92 uint32_t rsrvd3; /* 60-63 */
93} header_t;
94
95typedef struct _ext_header {
96 uint8_t type;
97 uint8_t offset;
98 uint16_t reserved;
99 uint32_t size;
100} ext_header_t;
101
102typedef struct _sec_entry {
103 uint8_t kak_key[MAX_RSA_DER_BYTE_LEN];
104 uint32_t jtag_delay;
105 uint32_t box_id;
106 uint32_t flash_id;
107 uint32_t jtag_en;
108 uint32_t encrypt_en;
109 uint32_t efuse_dis;
110 uint8_t header_sign[RSA_SIGN_BYTE_LEN];
111 uint8_t image_sign[RSA_SIGN_BYTE_LEN];
112 uint8_t csk_keys[CSK_ARR_SZ][MAX_RSA_DER_BYTE_LEN];
113 uint8_t csk_sign[RSA_SIGN_BYTE_LEN];
114 uint32_t cp_ctrl_arr[CP_CTRL_EL_ARRAY_SZ];
115 uint32_t cp_efuse_arr[CP_CTRL_EL_ARRAY_SZ];
116} sec_entry_t;
117
118/* A8K definitions end */
119
120/* UART argument bitfield */
121#define UART_MODE_UNMODIFIED 0x0
122#define UART_MODE_DISABLE 0x1
123#define UART_MODE_UPDATE 0x2
124
125#define uart_set_mode(arg, mode) (arg |= (mode & 0x3))
126
127typedef struct _sec_options {
128#ifdef CONFIG_MVEBU_SECURE_BOOT
129 char aes_key_file[MAX_FILENAME+1];
130 char kak_key_file[MAX_FILENAME+1];
131 char csk_key_file[CSK_ARR_SZ][MAX_FILENAME+1];
132 uint32_t box_id;
133 uint32_t flash_id;
134 uint32_t jtag_delay;
135 uint8_t csk_index;
136 uint8_t jtag_enable;
137 uint8_t efuse_disable;
138 uint32_t cp_ctrl_arr[CP_CTRL_EL_ARRAY_SZ];
139 uint32_t cp_efuse_arr[CP_CTRL_EL_ARRAY_SZ];
140 mbedtls_pk_context kak_pk;
141 mbedtls_pk_context csk_pk[CSK_ARR_SZ];
142 uint8_t aes_key[AES_KEY_BYTE_LEN];
143 uint8_t *encrypted_image;
144 uint32_t enc_image_sz;
145#endif
146} sec_options;
147
148typedef struct _options {
149 char bin_ext_file[MAX_FILENAME+1];
150 char sec_cfg_file[MAX_FILENAME+1];
151 sec_options *sec_opts;
152 uint32_t load_addr;
153 uint32_t exec_addr;
154 uint32_t baudrate;
155 uint8_t disable_print;
156 int8_t key_index; /* For header signatures verification only */
157 uint32_t nfc_io_args;
158} options_t;
159
160void usage_err(char *msg)
161{
162 fprintf(stderr, "Error: %s\n", msg);
163 fprintf(stderr, "run 'doimage -h' to get usage information\n");
164 exit(-1);
165}
166
167void usage(void)
168{
169 printf("\n\n%s\n\n", VERSION_STRING);
170 printf("Usage: doimage [options] <input_file> [output_file]\n");
171 printf("create bootrom image from u-boot and boot extensions\n\n");
172
173 printf("Arguments\n");
174 printf(" input_file name of boot image file.\n");
175 printf(" if -p is used, name of the bootrom image file");
176 printf(" to parse.\n");
177 printf(" output_file name of output bootrom image file\n");
178
179 printf("\nOptions\n");
180 printf(" -s target SOC name. supports a8020,a7020\n");
181 printf(" different SOCs may have different boot image\n");
182 printf(" format so it's mandatory to know the target SOC\n");
183 printf(" -i boot I/F name. supports nand, spi, nor\n");
184 printf(" This affects certain parameters coded in the\n");
185 printf(" image header\n");
186 printf(" -l boot image load address. default is 0x0\n");
187 printf(" -e boot image entry address. default is 0x0\n");
188 printf(" -b binary extension image file.\n");
189 printf(" This image is executed before the boot image.\n");
190 printf(" This is typically used to initialize the memory ");
191 printf(" controller.\n");
192 printf(" Currently supports only a single file.\n");
193#ifdef CONFIG_MVEBU_SECURE_BOOT
194 printf(" -c Make trusted boot image using parameters\n");
195 printf(" from the configuration file.\n");
196#endif
197 printf(" -p Parse and display a pre-built boot image\n");
198#ifdef CONFIG_MVEBU_SECURE_BOOT
199 printf(" -k Key index for RSA signatures verification\n");
200 printf(" when parsing the boot image\n");
201#endif
202 printf(" -m Disable prints of bootrom and binary extension\n");
203 printf(" -u UART baudrate used for bootrom prints.\n");
204 printf(" Must be multiple of 1200\n");
205 printf(" -h Show this help message\n");
206 printf(" IO-ROM NFC-NAND boot parameters:\n");
207 printf(" -n NAND device block size in KB [Default is 64KB].\n");
208 printf(" -t NAND cell technology (SLC [Default] or MLC)\n");
209
210 exit(-1);
211}
212
213/* globals */
Matteo Crocefd10a0a2018-09-24 02:27:21 +0200214static options_t opts = {
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200215 .bin_ext_file = "NA",
216 .sec_cfg_file = "NA",
217 .sec_opts = 0,
218 .load_addr = 0x0,
219 .exec_addr = 0x0,
220 .disable_print = 0,
221 .baudrate = 0,
222 .key_index = -1,
223};
224
225int get_file_size(char *filename)
226{
227 struct stat st;
228
229 if (stat(filename, &st) == 0)
230 return st.st_size;
231
232 return -1;
233}
234
235uint32_t checksum32(uint32_t *start, int len)
236{
237 uint32_t sum = 0;
238 uint32_t *startp = start;
239
240 do {
241 sum += *startp;
242 startp++;
243 len -= 4;
244 } while (len > 0);
245
246 return sum;
247}
248
249/*******************************************************************************
250 * create_rsa_signature (memory buffer content)
251 * Create RSASSA-PSS/SHA-256 signature for memory buffer
252 * using RSA Private Key
253 * INPUT:
254 * pk_ctx Private Key context
255 * input memory buffer
256 * ilen buffer length
257 * pers personalization string for seeding the RNG.
258 * For instance a private key file name.
259 * OUTPUT:
260 * signature RSA-2048 signature
261 * RETURN:
262 * 0 on success
263 */
264#ifdef CONFIG_MVEBU_SECURE_BOOT
265int create_rsa_signature(mbedtls_pk_context *pk_ctx,
266 const unsigned char *input,
267 size_t ilen,
268 const char *pers,
269 uint8_t *signature)
270{
271 mbedtls_entropy_context entropy;
272 mbedtls_ctr_drbg_context ctr_drbg;
273 unsigned char hash[32];
274 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
275 int rval;
276
277 /* Not sure this is required,
278 * but it's safer to start with empty buffers
279 */
280 memset(hash, 0, sizeof(hash));
281 memset(buf, 0, sizeof(buf));
282
283 mbedtls_ctr_drbg_init(&ctr_drbg);
284 mbedtls_entropy_init(&entropy);
285
286 /* Seed the random number generator */
287 rval = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
288 (const unsigned char *)pers, strlen(pers));
289 if (rval != 0) {
290 fprintf(stderr, " Failed in ctr_drbg_init call (%d)!\n", rval);
291 goto sign_exit;
292 }
293
294 /* The PK context should be already initialized.
295 * Set the padding type for this PK context
296 */
297 mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk_ctx),
298 MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
299
300 /* First compute the SHA256 hash for the input blob */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300301 mbedtls_sha256_ret(input, ilen, hash, 0);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200302
303 /* Then calculate the hash signature */
304 rval = mbedtls_rsa_rsassa_pss_sign(mbedtls_pk_rsa(*pk_ctx),
305 mbedtls_ctr_drbg_random,
306 &ctr_drbg,
307 MBEDTLS_RSA_PRIVATE,
308 MBEDTLS_MD_SHA256, 0, hash, buf);
309 if (rval != 0) {
310 fprintf(stderr,
311 "Failed to create RSA signature for %s. Error %d\n",
312 pers, rval);
313 goto sign_exit;
314 }
315 memcpy(signature, buf, 256);
316
317sign_exit:
318 mbedtls_ctr_drbg_free(&ctr_drbg);
319 mbedtls_entropy_free(&entropy);
320
321 return rval;
322} /* end of create_rsa_signature */
323
324/*******************************************************************************
325 * verify_rsa_signature (memory buffer content)
326 * Verify RSASSA-PSS/SHA-256 signature for memory buffer
327 * using RSA Public Key
328 * INPUT:
329 * pub_key Public Key buffer
330 * ilen Public Key buffer length
331 * input memory buffer
332 * ilen buffer length
333 * pers personalization string for seeding the RNG.
334 * signature RSA-2048 signature
335 * OUTPUT:
336 * none
337 * RETURN:
338 * 0 on success
339 */
340int verify_rsa_signature(const unsigned char *pub_key,
341 size_t klen,
342 const unsigned char *input,
343 size_t ilen,
344 const char *pers,
345 uint8_t *signature)
346{
347 mbedtls_entropy_context entropy;
348 mbedtls_ctr_drbg_context ctr_drbg;
349 mbedtls_pk_context pk_ctx;
350 unsigned char hash[32];
351 int rval;
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300352 unsigned char *pkey = (unsigned char *)pub_key;
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200353
354 /* Not sure this is required,
355 * but it's safer to start with empty buffer
356 */
357 memset(hash, 0, sizeof(hash));
358
359 mbedtls_pk_init(&pk_ctx);
360 mbedtls_ctr_drbg_init(&ctr_drbg);
361 mbedtls_entropy_init(&entropy);
362
363 /* Seed the random number generator */
364 rval = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
365 (const unsigned char *)pers, strlen(pers));
366 if (rval != 0) {
367 fprintf(stderr, " Failed in ctr_drbg_init call (%d)!\n", rval);
368 goto verify_exit;
369 }
370
371 /* Check ability to read the public key */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300372 rval = mbedtls_pk_parse_subpubkey(&pkey, pub_key + klen, &pk_ctx);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200373 if (rval != 0) {
374 fprintf(stderr, " Failed in pk_parse_public_key (%#x)!\n",
375 rval);
376 goto verify_exit;
377 }
378
379 /* Set the padding type for the new PK context */
380 mbedtls_rsa_set_padding(mbedtls_pk_rsa(pk_ctx),
381 MBEDTLS_RSA_PKCS_V21,
382 MBEDTLS_MD_SHA256);
383
384 /* Compute the SHA256 hash for the input buffer */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300385 mbedtls_sha256_ret(input, ilen, hash, 0);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200386
387 rval = mbedtls_rsa_rsassa_pss_verify(mbedtls_pk_rsa(pk_ctx),
388 mbedtls_ctr_drbg_random,
389 &ctr_drbg,
390 MBEDTLS_RSA_PUBLIC,
391 MBEDTLS_MD_SHA256, 0,
392 hash, signature);
393 if (rval != 0)
394 fprintf(stderr, "Failed to verify signature (%d)!\n", rval);
395
396verify_exit:
397
398 mbedtls_pk_free(&pk_ctx);
399 mbedtls_ctr_drbg_free(&ctr_drbg);
400 mbedtls_entropy_free(&entropy);
401 return rval;
402} /* end of verify_rsa_signature */
403
404/*******************************************************************************
405 * image_encrypt
406 * Encrypt image buffer using AES-256-CBC scheme.
407 * The resulting image is saved into opts.sec_opts->encrypted_image
408 * and the adjusted image size into opts.sec_opts->enc_image_sz
409 * First AES_BLOCK_SZ bytes of the output image contain IV
410 * INPUT:
411 * buf Source buffer to encrypt
412 * blen Source buffer length
413 * OUTPUT:
414 * none
415 * RETURN:
416 * 0 on success
417 */
418int image_encrypt(uint8_t *buf, uint32_t blen)
419{
420 struct timeval tv;
421 char *ptmp = (char *)&tv;
422 unsigned char digest[32];
423 unsigned char IV[AES_BLOCK_SZ];
Jaiprakash Singhfbf65552024-12-28 23:10:16 -0800424 size_t i, k;
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200425 mbedtls_aes_context aes_ctx;
426 int rval = -1;
427 uint8_t *test_img = 0;
428
429 if (AES_BLOCK_SZ > 32) {
430 fprintf(stderr, "Unsupported AES block size %d\n",
431 AES_BLOCK_SZ);
432 return rval;
433 }
434
435 mbedtls_aes_init(&aes_ctx);
436 memset(IV, 0, AES_BLOCK_SZ);
437 memset(digest, 0, 32);
438
439 /* Generate initialization vector and init the AES engine
440 * Use file name XOR current time and finally SHA-256
441 * [0...AES_BLOCK_SZ-1]
442 */
443 k = strlen(opts.sec_opts->aes_key_file);
444 if (k > AES_BLOCK_SZ)
445 k = AES_BLOCK_SZ;
446 memcpy(IV, opts.sec_opts->aes_key_file, k);
447 gettimeofday(&tv, 0);
448
449 for (i = 0, k = 0; i < AES_BLOCK_SZ; i++,
450 k = (k+1) % sizeof(struct timeval))
451 IV[i] ^= ptmp[k];
452
453 /* compute SHA-256 digest of the results
454 * and use it as the init vector (IV)
455 */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300456 mbedtls_sha256_ret(IV, AES_BLOCK_SZ, digest, 0);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200457 memcpy(IV, digest, AES_BLOCK_SZ);
458 mbedtls_aes_setkey_enc(&aes_ctx, opts.sec_opts->aes_key,
459 AES_KEY_BIT_LEN);
460
461 /* The output image has to include extra space for IV
462 * and to be aligned to the AES block size.
463 * The input image buffer has to be already aligned to AES_BLOCK_SZ
464 * and padded with zeroes
465 */
466 opts.sec_opts->enc_image_sz = (blen + 2 * AES_BLOCK_SZ - 1) &
467 ~(AES_BLOCK_SZ - 1);
468 opts.sec_opts->encrypted_image = calloc(opts.sec_opts->enc_image_sz, 1);
469 if (opts.sec_opts->encrypted_image == 0) {
470 fprintf(stderr, "Failed to allocate encrypted image!\n");
471 goto encrypt_exit;
472 }
473
474 /* Put IV into the output buffer next to the encrypted image
475 * Since the IV is modified by the encryption function,
476 * this should be done now
477 */
478 memcpy(opts.sec_opts->encrypted_image +
479 opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
480 IV, AES_BLOCK_SZ);
481 rval = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT,
482 opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
483 IV, buf, opts.sec_opts->encrypted_image);
484 if (rval != 0) {
485 fprintf(stderr, "Failed to encrypt the image! Error %d\n",
486 rval);
487 goto encrypt_exit;
488 }
489
490 mbedtls_aes_free(&aes_ctx);
491
492 /* Try to decrypt the image and compare it with the original data */
493 mbedtls_aes_init(&aes_ctx);
494 mbedtls_aes_setkey_dec(&aes_ctx, opts.sec_opts->aes_key,
495 AES_KEY_BIT_LEN);
496
497 test_img = calloc(opts.sec_opts->enc_image_sz - AES_BLOCK_SZ, 1);
498 if (test_img == 0) {
499 fprintf(stderr, "Failed to allocate test image!d\n");
500 rval = -1;
501 goto encrypt_exit;
502 }
503
504 memcpy(IV, opts.sec_opts->encrypted_image +
505 opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
506 AES_BLOCK_SZ);
507 rval = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT,
508 opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
509 IV, opts.sec_opts->encrypted_image, test_img);
510 if (rval != 0) {
511 fprintf(stderr, "Failed to decrypt the image! Error %d\n",
512 rval);
513 goto encrypt_exit;
514 }
515
516 for (i = 0; i < blen; i++) {
517 if (buf[i] != test_img[i]) {
518 fprintf(stderr, "Failed to compare the image after");
Jaiprakash Singhfbf65552024-12-28 23:10:16 -0800519 fprintf(stderr, " decryption! Byte count is %lu\n",
520 (unsigned long)i);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200521 rval = -1;
522 goto encrypt_exit;
523 }
524 }
525
526encrypt_exit:
527
528 mbedtls_aes_free(&aes_ctx);
529 if (test_img)
530 free(test_img);
531
532 return rval;
533} /* end of image_encrypt */
534
535/*******************************************************************************
536 * verify_secure_header_signatures
537 * Verify CSK array, header and image signatures and print results
538 * INPUT:
539 * main_hdr Main header
540 * sec_ext Secure extension
541 * OUTPUT:
542 * none
543 * RETURN:
544 * 0 on success
545 */
546int verify_secure_header_signatures(header_t *main_hdr, sec_entry_t *sec_ext)
547{
548 uint8_t *image = (uint8_t *)main_hdr + main_hdr->prolog_size;
549 uint8_t signature[RSA_SIGN_BYTE_LEN];
550 int rval = -1;
551
552 /* Save headers signature and reset it in the secure header */
553 memcpy(signature, sec_ext->header_sign, RSA_SIGN_BYTE_LEN);
554 memset(sec_ext->header_sign, 0, RSA_SIGN_BYTE_LEN);
555
556 fprintf(stdout, "\nCheck RSA Signatures\n");
557 fprintf(stdout, "#########################\n");
558 fprintf(stdout, "CSK Block Signature: ");
559 if (verify_rsa_signature(sec_ext->kak_key,
560 MAX_RSA_DER_BYTE_LEN,
561 &sec_ext->csk_keys[0][0],
562 sizeof(sec_ext->csk_keys),
563 "CSK Block Signature: ",
564 sec_ext->csk_sign) != 0) {
565 fprintf(stdout, "ERROR\n");
566 goto ver_error;
567 }
568 fprintf(stdout, "OK\n");
569
570 if (opts.key_index != -1) {
571 fprintf(stdout, "Image Signature: ");
572 if (verify_rsa_signature(sec_ext->csk_keys[opts.key_index],
573 MAX_RSA_DER_BYTE_LEN,
574 image, main_hdr->boot_image_size,
575 "Image Signature: ",
576 sec_ext->image_sign) != 0) {
577 fprintf(stdout, "ERROR\n");
578 goto ver_error;
579 }
580 fprintf(stdout, "OK\n");
581
582 fprintf(stdout, "Header Signature: ");
583 if (verify_rsa_signature(sec_ext->csk_keys[opts.key_index],
584 MAX_RSA_DER_BYTE_LEN,
585 (uint8_t *)main_hdr,
586 main_hdr->prolog_size,
587 "Header Signature: ",
588 signature) != 0) {
589 fprintf(stdout, "ERROR\n");
590 goto ver_error;
591 }
592 fprintf(stdout, "OK\n");
593 } else {
594 fprintf(stdout, "SKIP Image and Header Signatures");
595 fprintf(stdout, " check (undefined key index)\n");
596 }
597
598 rval = 0;
599
600ver_error:
601 memcpy(sec_ext->header_sign, signature, RSA_SIGN_BYTE_LEN);
602 return rval;
603}
604
605/*******************************************************************************
606 * verify_and_copy_file_name_entry
607 * INPUT:
608 * element_name
609 * element
610 * OUTPUT:
611 * copy_to
612 * RETURN:
613 * 0 on success
614 */
615int verify_and_copy_file_name_entry(const char *element_name,
616 const char *element, char *copy_to)
617{
Jaiprakash Singhfbf65552024-12-28 23:10:16 -0800618 size_t element_length = strlen(element);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200619
620 if (element_length >= MAX_FILENAME) {
Jaiprakash Singhfbf65552024-12-28 23:10:16 -0800621 fprintf(stderr, "The file name %s for %s is too long (%lu). ",
622 element, element_name, (unsigned long)element_length);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200623 fprintf(stderr, "Maximum allowed %d characters!\n",
624 MAX_FILENAME);
625 return -1;
626 } else if (element_length == 0) {
627 fprintf(stderr, "The file name for %s is empty!\n",
628 element_name);
629 return -1;
630 }
631 memcpy(copy_to, element, element_length);
632
633 return 0;
634}
635
636/*******************************************************************************
637 * parse_sec_config_file
638 * Read the secure boot configuration from a file
639 * into internal structures
640 * INPUT:
641 * filename File name
642 * OUTPUT:
643 * none
644 * RETURN:
645 * 0 on success
646 */
647int parse_sec_config_file(char *filename)
648{
649 config_t sec_cfg;
650 int array_sz, element, rval = -1;
651 const char *cfg_string;
652 int32_t cfg_int32;
653 const config_setting_t *csk_array, *control_array;
654 sec_options *sec_opt = 0;
655
656 config_init(&sec_cfg);
657
658 if (config_read_file(&sec_cfg, filename) != CONFIG_TRUE) {
659 fprintf(stderr, "Failed to read data from config file ");
660 fprintf(stderr, "%s\n\t%s at line %d\n",
661 filename, config_error_text(&sec_cfg),
662 config_error_line(&sec_cfg));
663 goto exit_parse;
664 }
665
666 sec_opt = (sec_options *)calloc(sizeof(sec_options), 1);
667 if (sec_opt == 0) {
668 fprintf(stderr,
669 "Cannot allocate memory for secure boot options!\n");
670 goto exit_parse;
671 }
672
673 /* KAK file name */
674 if (config_lookup_string(&sec_cfg, "kak_key_file",
675 &cfg_string) != CONFIG_TRUE) {
676 fprintf(stderr, "The \"kak_key_file\" undefined!\n");
677 goto exit_parse;
678 }
679 if (verify_and_copy_file_name_entry("kak_key_file",
680 cfg_string, sec_opt->kak_key_file))
681 goto exit_parse;
682
683
684 /* AES file name - can be empty/undefined */
685 if (config_lookup_string(&sec_cfg, "aes_key_file",
686 &cfg_string) == CONFIG_TRUE) {
687 if (verify_and_copy_file_name_entry("aes_key_file",
688 cfg_string,
689 sec_opt->aes_key_file))
690 goto exit_parse;
691 }
692
693 /* CSK file names array */
694 csk_array = config_lookup(&sec_cfg, "csk_key_file");
695 if (csk_array == NULL) {
696 fprintf(stderr, "The \"csk_key_file\" undefined!\n");
697 goto exit_parse;
698 }
699 array_sz = config_setting_length(csk_array);
700 if (array_sz > CSK_ARR_SZ) {
701 fprintf(stderr, "The \"csk_key_file\" array is too big! ");
702 fprintf(stderr, "Only first %d elements will be used\n",
703 CSK_ARR_SZ);
704 array_sz = CSK_ARR_SZ;
705 } else if (array_sz == 0) {
706 fprintf(stderr, "The \"csk_key_file\" array is empty!\n");
707 goto exit_parse;
708 }
709
710 for (element = 0; element < array_sz; element++) {
711 cfg_string = config_setting_get_string_elem(csk_array, element);
712 if (verify_and_copy_file_name_entry(
713 "csk_key_file", cfg_string,
714 sec_opt->csk_key_file[element])) {
715 fprintf(stderr, "Bad csk_key_file[%d] entry!\n",
716 element);
717 goto exit_parse;
718 }
719 }
720
721 /* JTAG options */
722 if (config_lookup_bool(&sec_cfg, "jtag.enable",
723 &cfg_int32) != CONFIG_TRUE) {
724 fprintf(stderr, "Error obtaining \"jtag.enable\" element. ");
725 fprintf(stderr, "Using default - FALSE\n");
726 cfg_int32 = 0;
727 }
728 sec_opt->jtag_enable = cfg_int32;
729
730 if (config_lookup_int(&sec_cfg, "jtag.delay",
731 &cfg_int32) != CONFIG_TRUE) {
732 fprintf(stderr, "Error obtaining \"jtag.delay\" element. ");
733 fprintf(stderr, "Using default - 0us\n");
734 cfg_int32 = 0;
735 }
736 sec_opt->jtag_delay = cfg_int32;
737
738 /* eFUSE option */
739 if (config_lookup_bool(&sec_cfg, "efuse_disable",
740 &cfg_int32) != CONFIG_TRUE) {
741 fprintf(stderr, "Error obtaining \"efuse_disable\" element. ");
742 fprintf(stderr, "Using default - TRUE\n");
743 cfg_int32 = 1;
744 }
745 sec_opt->efuse_disable = cfg_int32;
746
747 /* Box ID option */
748 if (config_lookup_int(&sec_cfg, "box_id", &cfg_int32) != CONFIG_TRUE) {
749 fprintf(stderr, "Error obtaining \"box_id\" element. ");
750 fprintf(stderr, "Using default - 0x0\n");
751 cfg_int32 = 0;
752 }
753 sec_opt->box_id = cfg_int32;
754
755 /* Flash ID option */
756 if (config_lookup_int(&sec_cfg, "flash_id",
757 &cfg_int32) != CONFIG_TRUE) {
758 fprintf(stderr, "Error obtaining \"flash_id\" element. ");
759 fprintf(stderr, "Using default - 0x0\n");
760 cfg_int32 = 0;
761 }
762 sec_opt->flash_id = cfg_int32;
763
764 /* CSK index option */
765 if (config_lookup_int(&sec_cfg, "csk_key_index",
766 &cfg_int32) != CONFIG_TRUE) {
Konstantin Porotchkin6d55ef12018-08-16 13:57:18 +0300767 fprintf(stderr, "Error obtaining \"flash_id\" element. ");
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200768 fprintf(stderr, "Using default - 0x0\n");
769 cfg_int32 = 0;
770 }
771 sec_opt->csk_index = cfg_int32;
772
773 /* Secure boot control array */
774 control_array = config_lookup(&sec_cfg, "control");
775 if (control_array != NULL) {
776 array_sz = config_setting_length(control_array);
777 if (array_sz == 0)
778 fprintf(stderr, "The \"control\" array is empty!\n");
779 } else {
780 fprintf(stderr, "The \"control\" is undefined!\n");
781 array_sz = 0;
782 }
783
784 for (element = 0; element < CP_CTRL_EL_ARRAY_SZ; element++) {
785 sec_opt->cp_ctrl_arr[element] =
786 config_setting_get_int_elem(control_array, element * 2);
787 sec_opt->cp_efuse_arr[element] =
788 config_setting_get_int_elem(control_array,
789 element * 2 + 1);
790 }
791
792 opts.sec_opts = sec_opt;
793 rval = 0;
794
795exit_parse:
796 config_destroy(&sec_cfg);
797 if (sec_opt && (rval != 0))
798 free(sec_opt);
799 return rval;
800} /* end of parse_sec_config_file */
801
802int format_sec_ext(char *filename, FILE *out_fd)
803{
804 ext_header_t header;
805 sec_entry_t sec_ext;
806 int index;
807 int written;
808
809#define DER_BUF_SZ 1600
810
811 /* First, parse the configuration file */
812 if (parse_sec_config_file(filename)) {
813 fprintf(stderr,
814 "failed parsing configuration file %s\n", filename);
815 return 1;
816 }
817
818 /* Everything except signatures can be created at this stage */
819 header.type = EXT_TYPE_SECURITY;
820 header.offset = 0;
821 header.size = sizeof(sec_entry_t);
822 header.reserved = 0;
823
824 /* Bring up RSA context and read private keys from their files */
825 for (index = 0; index < (CSK_ARR_SZ + 1); index++) {
826 /* for every private key file */
827 mbedtls_pk_context *pk_ctx = (index == CSK_ARR_SZ) ?
828 &opts.sec_opts->kak_pk :
829 &opts.sec_opts->csk_pk[index];
830 char *fname = (index == CSK_ARR_SZ) ?
831 opts.sec_opts->kak_key_file :
832 opts.sec_opts->csk_key_file[index];
833 uint8_t *out_der_key = (index == CSK_ARR_SZ) ?
834 sec_ext.kak_key :
835 sec_ext.csk_keys[index];
836 size_t output_len;
837 unsigned char output_buf[DER_BUF_SZ];
838 unsigned char *der_buf_start;
839
840 /* Handle invalid/reserved file names */
841 if (strncmp(CSK_ARR_EMPTY_FILE, fname,
842 strlen(CSK_ARR_EMPTY_FILE)) == 0) {
843 if (opts.sec_opts->csk_index == index) {
844 fprintf(stderr,
845 "CSK file with index %d cannot be %s\n",
846 index, CSK_ARR_EMPTY_FILE);
847 return 1;
848 } else if (index == CSK_ARR_SZ) {
849 fprintf(stderr, "KAK file name cannot be %s\n",
850 CSK_ARR_EMPTY_FILE);
851 return 1;
852 }
853 /* this key will be empty in CSK array */
854 continue;
855 }
856
857 mbedtls_pk_init(pk_ctx);
858 /* Read the private RSA key into the context
859 * and verify it (no password)
860 */
861 if (mbedtls_pk_parse_keyfile(pk_ctx, fname, "") != 0) {
862 fprintf(stderr,
863 "Cannot read RSA private key file %s\n", fname);
864 return 1;
865 }
866
867 /* Create a public key out of private one
868 * and store it in DER format
869 */
870 output_len = mbedtls_pk_write_pubkey_der(pk_ctx,
871 output_buf,
872 DER_BUF_SZ);
873 if (output_len < 0) {
874 fprintf(stderr,
875 "Failed to create DER coded PUB key (%s)\n",
876 fname);
877 return 1;
878 }
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300879
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200880 /* Data in the output buffer is aligned to the buffer end */
881 der_buf_start = output_buf + sizeof(output_buf) - output_len;
882 /* In the header DER data is aligned
883 * to the start of appropriate field
884 */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300885 bzero(out_der_key, MAX_RSA_DER_BYTE_LEN);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200886 memcpy(out_der_key, der_buf_start, output_len);
887
888 } /* for every private key file */
889
890 /* The CSK block signature can be created here */
891 if (create_rsa_signature(&opts.sec_opts->kak_pk,
892 &sec_ext.csk_keys[0][0],
893 sizeof(sec_ext.csk_keys),
894 opts.sec_opts->csk_key_file[
895 opts.sec_opts->csk_index],
896 sec_ext.csk_sign) != 0) {
897 fprintf(stderr, "Failed to sign CSK keys block!\n");
898 return 1;
899 }
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300900
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200901 /* Check that everything is correct */
Konstantin Porotchkina79df342019-05-01 17:08:18 +0300902 if (verify_rsa_signature(sec_ext.kak_key,
903 MAX_RSA_DER_BYTE_LEN,
Konstantin Porotchkin434e0292018-02-26 16:28:40 +0200904 &sec_ext.csk_keys[0][0],
905 sizeof(sec_ext.csk_keys),
906 opts.sec_opts->kak_key_file,
907 sec_ext.csk_sign) != 0) {
908 fprintf(stderr, "Failed to verify CSK keys block signature!\n");
909 return 1;
910 }
911
912 /* AES encryption stuff */
913 if (strlen(opts.sec_opts->aes_key_file) != 0) {
914 FILE *in_fd;
915
916 in_fd = fopen(opts.sec_opts->aes_key_file, "rb");
917 if (in_fd == NULL) {
918 fprintf(stderr, "Failed to open AES key file %s\n",
919 opts.sec_opts->aes_key_file);
920 return 1;
921 }
922
923 /* Read the AES key in ASCII format byte by byte */
924 for (index = 0; index < AES_KEY_BYTE_LEN; index++) {
925 if (fscanf(in_fd, "%02hhx",
926 opts.sec_opts->aes_key + index) != 1) {
927 fprintf(stderr,
928 "Failed to read AES key byte %d ",
929 index);
930 fprintf(stderr,
931 "from file %s\n",
932 opts.sec_opts->aes_key_file);
933 fclose(in_fd);
934 return 1;
935 }
936 }
937 fclose(in_fd);
938 sec_ext.encrypt_en = 1;
939 } else {
940 sec_ext.encrypt_en = 0;
941 }
942
943 /* Fill the rest of the trusted boot extension fields */
944 sec_ext.box_id = opts.sec_opts->box_id;
945 sec_ext.flash_id = opts.sec_opts->flash_id;
946 sec_ext.efuse_dis = opts.sec_opts->efuse_disable;
947 sec_ext.jtag_delay = opts.sec_opts->jtag_delay;
948 sec_ext.jtag_en = opts.sec_opts->jtag_enable;
949
950 memcpy(sec_ext.cp_ctrl_arr,
951 opts.sec_opts->cp_ctrl_arr,
952 sizeof(uint32_t) * CP_CTRL_EL_ARRAY_SZ);
953 memcpy(sec_ext.cp_efuse_arr,
954 opts.sec_opts->cp_efuse_arr,
955 sizeof(uint32_t) * CP_CTRL_EL_ARRAY_SZ);
956
957 /* Write the resulting extension to file
958 * (image and header signature fields are still empty)
959 */
960
961 /* Write extension header */
962 written = fwrite(&header, sizeof(ext_header_t), 1, out_fd);
963 if (written != 1) {
964 fprintf(stderr,
965 "Failed to write SEC extension header to the file\n");
966 return 1;
967 }
968 /* Write extension body */
969 written = fwrite(&sec_ext, sizeof(sec_entry_t), 1, out_fd);
970 if (written != 1) {
971 fprintf(stderr,
972 "Failed to write SEC extension body to the file\n");
973 return 1;
974 }
975
976 return 0;
977}
978
979/*******************************************************************************
980 * finalize_secure_ext
981 * Make final changes to secure extension - calculate image and header
982 * signatures and encrypt the image if needed.
983 * The main header checksum and image size fields updated accordingly
984 * INPUT:
985 * header Main header
986 * prolog_buf the entire prolog buffer
987 * prolog_size prolog buffer length
988 * image_buf buffer containing the input binary image
989 * image_size image buffer size.
990 * OUTPUT:
991 * none
992 * RETURN:
993 * 0 on success
994 */
995int finalize_secure_ext(header_t *header,
996 uint8_t *prolog_buf, uint32_t prolog_size,
997 uint8_t *image_buf, int image_size)
998{
999 int cur_ext, offset;
1000 uint8_t *final_image = image_buf;
1001 uint32_t final_image_sz = image_size;
1002 uint8_t hdr_sign[RSA_SIGN_BYTE_LEN];
1003 sec_entry_t *sec_ext = 0;
1004
1005 /* Find the Trusted Boot Header between available extensions */
1006 for (cur_ext = 0, offset = sizeof(header_t);
1007 cur_ext < header->ext_count; cur_ext++) {
1008 ext_header_t *ext_hdr = (ext_header_t *)(prolog_buf + offset);
1009
1010 if (ext_hdr->type == EXT_TYPE_SECURITY) {
1011 sec_ext = (sec_entry_t *)(prolog_buf + offset +
1012 sizeof(ext_header_t) + ext_hdr->offset);
1013 break;
1014 }
1015
1016 offset += sizeof(ext_header_t);
1017 /* If offset is Zero, the extension follows its header */
1018 if (ext_hdr->offset == 0)
1019 offset += ext_hdr->size;
1020 }
1021
1022 if (sec_ext == 0) {
1023 fprintf(stderr, "Error: No Trusted Boot extension found!\n");
1024 return -1;
1025 }
1026
1027 if (sec_ext->encrypt_en) {
1028 /* Encrypt the image if needed */
1029 fprintf(stdout, "Encrypting the image...\n");
1030
1031 if (image_encrypt(image_buf, image_size) != 0) {
1032 fprintf(stderr, "Failed to encrypt the image!\n");
1033 return -1;
1034 }
1035
1036 /* Image size and checksum should be updated after encryption.
1037 * This way the image could be verified by the BootROM
1038 * before decryption.
1039 */
1040 final_image = opts.sec_opts->encrypted_image;
1041 final_image_sz = opts.sec_opts->enc_image_sz;
1042
1043 header->boot_image_size = final_image_sz;
1044 header->boot_image_checksum =
1045 checksum32((uint32_t *)final_image, final_image_sz);
1046 } /* AES encryption */
1047
1048 /* Create the image signature first, since it will be later
1049 * signed along with the header signature
1050 */
1051 if (create_rsa_signature(&opts.sec_opts->csk_pk[
1052 opts.sec_opts->csk_index],
1053 final_image, final_image_sz,
1054 opts.sec_opts->csk_key_file[
1055 opts.sec_opts->csk_index],
1056 sec_ext->image_sign) != 0) {
1057 fprintf(stderr, "Failed to sign image!\n");
1058 return -1;
1059 }
1060 /* Check that the image signature is correct */
1061 if (verify_rsa_signature(sec_ext->csk_keys[opts.sec_opts->csk_index],
1062 MAX_RSA_DER_BYTE_LEN,
1063 final_image, final_image_sz,
1064 opts.sec_opts->csk_key_file[
1065 opts.sec_opts->csk_index],
1066 sec_ext->image_sign) != 0) {
1067 fprintf(stderr, "Failed to verify image signature!\n");
1068 return -1;
1069 }
1070
1071 /* Sign the headers and all the extensions block
1072 * when the header signature field is empty
1073 */
1074 if (create_rsa_signature(&opts.sec_opts->csk_pk[
1075 opts.sec_opts->csk_index],
1076 prolog_buf, prolog_size,
1077 opts.sec_opts->csk_key_file[
1078 opts.sec_opts->csk_index],
1079 hdr_sign) != 0) {
1080 fprintf(stderr, "Failed to sign header!\n");
1081 return -1;
1082 }
1083 /* Check that the header signature is correct */
1084 if (verify_rsa_signature(sec_ext->csk_keys[opts.sec_opts->csk_index],
1085 MAX_RSA_DER_BYTE_LEN,
1086 prolog_buf, prolog_size,
1087 opts.sec_opts->csk_key_file[
1088 opts.sec_opts->csk_index],
1089 hdr_sign) != 0) {
1090 fprintf(stderr, "Failed to verify header signature!\n");
1091 return -1;
1092 }
1093
1094 /* Finally, copy the header signature into the trusted boot extension */
1095 memcpy(sec_ext->header_sign, hdr_sign, RSA_SIGN_BYTE_LEN);
1096
1097 return 0;
1098}
1099
1100#endif /* CONFIG_MVEBU_SECURE_BOOT */
1101
1102
1103#define FMT_HEX 0
1104#define FMT_DEC 1
1105#define FMT_BIN 2
1106#define FMT_NONE 3
1107
1108void do_print_field(unsigned int value, char *name,
1109 int start, int size, int format)
1110{
1111 fprintf(stdout, "[0x%05x : 0x%05x] %-26s",
1112 start, start + size - 1, name);
1113
1114 switch (format) {
1115 case FMT_HEX:
1116 printf("0x%x\n", value);
1117 break;
1118 case FMT_DEC:
1119 printf("%d\n", value);
1120 break;
1121 default:
1122 printf("\n");
1123 break;
1124 }
1125}
1126
1127#define print_field(st, type, field, hex, base) \
1128 do_print_field((int)st->field, #field, \
1129 base + offsetof(type, field), sizeof(st->field), hex)
1130
1131int print_header(uint8_t *buf, int base)
1132{
1133 header_t *main_hdr;
1134
1135 main_hdr = (header_t *)buf;
1136
1137 fprintf(stdout, "########### Header ##############\n");
1138 print_field(main_hdr, header_t, magic, FMT_HEX, base);
1139 print_field(main_hdr, header_t, prolog_size, FMT_DEC, base);
1140 print_field(main_hdr, header_t, prolog_checksum, FMT_HEX, base);
1141 print_field(main_hdr, header_t, boot_image_size, FMT_DEC, base);
1142 print_field(main_hdr, header_t, boot_image_checksum, FMT_HEX, base);
1143 print_field(main_hdr, header_t, rsrvd0, FMT_HEX, base);
1144 print_field(main_hdr, header_t, load_addr, FMT_HEX, base);
1145 print_field(main_hdr, header_t, exec_addr, FMT_HEX, base);
1146 print_field(main_hdr, header_t, uart_cfg, FMT_HEX, base);
1147 print_field(main_hdr, header_t, baudrate, FMT_HEX, base);
1148 print_field(main_hdr, header_t, ext_count, FMT_DEC, base);
1149 print_field(main_hdr, header_t, aux_flags, FMT_HEX, base);
1150 print_field(main_hdr, header_t, io_arg_0, FMT_HEX, base);
1151 print_field(main_hdr, header_t, io_arg_1, FMT_HEX, base);
1152 print_field(main_hdr, header_t, io_arg_2, FMT_HEX, base);
1153 print_field(main_hdr, header_t, io_arg_3, FMT_HEX, base);
1154 print_field(main_hdr, header_t, rsrvd1, FMT_HEX, base);
1155 print_field(main_hdr, header_t, rsrvd2, FMT_HEX, base);
1156 print_field(main_hdr, header_t, rsrvd3, FMT_HEX, base);
1157
1158 return sizeof(header_t);
1159}
1160
1161int print_ext_hdr(ext_header_t *ext_hdr, int base)
1162{
1163 print_field(ext_hdr, ext_header_t, type, FMT_HEX, base);
1164 print_field(ext_hdr, ext_header_t, offset, FMT_HEX, base);
1165 print_field(ext_hdr, ext_header_t, reserved, FMT_HEX, base);
1166 print_field(ext_hdr, ext_header_t, size, FMT_DEC, base);
1167
1168 return base + sizeof(ext_header_t);
1169}
1170
1171void print_sec_ext(ext_header_t *ext_hdr, int base)
1172{
1173 sec_entry_t *sec_entry;
1174 uint32_t new_base;
1175
1176 fprintf(stdout, "\n########### Secure extension ###########\n");
1177
1178 new_base = print_ext_hdr(ext_hdr, base);
1179
1180 sec_entry = (sec_entry_t *)(ext_hdr + 1);
1181
1182 do_print_field(0, "KAK key", new_base, MAX_RSA_DER_BYTE_LEN, FMT_NONE);
1183 new_base += MAX_RSA_DER_BYTE_LEN;
1184 print_field(sec_entry, sec_entry_t, jtag_delay, FMT_DEC, base);
1185 print_field(sec_entry, sec_entry_t, box_id, FMT_HEX, base);
1186 print_field(sec_entry, sec_entry_t, flash_id, FMT_HEX, base);
1187 print_field(sec_entry, sec_entry_t, encrypt_en, FMT_DEC, base);
1188 print_field(sec_entry, sec_entry_t, efuse_dis, FMT_DEC, base);
1189 new_base += 6 * sizeof(uint32_t);
1190 do_print_field(0, "header signature",
1191 new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
1192 new_base += RSA_SIGN_BYTE_LEN;
1193 do_print_field(0, "image signature",
1194 new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
1195 new_base += RSA_SIGN_BYTE_LEN;
1196 do_print_field(0, "CSK keys", new_base,
1197 CSK_ARR_SZ * MAX_RSA_DER_BYTE_LEN, FMT_NONE);
1198 new_base += CSK_ARR_SZ * MAX_RSA_DER_BYTE_LEN;
1199 do_print_field(0, "CSK block signature",
1200 new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
1201 new_base += RSA_SIGN_BYTE_LEN;
1202 do_print_field(0, "control", new_base,
1203 CP_CTRL_EL_ARRAY_SZ * 2, FMT_NONE);
1204
1205}
1206
1207void print_bin_ext(ext_header_t *ext_hdr, int base)
1208{
1209 fprintf(stdout, "\n########### Binary extension ###########\n");
1210 base = print_ext_hdr(ext_hdr, base);
1211 do_print_field(0, "binary image", base, ext_hdr->size, FMT_NONE);
1212}
1213
1214int print_extension(void *buf, int base, int count, int ext_size)
1215{
1216 ext_header_t *ext_hdr = buf;
1217 int pad = ext_size;
1218 int curr_size;
1219
1220 while (count--) {
1221 if (ext_hdr->type == EXT_TYPE_BINARY)
1222 print_bin_ext(ext_hdr, base);
1223 else if (ext_hdr->type == EXT_TYPE_SECURITY)
1224 print_sec_ext(ext_hdr, base);
1225
1226 curr_size = sizeof(ext_header_t) + ext_hdr->size;
1227 base += curr_size;
1228 pad -= curr_size;
1229 ext_hdr = (ext_header_t *)((uintptr_t)ext_hdr + curr_size);
1230 }
1231
1232 if (pad)
1233 do_print_field(0, "padding", base, pad, FMT_NONE);
1234
1235 return ext_size;
1236}
1237
1238int parse_image(uint8_t *buf, int size)
1239{
1240 int base = 0;
1241 int ret = 1;
1242 header_t *main_hdr;
1243 uint32_t checksum, prolog_checksum;
1244
1245
1246 fprintf(stdout,
1247 "################### Prolog Start ######################\n\n");
1248 main_hdr = (header_t *)buf;
1249 base += print_header(buf, base);
1250
1251 if (main_hdr->ext_count)
1252 base += print_extension(buf + base, base,
1253 main_hdr->ext_count,
1254 main_hdr->prolog_size -
1255 sizeof(header_t));
1256
1257 if (base < main_hdr->prolog_size) {
1258 fprintf(stdout, "\n########### Padding ##############\n");
1259 do_print_field(0, "prolog padding",
1260 base, main_hdr->prolog_size - base, FMT_HEX);
1261 base = main_hdr->prolog_size;
1262 }
1263 fprintf(stdout,
1264 "\n################### Prolog End ######################\n");
1265
1266 fprintf(stdout,
1267 "\n################### Boot image ######################\n");
1268
1269 do_print_field(0, "boot image", base, size - base - 4, FMT_NONE);
1270
1271 fprintf(stdout,
1272 "################### Image end ########################\n");
1273
1274 /* Check sanity for certain values */
1275 printf("\nChecking values:\n");
1276
1277 if (main_hdr->magic == MAIN_HDR_MAGIC) {
1278 fprintf(stdout, "Headers magic: OK!\n");
1279 } else {
1280 fprintf(stderr,
1281 "\n****** ERROR: HEADER MAGIC 0x%08x != 0x%08x\n",
1282 main_hdr->magic, MAIN_HDR_MAGIC);
1283 goto error;
1284 }
1285
1286 /* headers checksum */
1287 /* clear the checksum field in header to calculate checksum */
1288 prolog_checksum = main_hdr->prolog_checksum;
1289 main_hdr->prolog_checksum = 0;
1290 checksum = checksum32((uint32_t *)buf, main_hdr->prolog_size);
1291
1292 if (checksum == prolog_checksum) {
1293 fprintf(stdout, "Headers checksum: OK!\n");
1294 } else {
1295 fprintf(stderr,
1296 "\n***** ERROR: BAD HEADER CHECKSUM 0x%08x != 0x%08x\n",
1297 checksum, prolog_checksum);
1298 goto error;
1299 }
1300
1301 /* boot image checksum */
1302 checksum = checksum32((uint32_t *)(buf + main_hdr->prolog_size),
1303 main_hdr->boot_image_size);
1304 if (checksum == main_hdr->boot_image_checksum) {
1305 fprintf(stdout, "Image checksum: OK!\n");
1306 } else {
1307 fprintf(stderr,
1308 "\n****** ERROR: BAD IMAGE CHECKSUM 0x%08x != 0x%08x\n",
1309 checksum, main_hdr->boot_image_checksum);
1310 goto error;
1311 }
1312
1313#ifdef CONFIG_MVEBU_SECURE_BOOT
1314 /* RSA signatures */
1315 if (main_hdr->ext_count) {
1316 uint8_t ext_num = main_hdr->ext_count;
1317 ext_header_t *ext_hdr = (ext_header_t *)(main_hdr + 1);
1318 unsigned char hash[32];
1319 int i;
1320
1321 while (ext_num--) {
1322 if (ext_hdr->type == EXT_TYPE_SECURITY) {
1323 sec_entry_t *sec_entry =
1324 (sec_entry_t *)(ext_hdr + 1);
1325
1326 ret = verify_secure_header_signatures(
1327 main_hdr, sec_entry);
1328 if (ret != 0) {
1329 fprintf(stderr,
1330 "\n****** FAILED TO VERIFY ");
1331 fprintf(stderr,
1332 "RSA SIGNATURES ********\n");
1333 goto error;
1334 }
1335
Konstantin Porotchkina79df342019-05-01 17:08:18 +03001336 mbedtls_sha256_ret(sec_entry->kak_key,
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001337 MAX_RSA_DER_BYTE_LEN, hash, 0);
1338 fprintf(stdout,
1339 ">>>>>>>>>> KAK KEY HASH >>>>>>>>>>\n");
1340 fprintf(stdout, "SHA256: ");
1341 for (i = 0; i < 32; i++)
1342 fprintf(stdout, "%02X", hash[i]);
1343
1344 fprintf(stdout,
1345 "\n<<<<<<<<< KAK KEY HASH <<<<<<<<<\n");
1346
1347 break;
1348 }
1349 ext_hdr =
1350 (ext_header_t *)((uint8_t *)(ext_hdr + 1) +
1351 ext_hdr->size);
1352 }
1353 }
1354#endif
1355
1356 ret = 0;
1357error:
1358 return ret;
1359}
1360
1361int format_bin_ext(char *filename, FILE *out_fd)
1362{
1363 ext_header_t header;
1364 FILE *in_fd;
1365 int size, written;
1366 int aligned_size, pad_bytes;
1367 char c;
1368
1369 in_fd = fopen(filename, "rb");
1370 if (in_fd == NULL) {
1371 fprintf(stderr, "failed to open bin extension file %s\n",
1372 filename);
1373 return 1;
1374 }
1375
1376 size = get_file_size(filename);
1377 if (size <= 0) {
1378 fprintf(stderr, "bin extension file size is bad\n");
1379 return 1;
1380 }
1381
1382 /* Align extension size to 8 bytes */
1383 aligned_size = (size + 7) & (~7);
1384 pad_bytes = aligned_size - size;
1385
1386 header.type = EXT_TYPE_BINARY;
1387 header.offset = 0;
1388 header.size = aligned_size;
1389 header.reserved = 0;
1390
1391 /* Write header */
1392 written = fwrite(&header, sizeof(ext_header_t), 1, out_fd);
1393 if (written != 1) {
1394 fprintf(stderr, "failed writing header to extension file\n");
1395 return 1;
1396 }
1397
1398 /* Write image */
1399 while (size--) {
1400 c = getc(in_fd);
1401 fputc(c, out_fd);
1402 }
1403
1404 while (pad_bytes--)
1405 fputc(0, out_fd);
1406
1407 fclose(in_fd);
1408
1409 return 0;
1410}
1411
1412/* ****************************************
1413 *
1414 * Write all extensions (binary, secure
1415 * extensions) to file
1416 *
1417 * ****************************************/
1418
1419int format_extensions(char *ext_filename)
1420{
1421 FILE *out_fd;
1422 int ret = 0;
1423
1424 out_fd = fopen(ext_filename, "wb");
1425 if (out_fd == NULL) {
1426 fprintf(stderr, "failed to open extension output file %s",
1427 ext_filename);
1428 return 1;
1429 }
1430
1431 if (strncmp(opts.bin_ext_file, "NA", MAX_FILENAME)) {
1432 if (format_bin_ext(opts.bin_ext_file, out_fd)) {
1433 ret = 1;
1434 goto error;
1435 }
1436 }
1437#ifdef CONFIG_MVEBU_SECURE_BOOT
1438 if (strncmp(opts.sec_cfg_file, "NA", MAX_FILENAME)) {
1439 if (format_sec_ext(opts.sec_cfg_file, out_fd)) {
1440 ret = 1;
1441 goto error;
1442 }
1443 }
1444#endif
1445
1446error:
1447 fflush(out_fd);
1448 fclose(out_fd);
1449 return ret;
1450}
1451
1452void update_uart(header_t *header)
1453{
1454 header->uart_cfg = 0;
1455 header->baudrate = 0;
1456
1457 if (opts.disable_print)
1458 uart_set_mode(header->uart_cfg, UART_MODE_DISABLE);
1459
1460 if (opts.baudrate)
1461 header->baudrate = (opts.baudrate / 1200);
1462}
1463
1464/* ****************************************
1465 *
1466 * Write the image prolog, i.e.
1467 * main header and extensions, to file
1468 *
1469 * ****************************************/
1470
1471int write_prolog(int ext_cnt, char *ext_filename,
1472 uint8_t *image_buf, int image_size, FILE *out_fd)
1473{
1474 header_t *header;
1475 int main_hdr_size = sizeof(header_t);
1476 int prolog_size = main_hdr_size;
1477 FILE *ext_fd;
1478 char *buf;
1479 int written, read;
1480 int ret = 1;
1481
1482
1483 if (ext_cnt)
1484 prolog_size += get_file_size(ext_filename);
1485
1486 prolog_size = ((prolog_size + PROLOG_ALIGNMENT) &
1487 (~(PROLOG_ALIGNMENT-1)));
1488
1489 /* Allocate a zeroed buffer to zero the padding bytes */
1490 buf = calloc(prolog_size, 1);
1491 if (buf == NULL) {
1492 fprintf(stderr, "Error: failed allocating checksum buffer\n");
1493 return 1;
1494 }
1495
1496 header = (header_t *)buf;
1497 header->magic = MAIN_HDR_MAGIC;
1498 header->prolog_size = prolog_size;
1499 header->load_addr = opts.load_addr;
1500 header->exec_addr = opts.exec_addr;
1501 header->io_arg_0 = opts.nfc_io_args;
1502 header->ext_count = ext_cnt;
1503 header->aux_flags = 0;
1504 header->boot_image_size = (image_size + 3) & (~0x3);
1505 header->boot_image_checksum = checksum32((uint32_t *)image_buf,
1506 image_size);
1507
1508 update_uart(header);
1509
1510 /* Populate buffer with main header and extensions */
1511 if (ext_cnt) {
1512 ext_fd = fopen(ext_filename, "rb");
1513 if (ext_fd == NULL) {
1514 fprintf(stderr,
1515 "Error: failed to open extensions file\n");
1516 goto error;
1517 }
1518
1519 read = fread(&buf[main_hdr_size],
1520 get_file_size(ext_filename), 1, ext_fd);
1521 if (read != 1) {
1522 fprintf(stderr,
1523 "Error: failed to open extensions file\n");
1524 goto error;
1525 }
1526
1527#ifdef CONFIG_MVEBU_SECURE_BOOT
1528 /* Secure boot mode? */
1529 if (opts.sec_opts != 0) {
1530 ret = finalize_secure_ext(header, (uint8_t *)buf,
1531 prolog_size, image_buf,
1532 image_size);
1533 if (ret != 0) {
1534 fprintf(stderr, "Error: failed to handle ");
1535 fprintf(stderr, "secure extension!\n");
1536 goto error;
1537 }
1538 } /* secure boot mode */
1539#endif
1540 }
1541
1542 /* Update the total prolog checksum */
1543 header->prolog_checksum = checksum32((uint32_t *)buf, prolog_size);
1544
1545 /* Now spill everything to output file */
1546 written = fwrite(buf, prolog_size, 1, out_fd);
1547 if (written != 1) {
1548 fprintf(stderr,
1549 "Error: failed to write prolog to output file\n");
1550 goto error;
1551 }
1552
1553 ret = 0;
1554
1555error:
1556 free(buf);
1557 return ret;
1558}
1559
1560int write_boot_image(uint8_t *buf, uint32_t image_size, FILE *out_fd)
1561{
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001562 int written;
1563
Konstantin Porotchkin5985a1e2019-05-02 15:10:07 +03001564 written = fwrite(buf, image_size, 1, out_fd);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001565 if (written != 1) {
1566 fprintf(stderr, "Error: Failed to write boot image\n");
1567 goto error;
1568 }
1569
1570 return 0;
1571error:
1572 return 1;
1573}
1574
1575int main(int argc, char *argv[])
1576{
Matteo Crocefd10a0a2018-09-24 02:27:21 +02001577 char in_file[MAX_FILENAME+1] = { 0 };
1578 char out_file[MAX_FILENAME+1] = { 0 };
1579 char ext_file[MAX_FILENAME+1] = { 0 };
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001580 FILE *in_fd = NULL;
1581 FILE *out_fd = NULL;
1582 int parse = 0;
1583 int ext_cnt = 0;
1584 int opt;
1585 int ret = 0;
Konstantin Porotchkin5985a1e2019-05-02 15:10:07 +03001586 int image_size, file_size;
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001587 uint8_t *image_buf = NULL;
1588 int read;
Matteo Crocefd10a0a2018-09-24 02:27:21 +02001589 size_t len;
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001590 uint32_t nand_block_size_kb, mlc_nand;
1591
1592 /* Create temporary file for building extensions
1593 * Use process ID for allowing multiple parallel runs
1594 */
1595 snprintf(ext_file, MAX_FILENAME, "/tmp/ext_file-%x", getpid());
1596
1597 while ((opt = getopt(argc, argv, "hpms:i:l:e:a:b:u:n:t:c:k:")) != -1) {
1598 switch (opt) {
1599 case 'h':
1600 usage();
1601 break;
1602 case 'l':
1603 opts.load_addr = strtoul(optarg, NULL, 0);
1604 break;
1605 case 'e':
1606 opts.exec_addr = strtoul(optarg, NULL, 0);
1607 break;
1608 case 'm':
1609 opts.disable_print = 1;
1610 break;
1611 case 'u':
1612 opts.baudrate = strtoul(optarg, NULL, 0);
1613 break;
1614 case 'b':
1615 strncpy(opts.bin_ext_file, optarg, MAX_FILENAME);
1616 ext_cnt++;
1617 break;
1618 case 'p':
1619 parse = 1;
1620 break;
1621 case 'n':
1622 nand_block_size_kb = strtoul(optarg, NULL, 0);
1623 opts.nfc_io_args |= (nand_block_size_kb / 64);
1624 break;
1625 case 't':
1626 mlc_nand = 0;
1627 if (!strncmp("MLC", optarg, 3))
1628 mlc_nand = 1;
1629 opts.nfc_io_args |= (mlc_nand << 8);
1630 break;
1631#ifdef CONFIG_MVEBU_SECURE_BOOT
1632 case 'c': /* SEC extension */
1633 strncpy(opts.sec_cfg_file, optarg, MAX_FILENAME);
1634 ext_cnt++;
1635 break;
1636 case 'k':
1637 opts.key_index = strtoul(optarg, NULL, 0);
1638 break;
1639#endif
1640 default: /* '?' */
1641 usage_err("Unknown argument");
1642 exit(EXIT_FAILURE);
1643 }
1644 }
1645
1646 /* Check validity of inputes */
1647 if (opts.load_addr % 8)
1648 usage_err("Load address must be 8 bytes aligned");
1649
1650 if (opts.baudrate % 1200)
1651 usage_err("Baudrate must be a multiple of 1200");
1652
1653 /* The remaining arguments are the input
1654 * and potentially output file
1655 */
1656 /* Input file must exist so exit if not */
1657 if (optind >= argc)
1658 usage_err("missing input file name");
1659
Matteo Crocefd10a0a2018-09-24 02:27:21 +02001660 len = strlen(argv[optind]);
1661 if (len > MAX_FILENAME)
1662 usage_err("file name too long");
1663 memcpy(in_file, argv[optind], len);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001664 optind++;
1665
1666 /* Output file must exist in non parse mode */
Matteo Crocefd10a0a2018-09-24 02:27:21 +02001667 if (optind < argc) {
1668 len = strlen(argv[optind]);
1669 if (len > MAX_FILENAME)
1670 usage_err("file name too long");
1671 memcpy(out_file, argv[optind], len);
1672 } else if (!parse)
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001673 usage_err("missing output file name");
1674
1675 /* open the input file */
1676 in_fd = fopen(in_file, "rb");
1677 if (in_fd == NULL) {
1678 printf("Error: Failed to open input file %s\n", in_file);
1679 goto main_exit;
1680 }
1681
Konstantin Porotchkin5985a1e2019-05-02 15:10:07 +03001682 /* Read the input file to buffer
1683 * Always align the image to 16 byte boundary
1684 */
1685 file_size = get_file_size(in_file);
1686 image_size = (file_size + AES_BLOCK_SZ - 1) & ~(AES_BLOCK_SZ - 1);
1687 image_buf = calloc(image_size, 1);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001688 if (image_buf == NULL) {
1689 fprintf(stderr, "Error: failed allocating input buffer\n");
1690 return 1;
1691 }
1692
Konstantin Porotchkin5985a1e2019-05-02 15:10:07 +03001693 read = fread(image_buf, file_size, 1, in_fd);
Konstantin Porotchkin434e0292018-02-26 16:28:40 +02001694 if (read != 1) {
1695 fprintf(stderr, "Error: failed to read input file\n");
1696 goto main_exit;
1697 }
1698
1699 /* Parse the input image and leave */
1700 if (parse) {
1701 if (opts.key_index >= CSK_ARR_SZ) {
1702 fprintf(stderr,
1703 "Wrong key IDX value. Valid values 0 - %d\n",
1704 CSK_ARR_SZ - 1);
1705 goto main_exit;
1706 }
1707 ret = parse_image(image_buf, image_size);
1708 goto main_exit;
1709 }
1710
1711 /* Create a blob file from all extensions */
1712 if (ext_cnt) {
1713 ret = format_extensions(ext_file);
1714 if (ret)
1715 goto main_exit;
1716 }
1717
1718 out_fd = fopen(out_file, "wb");
1719 if (out_fd == NULL) {
1720 fprintf(stderr,
1721 "Error: Failed to open output file %s\n", out_file);
1722 goto main_exit;
1723 }
1724
1725 ret = write_prolog(ext_cnt, ext_file, image_buf, image_size, out_fd);
1726 if (ret)
1727 goto main_exit;
1728
1729#ifdef CONFIG_MVEBU_SECURE_BOOT
1730 if (opts.sec_opts && (opts.sec_opts->encrypted_image != 0) &&
1731 (opts.sec_opts->enc_image_sz != 0)) {
1732 ret = write_boot_image(opts.sec_opts->encrypted_image,
1733 opts.sec_opts->enc_image_sz, out_fd);
1734 } else
1735#endif
1736 ret = write_boot_image(image_buf, image_size, out_fd);
1737 if (ret)
1738 goto main_exit;
1739
1740main_exit:
1741 if (in_fd)
1742 fclose(in_fd);
1743
1744 if (out_fd)
1745 fclose(out_fd);
1746
1747 if (image_buf)
1748 free(image_buf);
1749
1750 unlink(ext_file);
1751
1752#ifdef CONFIG_MVEBU_SECURE_BOOT
1753 if (opts.sec_opts) {
1754 if (opts.sec_opts->encrypted_image)
1755 free(opts.sec_opts->encrypted_image);
1756 free(opts.sec_opts);
1757 }
1758#endif
1759 exit(ret);
1760}