func (ctx *TPMContext) Random(n uint32) (rdata []byte, err error) { var randbytes *C.BYTE result := C.Tspi_TPM_GetRandom(ctx.tpm, C.UINT32(n), &randbytes) if result != C.TSS_SUCCESS { switch result { case C.TSS_E_INVALID_HANDLE: return nil, ErrInvalidHandle case C.TSS_E_INTERNAL_ERROR: return nil, ErrInternalError case C.TSS_E_BAD_PARAMETER: return nil, ErrBadParameter default: return nil, ErrUnknown } } rand := C.malloc(C.size_t(n)) if rand != nil { C.memcpy(rand, unsafe.Pointer(randbytes), C.size_t(n)) rdata = C.GoBytes(rand, C.int(n)) C.free(rand) } C.Tspi_Context_FreeMemory(ctx.ctx, randbytes) return }
// GetEventLog returns an array of structures representing the contents of the // TSS event log func (tpm *TPM) GetEventLog() ([]Log, error) { var count C.UINT32 var events *C.TSS_PCR_EVENT var event C.TSS_PCR_EVENT err := tspiError(C.Tspi_TPM_GetEventLog(tpm.handle, &count, &events)) if err != nil { return nil, err } if count == 0 { return nil, nil } log := make([]Log, count) length := count * C.UINT32(unsafe.Sizeof(event)) slice := (*[1 << 30]C.TSS_PCR_EVENT)(unsafe.Pointer(events))[:length:length] for i := 0; i < int(count); i++ { log[i].Pcr = int(slice[i].ulPcrIndex) log[i].Eventtype = int(slice[i].eventType) log[i].PcrValue = C.GoBytes(unsafe.Pointer(slice[i].rgbPcrValue), C.int(slice[i].ulPcrValueLength)) log[i].Event = C.GoBytes(unsafe.Pointer(slice[i].rgbEvent), C.int(slice[i].ulEventLength)) } C.Tspi_Context_FreeMemory(tpm.context, (*C.BYTE)(unsafe.Pointer(events))) return log, nil }
func (c *Context) Close() error { C.Tspi_Context_FreeMemory(c.ctx, nil) if result := C.Tspi_Context_Close(c.ctx); isError(result) { return Error{result} } return nil }
// CollateIdentityRequest creates a signing request for the provided AIKq func (tpm *TPM) CollateIdentityRequest(srk *Key, pubkey *Key, aik *Key) ([]byte, error) { var certLen C.UINT32 var cCertReq *C.BYTE err := tspiError(C.Tspi_TPM_CollateIdentityRequest(tpm.handle, srk.handle, pubkey.handle, 0, nil, aik.handle, C.TSS_ALG_AES, &certLen, &cCertReq)) certReq := C.GoBytes(unsafe.Pointer(cCertReq), (C.int)(certLen)) C.Tspi_Context_FreeMemory(tpm.context, cCertReq) return certReq, err }
// GetKeyBlob returns an encrypted blob containing the public and private // halves of the key func (key *Key) GetKeyBlob() ([]byte, error) { var dataLen C.UINT32 var cData *C.BYTE err := tspiError(C.Tspi_GetAttribData((C.TSS_HOBJECT)(key.handle), C.TSS_TSPATTRIB_KEY_BLOB, C.TSS_TSPATTRIB_KEYBLOB_BLOB, &dataLen, &cData)) data := C.GoBytes(unsafe.Pointer(cData), (C.int)(dataLen)) C.Tspi_Context_FreeMemory(key.context, cData) return data, err }
// GetModulus returns the modulus of the public key func (key *Key) GetModulus() (modulus []byte, err error) { var dataLen C.UINT32 var cData *C.BYTE err = tspiError(C.Tspi_GetAttribData((C.TSS_HOBJECT)(key.handle), C.TSS_TSPATTRIB_RSAKEY_INFO, C.TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &dataLen, &cData)) data := C.GoBytes(unsafe.Pointer(cData), (C.int)(dataLen)) C.Tspi_Context_FreeMemory(key.context, cData) return data, err }
//GetQuote takes an encrypted key blob representing the AIK, a set of PCRs //and a challenge and returns a blob containing a hash of the PCR hashes and //the challenge, and a validation blob signed by the AIK. func (tpm *TPM) GetQuote(aik *Key, pcrs *PCRs, challenge []byte) ([]byte, []byte, error) { var validation C.TSS_VALIDATION challangeHash := sha1.Sum(challenge[:]) validation.ulExternalDataLength = sha1.Size validation.rgbExternalData = (*C.BYTE)(&challangeHash[0]) err := tspiError(C.Tspi_TPM_Quote(tpm.handle, aik.handle, pcrs.handle, &validation)) if err != nil { return nil, nil, err } data := C.GoBytes(unsafe.Pointer(validation.rgbData), (C.int)(validation.ulDataLength)) validationOutput := C.GoBytes(unsafe.Pointer(validation.rgbValidationData), (C.int)(validation.ulValidationDataLength)) C.Tspi_Context_FreeMemory(tpm.context, validation.rgbData) C.Tspi_Context_FreeMemory(tpm.context, validation.rgbValidationData) return data, validationOutput, nil }
// Destroy properly shuts down the TPM context. func (ctx *TPMContext) Destroy() error { result := C.Tspi_Context_FreeMemory(ctx.ctx, nil) if result != C.TSS_SUCCESS { switch result { case C.TSS_E_INVALID_HANDLE: return ErrInvalidHandle case C.TSS_E_INTERNAL_ERROR: return ErrInternalError default: return ErrUnknown } } return nil }
// GetPCRValues obtains the PCR values for any PCRs that have been set. func (pcrs *PCRs) GetPCRValues() ([][]byte, error) { var buflen C.UINT32 var buf *C.BYTE for pcr := range pcrs.pcrs { if pcrs.pcrset[pcr] == false { continue } err := tspiError(C.Tspi_PcrComposite_GetPcrValue(pcrs.handle, (C.UINT32)(pcr), &buflen, &buf)) if err != nil { return nil, err } pcrs.pcrs[pcr] = C.GoBytes(unsafe.Pointer(buf), (C.int)(buflen)) C.Tspi_Context_FreeMemory(pcrs.context, buf) } return pcrs.pcrs[:], nil }
// ActivateIdentity accepts an encrypted key blob representing the AIK and // two blobs representing the asymmetric and symmetric challenges associated // with the AIK. If the TPM is able to decrypt the challenges and the // challenges correspond to the AIK, the TPM will return the original // challenge secret. func (tpm *TPM) ActivateIdentity(aik *Key, asymblob []byte, symblob []byte) (secret []byte, err error) { var creds *C.BYTE var credlen C.UINT32 err = tspiError(C.Tspi_TPM_ActivateIdentity(tpm.handle, aik.handle, (C.UINT32)(len(asymblob)), (*C.BYTE)(&asymblob[0]), (C.UINT32)(len(symblob)), (*C.BYTE)(&symblob[0]), &credlen, &creds)) if err != nil { return nil, err } plaintext := C.GoBytes(unsafe.Pointer(creds), (C.int)(credlen)) C.Tspi_Context_FreeMemory(tpm.context, creds) return plaintext, nil }
// ExtendPCR extends a pcr. If event is nil, data must be pre-hashed with // SHA1. If event is not nil, event is used to populate the TSS event // log. If both data and event are provided, both will be used to create the // extend hash. func (tpm *TPM) ExtendPCR(pcr int, data []byte, eventtype int, event []byte) error { var outlen C.UINT32 var pcrval *C.BYTE var eventstruct C.TSS_PCR_EVENT var err error shasum := sha1.Sum(data) if event != nil { var pcrdata *C.BYTE var pcrdatalen C.UINT32 eventstruct.versionInfo.bMajor = 1 eventstruct.versionInfo.bMinor = 2 eventstruct.versionInfo.bRevMajor = 1 eventstruct.versionInfo.bRevMinor = 0 eventstruct.ulPcrIndex = C.UINT32(pcr) eventstruct.rgbPcrValue = (*C.BYTE)(&shasum[0]) eventstruct.eventType = C.TSS_EVENTTYPE(eventtype) eventstruct.ulEventLength = C.UINT32(len(event)) eventstruct.rgbEvent = (*C.BYTE)(&event[0]) if data == nil || len(data) == 0 { pcrdata = nil pcrdatalen = C.UINT32(0) } else { pcrdata = (*C.BYTE)(&data[0]) pcrdatalen = C.UINT32(len(data)) } err = tspiError(C.Tspi_TPM_PcrExtend(tpm.handle, C.UINT32(pcr), pcrdatalen, pcrdata, &eventstruct, &outlen, &pcrval)) } else { err = tspiError(C.Tspi_TPM_PcrExtend(tpm.handle, C.UINT32(pcr), C.UINT32(len(shasum)), (*C.BYTE)(&shasum[0]), nil, &outlen, &pcrval)) } C.Tspi_Context_FreeMemory(tpm.context, pcrval) return err }
// GetEventLog returns an array of structures representing the contents of the // TSS event log func (tpm *TPM) GetEventLog() ([]tspiconst.Log, error) { var count C.UINT32 var events *C.TSS_PCR_EVENT var event C.TSS_PCR_EVENT var log []tspiconst.Log f, err := os.Open("/sys/kernel/security/tpm0/binary_bios_measurements") if err != nil { return nil, err } firmware_events := bufio.NewReader(f) for { var entry tspiconst.Log var datalen int32 err := binary.Read(firmware_events, binary.LittleEndian, &entry.Pcr) if err == io.EOF { break } if err != nil { return nil, err } err = binary.Read(firmware_events, binary.LittleEndian, &entry.Eventtype) if err != nil { return nil, err } err = binary.Read(firmware_events, binary.LittleEndian, &entry.PcrValue) if err != nil { return nil, err } err = binary.Read(firmware_events, binary.LittleEndian, &datalen) if err != nil { return nil, err } data := make([]byte, datalen) err = binary.Read(firmware_events, binary.LittleEndian, &data) if err != nil { return nil, err } entry.Event = data[:] log = append(log, entry) } err = tspiError(C.Tspi_TPM_GetEventLog(tpm.handle, &count, &events)) if err != nil { return nil, err } if count == 0 { return log, nil } length := count * C.UINT32(unsafe.Sizeof(event)) slice := (*[1 << 30]C.TSS_PCR_EVENT)(unsafe.Pointer(events))[:length:length] for i := 0; i < int(count); i++ { var entry tspiconst.Log entry.Pcr = int32(slice[i].ulPcrIndex) entry.Eventtype = int32(slice[i].eventType) copy(entry.PcrValue[:], C.GoBytes(unsafe.Pointer(slice[i].rgbPcrValue), C.int(slice[i].ulPcrValueLength))) entry.Event = C.GoBytes(unsafe.Pointer(slice[i].rgbEvent), C.int(slice[i].ulEventLength)) log = append(log, entry) } C.Tspi_Context_FreeMemory(tpm.context, (*C.BYTE)(unsafe.Pointer(events))) return log, nil }