Skip to content

Commit ad8ee8a

Browse files
committed
fea(mbr): MBR reader functions
Adds functionallity for reading the MBR table in the core library, sedlockctl, and tcgsdiag. It still needs to be added to the locking API library.
1 parent d2f7649 commit ad8ee8a

File tree

7 files changed

+408
-5
lines changed

7 files changed

+408
-5
lines changed

cmd/sedlockctl/.bb/hash.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2021 by library authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package sedlockctl
6+
7+
import (
8+
"crypto/sha1"
9+
"fmt"
10+
11+
"golang.org/x/crypto/pbkdf2"
12+
)
13+
14+
func HashSedutilDTA(password string, serial string) []byte {
15+
// This needs to match https://github.com/Drive-Trust-Alliance/sedutil/
16+
salt := fmt.Sprintf("%-20s", serial)
17+
return pbkdf2.Key([]byte(password), []byte(salt[:20]), 75000, 32, sha1.New)
18+
}

cmd/sedlockctl/.bb/main.go

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
// Copyright (c) 2021 by library authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package sedlockctl
6+
7+
import (
8+
"flag"
9+
"fmt"
10+
"log"
11+
"os"
12+
13+
"github.com/bluecmd/go-tcg-storage/pkg/drive"
14+
"github.com/bluecmd/go-tcg-storage/pkg/locking"
15+
bb "github.com/u-root/u-root/pkg/bb/bbmain"
16+
)
17+
18+
var (
19+
sidPIN *string
20+
sidPINMSID *bool
21+
sidPINHash *string
22+
user *string
23+
userPIN *string
24+
userPINHash *string
25+
)
26+
27+
func Main() {
28+
flag.Parse()
29+
30+
if flag.NArg() == 0 {
31+
fmt.Printf("Usage: %s [-flags ..] device [verb...]\n", os.Args[0])
32+
fmt.Printf("\nVerbs:\n")
33+
fmt.Printf(" list List all ranges (default)\n")
34+
fmt.Printf(" unlock-all Unlocks all ranges completely\n")
35+
fmt.Printf(" lock-all Lock all ranges completely\n")
36+
fmt.Printf(" mbr-done on|off Sets the MBRDone property (hide/show Shadow MBR)\n")
37+
return
38+
}
39+
d, err := drive.Open(flag.Arg(0))
40+
if err != nil {
41+
log.Fatalf("drive.Open: %v", err)
42+
}
43+
defer d.Close()
44+
snRaw, err := d.SerialNumber()
45+
if err != nil {
46+
log.Fatalf("drive.SerialNumber: %v", err)
47+
}
48+
sn := string(snRaw)
49+
50+
spin := []byte{}
51+
if *sidPIN != "" {
52+
switch *sidPINHash {
53+
case "sedutil-dta":
54+
spin = HashSedutilDTA(*sidPIN, sn)
55+
default:
56+
log.Fatalf("Unknown hash method %q", *sidPINHash)
57+
}
58+
}
59+
60+
initOps := []locking.InitializeOpt{}
61+
if len(spin) > 0 {
62+
initOps = append(initOps, locking.WithAuth(locking.DefaultAdminAuthority(spin)))
63+
}
64+
if *sidPINMSID {
65+
initOps = append(initOps, locking.WithAuth(locking.DefaultAuthorityWithMSID))
66+
}
67+
68+
cs, lmeta, err := locking.Initialize(d, initOps...)
69+
if err != nil {
70+
log.Fatalf("locking.Initalize: %v", err)
71+
}
72+
defer cs.Close()
73+
74+
var auth locking.LockingSPAuthenticator
75+
pin := []byte{}
76+
if *userPIN != "" {
77+
switch *userPINHash {
78+
case "sedutil-dta":
79+
pin = HashSedutilDTA(*userPIN, sn)
80+
default:
81+
log.Fatalf("Unknown hash method %q", *userPINHash)
82+
}
83+
}
84+
if *user != "" {
85+
var ok bool
86+
auth, ok = locking.AuthorityFromName(*user, pin)
87+
if !ok {
88+
log.Fatalf("Authority %q is not known for this device", *user)
89+
}
90+
} else {
91+
if len(pin) == 0 {
92+
auth = locking.DefaultAuthorityWithMSID
93+
} else {
94+
auth = locking.DefaultAuthority(pin)
95+
}
96+
}
97+
98+
l, err := locking.NewSession(cs, lmeta, auth)
99+
if err != nil {
100+
log.Fatalf("locking.NewSession: %v", err)
101+
}
102+
defer l.Close()
103+
104+
args := flag.Args()[1:]
105+
verb := "list"
106+
if len(args) > 0 {
107+
verb = args[0]
108+
}
109+
switch verb {
110+
case "list":
111+
list(l)
112+
case "unlock-all":
113+
unlockAll(l)
114+
case "lock-all":
115+
lockAll(l)
116+
case "mbr-done":
117+
if len(args) < 2 {
118+
log.Fatalf("Missing argument to mbr-done verb")
119+
}
120+
var v bool
121+
if args[1] == "on" {
122+
v = true
123+
} else if args[1] == "off" {
124+
v = false
125+
} else {
126+
log.Fatalf("Argument %q is not 'on' or 'off'", args[1])
127+
}
128+
setMBRDone(l, v)
129+
default:
130+
log.Fatalf("Unknown verb %q", verb)
131+
}
132+
}
133+
134+
func list(l *locking.LockingSP) {
135+
if len(l.Ranges) == 0 {
136+
log.Fatalf("No available locking ranges as this user\n")
137+
}
138+
for i, r := range l.Ranges {
139+
strr := "whole disk"
140+
if r.End > 0 {
141+
strr = fmt.Sprintf("%d to %d", r.Start, r.End)
142+
}
143+
if !r.WriteLockEnabled && !r.ReadLockEnabled {
144+
strr = "disabled"
145+
} else {
146+
if r.WriteLocked {
147+
strr += " [write locked]"
148+
}
149+
if r.ReadLocked {
150+
strr += " [read locked]"
151+
}
152+
}
153+
if r == l.GlobalRange {
154+
strr += " [global]"
155+
}
156+
if r.Name != nil {
157+
strr += fmt.Sprintf(" [name=%q]", *r.Name)
158+
}
159+
fmt.Printf("Range %3d: %s\n", i, strr)
160+
}
161+
}
162+
163+
func unlockAll(l *locking.LockingSP) {
164+
for i, r := range l.Ranges {
165+
if err := r.UnlockRead(); err != nil {
166+
log.Printf("Read unlock range %d failed: %v", i, err)
167+
}
168+
if err := r.UnlockWrite(); err != nil {
169+
log.Printf("Write unlock range %d failed: %v", i, err)
170+
}
171+
}
172+
}
173+
174+
func lockAll(l *locking.LockingSP) {
175+
for i, r := range l.Ranges {
176+
if err := r.LockRead(); err != nil {
177+
log.Printf("Read lock range %d failed: %v", i, err)
178+
}
179+
if err := r.LockWrite(); err != nil {
180+
log.Printf("Write lock range %d failed: %v", i, err)
181+
}
182+
}
183+
}
184+
185+
func setMBRDone(l *locking.LockingSP, v bool) {
186+
if err := l.SetMBRDone(v); err != nil {
187+
log.Fatalf("SetMBRDone failed: %v", err)
188+
}
189+
}
190+
func Init1() {
191+
sidPIN = flag.String("sid", "", "PIN to authenticate to the AdminSP as SID")
192+
}
193+
func Init2() {
194+
sidPINMSID = flag.Bool("try-sid-msid", false, "Try to use the MSID as PIN to authenticate to the AdminSP in addition to other methods")
195+
}
196+
func Init3() {
197+
sidPINHash = flag.String("sid-hash", "sedutil-dta", "If set, transform the SID PIN using the specified hash function")
198+
}
199+
func Init4() {
200+
user = flag.String("user", "", "Username to authenticate to the LockingSP (admin1 or bandmaster0 is the default)")
201+
}
202+
func Init5() {
203+
userPIN = flag.String("password", "", "PIN used to authenticate ot the LockingSP (MSID is the default)")
204+
}
205+
func Init6() {
206+
userPINHash = flag.String("hash", "sedutil-dta", "If set, transform the PIN using the specified hash function")
207+
}
208+
func Init0() {
209+
Init1()
210+
Init2()
211+
Init3()
212+
Init4()
213+
Init5()
214+
Init6()
215+
}
216+
func Init() {
217+
Init0()
218+
}
219+
func init() {
220+
bb.Register("sedlockctl", Init, Main)
221+
}

