github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tpm2/tpm2.go (about) 1 // Copyright (c) 2014, Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package tpm2 supports direct communication with a tpm 2.0 device under Linux. 16 17 package tpm2 18 19 import ( 20 "bytes" 21 "crypto/aes" 22 "crypto/cipher" 23 "crypto/hmac" 24 "crypto/rand" 25 "crypto/rsa" 26 "crypto/sha1" 27 "crypto/sha256" 28 "crypto/x509" 29 "crypto/x509/pkix" 30 "encoding/hex" 31 "errors" 32 "fmt" 33 "io" 34 "math/big" 35 "net" 36 "os" 37 "time" 38 "unsafe" 39 40 "github.com/golang/glog" 41 "github.com/golang/protobuf/proto" 42 ) 43 44 func ComputePcrDigest(alg uint16, in []byte) ([]byte, error) { 45 // in should just be a sequence of digest values 46 return ComputeHashValue(alg, in) 47 } 48 49 func GetSerialNumber() *big.Int { 50 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 32) 51 sn, _ := rand.Int(rand.Reader, serialNumberLimit) 52 return sn 53 } 54 55 type ValidPcrCheck func([]byte, []byte) bool 56 func ValidPcr(pcrSelect []byte, digest []byte) bool { 57 return true 58 } 59 60 // 61 // TPM functions 62 // 63 64 // OpenTPM opens a channel to the TPM at the given path. If the file is a 65 // device, then it treats it like a normal TPM device, and if the file is a 66 // Unix domain socket, then it opens a connection to the socket. 67 func OpenTPM(path string) (io.ReadWriteCloser, error) { 68 // If it's a regular file, then open it 69 var rwc io.ReadWriteCloser 70 fi, err := os.Stat(path) 71 if err != nil { 72 return nil, err 73 } 74 75 if fi.Mode()&os.ModeDevice != 0 { 76 var f *os.File 77 f, err = os.OpenFile(path, os.O_RDWR, 0600) 78 if err != nil { 79 return nil, err 80 } 81 rwc = io.ReadWriteCloser(f) 82 } else if fi.Mode()&os.ModeSocket != 0 { 83 uc, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: path, Net: "unix"}) 84 if err != nil { 85 return nil, err 86 } 87 rwc = io.ReadWriteCloser(uc) 88 } else { 89 return nil, fmt.Errorf("unsupported TPM file mode %s", fi.Mode().String()) 90 } 91 92 return rwc, nil 93 } 94 95 func reportCommand(name string, cmd []byte, resp []byte, 96 status TpmError, errOnly bool) { 97 if errOnly && status == ErrSuccess { 98 return 99 } 100 glog.Infof("reportCommand, %s, cmd: %x,\n\terr code: %x, resp: %x\n", name, cmd, status, resp) 101 // TODO: remove? 102 fmt.Printf("%s, cmd: %x,\n\terr code: %x, resp: %x\n", name, cmd, status, resp) 103 } 104 105 func PrintAttestData(parms *AttestParams) { 106 fmt.Printf("Magic_number: %x\n", parms.Magic_number) 107 fmt.Printf("Attest_type : %x\n", parms.Attest_type) 108 fmt.Printf("Name : %x\n", parms.Name) 109 fmt.Printf("Data : %x\n", parms.Data) 110 fmt.Printf("Clock : %x\n", parms.Clock) 111 fmt.Printf("ResetCount : %x\n", parms.ResetCount) 112 fmt.Printf("RestartCount: %x\n", parms.RestartCount) 113 fmt.Printf("Safe : %x\n", parms.Safe) 114 fmt.Printf("FirmwareVersion: %x\n", parms.FirmwareVersion) 115 fmt.Printf("PcrSelect : %x\n", parms.PcrSelect) 116 fmt.Printf("PcrDigest : %x\n", parms.PcrDigest) 117 } 118 119 func PrintKeyedHashParams(parms *KeyedHashParams) { 120 fmt.Printf("Type_alg : %x\n", parms.Type_alg) 121 fmt.Printf("Hash_alg : %x\n", parms.Hash_alg) 122 fmt.Printf("Attributes : %x\n", parms.Attributes) 123 fmt.Printf("Auth_policy: %x\n", parms.Auth_policy) 124 fmt.Printf("Symalg : %x\n", parms.Symalg) 125 fmt.Printf("Sym_sz : %x\n", parms.Sym_sz) 126 fmt.Printf("Mode : %x\n", parms.Mode) 127 fmt.Printf("Scheme : %x\n", parms.Scheme) 128 fmt.Printf("Unique : %x\n", parms.Unique) 129 } 130 131 func PrintRsaParams(parms *RsaParams) { 132 fmt.Printf("Enc_alg : %x\n", parms.Enc_alg) 133 fmt.Printf("Hash_alg : %x\n", parms.Hash_alg) 134 fmt.Printf("Attributes : %x\n", parms.Attributes) 135 fmt.Printf("Auth_policy : %x\n", parms.Auth_policy) 136 fmt.Printf("Symalg : %x\n", parms.Symalg) 137 fmt.Printf("Sym_sz : %x\n", parms.Sym_sz) 138 fmt.Printf("Mode : %x\n", parms.Mode) 139 fmt.Printf("Scheme : %x\n", parms.Scheme) 140 fmt.Printf("Scheme_hash : %x\n", parms.Scheme_hash) 141 fmt.Printf("Modulus size: %x\n", parms.Mod_sz) 142 fmt.Printf("Exp : %x\n", parms.Exp) 143 fmt.Printf("Modulus : %x\n", parms.Modulus) 144 } 145 146 func SetShortPcrs(pcr_nums []int) ([]byte, error) { 147 pcr := []byte{3, 0, 0, 0} 148 var byte_num int 149 var byte_pos byte 150 for _, e := range pcr_nums { 151 byte_num = 1 + e/8 152 byte_pos = 1 << uint16(e%8) 153 pcr[byte_num] |= byte_pos 154 } 155 return pcr, nil 156 } 157 158 // nil is error 159 func SetHandle(handle Handle) []byte { 160 uint32_handle := uint32(handle) 161 str, _ := pack([]interface{}{&uint32_handle}) 162 return str 163 } 164 165 // nil return is an error 166 func SetPasswordData(password string) []byte { 167 // len password 168 pw, err := hex.DecodeString(password) 169 if err != nil { 170 return nil 171 } 172 ret, _ := pack([]interface{}{&pw}) 173 return ret 174 } 175 176 // nil return is an error 177 // returns: len0 TPM_RS_PW 0000 01 password data as []byte 178 func CreatePasswordAuthArea(password string, owner Handle) []byte { 179 owner_str := SetHandle(owner) 180 suffix := []byte{0, 0, 1} 181 pw := SetPasswordData(password) 182 final_buf := append(owner_str, suffix...) 183 final_buf = append(final_buf, pw...) 184 out := []interface{}{&final_buf} 185 ret, _ := pack(out) 186 return ret 187 } 188 189 // nil is error 190 func CreateSensitiveArea(in1 []byte, in2 []byte) []byte { 191 // password (SENSITIVE CREATE) 192 // 0008 0004 01020304 193 // 0000 194 t1, err := pack([]interface{}{&in1}) 195 if err != nil { 196 return nil 197 } 198 t2, err := pack([]interface{}{&in2}) 199 if err != nil { 200 return nil 201 } 202 203 t := append(t1, t2...) 204 ret, err := pack([]interface{}{&t}) 205 if err != nil { 206 return nil 207 } 208 209 return ret 210 } 211 212 func DecodeRsaBuf(rsa_buf []byte) (*RsaParams, error) { 213 parms := new(RsaParams) 214 current := int(0) 215 template := []interface{}{&parms.Enc_alg, &parms.Hash_alg, 216 &parms.Attributes, &parms.Auth_policy} 217 err := unpack(rsa_buf[current:], template) 218 if err != nil { 219 return nil, errors.New("Can't unpack Rsa buffer 2") 220 } 221 current += 10 + len(parms.Auth_policy) 222 template = []interface{}{&parms.Symalg} 223 err = unpack(rsa_buf[current:], template) 224 if err != nil { 225 return nil, errors.New("Can't unpack Rsa buffer 3") 226 } 227 current += 2 228 if parms.Symalg != uint16(AlgTPM_ALG_NULL) { 229 template = []interface{}{&parms.Sym_sz, &parms.Mode} 230 err = unpack(rsa_buf[current:], template) 231 if err != nil { 232 return nil, errors.New("Can't unpack Rsa buffer 4") 233 } 234 current += 4 235 } else { 236 parms.Sym_sz = 0 237 parms.Mode = 0 238 parms.Scheme = 0 239 } 240 template = []interface{}{&parms.Scheme} 241 err = unpack(rsa_buf[current:], template) 242 if err != nil { 243 return nil, errors.New("Can't unpack Rsa buffer 5") 244 } 245 current += 2 246 if parms.Scheme == uint16(AlgTPM_ALG_RSASSA) { 247 template = []interface{}{&parms.Scheme_hash} 248 err = unpack(rsa_buf[current:], template) 249 if err != nil { 250 return nil, errors.New("Can't unpack Rsa buffer 6") 251 } 252 current += 2 253 } 254 255 template = []interface{}{&parms.Mod_sz, &parms.Exp, &parms.Modulus} 256 err = unpack(rsa_buf[current:], template) 257 if err != nil { 258 return nil, errors.New("Can't unpack Rsa buffer 7") 259 } 260 return parms, nil 261 } 262 263 // nil is error 264 func DecodeRsaArea(in []byte) (*RsaParams, error) { 265 var rsa_buf []byte 266 267 template := []interface{}{&rsa_buf} 268 err := unpack(in, template) 269 if err != nil { 270 return nil, errors.New("Can't unpack Rsa buffer 1") 271 } 272 return DecodeRsaBuf(rsa_buf) 273 } 274 275 // nil is error 276 func CreateKeyedHashParams(parms KeyedHashParams) []byte { 277 // 0 (uint16), type, attributes, auth, scheme, 0 (unique) 278 template := []interface{}{&parms.Type_alg, &parms.Hash_alg, 279 &parms.Attributes, &parms.Auth_policy, &parms.Scheme, 280 &parms.Unique} 281 t1, err := pack(template) 282 if err != nil { 283 return nil 284 } 285 return t1 286 } 287 288 // nil return is error 289 func CreateRsaParams(parms RsaParams) []byte { 290 template := []interface{}{&parms.Enc_alg, &parms.Hash_alg, 291 &parms.Attributes, &parms.Auth_policy} 292 t1, err := pack(template) 293 if err != nil { 294 return nil 295 } 296 297 if parms.Symalg != uint16(AlgTPM_ALG_NULL) { 298 template = []interface{}{&parms.Symalg, &parms.Sym_sz, 299 &parms.Mode, &parms.Scheme} 300 } else { 301 template = []interface{}{&parms.Symalg, &parms.Scheme} 302 } 303 t2, err := pack(template) 304 if err != nil { 305 return nil 306 } 307 if parms.Scheme == uint16(AlgTPM_ALG_RSASSA) { 308 template3 := []interface{}{&parms.Scheme_hash} 309 t3, err := pack(template3) 310 if err != nil { 311 return nil 312 } 313 t2 = append(t2, t3...) 314 } 315 316 template4 := []interface{}{&parms.Mod_sz, &parms.Exp, parms.Modulus} 317 t4, err := pack(template4) 318 if err != nil { 319 return nil 320 } 321 322 t5 := append(t1, t2...) 323 t5 = append(t5, t4...) 324 template5 := []interface{}{&t5} 325 buf, err := pack(template5) 326 if err != nil { 327 return nil 328 } 329 return buf 330 } 331 332 // nil return is error 333 func CreateLongPcr(count uint32, pcr_nums []int) []byte { 334 if count == 0 { 335 b1, err := pack([]interface{}{&count}) 336 if err != nil { 337 return nil 338 } 339 return b1 340 } 341 b1, err := SetShortPcrs(pcr_nums) 342 if err != nil { 343 return nil 344 } 345 template := []interface{}{&count, &b1} 346 b2, err := pack(template) 347 if err != nil { 348 return nil 349 } 350 return b2 351 } 352 353 // ConstructGetRandom constructs a GetRandom command. 354 func ConstructGetRandom(size uint32) ([]byte, error) { 355 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdGetRandom) 356 if err != nil { 357 return nil, errors.New("ConstructGetRandom failed") 358 } 359 num_bytes := []interface{}{uint16(size)} 360 cmd, _ := packWithHeader(cmdHdr, num_bytes) 361 return cmd, nil 362 } 363 364 // DecodeGetRandom decodes a GetRandom response. 365 func DecodeGetRandom(in []byte) ([]byte, error) { 366 var rand_bytes []byte 367 368 out := []interface{}{&rand_bytes} 369 err := unpack(in, out) 370 if err != nil { 371 return nil, errors.New("Can't decode GetRandom response") 372 } 373 return rand_bytes, nil 374 } 375 376 // GetRandom gets random bytes from the TPM. 377 func GetRandom(rw io.ReadWriteCloser, size uint32) ([]byte, error) { 378 // Construct command 379 cmd, err := ConstructGetRandom(size) 380 if err != nil { 381 return nil, err 382 } 383 384 // Send command 385 _, err = rw.Write(cmd) 386 if err != nil { 387 return nil, errors.New("Write Tpm fails") 388 } 389 390 // Get response 391 resp := make([]byte, 1024, 1024) 392 read, err := rw.Read(resp) 393 if err != nil { 394 return nil, errors.New("Read Tpm fails") 395 } 396 397 // Decode Response 398 if read < 10 { 399 return nil, errors.New("Read buffer too small") 400 } 401 _, size, status, err := DecodeCommandResponse(resp[0:10]) 402 if err != nil { 403 return nil, err 404 } 405 reportCommand("GetRandom", cmd, resp[0:size], status, true) 406 if status != ErrSuccess { 407 return nil, errors.New("Can't decode response") 408 } 409 rand, err := DecodeGetRandom(resp[10:read]) 410 if err != nil { 411 return nil, err 412 } 413 return rand, nil 414 } 415 416 // ConstructFlushContext constructs a FlushContext command. 417 func ConstructFlushContext(handle Handle) ([]byte, error) { 418 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdFlushContext) 419 if err != nil { 420 return nil, errors.New("ConstructFlushContext failed") 421 } 422 cmd_text := []interface{}{uint32(handle)} 423 x, _ := packWithHeader(cmdHdr, cmd_text) 424 return x, nil 425 } 426 427 // FlushContext 428 func FlushContext(rw io.ReadWriter, handle Handle) error { 429 // Construct command 430 cmd, err := ConstructFlushContext(handle) 431 if err != nil { 432 return errors.New("ConstructFlushContext fails") 433 } 434 435 // Send command 436 _, err = rw.Write(cmd) 437 if err != nil { 438 return errors.New("Write Tpm fails") 439 } 440 441 // Get response 442 var resp []byte 443 resp = make([]byte, 1024, 1024) 444 read, err := rw.Read(resp) 445 if err != nil { 446 return errors.New("Read Tpm fails") 447 } 448 449 // Decode Response 450 if read < 10 { 451 return errors.New("Read buffer too small") 452 } 453 _, _, status, err := DecodeCommandResponse(resp[0:10]) 454 if err != nil { 455 return errors.New("DecodeCommandResponse fails") 456 } 457 if status != ErrSuccess { 458 return errors.New("FlushContext unsuccessful") 459 } 460 return nil 461 } 462 463 // ConstructReadPcrs constructs a ReadPcr command. 464 func ConstructReadPcrs(num_spec int, num_pcr byte, pcrs []byte) ([]byte, error) { 465 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPCR_Read) 466 if err != nil { 467 return nil, errors.New("ConstructReadPcrs failed") 468 } 469 num := uint32(num_spec) 470 template := []interface{}{&num, &pcrs} 471 cmd, _ := packWithHeader(cmdHdr, template) 472 return cmd, nil 473 } 474 475 // DecodeReadPcrs decodes a ReadPcr response. 476 func DecodeReadPcrs(in []byte) (uint32, []byte, uint16, []byte, error) { 477 var pcr []byte 478 var digest []byte 479 var updateCounter uint32 480 var t uint32 481 var s uint32 482 483 out := []interface{}{&t, &updateCounter, &pcr, &s, &digest} 484 err := unpack(in, out) 485 if err != nil { 486 return 1, nil, 0, nil, errors.New("Can't decode ReadPcrs response") 487 } 488 return updateCounter, pcr, uint16(t), digest, nil 489 } 490 491 // ReadPcr reads a PCR value from the TPM. 492 // Output: updatecounter, selectout, digest 493 func ReadPcrs(rw io.ReadWriter, num_byte byte, pcrSelect []byte) (uint32, []byte, uint16, []byte, error) { 494 // Construct command 495 x, err := ConstructReadPcrs(1, 4, pcrSelect) 496 if err != nil { 497 return 1, nil, 0, nil, errors.New("MakeCommandHeader failed") 498 } 499 500 // Send command 501 _, err = rw.Write(x) 502 if err != nil { 503 return 0, nil, 0, nil, errors.New("Write Tpm fails") 504 } 505 506 // Get response 507 var resp []byte 508 resp = make([]byte, 1024, 1024) 509 read, err := rw.Read(resp) 510 if err != nil { 511 return 0, nil, 0, nil, errors.New("Read Tpm fails") 512 } 513 514 // Decode Response 515 if read < 10 { 516 return 0, nil, 0, nil, errors.New("Read buffer too small") 517 } 518 _, _, status, err := DecodeCommandResponse(resp[0:10]) 519 if err != nil { 520 return 0, nil, 0, nil, errors.New("DecodeCommandResponse fails") 521 } 522 if status != ErrSuccess { 523 return 0, nil, 0, nil, errors.New("ReadPcr command failed") 524 } 525 counter, pcr, alg, digest, err := DecodeReadPcrs(resp[10:]) 526 if err != nil { 527 return 0, nil, 0, nil, errors.New("DecodeReadPcrsfails") 528 } 529 return counter, pcr, alg, digest, err 530 } 531 532 // ConstructReadClock constructs a ReadClock command. 533 func ConstructReadClock() ([]byte, error) { 534 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdReadClock) 535 if err != nil { 536 return nil, errors.New("ConstructGetRandom failed") 537 } 538 cmd := packWithBytes(cmdHdr, nil) 539 return cmd, nil 540 } 541 542 // DecodeReadClock decodes a ReadClock response. 543 func DecodeReadClock(in []byte) (uint64, uint64, error) { 544 var current_time, current_clock uint64 545 546 template := []interface{}{¤t_time, ¤t_clock} 547 err := unpack(in, template) 548 if err != nil { 549 return 0, 0, errors.New("Can't decode DecodeReadClock response") 550 } 551 return current_time, current_clock, nil 552 } 553 554 // ReadClock 555 // Output: current time, current clock 556 func ReadClock(rw io.ReadWriter) (uint64, uint64, error) { 557 // Construct command 558 x, err := ConstructReadClock() 559 if err != nil { 560 return 0, 0, errors.New("Can't construct ReadClock response") 561 } 562 563 // Send command 564 _, err = rw.Write(x) 565 if err != nil { 566 return 0, 0, errors.New("Write Tpm fails") 567 } 568 569 // Get response 570 var resp []byte 571 resp = make([]byte, 1024, 1024) 572 read, err := rw.Read(resp) 573 if err != nil { 574 return 0, 0, errors.New("Read Tpm fails") 575 } 576 577 // Decode Response 578 if read < 10 { 579 return 0, 0, errors.New("Read buffer too small") 580 } 581 _, _, status, err := DecodeCommandResponse(resp[0:10]) 582 if err != nil { 583 return 0, 0, err 584 } 585 if status != ErrSuccess { 586 return 0, 0, errors.New("Can't decode response") 587 } 588 current_time, current_clock, err := DecodeReadClock(resp[10:read]) 589 if err != nil { 590 return 0, 0, err 591 } 592 return current_time, current_clock, nil 593 } 594 595 // ConstructGetCapabilities constructs a GetCapabilities command. 596 func ConstructGetCapabilities(cap uint32, count uint32, property uint32) ([]byte, error) { 597 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdGetCapability) 598 if err != nil { 599 return nil, errors.New("GetCapability failed") 600 } 601 cap_bytes := []interface{}{&cap, &property, &count} 602 cmd, _ := packWithHeader(cmdHdr, cap_bytes) 603 return cmd, nil 604 } 605 606 // DecodeGetCapabilities decodes a GetCapabilities response. 607 func DecodeGetCapabilities(in []byte) (uint32, []uint32, error) { 608 var num_handles uint32 609 var cap_reported uint32 610 611 out := []interface{}{&cap_reported, &num_handles} 612 err := unpack(in[1:9], out) 613 if err != nil { 614 return 0, nil, errors.New("Can't decode GetCapabilities response") 615 } 616 // only OrdTPM_CAP_HANDLES handled 617 if cap_reported != OrdTPM_CAP_HANDLES { 618 return 0, nil, errors.New("Only ordTPM_CAP_HANDLES supported") 619 } 620 var handles []uint32 621 var handle uint32 622 handle_out := []interface{}{&handle} 623 for i := 0; i < int(num_handles); i++ { 624 err := unpack(in[8+4*i:12+4*i], handle_out) 625 if err != nil { 626 return 0, nil, errors.New("Can't decode GetCapabilities handle") 627 } 628 handles = append(handles, handle) 629 } 630 631 return cap_reported, handles, nil 632 } 633 634 // GetCapabilities 635 // Output: output buf 636 func GetCapabilities(rw io.ReadWriter, cap uint32, count uint32, property uint32) ([]uint32, error) { 637 // Construct command 638 cmd, err := ConstructGetCapabilities(cap, count, property) 639 if err != nil { 640 return nil, err 641 } 642 643 // Send command 644 _, err = rw.Write(cmd) 645 if err != nil { 646 return nil, errors.New("Write Tpm fails") 647 } 648 649 // Get response 650 resp := make([]byte, 4096, 4096) 651 read, err := rw.Read(resp) 652 if err != nil { 653 return nil, errors.New("Read Tpm fails") 654 } 655 656 // Decode Response 657 if read < 10 { 658 return nil, errors.New("Read buffer too small") 659 } 660 _, _, status, err := DecodeCommandResponse(resp[0:10]) 661 if err != nil { 662 return nil, err 663 } 664 if status != ErrSuccess { 665 } 666 _, handles, err := DecodeGetCapabilities(resp[10:read]) 667 if err != nil { 668 return nil, err 669 } 670 return handles, nil 671 } 672 673 // ConstructPcrEvent 674 func ConstructPcrEvent(pcrnum int, eventData []byte) ([]byte, error) { 675 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdPcrEvent) 676 if err != nil { 677 return nil, errors.New("GetCapability failed") 678 } 679 // pcrnum, empty, emptyauth, eventData size, eventData 680 var empty []byte 681 pc := uint32(pcrnum) 682 b1, _ := pack([]interface{}{&pc, &empty}) 683 b2 := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW)) 684 b3, _ := pack([]interface{}{&eventData}) 685 cmd := packWithBytes(cmdHdr, append(append(b1, b2...), b3...)) 686 return cmd, nil 687 } 688 689 // PcrEvent 690 func PcrEvent(rw io.ReadWriter, pcrnum int, eventData []byte) error { 691 // Construct command 692 cmd, err := ConstructPcrEvent(pcrnum, eventData) 693 if err != nil { 694 return err 695 } 696 697 // Send command 698 _, err = rw.Write(cmd) 699 if err != nil { 700 return errors.New("Write Tpm fails") 701 } 702 703 // Get response 704 var resp []byte 705 resp = make([]byte, 4096, 4096) 706 read, err := rw.Read(resp) 707 if err != nil { 708 return errors.New("Read Tpm fails") 709 } 710 711 // Decode Response 712 if read < 10 { 713 return errors.New("Read buffer too small") 714 } 715 _, _, status, err := DecodeCommandResponse(resp[0:10]) 716 if err != nil { 717 return err 718 } 719 if status != ErrSuccess { 720 return errors.New("Command failure") 721 } 722 return nil 723 } 724 725 // Flushall 726 func Flushall(rw io.ReadWriter) error { 727 handles, err := GetCapabilities(rw, OrdTPM_CAP_HANDLES, 1, 0x80000000) 728 if err != nil { 729 return err 730 } 731 for _, e := range handles { 732 _ = FlushContext(rw, Handle(e)) 733 } 734 return nil 735 } 736 737 // ConstructCreatePrimary constructs a CreatePrimary command. 738 func ConstructCreatePrimary(owner uint32, pcr_nums []int, 739 parent_password string, owner_password string, 740 parms RsaParams) ([]byte, error) { 741 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreatePrimary) 742 if err != nil { 743 return nil, errors.New("ConstructCreatePrimary failed") 744 } 745 var empty []byte 746 b1 := SetHandle(Handle(owner)) 747 b2, _ := pack([]interface{}{&empty}) 748 b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW)) 749 t1 := SetPasswordData(owner_password) 750 b4 := CreateSensitiveArea(t1[2:], empty) 751 b5 := CreateRsaParams(parms) 752 b6, _ := pack([]interface{}{&empty}) 753 var b7 []byte 754 if len(pcr_nums) > 0 { 755 b7 = CreateLongPcr(uint32(1), pcr_nums) 756 } else { 757 b7 = CreateLongPcr(uint32(0), pcr_nums) 758 } 759 arg_bytes := append(b1, b2...) 760 arg_bytes = append(arg_bytes, b3...) 761 arg_bytes = append(arg_bytes, b4...) 762 arg_bytes = append(arg_bytes, b5...) 763 arg_bytes = append(arg_bytes, b6...) 764 arg_bytes = append(arg_bytes, b7...) 765 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 766 return cmd_bytes, nil 767 } 768 769 // DecodeCreatePrimary decodes a CreatePrimary response. 770 func DecodeCreatePrimary(in []byte) (Handle, []byte, error) { 771 var handle uint32 772 var auth []byte 773 774 // handle and auth data 775 template := []interface{}{&handle, &auth} 776 err := unpack(in, template) 777 if err != nil { 778 return Handle(0), nil, errors.New("Can't decode response 1") 779 } 780 781 var current int 782 current = 6 + 2*len(auth) 783 // size, size-public 784 var tpm2_public []byte 785 template = []interface{}{&tpm2_public} 786 err = unpack(in[current:], template) 787 if err != nil { 788 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 2") 789 } 790 791 var rsa_params_buf []byte 792 template = []interface{}{&rsa_params_buf} 793 err = unpack(tpm2_public, template) 794 if err != nil { 795 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 3") 796 } 797 798 // Creation data 799 current = 2 + len(rsa_params_buf) 800 var creation_data []byte 801 template = []interface{}{&creation_data} 802 err = unpack(tpm2_public[current:], template) 803 if err != nil { 804 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 4") 805 } 806 current += len(creation_data) + 2 807 808 // Digest 809 var digest []byte 810 template = []interface{}{&digest} 811 err = unpack(tpm2_public[current:], template) 812 if err != nil { 813 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5") 814 } 815 current += len(digest) + 2 816 817 // TPMT_TK_CREATION 818 current += 6 819 var crap []byte 820 template = []interface{}{&crap} 821 err = unpack(tpm2_public[current:], template) 822 if err != nil { 823 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5") 824 } 825 current += len(crap) + 2 826 827 // Name 828 var name []byte 829 template = []interface{}{&name} 830 err = unpack(tpm2_public[current:], template) 831 if err != nil { 832 return Handle(0), nil, errors.New("Can't decode CreatePrimary response 5") 833 } 834 835 return Handle(handle), tpm2_public, nil 836 } 837 838 // CreatePrimary 839 // Output: handle, public key blob 840 func CreatePrimary(rw io.ReadWriter, owner uint32, pcr_nums []int, 841 parent_password, owner_password string, parms RsaParams) (Handle, []byte, error) { 842 843 // Construct command 844 cmd, err := ConstructCreatePrimary(uint32(owner), pcr_nums, parent_password, 845 owner_password, parms) 846 if err != nil { 847 return Handle(0), nil, err 848 } 849 850 // Send command 851 _, err = rw.Write(cmd) 852 if err != nil { 853 return Handle(0), nil, errors.New("Write Tpm fails") 854 } 855 856 // Get response 857 var resp []byte 858 resp = make([]byte, 2048, 2048) 859 read, err := rw.Read(resp) 860 if err != nil { 861 return Handle(0), nil, errors.New("Read Tpm fails") 862 } 863 864 // Decode Response 865 if read < 10 { 866 return Handle(0), nil, errors.New("Read buffer too small") 867 } 868 _, size, status, err := DecodeCommandResponse(resp[0:10]) 869 if err != nil { 870 return Handle(0), nil, err 871 } 872 reportCommand("CreatePrimary", cmd, resp[0:size], status, true) 873 if status != ErrSuccess { 874 } 875 handle, public_blob, err := DecodeCreatePrimary(resp[10:read]) 876 if err != nil { 877 return Handle(0), nil, err 878 } 879 return Handle(handle), public_blob, nil 880 } 881 882 // ConstructReadPublic constructs a ReadPublic command. 883 func ConstructReadPublic(handle Handle) ([]byte, error) { 884 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdReadPublic) 885 if err != nil { 886 return nil, errors.New("ConstructReadPublic failed") 887 } 888 num_bytes := []interface{}{uint32(handle)} 889 cmd, _ := packWithHeader(cmdHdr, num_bytes) 890 return cmd, nil 891 } 892 893 // DecodeReadPublic decodes a ReadPublic response. 894 // public, name, qualified name 895 func DecodeReadPublic(in []byte) ([]byte, []byte, []byte, error) { 896 var public_blob []byte 897 var name []byte 898 var qualified_name []byte 899 900 out := []interface{}{&public_blob, &name, &qualified_name} 901 err := unpack(in, out) 902 if err != nil { 903 return nil, nil, nil, errors.New("Can't decode ReadPublic response") 904 } 905 return public_blob, name, qualified_name, nil 906 } 907 908 // ReadPublic 909 // Output: key blob, name, qualified name 910 func ReadPublic(rw io.ReadWriter, handle Handle) ([]byte, []byte, []byte, error) { 911 912 // Construct command 913 cmd, err := ConstructReadPublic(handle) 914 if err != nil { 915 return nil, nil, nil, err 916 } 917 918 // Send command 919 _, err = rw.Write(cmd) 920 if err != nil { 921 return nil, nil, nil, errors.New("Write Tpm fails") 922 } 923 924 // Get response 925 var resp []byte 926 resp = make([]byte, 4096, 4096) 927 read, err := rw.Read(resp) 928 if err != nil { 929 return nil, nil, nil, errors.New("Read Tpm fails") 930 } 931 932 // Decode Response 933 if read < 10 { 934 return nil, nil, nil, errors.New("Read buffer too small") 935 } 936 _, size, status, err := DecodeCommandResponse(resp[0:10]) 937 if err != nil { 938 return nil, nil, nil, err 939 } 940 reportCommand("ReadPublic", cmd, resp[0:size], status, true) 941 if status != ErrSuccess { 942 return nil, nil, nil, err 943 } 944 public_blob, name, qualified_name, err := DecodeReadPublic(resp[10:read]) 945 if err != nil { 946 return nil, nil, nil, err 947 } 948 return public_blob, name, qualified_name, nil 949 } 950 951 // CreateKey 952 953 // ConstructCreateKey constructs a CreateKey command. 954 func ConstructCreateKey(owner uint32, pcr_nums []int, parent_password string, owner_password string, 955 parms RsaParams) ([]byte, error) { 956 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreate) 957 if err != nil { 958 return nil, errors.New("ConstructCreateKey failed") 959 } 960 var empty []byte 961 b1 := SetHandle(Handle(owner)) 962 b2, _ := pack([]interface{}{&empty}) 963 b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW)) 964 t1 := SetPasswordData(owner_password) 965 b4 := CreateSensitiveArea(t1[2:], empty) 966 b5 := CreateRsaParams(parms) 967 b6, _ := pack([]interface{}{&empty}) 968 b7 := CreateLongPcr(uint32(1), pcr_nums) 969 arg_bytes := append(b1, b2...) 970 arg_bytes = append(arg_bytes, b3...) 971 arg_bytes = append(arg_bytes, b4...) 972 arg_bytes = append(arg_bytes, b5...) 973 arg_bytes = append(arg_bytes, b6...) 974 arg_bytes = append(arg_bytes, b7...) 975 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 976 return cmd_bytes, nil 977 } 978 979 // DecodeCreateKey decodes a CreateKey response. 980 // Output: private_blob, public_blob 981 func DecodeCreateKey(in []byte) ([]byte, []byte, error) { 982 var tpm2b_private []byte 983 var tpm2b_public []byte 984 985 // auth? 986 // tpm2b_private 987 // tpm2b_public 988 out := []interface{}{&tpm2b_private, &tpm2b_public} 989 err := unpack(in[4:], out) 990 if err != nil { 991 return nil, nil, errors.New("Can't decode CreateKey response") 992 } 993 // creation data 994 // tpmt_tk_creation 995 // digest 996 return tpm2b_private, tpm2b_public, nil 997 } 998 999 // Output: public blob, private blob, digest 1000 func CreateKey(rw io.ReadWriter, owner uint32, pcr_nums []int, parent_password string, owner_password string, 1001 parms RsaParams) ([]byte, []byte, error) { 1002 1003 // Construct command 1004 cmd, err := ConstructCreateKey(uint32(owner), pcr_nums, parent_password, owner_password, parms) 1005 if err != nil { 1006 return nil, nil, err 1007 } 1008 1009 // Send command 1010 _, err = rw.Write(cmd) 1011 if err != nil { 1012 return nil, nil, errors.New("Write Tpm fails") 1013 } 1014 1015 // Get response 1016 var resp []byte 1017 resp = make([]byte, 4096, 4096) 1018 read, err := rw.Read(resp) 1019 if err != nil { 1020 return nil, nil, errors.New("Read Tpm fails") 1021 } 1022 1023 // Decode Response 1024 if read < 10 { 1025 return nil, nil, errors.New("Read buffer too small") 1026 } 1027 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1028 if err != nil { 1029 return nil, nil, err 1030 } 1031 reportCommand("CreateKey", cmd, resp[0:size], status, true) 1032 if status != ErrSuccess { 1033 return nil, nil, errors.New("Error from command") 1034 } 1035 private_blob, public_blob, err := DecodeCreateKey(resp[10:read]) 1036 if err != nil { 1037 return nil, nil, err 1038 } 1039 return private_blob, public_blob, nil 1040 } 1041 1042 // ConstructLoad constructs a Load command. 1043 func ConstructLoad(parentHandle Handle, parentAuth string, ownerAuth string, 1044 public_blob []byte, private_blob []byte) ([]byte, error) { 1045 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdLoad) 1046 if err != nil { 1047 return nil, errors.New("ConstructLoad failed") 1048 } 1049 b1 := SetHandle(parentHandle) 1050 b3 := SetPasswordData(parentAuth) 1051 b4 := CreatePasswordAuthArea(ownerAuth, Handle(OrdTPM_RS_PW)) 1052 // private, public 1053 b5, _ := pack([]interface{}{&private_blob, &public_blob}) 1054 arg_bytes := append(b1, b3...) 1055 arg_bytes = append(arg_bytes, b4...) 1056 arg_bytes = append(arg_bytes, b5...) 1057 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1058 return cmd_bytes, nil 1059 } 1060 1061 // DecodeLoad decodes a Load response. 1062 // handle, name 1063 func DecodeLoad(in []byte) (Handle, []byte, error) { 1064 var handle uint32 1065 var auth []byte 1066 var name []byte 1067 1068 out := []interface{}{&handle, &auth, &name} 1069 err := unpack(in, out) 1070 if err != nil { 1071 return Handle(0), nil, errors.New("Can't decode Load response") 1072 } 1073 return Handle(handle), name, nil 1074 } 1075 1076 // Load 1077 // Output: handle 1078 func Load(rw io.ReadWriter, parentHandle Handle, parentAuth string, ownerAuth string, 1079 public_blob []byte, private_blob []byte) (Handle, []byte, error) { 1080 1081 // Construct command 1082 cmd, err := ConstructLoad(parentHandle, parentAuth, ownerAuth, public_blob, private_blob) 1083 if err != nil { 1084 return Handle(0), nil, err 1085 } 1086 1087 // Send command 1088 _, err = rw.Write(cmd) 1089 if err != nil { 1090 return Handle(0), nil, errors.New("Write Tpm fails") 1091 } 1092 1093 // Get response 1094 var resp []byte 1095 resp = make([]byte, 4096, 4096) 1096 read, err := rw.Read(resp) 1097 if err != nil { 1098 return Handle(0), nil, errors.New("Read Tpm fails") 1099 } 1100 1101 // Decode Response 1102 if read < 10 { 1103 return Handle(0), nil, errors.New("Read buffer too small") 1104 } 1105 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1106 if err != nil { 1107 return Handle(0), nil, err 1108 } 1109 reportCommand("Load", cmd, resp[0:size], status, true) 1110 if status != ErrSuccess { 1111 return Handle(0), nil, errors.New("Error from command") 1112 } 1113 handle, name, err := DecodeLoad(resp[10:read]) 1114 if err != nil { 1115 return Handle(0), nil, err 1116 } 1117 return handle, name, nil 1118 } 1119 1120 // Construct PolicyPcr command. 1121 func ConstructPolicyPcr(handle Handle, expected_digest []byte, 1122 pcr_nums []int) ([]byte, error) { 1123 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyPCR) 1124 if err != nil { 1125 return nil, errors.New("ConstructPcr failed") 1126 } 1127 u_handle := uint32(handle) 1128 template := []interface{}{&u_handle, &expected_digest} 1129 b1, err := pack(template) 1130 if err != nil { 1131 return nil, errors.New("Can't pack pcr buf") 1132 } 1133 b2 := CreateLongPcr(1, pcr_nums) 1134 cmd := packWithBytes(cmdHdr, append(b1, b2...)) 1135 return cmd, nil 1136 } 1137 1138 // ConstructPolicyPassword constructs a PolicyPassword command. 1139 func ConstructPolicyPassword(handle Handle) ([]byte, error) { 1140 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyPassword) 1141 if err != nil { 1142 return nil, errors.New("ConstructPassword failed") 1143 } 1144 u_handle := uint32(handle) 1145 template := []interface{}{&u_handle} 1146 b1, err := pack(template) 1147 if err != nil { 1148 return nil, errors.New("Can't pack pcr buf") 1149 } 1150 cmd := packWithBytes(cmdHdr, b1) 1151 return cmd, nil 1152 } 1153 1154 // PolicyPassword 1155 func PolicyPassword(rw io.ReadWriter, handle Handle) error { 1156 // Construct command 1157 cmd, err := ConstructPolicyPassword(handle) 1158 if err != nil { 1159 return err 1160 } 1161 1162 // Send command 1163 _, err = rw.Write(cmd) 1164 if err != nil { 1165 return errors.New("Write Tpm fails") 1166 } 1167 1168 // Get response 1169 var resp []byte 1170 resp = make([]byte, 1024, 1024) 1171 read, err := rw.Read(resp) 1172 if err != nil { 1173 return errors.New("Read Tpm fails") 1174 } 1175 1176 // Decode Response 1177 if read < 10 { 1178 return errors.New("Read buffer too small") 1179 } 1180 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1181 if err != nil { 1182 return err 1183 } 1184 reportCommand("PolicyPassword", cmd, resp[0:size], status, true) 1185 if status != ErrSuccess { 1186 return errors.New("Comand failure") 1187 } 1188 return nil 1189 } 1190 1191 // PolicyPcr 1192 func PolicyPcr(rw io.ReadWriter, handle Handle, expected_digest []byte, 1193 pcr_nums []int) error { 1194 // Construct command 1195 cmd, err := ConstructPolicyPcr(handle, expected_digest, pcr_nums) 1196 if err != nil { 1197 return err 1198 } 1199 1200 // Send command 1201 _, err = rw.Write(cmd) 1202 if err != nil { 1203 return errors.New("Write Tpm fails") 1204 } 1205 1206 // Get response 1207 var resp []byte 1208 resp = make([]byte, 1024, 1024) 1209 read, err := rw.Read(resp) 1210 if err != nil { 1211 return errors.New("Read Tpm fails") 1212 } 1213 1214 // Decode Response 1215 if read < 10 { 1216 return errors.New("Read buffer too small") 1217 } 1218 _, _, status, err := DecodeCommandResponse(resp[0:10]) 1219 if err != nil { 1220 return err 1221 } 1222 if status != ErrSuccess { 1223 return errors.New("Comand failure") 1224 } 1225 return nil 1226 } 1227 1228 // ConstructPolicyGetDigest constructs a PolicyGetDigest command. 1229 func ConstructPolicyGetDigest(handle Handle) ([]byte, error) { 1230 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdPolicyGetDigest) 1231 if err != nil { 1232 return nil, errors.New("ConstructGetDigest failed") 1233 } 1234 u_handle := uint32(handle) 1235 template := []interface{}{&u_handle} 1236 b1, err := pack(template) 1237 if err != nil { 1238 return nil, errors.New("Can't pack pcr buf") 1239 } 1240 cmd := packWithBytes(cmdHdr, b1) 1241 return cmd, nil 1242 } 1243 1244 // DecodePolicyGetDigest decodes a PolicyGetDigest response. 1245 func DecodePolicyGetDigest(in []byte) ([]byte, error) { 1246 var digest []byte 1247 1248 out := []interface{}{&digest} 1249 err := unpack(in, out) 1250 if err != nil { 1251 return nil, errors.New("Can't decode DecodePolicyGetDigest response") 1252 } 1253 return digest, nil 1254 } 1255 1256 // PolicyGetDigest 1257 // Output: digest 1258 func PolicyGetDigest(rw io.ReadWriter, handle Handle) ([]byte, error) { 1259 // Construct command 1260 cmd, err := ConstructPolicyGetDigest(handle) 1261 if err != nil { 1262 return nil, err 1263 } 1264 1265 // Send command 1266 _, err = rw.Write(cmd) 1267 if err != nil { 1268 return nil, errors.New("Write Tpm fails") 1269 } 1270 1271 // Get response 1272 var resp []byte 1273 resp = make([]byte, 4096, 4096) 1274 read, err := rw.Read(resp) 1275 if err != nil { 1276 return nil, errors.New("Read Tpm fails") 1277 } 1278 1279 // Decode Response 1280 if read < 10 { 1281 return nil, errors.New("Read buffer too small") 1282 } 1283 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1284 if err != nil { 1285 return nil, err 1286 } 1287 reportCommand("PolicyGetDigest", cmd, resp[0:size], status, true) 1288 if status != ErrSuccess { 1289 return nil, errors.New("Comand failure") 1290 } 1291 digest, err := DecodePolicyGetDigest(resp[10:]) 1292 if err != nil { 1293 return nil, err 1294 } 1295 return digest, nil 1296 } 1297 1298 // ConstructStartAuthSession constructs a StartAuthSession command. 1299 func ConstructStartAuthSession(tpm_key Handle, bind_key Handle, 1300 nonceCaller []byte, secret []byte, 1301 se byte, sym uint16, hash_alg uint16) ([]byte, error) { 1302 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdStartAuthSession) 1303 if err != nil { 1304 return nil, errors.New("ConstructStartAuthSession failed") 1305 } 1306 b1 := SetHandle(tpm_key) 1307 b2 := SetHandle(bind_key) 1308 b3, _ := pack([]interface{}{&nonceCaller, &secret}) 1309 // secret and se 1310 b4 := []byte{se} 1311 b5, _ := pack([]interface{}{&sym, &hash_alg}) 1312 arg_bytes := append(b1, b2...) 1313 arg_bytes = append(arg_bytes, b3...) 1314 arg_bytes = append(arg_bytes, b4...) 1315 arg_bytes = append(arg_bytes, b5...) 1316 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1317 return cmd_bytes, nil 1318 } 1319 1320 // DecodeStartAuthSession decodes a StartAuthSession response. 1321 // Output: session_handle, nonce 1322 func DecodeStartAuthSession(in []byte) (Handle, []byte, error) { 1323 var handle uint32 1324 var nonce []byte 1325 template := []interface{}{&handle, &nonce} 1326 err := unpack(in, template) 1327 if err != nil { 1328 return Handle(0), nil, errors.New("Can't decode StartAuthSession response") 1329 } 1330 return Handle(handle), nonce, nil 1331 } 1332 1333 // StartAuthSession 1334 func StartAuthSession(rw io.ReadWriter, tpm_key Handle, bind_key Handle, 1335 nonceCaller []byte, secret []byte, 1336 se byte, sym uint16, hash_alg uint16) (Handle, []byte, error) { 1337 1338 // Construct command 1339 cmd, err := ConstructStartAuthSession(tpm_key, bind_key, nonceCaller, secret, 1340 se, sym, hash_alg) 1341 if err != nil { 1342 return Handle(0), nil, errors.New("ConstructStartAuthSession fails") 1343 } 1344 1345 // Send command 1346 _, err = rw.Write(cmd) 1347 if err != nil { 1348 return Handle(0), nil, errors.New("Write Tpm fails") 1349 } 1350 1351 // Get response 1352 var resp []byte 1353 resp = make([]byte, 4096, 4096) 1354 read, err := rw.Read(resp) 1355 if err != nil { 1356 return Handle(0), nil, errors.New("Read Tpm fails") 1357 } 1358 1359 // Decode Response 1360 if read < 10 { 1361 return Handle(0), nil, errors.New("Read buffer too small") 1362 } 1363 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1364 if err != nil { 1365 return Handle(0), nil, errors.New("DecodeCommandResponse fails") 1366 } 1367 reportCommand("StartAuthSession", cmd, resp[0:size], status, true) 1368 if status != ErrSuccess { 1369 return Handle(0), nil, errors.New("StartAuthSession unsuccessful") 1370 } 1371 handle, nonce, err := DecodeStartAuthSession(resp[10:]) 1372 if err != nil { 1373 return Handle(0), nil, errors.New("DecodeStartAuthSession fails") 1374 } 1375 return handle, nonce, nil 1376 } 1377 1378 // ConstructCreateSealed constructs a CreateSealed command. 1379 func ConstructCreateSealed(parent Handle, policy_digest []byte, 1380 parent_password string, owner_password string, 1381 to_seal []byte, pcr_nums []int, 1382 parms KeyedHashParams) ([]byte, error) { 1383 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdCreate) 1384 if err != nil { 1385 return nil, errors.New("ConstructCreateKey failed") 1386 } 1387 var empty []byte 1388 b1 := SetHandle(parent) 1389 b2, _ := pack([]interface{}{&empty}) 1390 b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW)) 1391 t1 := SetPasswordData(owner_password) 1392 b4 := CreateSensitiveArea(t1[2:], to_seal) 1393 parms.Auth_policy = policy_digest 1394 b5 := CreateKeyedHashParams(parms) 1395 b6, _ := pack([]interface{}{&b5}) 1396 b7, _ := pack([]interface{}{&empty}) 1397 b8 := CreateLongPcr(uint32(1), pcr_nums) 1398 arg_bytes := append(b1, b2...) 1399 arg_bytes = append(arg_bytes, b3...) 1400 arg_bytes = append(arg_bytes, b4...) 1401 arg_bytes = append(arg_bytes, b6...) 1402 arg_bytes = append(arg_bytes, b7...) 1403 arg_bytes = append(arg_bytes, b8...) 1404 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1405 return cmd_bytes, nil 1406 } 1407 1408 // DecodeCreateSealed decodes a CreateSealed response. 1409 // Output: private, public, creation_out, digest_out, creation_ticket 1410 func DecodeCreateSealed(in []byte) ([]byte, []byte, error) { 1411 var tpm2b_private []byte 1412 var tpm2b_public []byte 1413 1414 // auth, tpm2b_private, tpm2b_public 1415 template := []interface{}{&tpm2b_private, &tpm2b_public} 1416 err := unpack(in[4:], template) 1417 if err != nil { 1418 return nil, nil, errors.New("Can't decode CreateSealed response") 1419 } 1420 // creation data 1421 // tpmt_tk_creation 1422 // digest 1423 return tpm2b_private, tpm2b_public, nil 1424 } 1425 1426 // CreateSealed 1427 // Output: public blob, private blob 1428 func CreateSealed(rw io.ReadWriter, parent Handle, policy_digest []byte, 1429 parent_password string, owner_password string, 1430 to_seal []byte, pcr_nums []int, parms KeyedHashParams) ([]byte, []byte, error) { 1431 // Construct command 1432 cmd, err := ConstructCreateSealed(parent, policy_digest, 1433 parent_password, owner_password, 1434 to_seal, pcr_nums, parms) 1435 if err != nil { 1436 return nil, nil, errors.New("ConstructCreateSealed fails") 1437 } 1438 1439 // Send command 1440 _, err = rw.Write(cmd) 1441 if err != nil { 1442 return nil, nil, errors.New("Write Tpm fails") 1443 } 1444 1445 // Get response 1446 var resp []byte 1447 resp = make([]byte, 4096, 4096) 1448 read, err := rw.Read(resp) 1449 if err != nil { 1450 return nil, nil, errors.New("Read Tpm fails") 1451 } 1452 1453 // Decode Response 1454 if read < 10 { 1455 return nil, nil, errors.New("Read buffer too small") 1456 } 1457 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1458 if err != nil { 1459 return nil, nil, errors.New("DecodeCommandResponse fails") 1460 } 1461 reportCommand("CreateSealed", cmd, resp[0:size], status, true) 1462 if status != ErrSuccess { 1463 return nil, nil, errors.New("CreateSealed unsuccessful") 1464 } 1465 handle, nonce, err := DecodeCreateSealed(resp[10:]) 1466 if err != nil { 1467 return nil, nil, errors.New("DecodeCreateSealed fails") 1468 } 1469 return handle, nonce, nil 1470 } 1471 1472 // ConstructUnseal constructs a Unseal command. 1473 func ConstructUnseal(item_handle Handle, password string, session_handle Handle) ([]byte, error) { 1474 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdUnseal) 1475 if err != nil { 1476 return nil, errors.New("Construct Unseal failed") 1477 } 1478 // item_handle 1479 var empty []byte 1480 handle1 := uint32(item_handle) 1481 template := []interface{}{&handle1, &empty} 1482 b1, err := pack(template) 1483 if err != nil { 1484 return nil, errors.New("Can't construct Unseal") 1485 } 1486 session_attributes := uint8(1) 1487 b2 := CreatePasswordAuthArea(password, session_handle) 1488 template = []interface{}{&empty, &session_attributes} // null hmac 1489 cmd_bytes := packWithBytes(cmdHdr, append(b1, b2...)) 1490 return cmd_bytes, nil 1491 } 1492 1493 // DecodeUnseal decodes a Unseal response. 1494 // Output: sensitive data 1495 func DecodeUnseal(in []byte) ([]byte, []byte, error) { 1496 var unsealed []byte 1497 var digest []byte 1498 1499 template := []interface{}{&unsealed, &digest} 1500 err := unpack(in[4:], template) 1501 if err != nil { 1502 return nil, nil, errors.New("Can't decode Unseal response") 1503 } 1504 return unsealed, digest, nil 1505 } 1506 1507 // Unseal 1508 func Unseal(rw io.ReadWriter, item_handle Handle, password string, session_handle Handle, 1509 digest []byte) ([]byte, []byte, error) { 1510 // Construct command 1511 cmd, err := ConstructUnseal(item_handle, password, session_handle) 1512 if err != nil { 1513 return nil, nil, errors.New("ConstructUnseal fails") 1514 } 1515 1516 // Send command 1517 _, err = rw.Write(cmd) 1518 if err != nil { 1519 return nil, nil, errors.New("Write Tpm fails") 1520 } 1521 1522 // Get response 1523 var resp []byte 1524 resp = make([]byte, 4096, 4096) 1525 read, err := rw.Read(resp) 1526 if err != nil { 1527 return nil, nil, errors.New("Read Tpm fails") 1528 } 1529 1530 // Decode Response 1531 if read < 10 { 1532 return nil, nil, errors.New("Read buffer too small") 1533 } 1534 _, _, status, err := DecodeCommandResponse(resp[0:10]) 1535 if err != nil { 1536 return nil, nil, errors.New("DecodeCommandResponse fails") 1537 } 1538 if status != ErrSuccess { 1539 return nil, nil, errors.New("Unseal unsuccessful") 1540 } 1541 unsealed, nonce, err := DecodeUnseal(resp[10:]) 1542 if err != nil { 1543 return nil, nil, errors.New("DecodeStartAuthSession fails") 1544 } 1545 return unsealed, nonce, nil 1546 } 1547 1548 // ConstructQuote constructs a Quote command. 1549 func ConstructQuote(signing_handle Handle, parent_password, owner_password string, 1550 to_quote []byte, pcr_nums []int, sig_alg uint16) ([]byte, error) { 1551 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdQuote) 1552 if err != nil { 1553 return nil, errors.New("ConstructQuote failed") 1554 } 1555 // TODO: no scheme or sig_alg? 1556 // handle 1557 var empty []byte 1558 b1 := SetHandle(signing_handle) 1559 b2, _ := pack([]interface{}{&empty}) 1560 b3 := CreatePasswordAuthArea(parent_password, Handle(OrdTPM_RS_PW)) 1561 b4, _ := pack([]interface{}{&to_quote, &sig_alg}) 1562 b5 := CreateLongPcr(uint32(1), pcr_nums) 1563 arg_bytes := append(b1, b2...) 1564 arg_bytes = append(arg_bytes, b3...) 1565 arg_bytes = append(arg_bytes, b4...) 1566 // Scheme info? 1567 arg_bytes = append(arg_bytes, b5...) 1568 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1569 return cmd_bytes, nil 1570 } 1571 1572 // DecodeQuote decodes a Quote response. 1573 // Output: attest, signature 1574 func DecodeQuote(in []byte) ([]byte, uint16, uint16, []byte, error) { 1575 var empty []byte 1576 var buf []byte 1577 var attest []byte 1578 var signature []byte 1579 var s1 uint16 1580 var s2 uint16 1581 1582 template := []interface{}{&empty, &buf} 1583 err := unpack(in, template) 1584 if err != nil { 1585 return nil, 0, 0, nil, errors.New("Can't decode Quote response") 1586 } 1587 1588 template = []interface{}{&attest, &s1, &s2, &signature} 1589 err = unpack(buf, template) 1590 if err != nil { 1591 return nil, 0, 0, nil, errors.New("Can't decode Quote response") 1592 } 1593 return attest, s1, s2, signature, nil 1594 } 1595 1596 // Quote 1597 // Output: attest, sig 1598 func Quote(rw io.ReadWriter, signing_handle Handle, parent_password string, owner_password string, 1599 to_quote []byte, pcr_nums []int, sig_alg uint16) ([]byte, []byte, error) { 1600 // Construct command 1601 cmd, err := ConstructQuote(signing_handle, parent_password, owner_password, 1602 to_quote, pcr_nums, sig_alg) 1603 if err != nil { 1604 return nil, nil, errors.New("ConstructQuote fails") 1605 } 1606 1607 // Send command 1608 _, err = rw.Write(cmd) 1609 if err != nil { 1610 return nil, nil, errors.New("Write Tpm fails") 1611 } 1612 1613 // Get response 1614 var resp []byte 1615 resp = make([]byte, 4096, 4096) 1616 read, err := rw.Read(resp) 1617 if err != nil { 1618 return nil, nil, errors.New("Read Tpm fails") 1619 } 1620 1621 // Decode Response 1622 if read < 10 { 1623 return nil, nil, errors.New("Read buffer too small") 1624 } 1625 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1626 if err != nil { 1627 return nil, nil, errors.New("DecodeCommandResponse fails") 1628 } 1629 reportCommand("Quote", cmd, resp[0:size], status, true) 1630 if status != ErrSuccess { 1631 return nil, nil, errors.New("Quote unsuccessful") 1632 } 1633 attest, _, _, sig, err := DecodeQuote(resp[10:size]) 1634 if err != nil { 1635 return nil, nil, errors.New("DecodeQuote fails") 1636 } 1637 return attest, sig, nil 1638 } 1639 1640 // ConstructActivateCredential constructs a ActivateCredential command. 1641 func ConstructActivateCredential(active_handle Handle, key_handle Handle, 1642 activePassword string, protectorPassword string, 1643 credBlob []byte, secret []byte) ([]byte, error) { 1644 var empty []byte 1645 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdActivateCredential) 1646 if err != nil { 1647 return nil, errors.New("ConstructActivateCredential failed") 1648 } 1649 b1 := SetHandle(active_handle) 1650 b2 := SetHandle(key_handle) 1651 b3, _ := pack([]interface{}{&empty}) 1652 b4a := CreatePasswordAuthArea(activePassword, Handle(OrdTPM_RS_PW)) 1653 b4b := CreatePasswordAuthArea(protectorPassword, Handle(OrdTPM_RS_PW)) 1654 b4t := append(b4a[2:], b4b[2:]...) 1655 b4, _ := pack([]interface{}{&b4t}) 1656 b5, _ := pack([]interface{}{&credBlob, &secret}) 1657 arg_bytes := append(b1, b2...) 1658 arg_bytes = append(arg_bytes, b3...) 1659 arg_bytes = append(arg_bytes, b4...) 1660 arg_bytes = append(arg_bytes, b5...) 1661 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1662 return cmd_bytes, nil 1663 } 1664 1665 // DecodeActivateCredential decodes a ActivateCredential response. 1666 // returns certInfo 1667 func DecodeActivateCredential(in []byte) ([]byte, error) { 1668 var empty []byte 1669 var buf []byte 1670 var certInfo []byte 1671 1672 template := []interface{}{&empty, &buf} 1673 err := unpack(in, template) 1674 if err != nil { 1675 return nil, errors.New("Can't decode ActivateCredential response") 1676 } 1677 template = []interface{}{&certInfo} 1678 err = unpack(buf, template) 1679 if err != nil { 1680 return nil, errors.New("Can't decode ActivateCredential response") 1681 } 1682 return certInfo, nil 1683 } 1684 1685 // ActivateCredential 1686 // Output: certinfo 1687 func ActivateCredential(rw io.ReadWriter, active_handle Handle, key_handle Handle, 1688 activePassword string, protectorPassword string, 1689 credBlob []byte, secret []byte) ([]byte, error) { 1690 // Construct command 1691 cmd, err := ConstructActivateCredential(active_handle, key_handle, activePassword, 1692 protectorPassword, credBlob, secret) 1693 if err != nil { 1694 return nil, errors.New("ConstructActivateCredential fails") 1695 } 1696 1697 // Send command 1698 _, err = rw.Write(cmd) 1699 if err != nil { 1700 return nil, errors.New("Write Tpm fails") 1701 } 1702 1703 // Get response 1704 var resp []byte 1705 resp = make([]byte, 4096, 4096) 1706 read, err := rw.Read(resp) 1707 if err != nil { 1708 return nil, errors.New("Read Tpm fails") 1709 } 1710 1711 // Decode Response 1712 if read < 10 { 1713 return nil, errors.New("Read buffer too small") 1714 } 1715 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1716 if err != nil { 1717 return nil, errors.New("DecodeCommandResponse fails") 1718 } 1719 reportCommand("ActivateCredential", cmd, resp[0:size], status, true) 1720 if status != ErrSuccess { 1721 return nil, errors.New("ActivateCredential unsuccessful") 1722 } 1723 cred, err := DecodeActivateCredential(resp[10:]) 1724 if err != nil { 1725 return nil, errors.New("DecodeActivateCredential fails") 1726 } 1727 return cred, nil 1728 } 1729 1730 // ConstructEvictControl constructs a EvictControl command. 1731 func ConstructEvictControl(owner Handle, tmp_handle Handle, 1732 persistant_handle Handle) ([]byte, error) { 1733 var empty []byte 1734 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdEvictControl) 1735 if err != nil { 1736 return nil, errors.New("ConstructEvictControl failed") 1737 } 1738 b1 := SetHandle(owner) 1739 b2 := SetHandle(tmp_handle) 1740 b3, err := pack([]interface{}{&empty}) 1741 if err != nil { 1742 return nil, errors.New("can't encode empty") 1743 } 1744 b4 := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW)) 1745 b5 := SetHandle(persistant_handle) 1746 arg_bytes := append(b1, b2...) 1747 arg_bytes = append(arg_bytes, b3...) 1748 arg_bytes = append(arg_bytes, b4...) 1749 arg_bytes = append(arg_bytes, b5...) 1750 cmd_bytes := packWithBytes(cmdHdr, arg_bytes) 1751 return cmd_bytes, nil 1752 } 1753 1754 // DecodeEvictControl decodes a EvictControl response. 1755 func DecodeEvictControl(in []byte) error { 1756 return nil 1757 } 1758 1759 // EvictControl 1760 func EvictControl(rw io.ReadWriter, owner Handle, tmp_handle Handle, persistant_handle Handle) error { 1761 // Construct command 1762 cmd, err := ConstructEvictControl(owner, tmp_handle, persistant_handle) 1763 if err != nil { 1764 return errors.New("ConstructEvictControl fails") 1765 } 1766 1767 // Send command 1768 _, err = rw.Write(cmd) 1769 if err != nil { 1770 return errors.New("Write Tpm fails") 1771 } 1772 1773 // Get response 1774 var resp []byte 1775 resp = make([]byte, 1024, 1024) 1776 read, err := rw.Read(resp) 1777 if err != nil { 1778 return errors.New("Read Tpm fails") 1779 } 1780 1781 // Decode Response 1782 if read < 10 { 1783 return errors.New("Read buffer too small") 1784 } 1785 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1786 if err != nil { 1787 return errors.New("DecodeCommandResponse fails") 1788 } 1789 reportCommand("EvictControl", cmd, resp[0:size], status, true) 1790 if status != ErrSuccess { 1791 return errors.New("EvictControl unsuccessful") 1792 } 1793 err = DecodeEvictControl(resp[10:]) 1794 if err != nil { 1795 return errors.New("DecodeEvictControl fails") 1796 } 1797 return nil 1798 } 1799 1800 // ConstructSaveContext constructs a SaveContext command. 1801 func ConstructSaveContext(handle Handle) ([]byte, error) { 1802 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdContextSave) 1803 if err != nil { 1804 return nil, errors.New("ConstructSaveContext failed") 1805 } 1806 b1 := SetHandle(handle) 1807 cmd_bytes := packWithBytes(cmdHdr, b1) 1808 return cmd_bytes, nil 1809 } 1810 1811 // DecodeSaveContext constructs a SaveContext command. 1812 func DecodeSaveContext(save_area []byte) ([]byte, error) { 1813 return save_area, nil 1814 } 1815 1816 func SaveContext(rw io.ReadWriter, handle Handle) ([]byte, error) { 1817 // Construct command 1818 cmd, err := ConstructSaveContext(handle) 1819 if err != nil { 1820 return nil, errors.New("ConstructSaveContext fails") 1821 } 1822 1823 // Send command 1824 _, err = rw.Write(cmd) 1825 if err != nil { 1826 return nil, errors.New("Write Tpm fails") 1827 } 1828 1829 // Get response 1830 var resp []byte 1831 resp = make([]byte, 4096, 4096) 1832 read, err := rw.Read(resp) 1833 if err != nil { 1834 return nil, errors.New("Read Tpm fails") 1835 } 1836 1837 // Decode Response 1838 if read < 10 { 1839 return nil, errors.New("Read buffer too small") 1840 } 1841 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1842 if err != nil { 1843 return nil, errors.New("DecodeCommandResponse fails") 1844 } 1845 reportCommand("SaveContext", cmd, resp[0:size], status, true) 1846 if status != ErrSuccess { 1847 return nil, errors.New("SaveContext unsuccessful") 1848 } 1849 save_area, err := DecodeSaveContext(resp[10:size]) 1850 if err != nil { 1851 return nil, errors.New("DecodeSaveContext fails") 1852 } 1853 return save_area, nil 1854 } 1855 1856 // LoadContext 1857 1858 // ConstructLoadContext constructs a LoadContext command. 1859 func ConstructLoadContext(save_area []byte) ([]byte, error) { 1860 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdContextLoad) 1861 if err != nil { 1862 return nil, errors.New("ConstructLoadContext failed") 1863 } 1864 cmd_bytes := packWithBytes(cmdHdr, save_area[0:len(save_area)]) 1865 return cmd_bytes, nil 1866 } 1867 1868 // DecodeLoadContext decodes a LoadContext response. 1869 func DecodeLoadContext(in []byte) (Handle, error) { 1870 var handle uint32 1871 template := []interface{}{&handle} 1872 err := unpack(in, template) 1873 if err != nil { 1874 return Handle(0), errors.New("Can't decode LoadContext response") 1875 } 1876 return Handle(handle), nil 1877 } 1878 1879 // LoadContext 1880 func LoadContext(rw io.ReadWriter, save_area []byte) (Handle, error) { 1881 // Construct command 1882 cmd, err := ConstructLoadContext(save_area) 1883 if err != nil { 1884 return Handle(0), errors.New("ConstructLoadContext fails") 1885 } 1886 1887 // Send command 1888 _, err = rw.Write(cmd) 1889 if err != nil { 1890 return Handle(0), errors.New("Write Tpm fails") 1891 } 1892 1893 // Get response 1894 var resp []byte 1895 resp = make([]byte, 2048, 2048) 1896 read, err := rw.Read(resp) 1897 if err != nil { 1898 return Handle(0), errors.New("Read Tpm fails") 1899 } 1900 1901 // Decode Response 1902 if read < 10 { 1903 return Handle(0), errors.New("Read buffer too small") 1904 } 1905 _, size, status, err := DecodeCommandResponse(resp[0:10]) 1906 if err != nil { 1907 return Handle(0), errors.New("DecodeCommandResponse fails") 1908 } 1909 reportCommand("LoadContext", cmd, resp[0:size], status, true) 1910 if status != ErrSuccess { 1911 return Handle(0), errors.New("LoadContext unsuccessful") 1912 } 1913 handle, err := DecodeLoadContext(resp[10:size]) 1914 if err != nil { 1915 return Handle(0), errors.New("DecodeLoadContext fails") 1916 } 1917 return handle, nil 1918 } 1919 1920 func UnmarshalCertifyInfo(in []byte) (*AttestParams, error) { 1921 attest := new(AttestParams) 1922 var count uint32 1923 template := []interface{}{&attest.Magic_number, &attest.Attest_type, 1924 &attest.Name, &attest.Data, &attest.Clock, 1925 &attest.ResetCount, &attest.RestartCount, 1926 &attest.Safe, &attest.FirmwareVersion, &count} 1927 err := unpack(in, template) 1928 if err != nil { 1929 return nil, err 1930 } 1931 i := 4 + 2 + 2 + 2 + 8 + 4 + 4 + 1 + 8 + 4 + len(attest.Name) + len(attest.Data) 1932 attest.PcrSelect = in[i : i+4] 1933 template = []interface{}{&attest.PcrDigest} 1934 err = unpack(in[i+6:], template) 1935 if err != nil { 1936 return nil, err 1937 } 1938 return attest, nil 1939 } 1940 1941 // 1. Generate Seed 1942 // 2. encrypted_secret= E(protector_key, seed || "IDENTITY") 1943 // 3. symKey ≔ KDFa (ekNameAlg, seed, “STORAGE”, name, NULL , bits) 1944 // 4. encIdentity ≔ AesCFB(symKey, 0, credential) 1945 // 5. HMACkey ≔ KDFa (ekNameAlg, seed, “INTEGRITY”, NULL, NULL, bits) 1946 // 6. outerHMAC ≔ HMAC(HMACkey, encIdentity || Name) 1947 // 1948 // Return (all []byte) 1949 // encrypted_secret 1950 // encIdentity 1951 // integrityHmac 1952 func MakeCredential(protectorPublic *rsa.PublicKey, hash_alg_id uint16, 1953 unmarshaled_credential []byte, 1954 unmarshaled_name []byte) ([]byte, []byte, []byte, error) { 1955 var a [9]byte 1956 copy(a[0:9], "IDENTITY") 1957 1958 // Seed. 1959 var seed [16]byte 1960 rand.Read(seed[0:16]) 1961 1962 // encrypt secret 1963 var encrypted_secret []byte 1964 var err error 1965 if hash_alg_id == uint16(AlgTPM_ALG_SHA1) { 1966 encrypted_secret, err = rsa.EncryptOAEP(sha1.New(), 1967 rand.Reader, protectorPublic, seed[0:16], a[0:9]) 1968 } else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) { 1969 encrypted_secret, err = rsa.EncryptOAEP(sha256.New(), 1970 rand.Reader, protectorPublic, seed[0:16], a[0:9]) 1971 } else { 1972 return nil, nil, nil, errors.New("Unsupported hash") 1973 } 1974 if err != nil { 1975 return nil, nil, nil, errors.New("Can't encrypt secret") 1976 } 1977 1978 var symKey []byte 1979 iv := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 1980 if hash_alg_id == uint16(AlgTPM_ALG_SHA1) { 1981 symKey, err = KDFA(hash_alg_id, seed[0:16], "STORAGE", 1982 unmarshaled_name, nil, 128) 1983 if err != nil { 1984 return nil, nil, nil, err 1985 } 1986 } else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) { 1987 symKey, err = KDFA(hash_alg_id, seed[0:16], "STORAGE", 1988 unmarshaled_name, nil, 256) 1989 if err != nil { 1990 return nil, nil, nil, err 1991 } 1992 } else { 1993 return nil, nil, nil, errors.New("Unsupported hash alg") 1994 } 1995 block, err := aes.NewCipher(symKey[0:16]) 1996 if err != nil { 1997 return nil, nil, nil, err 1998 } 1999 2000 // encIdentity is encrypted(size || byte-stream), size in big endian 2001 marshaled_credential := make([]byte, 2+len(unmarshaled_credential)) 2002 encIdentity := make([]byte, 2+len(unmarshaled_credential)) 2003 l := uint16(len(unmarshaled_credential)) 2004 marshaled_credential[0] = byte(l >> 8) 2005 marshaled_credential[1] = byte(l & 0xff) 2006 copy(marshaled_credential[2:], unmarshaled_credential) 2007 cfb := cipher.NewCFBEncrypter(block, iv) 2008 cfb.XORKeyStream(encIdentity, marshaled_credential) 2009 cfbdec := cipher.NewCFBDecrypter(block, iv) 2010 decrypted_credential := make([]byte, 2+len(unmarshaled_credential)) 2011 cfbdec.XORKeyStream(decrypted_credential, encIdentity) 2012 if bytes.Compare(marshaled_credential, decrypted_credential) != 0 { 2013 return nil, nil, nil, errors.New("decrypted cred mismatch") 2014 } 2015 2016 hmacKey, err := KDFA(hash_alg_id, seed[0:16], "INTEGRITY", 2017 nil, nil, 8*SizeHash(hash_alg_id)) 2018 if err != nil { 2019 return nil, nil, nil, err 2020 } 2021 2022 var hmac_bytes []byte 2023 if hash_alg_id == uint16(AlgTPM_ALG_SHA1) { 2024 mac := hmac.New(sha1.New, hmacKey[0:20]) 2025 mac.Write(append(encIdentity, unmarshaled_name...)) 2026 hmac_bytes = mac.Sum(nil) 2027 } else if hash_alg_id == uint16(AlgTPM_ALG_SHA256) { 2028 mac := hmac.New(sha256.New, hmacKey[0:32]) 2029 mac.Write(append(encIdentity, unmarshaled_name...)) 2030 hmac_bytes = mac.Sum(nil) 2031 } else { 2032 return nil, nil, nil, errors.New("Unsupported has alg") 2033 } 2034 marshalled_hmac, _ := pack([]interface{}{&hmac_bytes}) 2035 return encrypted_secret, encIdentity, marshalled_hmac, nil 2036 } 2037 2038 func VerifyRsaQuote(to_quote []byte, rsaQuoteKey *rsa.PublicKey, 2039 hash_alg_id uint16, quote_struct_blob []byte, 2040 signature []byte, checkPcrFunc ValidPcrCheck) bool { 2041 // Decode attest 2042 attest, err := UnmarshalCertifyInfo(quote_struct_blob) 2043 if err != nil { 2044 return false 2045 } 2046 PrintAttestData(attest) 2047 2048 if attest.Magic_number != ordTpmMagic { 2049 glog.Infof("VerifyRsaQuote: Bad magic number") 2050 return false 2051 } 2052 2053 // PCR's valid? 2054 if !checkPcrFunc(attest.PcrSelect, attest.PcrDigest) { 2055 return false 2056 } 2057 2058 // Compute quote 2059 quote_hash, err := ComputeHashValue(hash_alg_id, quote_struct_blob) 2060 if err != nil { 2061 glog.Infof("VerifyRsaQuote: ComputeHashValue fails") 2062 return false 2063 } 2064 2065 // Verify quote 2066 e := new(big.Int) 2067 e.SetUint64(uint64(rsaQuoteKey.E)) 2068 x := new(big.Int) 2069 x.SetBytes(signature) 2070 z := new(big.Int) 2071 z = z.Exp(x, e, rsaQuoteKey.N) 2072 decrypted_quote := z.Bytes() 2073 start_quote_blob := len(decrypted_quote) - SizeHash(hash_alg_id) 2074 if bytes.Compare(decrypted_quote[start_quote_blob:], quote_hash) != 0 { 2075 glog.Infof("VerifyRsaQuote: Compare fails. %x %x\n", quote_hash, decrypted_quote[start_quote_blob:]) 2076 return false 2077 } 2078 return true 2079 } 2080 2081 func VerifyQuote(to_quote []byte, quote_key_info QuoteKeyInfoMessage, 2082 hash_alg_id uint16, quote_struct_blob []byte, 2083 signature []byte, checkPcrFunc ValidPcrCheck) bool { 2084 // Decode attest 2085 attest, err := UnmarshalCertifyInfo(quote_struct_blob) 2086 if err != nil { 2087 return false 2088 } 2089 PrintAttestData(attest) 2090 2091 if attest.Magic_number != ordTpmMagic { 2092 glog.Infof("VerifyQuote: Bad magic number") 2093 return false 2094 } 2095 2096 // PCR's valid? 2097 if !checkPcrFunc(attest.PcrSelect, attest.PcrDigest) { 2098 return false 2099 } 2100 2101 // Compute quote 2102 quote_hash, err := ComputeHashValue(hash_alg_id, quote_struct_blob) 2103 if err != nil { 2104 glog.Infof("VerifyQuote: ComputeHashValue fails") 2105 return false 2106 } 2107 2108 // Get quote key from quote_key_info 2109 if *quote_key_info.PublicKey.KeyType != "rsa" { 2110 glog.Infof("VerifyQuote: Bad key type %s\n", quote_key_info.PublicKey.KeyType) 2111 return false 2112 } 2113 2114 // Verify quote 2115 var N *big.Int 2116 var E *big.Int 2117 N = new(big.Int) 2118 N.SetBytes(quote_key_info.PublicKey.RsaKey.Modulus) 2119 E = new(big.Int) 2120 E.SetBytes([]byte{0, 1, 0, 1}) 2121 x := new(big.Int) 2122 x.SetBytes(signature) 2123 z := new(big.Int) 2124 z = z.Exp(x, E, N) 2125 decrypted_quote := z.Bytes() 2126 start_quote_blob := len(decrypted_quote) - SizeHash(hash_alg_id) 2127 if bytes.Compare(decrypted_quote[start_quote_blob:], quote_hash) != 0 { 2128 glog.Infof("VerifyQuote: Compare fails. %x %x\n", quote_hash, decrypted_quote[start_quote_blob:]) 2129 return false 2130 } 2131 return true 2132 } 2133 2134 // ConstructInternalMakeCredential constructs a InternalMakeCredential command. 2135 func ConstructInternalMakeCredential(protectorHandle Handle, credential []byte, 2136 activeName []byte) ([]byte, error) { 2137 cmdHdr, err := MakeCommandHeader(tagNO_SESSIONS, 0, cmdMakeCredential) 2138 if err != nil { 2139 return nil, errors.New("ConstructInternalMakeCredential failed") 2140 } 2141 b1 := SetHandle(protectorHandle) 2142 b2, _ := pack([]interface{}{&credential, activeName}) 2143 cmd_bytes := packWithBytes(cmdHdr, append(b1, b2...)) 2144 return cmd_bytes, nil 2145 } 2146 2147 // DecodeInternalMakeCredential decodes a InternalMakeCredential response. 2148 // returns blob, encrypted_secret 2149 func DecodeInternalMakeCredential(in []byte) ([]byte, []byte, error) { 2150 var credBlob []byte 2151 var encrypted_secret []byte 2152 2153 template := []interface{}{&credBlob, &encrypted_secret} 2154 err := unpack(in, template) 2155 if err != nil { 2156 return nil, nil, errors.New("Can't decode InternalMakeCredential response") 2157 } 2158 return credBlob, encrypted_secret, nil 2159 } 2160 2161 // InternalMakeCredential 2162 // Output: blob, secret 2163 func InternalMakeCredential(rw io.ReadWriter, protectorHandle Handle, credential []byte, 2164 activeName []byte) ([]byte, []byte, error) { 2165 // Construct command 2166 cmd, err := ConstructInternalMakeCredential(protectorHandle, credential, activeName) 2167 if err != nil { 2168 return nil, nil, errors.New("ConstructInternalMakeCredential fails") 2169 } 2170 2171 // Send command 2172 _, err = rw.Write(cmd) 2173 if err != nil { 2174 return nil, nil, errors.New("Write Tpm fails") 2175 } 2176 2177 // Get response 2178 var resp []byte 2179 resp = make([]byte, 2048, 2048) 2180 read, err := rw.Read(resp) 2181 if err != nil { 2182 return nil, nil, errors.New("Read Tpm fails") 2183 } 2184 2185 // Decode Response 2186 if read < 10 { 2187 return nil, nil, errors.New("Read buffer too small") 2188 } 2189 _, _, status, err := DecodeCommandResponse(resp[0:10]) 2190 if err != nil { 2191 return nil, nil, errors.New("DecodeCommandResponse fails") 2192 } 2193 if status != ErrSuccess { 2194 return nil, nil, errors.New("InternalMakeCredential unsuccessful") 2195 } 2196 credBlob, encrypted_secret, err := DecodeInternalMakeCredential(resp[10:]) 2197 if err != nil { 2198 return nil, nil, errors.New("DecodeInternalMakeCredential fails") 2199 } 2200 return credBlob, encrypted_secret, nil 2201 } 2202 2203 /* 2204 * TPM Activate Credential interface 2205 */ 2206 2207 // Input: Der encoded endorsement cert and handles 2208 // Returns program private key protobuf, CertRequestMessage 2209 func ConstructClientRequest(rw io.ReadWriter, der_endorsement_cert []byte, 2210 quote_handle Handle, parent_pw string, owner_pw string, 2211 program_name string) (*RsaPrivateKeyMessage, 2212 *ProgramCertRequestMessage, error) { 2213 2214 // Generate Program Key. 2215 programPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) 2216 if err != nil { 2217 return nil, nil, err 2218 } 2219 // TODO(jlm): replace with helper 2220 privateKeyMsg, err := MarshalRsaPrivateToProto(programPrivateKey) 2221 if err != nil { 2222 return nil, nil, err 2223 } 2224 programPublicKey := programPrivateKey.PublicKey 2225 2226 // Generate Request 2227 request := new(ProgramCertRequestMessage) 2228 request.ProgramKey = new(ProgramKeyParameters) 2229 request.EndorsementCertBlob = der_endorsement_cert 2230 req_id := "001" 2231 request.RequestId = &req_id 2232 modulus_bits := int32(2048) 2233 key_type := "rsa" 2234 request.ProgramKey.ProgramName = &program_name 2235 request.ProgramKey.ProgramKeyType = &key_type 2236 request.ProgramKey.ProgramBitModulusSize = &modulus_bits 2237 2238 request.ProgramKey.ProgramKeyExponent = []byte{0, 1, 0, 1} 2239 request.ProgramKey.ProgramKeyModulus = programPublicKey.N.Bytes() 2240 serialized_program_key := proto.CompactTextString(request.ProgramKey) 2241 sha1Hash := sha1.New() 2242 sha1Hash.Write([]byte(serialized_program_key)) 2243 hashed_program_key := sha1Hash.Sum(nil) 2244 2245 // Quote key 2246 key_blob, quote_key_name, _, err := ReadPublic(rw, quote_handle) 2247 if err != nil { 2248 return nil, nil, err 2249 } 2250 rsaQuoteParams, err := DecodeRsaBuf(key_blob) 2251 if err != nil { 2252 return nil, nil, err 2253 } 2254 2255 sig_alg := uint16(AlgTPM_ALG_NULL) 2256 attest, sig, err := Quote(rw, quote_handle, owner_pw, owner_pw, 2257 hashed_program_key, []int{7}, sig_alg) 2258 if err != nil { 2259 return nil, nil, err 2260 } 2261 2262 // Quote key info. 2263 request.QuoteKeyInfo = new(QuoteKeyInfoMessage) 2264 request.QuoteKeyInfo.Name = quote_key_name 2265 tmp_name := "Quote-Key" 2266 request.QuoteKeyInfo.PublicKey = new(PublicKeyMessage) 2267 request.QuoteKeyInfo.PublicKey.RsaKey = new(RsaPublicKeyMessage) 2268 request.QuoteKeyInfo.PublicKey.RsaKey.KeyName = &tmp_name 2269 var enc_alg string 2270 var hash_alg string 2271 if rsaQuoteParams.Enc_alg == AlgTPM_ALG_RSA { 2272 enc_alg = "rsa" 2273 } else { 2274 return nil, nil, err 2275 } 2276 if rsaQuoteParams.Hash_alg == AlgTPM_ALG_SHA1 { 2277 hash_alg = "sha1" 2278 } else if rsaQuoteParams.Hash_alg == AlgTPM_ALG_SHA256 { 2279 hash_alg = "sha256" 2280 } else { 2281 return nil, nil, err 2282 } 2283 request.QuoteKeyInfo.PublicKey.KeyType = &enc_alg 2284 size := int32(rsaQuoteParams.Mod_sz) 2285 request.QuoteKeyInfo.PublicKey.RsaKey.BitModulusSize = &size 2286 request.QuoteKeyInfo.PublicKey.RsaKey.Modulus = rsaQuoteParams.Modulus 2287 request.QuoteSignAlg = &enc_alg 2288 request.QuoteSignHashAlg = &hash_alg 2289 2290 request.ProgramKey = new(ProgramKeyParameters) 2291 request.ProgramKey.ProgramName = &program_name 2292 request.ProgramKey.ProgramKeyType = &enc_alg 2293 request.ProgramKey.ProgramBitModulusSize = &modulus_bits 2294 request.ProgramKey.ProgramKeyModulus = programPublicKey.N.Bytes() 2295 2296 request.QuotedBlob = attest 2297 request.QuoteSignature = sig 2298 return privateKeyMsg, request, nil 2299 } 2300 2301 // Input: policy private key 2302 func ConstructServerResponse(policy_private_key *rsa.PrivateKey, der_policy_cert []byte, 2303 signing_instructions_message SigningInstructionsMessage, 2304 request ProgramCertRequestMessage) (*ProgramCertResponseMessage, error) { 2305 2306 if request.ProgramKey == nil { 2307 glog.Infof("ConstructServerResponse: program key is nil") 2308 } 2309 // hash program key 2310 serialized_program_key := proto.CompactTextString(request.ProgramKey) 2311 sha256Hash := sha256.New() 2312 sha256Hash.Write([]byte(serialized_program_key)) 2313 hashed_program_key := sha256Hash.Sum(nil) 2314 2315 var hash_alg_id uint16 2316 if *request.QuoteSignHashAlg == "sha256" { 2317 hash_alg_id = uint16(AlgTPM_ALG_SHA256) 2318 } else { 2319 hash_alg_id = uint16(AlgTPM_ALG_SHA1) 2320 } 2321 if !VerifyQuote(hashed_program_key, *request.QuoteKeyInfo, hash_alg_id, 2322 request.QuotedBlob, request.QuoteSignature, ValidPcr) { 2323 return nil, errors.New("Can't verify quote") 2324 } 2325 2326 // Create Program Key Certificate 2327 progName := request.ProgramKey.ProgramName 2328 var notBefore time.Time 2329 notBefore = time.Now() 2330 validFor := 365 * 24 * time.Hour 2331 notAfter := notBefore.Add(validFor) 2332 template := x509.Certificate{ 2333 SerialNumber: GetSerialNumber(), 2334 Subject: pkix.Name{ 2335 Organization: []string{"CloudProxyAuthority"}, 2336 CommonName: *progName, 2337 }, 2338 NotBefore: notBefore, 2339 NotAfter: notAfter, 2340 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 2341 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 2342 BasicConstraintsValid: true, 2343 } 2344 pub := new(rsa.PublicKey) 2345 m := new(big.Int) 2346 m.SetBytes(request.ProgramKey.ProgramKeyModulus) 2347 pub.N = m 2348 pub.E = 0x00010001 2349 der_program_cert, err := x509.CreateCertificate(rand.Reader, &template, &template, 2350 pub, policy_private_key) 2351 if err != nil { 2352 return nil, err 2353 } 2354 2355 // Get Endorsement blob 2356 endorsement_cert, err := x509.ParseCertificate(request.EndorsementCertBlob) 2357 if err != nil { 2358 return nil, err 2359 } 2360 2361 // Verify Endorsement Cert 2362 ok, err := VerifyDerCert(request.EndorsementCertBlob, der_policy_cert) 2363 if !ok { 2364 return nil, errors.New("Bad endorsement cert") 2365 } 2366 2367 var protectorPublic *rsa.PublicKey 2368 switch k := endorsement_cert.PublicKey.(type) { 2369 case *rsa.PublicKey: 2370 protectorPublic = k 2371 case *rsa.PrivateKey: 2372 protectorPublic = &k.PublicKey 2373 default: 2374 return nil, errors.New("endorsement cert not an rsa key") 2375 } 2376 2377 // Generate credential 2378 var credential [16]byte 2379 rand.Read(credential[0:16]) 2380 // fmt.Printf("Credential: %x, hashid: %x\n", credential, hash_alg_id) 2381 // fmt.Printf("Name: %x\n", request.QuoteKeyInfo.Name) 2382 encrypted_secret, encIdentity, integrityHmac, err := MakeCredential( 2383 protectorPublic, hash_alg_id, 2384 credential[0:16], request.QuoteKeyInfo.Name) 2385 if err != nil { 2386 return nil, err 2387 } 2388 2389 // Response 2390 response := new(ProgramCertResponseMessage) 2391 response.RequestId = request.RequestId 2392 response.ProgramName = progName 2393 integrity_alg := *request.QuoteSignHashAlg 2394 response.Secret = encrypted_secret 2395 response.IntegrityAlg = &integrity_alg 2396 response.IntegrityHMAC = integrityHmac 2397 response.EncIdentity = encIdentity 2398 2399 // Encrypt cert with credential 2400 cert_hmac, cert_out, err := EncryptDataWithCredential(true, hash_alg_id, 2401 credential[0:16], der_program_cert, nil) 2402 if err != nil { 2403 return nil, err 2404 } 2405 response.EncryptedCert = cert_out 2406 response.EncryptedCertHmac = cert_hmac 2407 return response, nil 2408 } 2409 2410 // Output is der encoded Program Cert 2411 func ClientDecodeServerResponse(rw io.ReadWriter, protectorHandle Handle, 2412 quoteHandle Handle, password string, 2413 response ProgramCertResponseMessage) ([]byte, error) { 2414 certBlob := append(response.IntegrityHMAC, response.EncIdentity...) 2415 certInfo, err := ActivateCredential(rw, quoteHandle, protectorHandle, 2416 password, "", certBlob, response.Secret) 2417 if err != nil { 2418 return nil, err 2419 } 2420 // fmt.Printf("certInfo: %x\n", certInfo) 2421 2422 // Decrypt cert. 2423 _, out, err := EncryptDataWithCredential(false, uint16(AlgTPM_ALG_SHA1), 2424 certInfo, response.EncryptedCert, response.EncryptedCertHmac) 2425 if err != nil { 2426 return nil, err 2427 } 2428 return out, nil 2429 } 2430 2431 // Make an NvHandle 2432 func GetNvHandle(slot uint32) (Handle, error) { 2433 return Handle((OrdTPM_HT_NV_INDEX << OrdHR_SHIFT) + slot), nil 2434 } 2435 2436 // UndefineSpace command: 80020000001f0000012240000001010003e800000009400000090000010000 2437 // UndefineSpace response, cap: 8002, size: 00000013, error code: 00000000 2438 // 80020000001300000000000000000000010000 2439 2440 func ConstructUndefineSpace(owner Handle, handle Handle) ([]byte, error) { 2441 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdUndefineSpace) 2442 if err != nil { 2443 return nil, errors.New("ConstructUndefineSpace failed") 2444 } 2445 auth := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW)) 2446 zero := uint16(0) 2447 num_bytes := []interface{}{uint32(owner), uint32(handle), zero} 2448 out, err := pack(num_bytes) 2449 if err != nil { 2450 return nil, err 2451 } 2452 out = append(out, auth...) 2453 cmd := packWithBytes(cmdHdr, out) 2454 return cmd, nil 2455 } 2456 2457 // UndefineSpace 2458 func UndefineSpace(rw io.ReadWriter, owner Handle, handle Handle) (error) { 2459 cmd, err := ConstructUndefineSpace(owner, handle) 2460 if err != nil { 2461 return errors.New("UndefineSpace: Can't construct UndefineSpace command") 2462 } 2463 // Send command 2464 _, err = rw.Write(cmd) 2465 if err != nil { 2466 return errors.New("UndefineSpace: Write Tpm fails") 2467 } 2468 // Get response 2469 var resp []byte 2470 resp = make([]byte, 1024, 1024) 2471 read, err := rw.Read(resp) 2472 if err != nil { 2473 return errors.New("UndefineSpace: Read Tpm fails") 2474 } 2475 // Decode Response 2476 if read < 10 { 2477 return errors.New("Read buffer too small") 2478 } 2479 _, size, status, err := DecodeCommandResponse(resp[0:10]) 2480 if err != nil { 2481 return errors.New("UndefineSpace: DecodeCommandResponse fails") 2482 } 2483 reportCommand("UndefineSpace", cmd, resp[0:size], status, true) 2484 if status != ErrSuccess { 2485 return errors.New("UndefineSpace: error") 2486 } 2487 return nil 2488 } 2489 2490 // DefineSpace command: 8002000000310000012a4000000100000009400000090000010000000401020304000e010003e800040004001400000008 2491 // Definespace response, cap: 8002, size: 00000013, error code: 00000000 2492 // 80020000001300000000000000000000010000 2493 2494 func ConstructDefineSpace(owner Handle, handle Handle, authString string, 2495 attributes uint32, policy []byte, dataSize uint16) ([]byte, error) { 2496 pw := SetPasswordData(authString) 2497 auth := CreatePasswordAuthArea("", Handle(OrdTPM_RS_PW)) 2498 var empty []byte 2499 num_bytes := []interface{}{uint32(owner), empty} 2500 out1, err := pack(num_bytes) 2501 if err != nil { 2502 return nil, errors.New("DefineSpace: pack error") 2503 } 2504 hashAlg := uint16(AlgTPM_ALG_SHA1) 2505 sizeNvArea := uint16(2 * int(unsafe.Sizeof(owner)) + 3 * int(unsafe.Sizeof(dataSize)) + len(policy)) 2506 out1 = append(append(out1, auth...), pw...) 2507 num_bytes2 := []interface{}{sizeNvArea, uint32(handle), hashAlg, attributes, policy, dataSize} 2508 out2, err := pack(num_bytes2) 2509 if err != nil { 2510 return nil, errors.New("DefineSpace: pack error") 2511 } 2512 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdDefineSpace) 2513 if err != nil { 2514 return nil, errors.New("DefineSpace: MakeCommandHeader error") 2515 } 2516 cmd := packWithBytes(cmdHdr, append(out1, out2...)) 2517 return cmd, nil 2518 } 2519 2520 // DefineSpace 2521 func DefineSpace(rw io.ReadWriter, owner Handle, handle Handle, 2522 authString string, policy []byte, 2523 attributes uint32, dataSize uint16) (error) { 2524 cmd, err := ConstructDefineSpace(owner, handle, authString, attributes, policy, dataSize) 2525 if err != nil { 2526 return errors.New("DefineSpace: Can't construct DefineSpace command") 2527 } 2528 // Send command 2529 _, err = rw.Write(cmd) 2530 if err != nil { 2531 return errors.New("DefineSpace: Write Tpm fails") 2532 } 2533 // Get response 2534 var resp []byte 2535 resp = make([]byte, 1024, 1024) 2536 read, err := rw.Read(resp) 2537 if err != nil { 2538 return errors.New("DefineSpace: Read Tpm fails") 2539 } 2540 // Decode Response 2541 if read < 10 { 2542 return errors.New("Read buffer too small") 2543 } 2544 _, size, status, err := DecodeCommandResponse(resp[0:10]) 2545 if err != nil { 2546 return errors.New("DefineSpace: DecodeCommandResponse fails") 2547 } 2548 reportCommand("DefineSpace", cmd, resp[0:size], status, true) 2549 if status != ErrSuccess { 2550 return errors.New("DefineSpace: Can't decode response") 2551 } 2552 return nil 2553 } 2554 2555 // IncrementNv command: 80020000002300000134010003e8010003e80000000d40000009000001000401020304 2556 // IncrementNv response, cap: 8002, size: 00000013, error code: 00000000 2557 // 80020000001300000000000000000000010000 2558 2559 func ConstructIncrementNv(handle Handle, authString string) ([]byte, error) { 2560 // handle, handle, 0(16), autharea 2561 auth := CreatePasswordAuthArea(authString, Handle(OrdTPM_RS_PW)) 2562 var empty []byte 2563 num_bytes := []interface{}{uint32(handle), int32(handle), empty} 2564 out, err := pack(num_bytes) 2565 if err != nil { 2566 return nil, errors.New("ConstructIncrementNv: pack failed") 2567 } 2568 out = append(out, auth...) 2569 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdIncrementNvCounter) 2570 if err != nil { 2571 return nil, errors.New("ConstructIncrementNv: MakeCommandHeader failed") 2572 } 2573 cmd := packWithBytes(cmdHdr, out) 2574 return cmd, nil 2575 } 2576 2577 // IncrementNv 2578 func IncrementNv(rw io.ReadWriter, handle Handle, authString string) (error) { 2579 cmd, err := ConstructIncrementNv(handle, authString) 2580 if err != nil { 2581 return errors.New("IncrementNv: Can't construct UndefineSpace command") 2582 } 2583 // Send command 2584 _, err = rw.Write(cmd) 2585 if err != nil { 2586 return errors.New("IncrementNv: Write Tpm fails") 2587 } 2588 // Get response 2589 var resp []byte 2590 resp = make([]byte, 1024, 1024) 2591 read, err := rw.Read(resp) 2592 if err != nil { 2593 return errors.New("IncrementNv: Read Tpm fails") 2594 } 2595 // Decode Response 2596 if read < 10 { 2597 return errors.New("Read buffer too small") 2598 } 2599 _, size, status, err := DecodeCommandResponse(resp[0:10]) 2600 if err != nil { 2601 return errors.New("IncrementNv: DecodeCommandResponse fails") 2602 } 2603 reportCommand("IncrementNv", cmd, resp[0:size], status, true) 2604 if status != ErrSuccess { 2605 return errors.New("IncrementNv: Can't decode response") 2606 } 2607 return nil 2608 } 2609 2610 // ReadNv command: 8002000000270000014e010003e8010003e80000000d4000000900000100040102030400080000 2611 // ReadNv response, cap: 8002, size: 0000001d, error code: 00000000 2612 // 80020000001d000000000000000a000800000000000000cf0000010000 2613 // Tpm2_ReadNv succeeds 2614 // Counter value: 00000000000000cf 2615 2616 func DecodeReadNv(in []byte) (uint64, error) { 2617 var respSize uint32 2618 var byteCounter []byte 2619 err := unpack(in, []interface{}{&respSize, &byteCounter}) 2620 if err != nil { 2621 return uint64(0), errors.New("ReadNv: unpack failed") 2622 } 2623 c := uint64(0) 2624 for i := 0; i < len(byteCounter); i++ { 2625 c = c * 256 + uint64(byteCounter[i]) 2626 } 2627 return c, nil 2628 } 2629 2630 func ConstructReadNv(handle Handle, authString string, offset uint16, dataSize uint16) ([]byte, error) { 2631 // handle, handle, 0(16), pw-autharea, size(16), offset(16) 2632 auth := CreatePasswordAuthArea(authString, Handle(OrdTPM_RS_PW)) 2633 var empty []byte 2634 num_bytes := []interface{}{uint32(handle), int32(handle), empty} 2635 out, err := pack(num_bytes) 2636 if err != nil { 2637 return nil, errors.New("ReadNv: pack failed") 2638 } 2639 out = append(out, auth...) 2640 num_bytes2 := []interface{}{dataSize, offset} 2641 out2, err := pack(num_bytes2) 2642 if err != nil { 2643 return nil, errors.New("ReadNv: pack failed") 2644 } 2645 cmdHdr, err := MakeCommandHeader(tagSESSIONS, 0, cmdReadNv) 2646 if err != nil { 2647 return nil, errors.New("ReadNv: MakeCommandHeader failed") 2648 } 2649 cmd := packWithBytes(cmdHdr, append(out, out2...)) 2650 return cmd, nil 2651 } 2652 2653 // ReadNv 2654 func ReadNv(rw io.ReadWriter, handle Handle, authString string, 2655 offset uint16, dataSize uint16) (uint64, error) { 2656 cmd, err := ConstructReadNv(handle, authString, offset, dataSize) 2657 if err != nil { 2658 return uint64(0), errors.New("ReadNv: Can't construct ReadNv command") 2659 } 2660 // Send command 2661 _, err = rw.Write(cmd) 2662 if err != nil { 2663 return uint64(0), errors.New("ReadNv: Write Tpm fails") 2664 } 2665 // Get response 2666 var resp []byte 2667 resp = make([]byte, 1024, 1024) 2668 read, err := rw.Read(resp) 2669 if err != nil { 2670 return uint64(0), errors.New("ReadNv: Read Tpm fails") 2671 } 2672 // Decode Response 2673 if read < 10 { 2674 return uint64(0), errors.New("Read buffer too small") 2675 } 2676 _, size, status, err := DecodeCommandResponse(resp[0:10]) 2677 if err != nil { 2678 return uint64(0), errors.New("ReadNv: DecodeCommandResponse fails") 2679 } 2680 reportCommand("ReadNv", cmd, resp[0:size], status, true) 2681 if status != ErrSuccess { 2682 return uint64(0), errors.New("ReadNv: error from command") 2683 } 2684 return DecodeReadNv(resp[10:]) 2685 } 2686 2687 // See note in tpm2_tao.go about counter values for Rollback support. 2688 2689 // Tpm2 GetCounter 2690 func GetCounter(rw io.ReadWriter, nvHandle Handle, authString string) (int64, error) { 2691 c, err := ReadNv(rw, nvHandle, authString, uint16(0), uint16(8)) 2692 if err != nil { 2693 return int64(0), errors.New("Can't read tpm2 counter") 2694 } 2695 return int64(c), nil 2696 } 2697 2698 // Tpm2 InitCounter 2699 func InitCounter(rw io.ReadWriter, nvHandle Handle, authString string) (error) { 2700 owner := Handle(OrdTPM_RH_OWNER) 2701 dataSize := uint16(8) 2702 var tpmPolicy []byte // empty 2703 attributes := OrdNV_COUNTER | OrdNV_AUTHWRITE | OrdNV_AUTHREAD 2704 err := UndefineSpace(rw, owner, nvHandle) 2705 if err != nil { 2706 fmt.Printf("UndefineSpace failed (ok) %s\n", err) 2707 } else { 2708 fmt.Printf("UndefineSpace succeeded\n") 2709 } 2710 err = DefineSpace(rw, owner, nvHandle, authString, 2711 tpmPolicy, attributes, dataSize) 2712 if err != nil { 2713 fmt.Printf("Space already defined?\n") 2714 } 2715 err = IncrementNv(rw, nvHandle, authString) 2716 return err 2717 } 2718