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

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

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

First post the source code of the function again:

static bool tpm2_tool_onstart(tpm2_options **opts) {

    static struct option topts[] = {
      { "parent-auth",    required_argument, NULL, 'P' },
      { "key-auth",       required_argument, NULL, 'p' },
      { "hash-algorithm", required_argument, NULL, 'g' },
      { "key-algorithm",  required_argument, NULL, 'G' },
      { "attributes",     required_argument, NULL, 'a' },
      { "sealing-input",  required_argument, NULL, 'i' },
      { "policy",         required_argument, NULL, 'L' },
      { "public",         required_argument, NULL, 'u' },
      { "private",        required_argument, NULL, 'r' },
      { "parent-context", required_argument, NULL, 'C' },
      { "key-context",    required_argument, NULL, 'c' },
      { "creation-data",  required_argument, NULL,  0  },
      { "template-data",  required_argument, NULL,  1  },
      { "creation-ticket",required_argument, NULL, 't' },
      { "creation-hash",  required_argument, NULL, 'd' },
      { "outside-info",   required_argument, NULL, 'q' },
      { "pcr-list",       required_argument, NULL, 'l' },
      { "cphash",         required_argument, NULL,  2  },
      { "rphash",         required_argument, NULL,  3  },
      { "session",        required_argument, NULL, 'S' },
      { "format",         required_argument, NULL, 'f' },
      { "output",         required_argument, NULL, 'o' },
    };

    *opts = tpm2_options_new("P:p:g:G:a:i:L:u:r:C:c:t:d:q:l:S:o:f:",
    ARRAY_LEN(topts), topts, on_option, NULL, 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/tpm_create.c), as follows:

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

    switch (key) {
    case 'P':
        ctx.parent.auth_str = value;
        break;
    case 'p':
        ctx.object.auth_str = value;
        break;
    case 'g':
        ctx.object.name_alg = value;
        break;
    case 'G':
        ctx.object.alg = value;
        ctx.object.is_object_alg_specified = true;
        break;
    case 'a':
        ctx.object.attrs = value;
        break;
    case 'i':
        ctx.object.sealed_data = strcmp("-", value) ? value : NULL;
        ctx.object.alg = "keyedhash";
        ctx.object.is_sealing_input_specified = true;
        bool res = load_sensitive();
        if (!res) {
            return false;
        }
        break;
    case 'L':
        ctx.object.policy = value;
        break;
    case 'u':
        ctx.object.public_path = value;
        break;
    case 'r':
        ctx.object.private_path = value;
        break;
    case 'C':
        ctx.parent.ctx_path = value;
        break;
    case 'c':
        ctx.object.ctx_path = value;
        break;
    case 0:
        ctx.object.creation_data_file = value;
        break;
    case 1:
        ctx.object.template_data_path = value;
        break;
    case 't':
        ctx.object.creation_ticket_file = value;
        break;
    case 'd':
        ctx.object.creation_hash_file = value;
        break;
    case 'q':
        ctx.object.outside_info_data = value;
        break;
    case 'l':
        if (!pcr_parse_selections(value, &ctx.object.creation_pcr)) {
            LOG_ERR("Could not parse pcr selections, got: \"%s\"", value);
            return false;
        }
        break;
    case 2:
        ctx.cp_hash_path = value;
        break;
    case 3:
        ctx.rp_hash_path = value;
        break;
    case 'S':
        ctx.aux_session_path[ctx.aux_session_cnt] = value;
        if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) {
            ctx.aux_session_cnt++;
        } else {
            LOG_ERR("Specify a max of 3 sessions");
            return false;
        }
        break;
    case 'f':
        ctx.format = tpm2_convert_pubkey_fmt_from_optarg(value);
        if (ctx.format == pubkey_format_err) {
            return false;
        }
        ctx.format_set = true;
        break;
    case 'o':
        ctx.output_path = value;
        break;
        /* no default */
    };

    return true;
}

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

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

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

The parameters are described as follows:

OPTIONS

