blob: 8593323d9212152122fb737896cd83da1e3bd93f [file] [log] [blame]
From fe4bab82bbd2e6972899d6ada13235a330cba008 Mon Sep 17 00:00:00 2001
From: Erdi Chen <erdi@google.com>
Date: Thu, 28 May 2015 13:53:20 -0700
Subject: [PATCH] Add support for NV read.
The internal nvRead function supports optional owner authorization.
If nvLocked is true, owner authorization is required. If authorization
is supplied, it must be correct even when nvLocked is false.
The public NVRead function will fail if nvLocked is true. A version
with owner authorization is not implemented yet.
---
tpm/commands.go | 21 +++++++++++++++++++++
tpm/constants.go | 18 ++++++++++++++++++
tpm/tpm.go | 21 +++++++++++++++++++++
3 files changed, 60 insertions(+)
diff --git a/tpm/commands.go b/tpm/commands.go
index e4c028c..5931268 100644
--- a/tpm/commands.go
+++ b/tpm/commands.go
@@ -320,3 +320,24 @@ func takeOwnership(f *os.File, encOwnerAuth []byte, encSRKAuth []byte, srk *key,
return &k, &ra, ret, nil
}
+
+// nvRead reads data from the NV store. If nvLocked is true, owner
+// authorization is required. If authorization is supplied, it must
+// be correct even when nvLocked is false.
+func nvRead(f *os.File, nvIndex uint32, offset uint32, data []byte, ca *commandAuth) (*responseAuth, uint32, error) {
+ in := []interface{}{nvIndex, offset, uint32(len(data))}
+ cmd := tagRQUCommand
+ var ra responseAuth
+ out := []interface{}{&data}
+ if ca != nil {
+ cmd = tagRQUAuth1Command
+ in = append(in, ca)
+ out = append(out, &ra)
+ }
+ ret, err := submitTPMRequest(f, cmd, ordNVReadValue, in, out)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ return &ra, ret, nil
+}
diff --git a/tpm/constants.go b/tpm/constants.go
index df94e1e..f50a926 100644
--- a/tpm/constants.go
+++ b/tpm/constants.go
@@ -14,6 +14,20 @@
package tpm
+type NVIndex uint32
+
+const (
+ NVIndex0 uint32 = 0x00000000
+ NVIndexDir uint32 = 0x10000001
+ NVIndexLock uint32 = 0xffffffff
+
+ NVIndexEKCert NVIndex = 0x1000f000
+ NVIndexTPMCC = iota
+ NVIndexPlatformCert
+ NVIndexPlatformCC
+ NVIndexTrial
+)
+
// Supported TPM commands.
const (
tagPCRInfoLong uint16 = 0x06
@@ -44,6 +58,7 @@ const (
ordReadPubEK uint32 = 0x0000007C
ordOwnerReadInternalPub uint32 = 0x00000081
ordFlushSpecific uint32 = 0x000000BA
+ ordNVReadValue uint32 = 0x000000CF
)
// Entity types. The LSB gives the entity type, and the MSB (currently fixed to
@@ -154,3 +169,6 @@ const quoteVersion uint32 = 0x01010000
// oaepLabel is the label used for OEAP encryption in esRSAEsOAEPSHA1MGF1
var oaepLabel = []byte{byte('T'), byte('C'), byte('P'), byte('A')}
+
+// blockSize is the maximum NV write/read size.
+const blockSize = 80
diff --git a/tpm/tpm.go b/tpm/tpm.go
index 055d129..c1bd3b2 100644
--- a/tpm/tpm.go
+++ b/tpm/tpm.go
@@ -809,3 +809,24 @@ func TakeOwnership(f *os.File, newOwnerAuth digest, newSRKAuth digest, pubEK []b
raIn := []interface{}{ret, ordTakeOwnership, k}
return ra.verify(ca.NonceOdd, newOwnerAuth[:], raIn)
}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+// NVRead reads data from the NV store. This function will fail if nvLocked
+// is true.
+func NVRead(f *os.File, nvIndex NVIndex, offset uint32, data []byte) error {
+ for off := int(offset); off < len(data); {
+ end := min(int(off+blockSize), len(data))
+ _, _, err := nvRead(f, uint32(nvIndex), uint32(off), data[off:end], nil)
+ if err != nil {
+ return err
+ }
+ off = end
+ }
+ return nil
+}
--
2.2.0.rc0.207.ga3a616c