Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | // SPDX-License-Identifier: GPL-2.0+ #include <image.h> #include "fit_common.h" static const char *cmdname; static const char *algo_name = "sha1,rsa2048"; /* -a <algo> */ static const char *keydir = "."; /* -k <keydir> */ static const char *keyname = "key"; /* -n <keyname> */ static const char *require_keys; /* -r <conf|image> */ static const char *keydest; /* argv[n] */ static void __attribute__((__noreturn__)) print_usage(const char *msg) { fprintf(stderr, "Error: %s\n", msg); fprintf(stderr, "Usage: %s [-a <algo>] [-k <keydir>] [-n <keyname>] [-r <conf|image>]" " <fdt blob>\n", cmdname); fprintf(stderr, "Help information: %s [-h]\n", cmdname); exit(EXIT_FAILURE); } static void __attribute__((__noreturn__)) print_help(void) { fprintf(stderr, "Options:\n" "\t-a <algo> Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n" "\t-k <keydir> Directory with public key. Optional parameter, default value: .\n" "\t-n <keyname> Public key name. Optional parameter, default value: key\n" "\t-r <conf|image> Required: If present this indicates that the key must be verified for the image / configuration to be considered valid.\n" "\t<fdt blob> FDT blob file for adding of the public key. Required parameter.\n"); exit(EXIT_FAILURE); } static void process_args(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "a:k:n:r:h")) != -1) { switch (opt) { case 'k': keydir = optarg; break; case 'a': algo_name = optarg; break; case 'n': keyname = optarg; break; case 'r': require_keys = optarg; break; case 'h': print_help(); default: print_usage("Invalid option"); } } /* The last parameter is expected to be the .dtb to add the public key to */ if (optind < argc) keydest = argv[optind]; if (!keydest) print_usage("Missing dtb file to update"); } static void reset_info(struct image_sign_info *info) { if (!info) fprintf(stderr, "Error: info is NULL in %s\n", __func__); memset(info, 0, sizeof(struct image_sign_info)); info->keydir = keydir; info->keyname = keyname; info->name = algo_name; info->require_keys = require_keys; info->crypto = image_get_crypto_algo(algo_name); if (!info->crypto) { fprintf(stderr, "Unsupported signature algorithm '%s'\n", algo_name); exit(EXIT_FAILURE); } } static int add_pubkey(struct image_sign_info *info) { int destfd = -1, ret; void *dest_blob = NULL; struct stat dest_sbuf; size_t size_inc = 0; if (!info) fprintf(stderr, "Error: info is NULL in %s\n", __func__); do { if (destfd >= 0) { munmap(dest_blob, dest_sbuf.st_size); close(destfd); fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n"); size_inc = 1024; } destfd = mmap_fdt(cmdname, keydest, size_inc, &dest_blob, &dest_sbuf, false, false); if (destfd < 0) exit(EXIT_FAILURE); ret = info->crypto->add_verify_data(info, dest_blob); if (ret == -ENOSPC) continue; else if (ret < 0) break; } while (ret == -ENOSPC); return ret; } int main(int argc, char *argv[]) { struct image_sign_info info; int ret; cmdname = argv[0]; process_args(argc, argv); reset_info(&info); ret = add_pubkey(&info); if (ret < 0) { fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n", cmdname, strerror(ret)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } |