Skip to content

Commit b3f77a5

Browse files
DenisKarchAndrew Lytvynov
authored and
Andrew Lytvynov
committed
Replace global prefix size with U32Bytes and U16Bytes (#92)
* Replace global prefix size with U32Bytes and U16Bytes * Modify tpm1.2 and tpm2.0 commands to use these types instead of []byte * Make *[]Handle a SelfMarshaler
1 parent 52dce99 commit b3f77a5

14 files changed

+426
-453
lines changed

tpm/commands.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func osap(rw io.ReadWriter, osap *osapCommand) (*osapResponse, error) {
6767
}
6868

6969
// seal performs a seal operation on the TPM.
70-
func seal(rw io.ReadWriter, sc *sealCommand, pcrs *pcrInfoLong, data []byte, ca *commandAuth) (*tpmStoredData, *responseAuth, uint32, error) {
70+
func seal(rw io.ReadWriter, sc *sealCommand, pcrs *pcrInfoLong, data tpmutil.U32Bytes, ca *commandAuth) (*tpmStoredData, *responseAuth, uint32, error) {
7171
pcrsize := binary.Size(pcrs)
7272
if pcrsize < 0 {
7373
return nil, nil, 0, errors.New("couldn't compute the size of a pcrInfoLong")
@@ -91,7 +91,7 @@ func seal(rw io.ReadWriter, sc *sealCommand, pcrs *pcrInfoLong, data []byte, ca
9191
// unseal data sealed by the TPM.
9292
func unseal(rw io.ReadWriter, keyHandle tpmutil.Handle, sealed *tpmStoredData, ca1 *commandAuth, ca2 *commandAuth) ([]byte, *responseAuth, *responseAuth, uint32, error) {
9393
in := []interface{}{keyHandle, sealed, ca1, ca2}
94-
var outb []byte
94+
var outb tpmutil.U32Bytes
9595
var ra1 responseAuth
9696
var ra2 responseAuth
9797
out := []interface{}{&outb, &ra1, &ra2}
@@ -149,8 +149,8 @@ func getCapability(rw io.ReadWriter, cap, subcap uint32) ([]byte, error) {
149149
if err != nil {
150150
return nil, err
151151
}
152-
var b []byte
153-
in := []interface{}{cap, subCapBytes}
152+
var b tpmutil.U32Bytes
153+
in := []interface{}{cap, tpmutil.U32Bytes(subCapBytes)}
154154
out := []interface{}{&b}
155155
if _, err := submitTPMRequest(rw, tagRQUCommand, ordGetCapability, in, out); err != nil {
156156
return nil, err
@@ -159,7 +159,7 @@ func getCapability(rw io.ReadWriter, cap, subcap uint32) ([]byte, error) {
159159
}
160160

161161
func nvReadValue(rw io.ReadWriter, index, offset, len uint32, ca *commandAuth) ([]byte, *responseAuth, uint32, error) {
162-
var b []byte
162+
var b tpmutil.U32Bytes
163163
var ra responseAuth
164164
in := []interface{}{index, offset, len, ca}
165165
out := []interface{}{&b, &ra}
@@ -179,8 +179,8 @@ func quote2(rw io.ReadWriter, keyHandle tpmutil.Handle, hash [20]byte, pcrs *pcr
179179
in := []interface{}{keyHandle, hash, pcrs, addVersion, ca}
180180
var pcrShort pcrInfoShort
181181
var capInfo capVersionInfo
182-
var capBytes []byte
183-
var sig []byte
182+
var capBytes tpmutil.U32Bytes
183+
var sig tpmutil.U32Bytes
184184
var ra responseAuth
185185
out := []interface{}{&pcrShort, &capBytes, &sig, &ra}
186186
ret, err := submitTPMRequest(rw, tagRQUAuth1Command, ordQuote2, in, out)
@@ -189,17 +189,17 @@ func quote2(rw io.ReadWriter, keyHandle tpmutil.Handle, hash [20]byte, pcrs *pcr
189189
}
190190

191191
// Deserialize the capInfo, if any.
192-
if len(capBytes) == 0 {
192+
if len([]byte(capBytes)) == 0 {
193193
return &pcrShort, nil, capBytes, sig, &ra, ret, nil
194194
}
195195

196196
size := binary.Size(capInfo.CapVersionFixed)
197-
capInfo.VendorSpecific = make([]byte, len(capBytes)-size)
198-
if _, err := tpmutil.Unpack(capBytes[:size], &capInfo.CapVersionFixed); err != nil {
197+
capInfo.VendorSpecific = make([]byte, len([]byte(capBytes))-size)
198+
if _, err := tpmutil.Unpack([]byte(capBytes)[:size], &capInfo.CapVersionFixed); err != nil {
199199
return nil, nil, nil, nil, nil, 0, err
200200
}
201201

202-
copy(capInfo.VendorSpecific, capBytes[size:])
202+
copy(capInfo.VendorSpecific, []byte(capBytes)[size:])
203203

204204
return &pcrShort, &capInfo, capBytes, sig, &ra, ret, nil
205205
}
@@ -209,7 +209,7 @@ func quote2(rw io.ReadWriter, keyHandle tpmutil.Handle, hash [20]byte, pcrs *pcr
209209
func quote(rw io.ReadWriter, keyHandle tpmutil.Handle, hash [20]byte, pcrs *pcrSelection, ca *commandAuth) (*pcrComposite, []byte, *responseAuth, uint32, error) {
210210
in := []interface{}{keyHandle, hash, pcrs, ca}
211211
var pcrc pcrComposite
212-
var sig []byte
212+
var sig tpmutil.U32Bytes
213213
var ra responseAuth
214214
out := []interface{}{&pcrc, &sig, &ra}
215215
ret, err := submitTPMRequest(rw, tagRQUAuth1Command, ordQuote, in, out)
@@ -225,7 +225,7 @@ func quote(rw io.ReadWriter, keyHandle tpmutil.Handle, hash [20]byte, pcrs *pcrS
225225
func makeIdentity(rw io.ReadWriter, encAuth digest, idDigest digest, k *key, ca1 *commandAuth, ca2 *commandAuth) (*key, []byte, *responseAuth, *responseAuth, uint32, error) {
226226
in := []interface{}{encAuth, idDigest, k, ca1, ca2}
227227
var aik key
228-
var sig []byte
228+
var sig tpmutil.U32Bytes
229229
var ra1 responseAuth
230230
var ra2 responseAuth
231231
out := []interface{}{&aik, &sig, &ra1, &ra2}
@@ -239,7 +239,7 @@ func makeIdentity(rw io.ReadWriter, encAuth digest, idDigest digest, k *key, ca1
239239

240240
// activateIdentity provides the TPM with an EK encrypted challenge and asks it to
241241
// decrypt the challenge and return the secret (symmetric key).
242-
func activateIdentity(rw io.ReadWriter, keyHandle tpmutil.Handle, blob []byte, ca1 *commandAuth, ca2 *commandAuth) (*symKey, *responseAuth, *responseAuth, uint32, error) {
242+
func activateIdentity(rw io.ReadWriter, keyHandle tpmutil.Handle, blob tpmutil.U32Bytes, ca1 *commandAuth, ca2 *commandAuth) (*symKey, *responseAuth, *responseAuth, uint32, error) {
243243
in := []interface{}{keyHandle, blob, ca1, ca2}
244244
var symkey symKey
245245
var ra1 responseAuth
@@ -317,7 +317,7 @@ func ownerClear(rw io.ReadWriter, ca *commandAuth) (*responseAuth, uint32, error
317317
// owner auth. This operation can only be performed if there is no owner. The
318318
// TPM can be put into this state using TPM_OwnerClear. The encOwnerAuth and
319319
// encSRKAuth values must be encrypted using the endorsement key.
320-
func takeOwnership(rw io.ReadWriter, encOwnerAuth []byte, encSRKAuth []byte, srk *key, ca *commandAuth) (*key, *responseAuth, uint32, error) {
320+
func takeOwnership(rw io.ReadWriter, encOwnerAuth tpmutil.U32Bytes, encSRKAuth tpmutil.U32Bytes, srk *key, ca *commandAuth) (*key, *responseAuth, uint32, error) {
321321
in := []interface{}{pidOwner, encOwnerAuth, encSRKAuth, srk, ca}
322322
var k key
323323
var ra responseAuth
@@ -344,9 +344,9 @@ func createWrapKey(rw io.ReadWriter, encUsageAuth digest, encMigrationAuth diges
344344
return &k, &ra, ret, nil
345345
}
346346

347-
func sign(rw io.ReadWriter, keyHandle tpmutil.Handle, data []byte, ca *commandAuth) ([]byte, *responseAuth, uint32, error) {
347+
func sign(rw io.ReadWriter, keyHandle tpmutil.Handle, data tpmutil.U32Bytes, ca *commandAuth) ([]byte, *responseAuth, uint32, error) {
348348
in := []interface{}{keyHandle, data, ca}
349-
var signature []byte
349+
var signature tpmutil.U32Bytes
350350
var ra responseAuth
351351
out := []interface{}{&signature, &ra}
352352
ret, err := submitTPMRequest(rw, tagRQUAuth1Command, ordSign, in, out)

tpm/constants.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ package tpm
1616

1717
import "github.com/google/go-tpm/tpmutil"
1818

19-
func init() {
20-
// TPM 1.2 spec uses uint32 for length prefix of byte arrays.
21-
tpmutil.UseTPM12LengthPrefixSize()
22-
}
23-
2419
// Supported TPM commands.
2520
const (
2621
tagPCRInfoLong uint16 = 0x06

tpm/structures.go

Lines changed: 14 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package tpm
1717
import (
1818
"crypto"
1919
"crypto/rsa"
20-
"encoding/binary"
2120
"errors"
2221
"fmt"
2322
"io"
@@ -193,7 +192,7 @@ type keyParams struct {
193192
AlgID uint32
194193
EncScheme uint16
195194
SigScheme uint16
196-
Params []byte // Serialized rsaKeyParams or symmetricKeyParams.
195+
Params tpmutil.U32Bytes // Serialized rsaKeyParams or symmetricKeyParams.
197196
}
198197

199198
// An rsaKeyParams encodes the length of the RSA prime in bits, the number of
@@ -202,13 +201,13 @@ type keyParams struct {
202201
type rsaKeyParams struct {
203202
KeyLength uint32
204203
NumPrimes uint32
205-
Exponent []byte
204+
Exponent tpmutil.U32Bytes
206205
}
207206

208207
type symmetricKeyParams struct {
209208
KeyLength uint32
210209
BlockSize uint32
211-
IV []byte
210+
IV tpmutil.U32Bytes
212211
}
213212

214213
// A key is a TPM representation of a key.
@@ -218,9 +217,9 @@ type key struct {
218217
KeyFlags uint32
219218
AuthDataUsage byte
220219
AlgorithmParams keyParams
221-
PCRInfo []byte
222-
PubKey []byte
223-
EncData []byte
220+
PCRInfo tpmutil.U32Bytes
221+
PubKey tpmutil.U32Bytes
222+
EncData tpmutil.U32Bytes
224223
}
225224

226225
// A key12 is a newer TPM representation of a key.
@@ -231,73 +230,29 @@ type key12 struct {
231230
KeyFlags uint32
232231
AuthDataUsage byte
233232
AlgorithmParams keyParams
234-
PCRInfo []byte // This must be a serialization of a pcrInfoLong.
235-
PubKey []byte
236-
EncData []byte
233+
PCRInfo tpmutil.U32Bytes // This must be a serialization of a pcrInfoLong.
234+
PubKey tpmutil.U32Bytes
235+
EncData tpmutil.U32Bytes
237236
}
238237

239238
// A pubKey represents a public key known to the TPM.
240239
type pubKey struct {
241240
AlgorithmParams keyParams
242-
Key []byte
241+
Key tpmutil.U32Bytes
243242
}
244243

245244
// A symKey is a TPM representation of a symmetric key.
246245
type symKey struct {
247246
AlgID uint32
248247
EncScheme uint16
249-
Key []byte
250-
}
251-
252-
// TPMMarshal will marshal the symKey into a byte Buffer as specified the TPM spec.
253-
func (k *symKey) TPMMarshal(out io.Writer) error {
254-
if err := binary.Write(out, binary.BigEndian, &k.AlgID); err != nil {
255-
return err
256-
}
257-
if err := binary.Write(out, binary.BigEndian, &k.EncScheme); err != nil {
258-
return err
259-
}
260-
if err := binary.Write(out, binary.BigEndian, uint16(len(k.Key))); err != nil {
261-
return err
262-
}
263-
if err := binary.Write(out, binary.BigEndian, k.Key); err != nil {
264-
return err
265-
}
266-
return nil
267-
}
268-
269-
// TPMUnmarshal will parse the byte Buffer and populate the symKey.
270-
func (k *symKey) TPMUnmarshal(in io.Reader) error {
271-
if err := binary.Read(in, binary.BigEndian, &k.AlgID); err != nil {
272-
return err
273-
}
274-
if err := binary.Read(in, binary.BigEndian, &k.EncScheme); err != nil {
275-
return err
276-
}
277-
var size uint16
278-
if err := binary.Read(in, binary.BigEndian, &size); err != nil {
279-
return err
280-
}
281-
key := make([]byte, size)
282-
if err := binary.Read(in, binary.BigEndian, &key); err != nil {
283-
return err
284-
}
285-
k.Key = key
286-
return nil
287-
}
288-
289-
// TPMPackedSize will return the expected size in bytes of the marshaled symKey.
290-
func (k *symKey) TPMPackedSize() int {
291-
// AlgID + EncScheme + len(Key) + Key
292-
// uint32 + uint16 + uint16 + BYTE[]
293-
return binary.Size(k.AlgID) + binary.Size(k.EncScheme) + binary.Size(uint16(len(k.Key))) + binary.Size(k.Key)
248+
Key tpmutil.U16Bytes // TPM_SYMMETRIC_KEY uses a 16-bit header for Key data
294249
}
295250

296251
// A tpmStoredData holds sealed data from the TPM.
297252
type tpmStoredData struct {
298253
Version uint32
299-
Info []byte
300-
Enc []byte
254+
Info tpmutil.U32Bytes
255+
Enc tpmutil.U32Bytes
301256
}
302257

303258
// String returns a string representation of a tpmStoredData.
@@ -323,7 +278,7 @@ type quoteInfo struct {
323278
// A pcrComposite stores a selection of PCRs with the selected PCR values.
324279
type pcrComposite struct {
325280
Selection pcrSelection
326-
Values []byte
281+
Values tpmutil.U32Bytes
327282
}
328283

329284
// convertPubKey converts a public key into TPM form. Currently, this function

tpm/tpm.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func FetchPCRValues(rw io.ReadWriter, pcrVals []int) ([]byte, error) {
9393

9494
// GetRandom gets random bytes from the TPM.
9595
func GetRandom(rw io.ReadWriter, size uint32) ([]byte, error) {
96-
var b []byte
96+
var b tpmutil.U32Bytes
9797
in := []interface{}{size}
9898
out := []interface{}{&b}
9999
// There's no need to check the ret value here, since the err value
@@ -177,7 +177,7 @@ func Quote2(rw io.ReadWriter, handle tpmutil.Handle, data []byte, pcrVals []int,
177177
}
178178

179179
// Check response authentication.
180-
raIn := []interface{}{ret, ordQuote2, pcrShort, capBytes, sig}
180+
raIn := []interface{}{ret, ordQuote2, pcrShort, tpmutil.U32Bytes(capBytes), tpmutil.U32Bytes(sig)}
181181
if err := ra.verify(ca.NonceOdd, sharedSecret[:], raIn); err != nil {
182182
return nil, err
183183
}
@@ -353,7 +353,7 @@ func sealHelper(rw io.ReadWriter, pcrInfo *pcrInfoLong, data []byte, srkAuth []b
353353
// digest = SHA1(ordSeal || encAuth || binary.Size(pcrInfo) || pcrInfo ||
354354
// len(data) || data)
355355
//
356-
authIn := []interface{}{ordSeal, sc.EncAuth, uint32(binary.Size(pcrInfo)), pcrInfo, data}
356+
authIn := []interface{}{ordSeal, sc.EncAuth, uint32(binary.Size(pcrInfo)), pcrInfo, tpmutil.U32Bytes(data)}
357357
ca, err := newCommandAuth(osapr.AuthHandle, osapr.NonceEven, sharedSecret[:], authIn)
358358
if err != nil {
359359
return nil, err
@@ -446,7 +446,7 @@ func Unseal(rw io.ReadWriter, sealed []byte, srkAuth []byte) ([]byte, error) {
446446
}
447447

448448
// Check the response authentication.
449-
raIn := []interface{}{ret, ordUnseal, unsealed}
449+
raIn := []interface{}{ret, ordUnseal, tpmutil.U32Bytes(unsealed)}
450450
if err := ra1.verify(ca1.NonceOdd, sharedSecret[:], raIn); err != nil {
451451
return nil, err
452452
}
@@ -488,7 +488,7 @@ func Quote(rw io.ReadWriter, handle tpmutil.Handle, data []byte, pcrNums []int,
488488
}
489489

490490
// Check response authentication.
491-
raIn := []interface{}{ret, ordQuote, pcrc, sig}
491+
raIn := []interface{}{ret, ordQuote, pcrc, tpmutil.U32Bytes(sig)}
492492
if err := ra.verify(ca.NonceOdd, sharedSecret[:], raIn); err != nil {
493493
return nil, nil, err
494494
}
@@ -607,7 +607,7 @@ func MakeIdentity(rw io.ReadWriter, srkAuth []byte, ownerAuth []byte, aikAuth []
607607
}
608608

609609
// Check response authentication.
610-
raIn := []interface{}{ret, ordMakeIdentity, k, sig}
610+
raIn := []interface{}{ret, ordMakeIdentity, k, tpmutil.U32Bytes(sig)}
611611
if err := ra1.verify(ca1.NonceOdd, sharedSecretSRK[:], raIn); err != nil {
612612
return nil, err
613613
}
@@ -679,7 +679,7 @@ func ActivateIdentity(rw io.ReadWriter, aikAuth []byte, ownerAuth []byte, aik tp
679679
defer osaprOwn.Close(rw)
680680
defer zeroBytes(sharedSecretOwn[:])
681681

682-
authIn := []interface{}{ordActivateIdentity, asym}
682+
authIn := []interface{}{ordActivateIdentity, tpmutil.U32Bytes(asym)}
683683
ca1, err := newCommandAuth(oiaprAIK.AuthHandle, oiaprAIK.NonceEven, aikAuth, authIn)
684684
if err != nil {
685685
return nil, fmt.Errorf("newCommandAuth failed: %v", err)
@@ -927,7 +927,7 @@ func NVReadValue(rw io.ReadWriter, index, offset, len uint32, ownAuth digest) ([
927927
if err != nil {
928928
return nil, fmt.Errorf("failed to read from NVRAM: %v", err)
929929
}
930-
raIn := []interface{}{ret, ordNVReadValue, data}
930+
raIn := []interface{}{ret, ordNVReadValue, tpmutil.U32Bytes(data)}
931931
if err := ra.verify(ca.NonceOdd, sharedSecretOwn[:], raIn); err != nil {
932932
return nil, fmt.Errorf("failed to verify authenticity of response: %v", err)
933933
}
@@ -1214,7 +1214,7 @@ func Sign(rw io.ReadWriter, keyAuth []byte, keyHandle tpmutil.Handle, hash crypt
12141214
defer osapr.Close(rw)
12151215
defer zeroBytes(sharedSecret[:])
12161216

1217-
authIn := []interface{}{ordSign, data}
1217+
authIn := []interface{}{ordSign, tpmutil.U32Bytes(data)}
12181218
ca, err := newCommandAuth(osapr.AuthHandle, osapr.NonceEven, sharedSecret[:], authIn)
12191219
if err != nil {
12201220
return nil, err
@@ -1225,7 +1225,7 @@ func Sign(rw io.ReadWriter, keyAuth []byte, keyHandle tpmutil.Handle, hash crypt
12251225
return nil, err
12261226
}
12271227

1228-
raIn := []interface{}{ret, ordSign, signature}
1228+
raIn := []interface{}{ret, ordSign, tpmutil.U32Bytes(signature)}
12291229
err = ra.verify(ca.NonceOdd, sharedSecret[:], raIn)
12301230
if err != nil {
12311231
return nil, err

tpm/tpm_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,13 @@ func TestResizeableSlice(t *testing.T) {
216216
t.Fatal("Couldn't read random bytes into the byte array")
217217
}
218218

219-
bb, err := tpmutil.Pack(ra, b)
219+
bb, err := tpmutil.Pack(ra, tpmutil.U32Bytes(b))
220220
if err != nil {
221221
t.Fatal("Couldn't pack the bytes:", err)
222222
}
223223

224224
var ra2 responseAuth
225-
var b2 []byte
225+
var b2 tpmutil.U32Bytes
226226
if _, err := tpmutil.Unpack(bb, &ra2, &b2); err != nil {
227227
t.Fatal("Couldn't unpack the resizeable values:", err)
228228
}

tpm2/constants.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ import (
2525
"github.com/google/go-tpm/tpmutil"
2626
)
2727

28-
func init() {
29-
tpmutil.UseTPM20LengthPrefixSize()
30-
}
31-
3228
// MAX_DIGEST_BUFFER is the maximum size of []byte request or response fields.
3329
// Typically used for chunking of big blobs of data (such as for hashing or
3430
// encryption).

0 commit comments

Comments
 (0)