Exemple #1
0
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

}
Exemple #2
0
// 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
}
Exemple #3
0
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
}
Exemple #4
0
// 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
}
Exemple #5
0
// 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
}
Exemple #6
0
// 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
}
Exemple #7
0
//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
}
Exemple #8
0
// 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
}
Exemple #9
0
// 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
}
Exemple #10
0
// 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
}
Exemple #11
0
// 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
}
Exemple #12
0
// 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
}