google / go-tpm

Apache License 2.0
562 stars 161 forks source link

cmdAuths not respecting auth value #363

Closed jeremyhahn closed 4 months ago

jeremyhahn commented 4 months ago

Steps to reproduce:

  1. Use tpm2.HierarchyChangeAuth to set the password for a hierarchy.
  2. Try to pass the auth option when creating a primary key

         primaryKey, err := tpm2.CreatePrimary{
        PrimaryHandle: hierarchy,
        InPublic:      tpm2.New2B(tpm2.RSAEKTemplate),
        InSensitive: tpm2.TPM2BSensitiveCreate{
            Sensitive: &tpm2.TPMSSensitiveCreate{
                UserAuth: tpm2.TPM2BAuth{
                    Buffer: []byte("my-hierarchy-password"),
                },
            },
        },
    }.Execute(rwc)
    
        // TPM_RC_BAD_AUTH (session 1): authorization failure without DA implications

I can see that my password is being passed into tpm2.execute[R any] properly and passed to cmdAuths, where I enter this function:

// cmdAuths returns the authorization sessions of the command.
func cmdAuths[R any](cmd Command[R, *R]) ([]Session, error) {
    authHandles := taggedMembers(reflect.ValueOf(cmd), "auth", false)
    var result []Session
    for i, authHandle := range authHandles {
        // TODO: A cleaner way to do this would be to have an interface method that
        // returns a Session.
        if h, ok := authHandle.Interface().(AuthHandle); ok {
            if h.Auth == nil {
                return nil, fmt.Errorf("missing auth for '%v' parameter",
                    reflect.ValueOf(cmd).Type().Field(i).Name)
            }
            result = append(result, h.Auth)
        } else {
            result = append(result, PasswordAuth(nil))
        }
    }

    return result, nil
}

The if statement with the TODO seems to be incorrectly parsing the command, leading to the PasswordAuth(nil) being set instead of my password.

Is this a bug or am I doing something wrong here?

jeremyhahn commented 4 months ago

I realized my mistake, I was passing the hierarchy password as the primary key auth, and needed to pass the hierarchy auth like this instead:

PrimaryHandle: tpm2.AuthHandle{
    Handle: tpm2.TPMRHOwner,
    Auth:   tpm2.PasswordAuth([]byte("my-hierarchy-password")),
},