cmd/sedlockctl/main.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import (
1212

1313
"github.com/bluecmd/go-tcg-storage/pkg/drive"
1414
"github.com/bluecmd/go-tcg-storage/pkg/locking"
15+
16+
// TODO: Move to locking API when it has MBR functions
17+
"github.com/bluecmd/go-tcg-storage/pkg/core/table"
1518
)
1619

1720
var (
@@ -21,6 +24,7 @@ var (
2124
user = flag.String("user", "", "Username to authenticate to the LockingSP (admin1 or bandmaster0 is the default)")
2225
userPIN = flag.String("password", "", "PIN used to authenticate ot the LockingSP (MSID is the default)")
2326
userPINHash = flag.String("hash", "sedutil-dta", "If set, transform the PIN using the specified hash function")
27+
readMBRSize = flag.Int("read-mbr-size", 0, "If set to >0, specify how many bytes to read from the MBR table (otherwise read the whole table).")
2428
)
2529

2630
func main() {
@@ -33,6 +37,7 @@ func main() {
3337
fmt.Printf(" unlock-all Unlocks all ranges completely\n")
3438
fmt.Printf(" lock-all Lock all ranges completely\n")
3539
fmt.Printf(" mbr-done on|off Sets the MBRDone property (hide/show Shadow MBR)\n")
40+
fmt.Printf(" read-mbr Prints the binary data in the MBR area\n")
3641
return
3742
}
3843
d, err := drive.Open(flag.Arg(0))
@@ -125,6 +130,30 @@ func main() {
125130
log.Fatalf("Argument %q is not 'on' or 'off'", args[1])
126131
}
127132
setMBRDone(l, v)
133+
case "read-mbr":
134+
mbi, err := table.MBR_TableInfo(l.Session)
135+
if err != nil {
136+
log.Fatalf("table.MBR_TableInfo failed: %v", err)
137+
}
138+
mbuf := make([]byte, mbi.SuggestBufferSize(l.Session))
139+
sz := mbi.Size
140+
if *readMBRSize > 0 && uint32(*readMBRSize) < sz {
141+
sz = uint32(*readMBRSize)
142+
}
143+
pos := uint32(0)
144+
chk := uint32(len(mbuf))
145+
for i := sz; i != 0; i -= chk {
146+
if n, err := table.MBR_Read(l.Session, mbuf, pos); n != len(mbuf) || err != nil {
147+
log.Fatalf("table.MBR_Read failed: %v (read: %d)", err, n)
148+
}
149+
pos += chk
150+
if i < chk {
151+
os.Stdout.Write(mbuf[:i])
152+
break
153+
} else {
154+
os.Stdout.Write(mbuf)
155+
}
156+
}
128157
default:
129158
log.Fatalf("Unknown verb %q", verb)
130159
}

cmd/tcgsdiag/main.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,21 @@ func main() {
281281
log.Printf("Locking SP LockingInfo:")
282282
spew.Dump(table.LockingInfo(s))
283283

284+
log.Printf("Locking SP MBRTableInfo:")
285+
mbi, err := table.MBR_TableInfo(s)
286+
if err != nil {
287+
log.Printf("Failed: %v", err)
288+
} else {
289+
spew.Dump(mbi)
290+
mbuf := make([]byte, mbi.SuggestBufferSize(s))
291+
log.Printf("Reading %d first bytes of MBR", len(mbuf))
292+
if n, err := table.MBR_Read(s, mbuf, 0); n != len(mbuf) || err != nil {
293+
log.Printf("Failed: %d, %v", n, err)
294+
} else {
295+
log.Printf("MBR start:\n%s", hex.Dump(mbuf[:128]))
296+
}
297+
}
298+
284299
lockList, err := table.Locking_Enumerate(s)
285300
if err != nil {
286301
log.Printf("table.Locking_Enumerate failed: %v", err)

pkg/core/table/base.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ var (
1111
Base_MethodIDTable = TableUID{0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00}
1212
Base_AccessControlTable = TableUID{0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00}
1313
)
14+
15+
func Base_TableRowForTable(tid TableUID) RowUID {
16+
return Base_TableTable.Row([4]byte{tid[0], tid[1], tid[2], tid[3]})
17+
}

0 commit comments

Comments
 (0)