123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*
- * Copyright (c) 2019, Linaro Limited. All rights reserved.
- * Author: Sumit Garg <sumit.garg@linaro.org>
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <assert.h>
- #include <ctype.h>
- #include <getopt.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include <openssl/conf.h>
- #include "cmd_opt.h"
- #include "debug.h"
- #include "encrypt.h"
- #include "firmware_encrypted.h"
- #define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0])))
- #define HELP_OPT_MAX_LEN 128
- /* Global options */
- /* Info messages created in the Makefile */
- extern const char build_msg[];
- static char *key_algs_str[] = {
- [KEY_ALG_GCM] = "gcm",
- };
- static void print_help(const char *cmd, const struct option *long_opt)
- {
- int rem, i = 0;
- const struct option *opt;
- char line[HELP_OPT_MAX_LEN];
- char *p;
- assert(cmd != NULL);
- assert(long_opt != NULL);
- printf("\n\n");
- printf("The firmware encryption tool loads the binary image and\n"
- "outputs encrypted binary image using an encryption key\n"
- "provided as an input hex string.\n");
- printf("\n");
- printf("Usage:\n");
- printf("\t%s [OPTIONS]\n\n", cmd);
- printf("Available options:\n");
- opt = long_opt;
- while (opt->name) {
- p = line;
- rem = HELP_OPT_MAX_LEN;
- if (isalpha(opt->val)) {
- /* Short format */
- sprintf(p, "-%c,", (char)opt->val);
- p += 3;
- rem -= 3;
- }
- snprintf(p, rem, "--%s %s", opt->name,
- (opt->has_arg == required_argument) ? "<arg>" : "");
- printf("\t%-32s %s\n", line, cmd_opt_get_help_msg(i));
- opt++;
- i++;
- }
- printf("\n");
- }
- static int get_key_alg(const char *key_alg_str)
- {
- int i;
- for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
- if (strcmp(key_alg_str, key_algs_str[i]) == 0) {
- return i;
- }
- }
- return -1;
- }
- static void parse_fw_enc_status_flag(const char *arg,
- unsigned short *fw_enc_status)
- {
- unsigned long flag;
- char *endptr;
- flag = strtoul(arg, &endptr, 16);
- if (*endptr != '\0' || flag > FW_ENC_WITH_BSSK) {
- ERROR("Invalid fw_enc_status flag '%s'\n", arg);
- exit(1);
- }
- *fw_enc_status = flag & FW_ENC_STATUS_FLAG_MASK;
- }
- /* Common command line options */
- static const cmd_opt_t common_cmd_opt[] = {
- {
- { "help", no_argument, NULL, 'h' },
- "Print this message and exit"
- },
- {
- { "fw-enc-status", required_argument, NULL, 'f' },
- "Firmware encryption status flag (with SSK=0 or BSSK=1)."
- },
- {
- { "key-alg", required_argument, NULL, 'a' },
- "Encryption key algorithm: 'gcm' (default)"
- },
- {
- { "key", required_argument, NULL, 'k' },
- "Encryption key (for supported algorithm)."
- },
- {
- { "nonce", required_argument, NULL, 'n' },
- "Nonce or Initialization Vector (for supported algorithm)."
- },
- {
- { "in", required_argument, NULL, 'i' },
- "Input filename to be encrypted."
- },
- {
- { "out", required_argument, NULL, 'o' },
- "Encrypted output filename."
- },
- };
- int main(int argc, char *argv[])
- {
- int i, key_alg, ret;
- int c, opt_idx = 0;
- const struct option *cmd_opt;
- char *key = NULL;
- char *nonce = NULL;
- char *in_fn = NULL;
- char *out_fn = NULL;
- unsigned short fw_enc_status = 0;
- NOTICE("Firmware Encryption Tool: %s\n", build_msg);
- /* Set default options */
- key_alg = KEY_ALG_GCM;
- /* Add common command line options */
- for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
- cmd_opt_add(&common_cmd_opt[i]);
- }
- /* Get the command line options populated during the initialization */
- cmd_opt = cmd_opt_get_array();
- while (1) {
- /* getopt_long stores the option index here. */
- c = getopt_long(argc, argv, "a:f:hi:k:n:o:", cmd_opt, &opt_idx);
- /* Detect the end of the options. */
- if (c == -1) {
- break;
- }
- switch (c) {
- case 'a':
- key_alg = get_key_alg(optarg);
- if (key_alg < 0) {
- ERROR("Invalid key algorithm '%s'\n", optarg);
- exit(1);
- }
- break;
- case 'f':
- parse_fw_enc_status_flag(optarg, &fw_enc_status);
- break;
- case 'k':
- key = optarg;
- break;
- case 'i':
- in_fn = optarg;
- break;
- case 'o':
- out_fn = optarg;
- break;
- case 'n':
- nonce = optarg;
- break;
- case 'h':
- print_help(argv[0], cmd_opt);
- exit(0);
- case '?':
- default:
- print_help(argv[0], cmd_opt);
- exit(1);
- }
- }
- if (!key) {
- ERROR("Key must not be NULL\n");
- exit(1);
- }
- if (!nonce) {
- ERROR("Nonce must not be NULL\n");
- exit(1);
- }
- if (!in_fn) {
- ERROR("Input filename must not be NULL\n");
- exit(1);
- }
- if (!out_fn) {
- ERROR("Output filename must not be NULL\n");
- exit(1);
- }
- ret = encrypt_file(fw_enc_status, key_alg, key, nonce, in_fn, out_fn);
- CRYPTO_cleanup_all_ex_data();
- return ret;
- }
|