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