These options for creating the TPM entity:

  • -C--parent-context=OBJECT:

    The parent of the object to be created. —— The parent of the object to be created.

  • -P--parent-auth=AUTH:

    The authorization value of the parent object specified with  -C . —— Use the authorization value of the parent object specified by -C .

  • -p--key-auth=AUTH:

    The authorization value for the created object. —— The authorization value for the created object.

  • -g--hash-algorithm=ALGORITHM:

    The hash algorithm for generating the objects name. This is optional and defaults to sha256 when not specified. —— The hash algorithm for generating the objects name. This is optional and defaults to sha256 when not specified.

  • -G--key-algorithm=ALGORITHM:

    The key algorithm associated with this object. It defaults to "rsa" if not specified. —— The key algorithm associated with this object. Defaults to "rsa" if not specified.

  • -a--attributes=ATTRIBUTES:

    The object attributes, optional. The default for created objects is: —— Object attributes, optional. The default is:

    TPMA_OBJECT_SIGN_ENCRYPT|TPMA_OBJECT_DECRYPT|TPMA_OBJECT_FIXEDTPM| TPMA_OBJECT_FIXEDPARENT|TPMA_OBJECT_SENSITIVEDATAORIGIN| TPMA_OBJECT_USERWITHAUTH

    When  -i  is specified for sealing,  TPMA_OBJECT_SIGN_ENCRYPT and  TPMA_OBJECT_DECRYPT are removed from the default attribute set. The algorithm is set in a way where the the object is only good for sealing and unsealing. Ie one cannot use an object for sealing and cryptography operations. —— When  –i  is specified as sealed, TPMA_OBJECT_SIGN_ENCRYPT and TPMA_OBJECT_DECRYPT are removed from the default attribute set. The algorithm is set in such a way that the object is only valid for sealing and unsealing. That is, objects cannot be used for sealed cryptographic operations.

    When  -L  is specified for adding policy based authorization information AND no string password is specified, the attribute  TPMA_OBJECT_USERWITHAUTH is cleared unless an explicit choice is made by setting of the attribute with  -a  option. This prevents creation of objects with inadvertent auth model where in user intended to enforce a policy but inadvertently created an object with empty auth which can be used instead of policy authorization. —— When specifying -L and not specifying a string password is to add policy-based authorization information, unless the property is set by using the -a option Make an explicit choice, otherwise the property TPMA_OBJECT_USERWITHAUTH will be cleared. This prevents the creation of objects with an unintentional authentication model, where a user intends to enforce policy, but inadvertently creates an object with empty authentication, which can be used in place of policy authorization.

  • -i--sealing-input=FILE or STDIN:

    The data file to be sealed, optional. If file is -, read from stdin. When sealing data only the  TPM_ALG_KEYEDHASH  algorithm with a NULL scheme is allowed. Thus,  -G  cannot be specified. —— the data file to be sealed, optional . If file is -, read from standard input. When sealing data, only TPM_ALG_KEYEDHASH algorithm with NULL scheme is allowed. Therefore, -G cannot be specified.

  • -L--policy=FILE or HEX_STRING:

    The input policy file or a hex string, optional. —— input policy file, optional.

  • -u--public=FILE:

    The output file which contains the public portion of the created object, optional.

  • -r--private=FILE:

    The output file which contains the sensitive portion of the object, optional. Objects that can be moved out of the TPM need to have their confidentiality and integrity protected. This blob contains sensitive parts of the object. Sensitive parts of the object are protected by the parent object, using the parent object's symmetric encryption details to encrypt sensitive data and HMAC it.

  • -c--key-context=FILE:

    The output file which contains the key context, optional. The key context is analogous to the context file produced by  tpm2_load (1), however is generated via a  tpm2_createloaded (1) command. This option can be used to avoid the normal  tpm2_create (1 ) and  tpm2_load (1) command sequences and do it all in one command, atomically. - output file containing key context, optional. key-context is similar to the context file generated by tpm2_load , but is generated by the tpm2_createloaded command. This option can be used to avoid the normal sequence of tpm2_create and tpm2_load commands and do it all atomically in one command.

  • --creation-data=FILE:

    An optional file output that saves the creation data for certification. - An optional file output that saves the creation data for certification.

    • --template-data=FILE:

    An optional file output that saves the key template data (TPM2B_PUBLIC) to be used in  tpm2_policytemplate . —— An optional file output that saves the key template data (TPM2B_PUBLIC) to be used in tpm2_policytemplate.

  • -t--creation-ticket=FILE:

    An optional file output that saves the creation ticket for certification. —— An optional file output that saves the creation ticket for certification.

  • -d--creation-hash=FILE:

    An optional file output that saves the creation hash for certification. - An optional file output that saves the creation hash for certification.

  • -q--outside-info=HEX_STR_OR_FILE:

    An optional hex string or path to add unique data to the creation data. Note that it does not contribute in creating statistically unique object. It won't help in creating statistically unique objects.

  • -l--pcr-list=PCR:

    The list of PCR banks and selected PCRs' ids for each bank to be included in the creation data for certification.

  • --cphash=FILE

    File path to record the hash of the command parameters. This is commonly termed as cpHash. NOTE: When this option is selected, The tool will not actually execute the command, it simply returns a cpHash. path. This is often called cpHash. NOTE: When this option is selected, the tool does not actually execute the command, it just returns a cpHash.

  • --rphash=FILE

    File path to record the hash of the response parameters. This is commonly termed as rpHash. This is often called rpHash.

  • -S--session=FILE:

    The session created using  tpm2_startauthsession . Multiple of these can be specified. For example, you can have one session for auditing and another for encryption/decryption of the parameters. —— session created using tpm2_startauthsession . Multiple of these can be specified. For example, you can have one session for auditing and another for encryption/decryption of parameters.

pubkey options

Public key format.
  • -o--output=FILE:

    The output file path, recording the public portion of the object. —— The output file path, recording the public portion of the object.

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_create.c is basically analyzed.

Guess you like

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