File: caps.go

package info (click to toggle)
golang-github-smallstep-crypto 0.57.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,284 kB
  • sloc: sh: 53; makefile: 36
file content (80 lines) | stat: -rw-r--r-- 1,786 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package tpm

import (
	"context"
	"fmt"
	"slices"

	"github.com/google/go-tpm/legacy/tpm2"
	"go.step.sm/crypto/tpm/algorithm"
)

// Capabilities represents the capabilities of the TPM.
type Capabilities struct {
	Algorithms []algorithm.Algorithm
}

// SupportsAlgorithm return whether the provided algorithm
// is supported by the TPM
func (c *Capabilities) SupportsAlgorithm(alg algorithm.Algorithm) bool {
	return slices.Contains(c.Algorithms, alg)
}

// SupportsAlgorithms return whether all algorithms in the provided
// slice are supported by the TPM
func (c *Capabilities) SupportsAlgorithms(algs []algorithm.Algorithm) bool {
	for _, alg := range algs {
		if !c.SupportsAlgorithm(alg) {
			return false
		}
	}
	return true
}

// GetCapabilities returns the capabilities of the TPM; currently suports
// enumerating the supported algorithms
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
// release.
func (t *TPM) GetCapabilities(ctx context.Context) (caps *Capabilities, err error) {
	if t.caps != nil {
		return t.caps, nil
	}

	if err = t.open(goTPMCall(ctx)); err != nil {
		return nil, fmt.Errorf("failed opening TPM: %w", err)
	}
	defer closeTPM(ctx, t, &err)

	current := tpm2.AlgUnknown // 0x0000, first property
	caps = &Capabilities{}

	for {
		var (
			data []any
			more bool
		)

		data, more, err := tpm2.GetCapability(t.rwc, tpm2.CapabilityAlgs, 1, uint32(current))
		if err != nil {
			return nil, fmt.Errorf("error getting algorithms capability: %w", err)
		}

		if d, ok := data[0].(tpm2.AlgorithmDescription); ok {
			alg := algorithm.Algorithm(d.ID)
			if !slices.Contains(caps.Algorithms, alg) {
				caps.Algorithms = append(caps.Algorithms, alg)
			}
		}

		if !more {
			break
		}

		current++
	}

	t.caps = caps

	return
}