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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
package googletpm
import (
"bytes"
"fmt"
"math/big"
)
// DecodePublic decodes a TPMT_PUBLIC message. No error is returned if
// the input has extra trailing data.
func DecodePublic(buf []byte) (Public, error) {
in := bytes.NewBuffer(buf)
var pub Public
var err error
if err = UnpackBuf(in, &pub.Type, &pub.NameAlg, &pub.Attributes, &pub.AuthPolicy); err != nil {
return pub, fmt.Errorf("decoding TPMT_PUBLIC: %v", err)
}
switch pub.Type {
case AlgRSA:
pub.RSAParameters, err = decodeRSAParams(in)
case AlgECC:
pub.ECCParameters, err = decodeECCParams(in)
default:
err = fmt.Errorf("unsupported type in TPMT_PUBLIC: %v", pub.Type)
}
return pub, err
}
// Public contains the public area of an object.
type Public struct {
Type Algorithm
NameAlg Algorithm
Attributes KeyProp
AuthPolicy []byte
// If Type is AlgKeyedHash, then do not set these.
// Otherwise, only one of the Parameters fields should be set. When encoding/decoding,
// one will be picked based on Type.
RSAParameters *RSAParams
ECCParameters *ECCParams
}
// Algorithm represents a TPM_ALG_ID value.
type Algorithm uint16
// KeyProp is a bitmask used in Attributes field of key templates. Individual
// flags should be OR-ed to form a full mask.
type KeyProp uint32
// Key properties.
const (
FlagFixedTPM KeyProp = 0x00000002
FlagFixedParent KeyProp = 0x00000010
FlagSensitiveDataOrigin KeyProp = 0x00000020
FlagUserWithAuth KeyProp = 0x00000040
FlagAdminWithPolicy KeyProp = 0x00000080
FlagNoDA KeyProp = 0x00000400
FlagRestricted KeyProp = 0x00010000
FlagDecrypt KeyProp = 0x00020000
FlagSign KeyProp = 0x00040000
FlagSealDefault = FlagFixedTPM | FlagFixedParent
FlagSignerDefault = FlagSign | FlagRestricted | FlagFixedTPM |
FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
FlagStorageDefault = FlagDecrypt | FlagRestricted | FlagFixedTPM |
FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
)
func decodeRSAParams(in *bytes.Buffer) (*RSAParams, error) {
var params RSAParams
var err error
if params.Symmetric, err = decodeSymScheme(in); err != nil {
return nil, fmt.Errorf("decoding Symmetric: %v", err)
}
if params.Sign, err = decodeSigScheme(in); err != nil {
return nil, fmt.Errorf("decoding Sign: %v", err)
}
var modBytes []byte
if err := UnpackBuf(in, ¶ms.KeyBits, ¶ms.Exponent, &modBytes); err != nil {
return nil, fmt.Errorf("decoding KeyBits, Exponent, Modulus: %v", err)
}
if params.Exponent == 0 {
params.encodeDefaultExponentAsZero = true
params.Exponent = defaultRSAExponent
}
params.Modulus = new(big.Int).SetBytes(modBytes)
return ¶ms, nil
}
const defaultRSAExponent = 1<<16 + 1
// RSAParams represents parameters of an RSA key pair.
//
// Symmetric and Sign may be nil, depending on key Attributes in Public.
//
// One of Modulus and ModulusRaw must always be non-nil. Modulus takes
// precedence. ModulusRaw is used for key templates where the field named
// "unique" must be a byte array of all zeroes.
type RSAParams struct {
Symmetric *SymScheme
Sign *SigScheme
KeyBits uint16
// The default Exponent (65537) has two representations; the
// 0 value, and the value 65537.
// If encodeDefaultExponentAsZero is set, an exponent of 65537
// will be encoded as zero. This is necessary to produce an identical
// encoded bitstream, so Name digest calculations will be correct.
encodeDefaultExponentAsZero bool
Exponent uint32
ModulusRaw []byte
Modulus *big.Int
}
// SymScheme represents a symmetric encryption scheme.
type SymScheme struct {
Alg Algorithm
KeyBits uint16
Mode Algorithm
} // SigScheme represents a signing scheme.
type SigScheme struct {
Alg Algorithm
Hash Algorithm
Count uint32
}
func decodeSigScheme(in *bytes.Buffer) (*SigScheme, error) {
var scheme SigScheme
if err := UnpackBuf(in, &scheme.Alg); err != nil {
return nil, fmt.Errorf("decoding Alg: %v", err)
}
if scheme.Alg == AlgNull {
return nil, nil
}
if err := UnpackBuf(in, &scheme.Hash); err != nil {
return nil, fmt.Errorf("decoding Hash: %v", err)
}
if scheme.Alg.UsesCount() {
if err := UnpackBuf(in, &scheme.Count); err != nil {
return nil, fmt.Errorf("decoding Count: %v", err)
}
}
return &scheme, nil
}
// UsesCount returns true if a signature algorithm uses count value.
func (a Algorithm) UsesCount() bool {
return a == AlgECDAA
}
func decodeKDFScheme(in *bytes.Buffer) (*KDFScheme, error) {
var scheme KDFScheme
if err := UnpackBuf(in, &scheme.Alg); err != nil {
return nil, fmt.Errorf("decoding Alg: %v", err)
}
if scheme.Alg == AlgNull {
return nil, nil
}
if err := UnpackBuf(in, &scheme.Hash); err != nil {
return nil, fmt.Errorf("decoding Hash: %v", err)
}
return &scheme, nil
}
func decodeSymScheme(in *bytes.Buffer) (*SymScheme, error) {
var scheme SymScheme
if err := UnpackBuf(in, &scheme.Alg); err != nil {
return nil, fmt.Errorf("decoding Alg: %v", err)
}
if scheme.Alg == AlgNull {
return nil, nil
}
if err := UnpackBuf(in, &scheme.KeyBits, &scheme.Mode); err != nil {
return nil, fmt.Errorf("decoding KeyBits, Mode: %v", err)
}
return &scheme, nil
}
func decodeECCParams(in *bytes.Buffer) (*ECCParams, error) {
var params ECCParams
var err error
if params.Symmetric, err = decodeSymScheme(in); err != nil {
return nil, fmt.Errorf("decoding Symmetric: %v", err)
}
if params.Sign, err = decodeSigScheme(in); err != nil {
return nil, fmt.Errorf("decoding Sign: %v", err)
}
if err := UnpackBuf(in, ¶ms.CurveID); err != nil {
return nil, fmt.Errorf("decoding CurveID: %v", err)
}
if params.KDF, err = decodeKDFScheme(in); err != nil {
return nil, fmt.Errorf("decoding KDF: %v", err)
}
var x, y []byte
if err := UnpackBuf(in, &x, &y); err != nil {
return nil, fmt.Errorf("decoding Point: %v", err)
}
params.Point.X = new(big.Int).SetBytes(x)
params.Point.Y = new(big.Int).SetBytes(y)
return ¶ms, nil
}
// ECCParams represents parameters of an ECC key pair.
//
// Symmetric, Sign and KDF may be nil, depending on key Attributes in Public.
type ECCParams struct {
Symmetric *SymScheme
Sign *SigScheme
CurveID EllipticCurve
KDF *KDFScheme
Point ECPoint
}
// EllipticCurve identifies specific EC curves.
type EllipticCurve uint16
// ECC curves supported by TPM 2.0 spec.
const (
CurveNISTP192 = EllipticCurve(iota + 1)
CurveNISTP224
CurveNISTP256
CurveNISTP384
CurveNISTP521
CurveBNP256 = EllipticCurve(iota + 10)
CurveBNP638
CurveSM2P256 = EllipticCurve(0x0020)
)
// ECPoint represents a ECC coordinates for a point.
type ECPoint struct {
X, Y *big.Int
}
// KDFScheme represents a KDF (Key Derivation Function) scheme.
type KDFScheme struct {
Alg Algorithm
Hash Algorithm
}
|