tpm2_rsaencrypt.c of tpm2-tools source code analysis (2)

Continued from the previous article: tpm2_rsaencrypt.c of tpm2-tools source code analysis (1)

This article analyzes the tpm2_tool_onstart function in tpm2_rsaencrypt.c in detail.

First post the source code of the function again:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    static const struct option topts[] = {
      {"output",      required_argument, NULL, 'o'},
      {"key-context", required_argument, NULL, 'c'},
      {"scheme",      required_argument, NULL, 's'},
      {"label",       required_argument, NULL, 'l'},
    };

    *opts = tpm2_options_new("o:c:s:l:", ARRAY_LEN(topts), topts, on_option,
            on_args, 0);

    return *opts != NULL;
}

The definition of the tpm2_options structure is in tpm2-tools/lib/tpm2_options.h, the code is as follows:

struct tpm2_options {
    struct {
        tpm2_option_handler on_opt;
        tpm2_arg_handler on_arg;
    } callbacks;
    char *short_opts;
    size_t len;
    uint32_t flags;
    struct option long_opts[];
};
 
typedef struct tpm2_options tpm2_options;

The definition of struct option is in /usr/include/bits/getopt_ext.h, the code is as follows:

struct option
{
  const char *name;
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;
  int *flag;
  int val;
};

The implementation of the on_option function is in the same file (tools/tpm2_rsaencrypt.c), as follows:

static bool on_option(char key, char *value) {

    switch (key) {
    case 'c':
        ctx.context_arg = value;
        break;
    case 'o':
        ctx.output_path = value;
        break;
    case 's':
        ctx.scheme_str = value;
        break;
    case 'l':
        return tpm2_util_get_label(value, &ctx.label);
    }
    return true;
}

To better understand these options and even the function of the tpm2_tool_onstart function, it needs to be combined with the description of the tpm2_rsaencrypt command. For a detailed description of the tpm2_rsaencrypt command, see:

tpm2-tools/tpm2_rsaencrypt.1.md at master · tpm2-software/tpm2-tools · GitHub

After downloading the source code, it is in tpm2-tools/man/tpm2_rsaencrypt.1.md.

The parameters are described as follows:

OPTIONS

  • -c--key-context=OBJECT:

    Context object pointing to the the public portion of RSA key to use for encryption. —— Pointing to the context object of the public portion of the RSA key used for encryption.

  • -o--output=FILE:

    Optional output file path to record the encrypted data to. The default is to print the binary encrypted data to stdout. Prints binary encrypted data to standard output (stdout) by default.

  • -s--scheme=FORMAT:

    Optional, set the padding scheme (defaults to rsaes). —— Optional, set the padding scheme (defaults to rsaes).

    • null - TPM_ALG_NULL uses the key's scheme if set.
    • rsaes - TPM_ALG_RSAES which is RSAES_PKCSV1.5.
    • oaep - TPM_ALG_OAEP which is RSAES_OAEP.
  • -l--label=FILE or STRING:

    Optional, set the label data. Can either be a string or file path. The TPM requires the last byte of the label to be zero, this is handled internally to the tool. No other embedded 0 bytes can exist or the TPM will truncate your label. - optional, set the label data. Can be a string or a file path. The TPM requires the last byte of the tag to be zero, this is handled internally by the tool. There are no other embedded 0 bytes, otherwise the TPM will truncate your tag.

  • ARGUMENT  the command line argument specifies the path of the file with data to be encrypted. —— Specifies the command line parameter of the file path containing the data to be encrypted.

The tpm2_options_new function belongs to the public code. In tpm2-tools/lib/tpm2_options.c, the code is as follows:

tpm2_options *tpm2_options_new(const char *short_opts, size_t len,
        const struct option *long_opts, tpm2_option_handler on_opt,
        tpm2_arg_handler on_arg, uint32_t flags) {
 
    tpm2_options *opts = calloc(1, sizeof(*opts) + (sizeof(*long_opts) * len));
    if (!opts) {
        LOG_ERR("oom");
        return NULL;
    }
 
    /*
     * On NULL, just make it a zero length string so we don't have to keep
     * checking it for NULL.
     */
    if (!short_opts) {
        short_opts = "";
    }
 
    opts->short_opts = strdup(short_opts);
    if (!opts->short_opts) {
        LOG_ERR("oom");
        free(opts);
        return NULL;
    }
 
    opts->callbacks.on_opt = on_opt;
    opts->callbacks.on_arg = on_arg;
    opts->len = len;
    opts->flags = flags;
    memcpy(opts->long_opts, long_opts, len * sizeof(*long_opts));
 
    return opts;
}

The tpm2_new_options function is easy to understand, and its function is to construct a tpm2_options instance (*opts) based on the struct option topts in the tpm2_tool_onstart function.

So far, the tpm2_tool_onstart function in tpm2_rsaencrypt.c is basically analyzed.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/130606477