All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tss.TpmBase Maven / Gradle / Ivy

The newest version!
package tss;

import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;

import tss.tpm.*;


/**
 * TpmBase is the base class for Tpm (Tpm is auto-generated)
 *
 */
public abstract class TpmBase implements Closeable 
{
	/**
	 * Admin handles (and associated auth values) can be associated with a TPM object
	 */
	public TPM_HANDLE _OwnerHandle = TPM_HANDLE.from(TPM_RH.OWNER);
	/**
	 * Admin handles (and associated auth values) can be associated with a TPM object
	 */
	public TPM_HANDLE _EndorsementHandle = TPM_HANDLE.from(TPM_RH.ENDORSEMENT);
	/**
	 * Admin handles (and associated auth values) can be associated with a TPM object
	 */
	public TPM_HANDLE _PlatformHandle = TPM_HANDLE.from(TPM_RH.PLATFORM);
	/**
	 * Admin handles (and associated auth values) can be associated with a TPM object
	 */
	public TPM_HANDLE _LockoutHandle = TPM_HANDLE.from(TPM_RH.LOCKOUT);

	/**
	 * Tpm objects can interact with TPMs over a variety of interfaces.  This attaches a "TPM transport" interface
	 * to the TPM so that commands can be sent and received
	 * 
	 * @param theDevice A transport connection to a TPM device
	 */
	public void _setDevice(TpmDeviceBase theDevice)
	{
		device = theDevice;
		lastResponseCode = TPM_RC.SUCCESS;
	}
	/**
	 * Tpm objects can interact with TPMs over a variety of interfaces called "devices."  This returns
	 * the current attached device
	 *  
	 * @return The current TPM device
	 */
	public TpmDeviceBase _getDevice()
	{
		return device;
	}

	
	/**
	 * For the next TPM command invocation, errors will not cause an exception to be thrown
	 * (use _lastCommandSucceeded or _getLastResponseCode() to check for an error)
	 * 
	 * @return The same object (to allow modifier chaining)
	 */
	public Tpm _allowErrors()
	{
		AllowErrors = true;
		return (Tpm)this;
	}
	
	/**
     * @return The list of response codes allowed to be returned by the next executed command.
     */
    public TPM_RC[] _GetExpectedResponses()
    {
        return ExpectedResponses;
    }

	/**
	 * For the next TPM command invocation, an exception will be throw if the command 
	 * returns a response code different from expectedResponse.
	 * @param expectedResponse Expected response code. May be null or TPM_RC.SUCCESS.
	 * @return This Tpm object (to allow modifier chaining)
	 */
	public Tpm _expectError(TPM_RC expectedResponse)
	{
		return _expectResponses(expectedResponse);
	}
	
    /**
     * The next executed command should return one of the response codes contained
     * in the given list. Otherwise a run-time warning is issued.
     * If the only expected response code is TPM_RC.SUCCESS, and the command returns
     * an error code, a TssException is thrown.
     * 
     * @param expectedResponses One or more allowed response codes. May be null.
     * @return This Tpm object (to allow modifier chaining)
     */
    public Tpm _expectResponses(TPM_RC... expectedResponses)
    {
        // Empty responses list indicates success
        ExpectedResponses = null;

        if (expectedResponses.length == 0 ||
        	(expectedResponses.length == 1 &&
        	 Helpers.isOneOf(expectedResponses[0], TPM_RC.SUCCESS, null)))
        {
            return (Tpm)this;
        }

        ExpectedResponses = new TPM_RC[0];
        return _expectMoreResponses(expectedResponses);
    }
    
    /**
     * Adds more response codes allowed to be returned by the next executed command.
     * If no expected response codes have been specified with the _ExpectResponses()
     * method before this call, TpmRc.Success is implicitly added to the list.
     * @param expectedResponses Additional allowed response codes. May not be null.
     * @return this TPM object 
     */
    public Tpm _expectMoreResponses(TPM_RC... expectedResponses)
    {
        if (ExpectedResponses == null)
        {
            ExpectedResponses = new TPM_RC[] {TPM_RC.SUCCESS};
        }
        TPM_RC[] old = ExpectedResponses;
        ExpectedResponses = new TPM_RC[expectedResponses.length + old.length];
        for (int i = 0; i < old.length; ++i)
        {
        	ExpectedResponses[i] = old[i];  
        }

        for (int i = 0; i < expectedResponses.length; ++i)
        {
        	TPM_RC rc =expectedResponses[i];
            int curPos = old.length + i;
            if (rc == TPM_RC.SUCCESS && curPos != 0)
            {
                if (ExpectedResponses[0] == TPM_RC.SUCCESS)
                    continue;
                rc = ExpectedResponses[0];
                ExpectedResponses[0] = TPM_RC.SUCCESS;
            }
            ExpectedResponses[curPos] = rc;
        }
        return (Tpm)this;
    }

    private boolean _isSuccessExpected()
    {
        return ExpectedResponses == null || ExpectedResponses[0] == TPM_RC.SUCCESS;
    }
    
	/**
	 * Did the last TPM command return RC_SUCCESS?
	 * 
	 * @return Success?
	 */
	public Boolean _lastCommandSucceeded()
	{
		return (lastResponseCode == TPM_RC.SUCCESS);
	}

	/**
	 * Get the last TPM response code
	 * 
	 * @return The response code
	 */
	public TPM_RC _getLastResponseCode()
	{
		return lastResponseCode;
	}

	/**
	 * Specifies a single session handle to use with the next command 
	 * 
	 * @param h Session handle
	 * @return this TPM object
	 */
	public Tpm _withSession(TPM_HANDLE h)
	{
		ExplicitSessionHandles = new TPM_HANDLE[] { h };
		return (Tpm)this;
	}

	/**
	 * Specifies the session handles to use with the next command 
	 * 
	 * @param hh List of up to 3 session handles 
	 * @return this TPM object
	 */
	public Tpm _withSessions(TPM_HANDLE ... hh)
	{
		ExplicitSessionHandles = hh;
		return (Tpm)this;
	}

	/**
	 * Get last response code returned from the TPM (e.g. TPM_RC.SUCCESS)
	 * @return The response code
	 */
	public TPM_RC getLastResponseCode()
	{
		return lastResponseCode;
	}
	
	/**
	 * Send a command to the underlying TPM
	 * @param command The command code
	 * @param inHandles Input handles
	 * @param authHandleCount Number of handles that need authorization
	 * @param outHandleCount count
	 * @param inParms The input parameter structure
	 * @param outParms The output parameter structure
	 */
	protected void DispatchCommand(TPM_CC command,
			TPM_HANDLE[] inHandles,
			int authHandleCount,
			int outHandleCount,
			TpmStructure inParms, 
			TpmStructure outParms)
	{
		try {
		int numExplicitSessions = ExplicitSessionHandles==null? 0:ExplicitSessionHandles.length;
		boolean haveSessions = (authHandleCount!=0) || (numExplicitSessions!=0);
		OutByteBuf outBuf = new OutByteBuf();
		int tag = haveSessions ? TPM_ST.SESSIONS.toInt() : TPM_ST.NO_SESSIONS.toInt();
		// standard header {tag, length, commandCode}
		outBuf.writeInt(tag,  2);
		outBuf.writeInt(0, 4);		// to be filled in later
		outBuf.writeInt(command.toInt(),4);
		// handles
		for(int j=0;j 4)
            {
                break;
            }
            // TODO: Enable TPM property retrieval and sleep below, and remove the following break
            break;
            //System.out.println(">>>> NV_RATE: Retrying... Attempt " + nvRateRecoveryCount.toString());
            //Thread.Sleep((int)Tpm2.GetProperty(this, Pt.NvWriteRecovery) + 100);
        }
		// Interpretation of the response code depends on whether the programmer
		// has indicated that an error is expected or allowed.
//		if(rawResponseCode != 0)
        if (lastResponseCode != TPM_RC.SUCCESS)
		{
			// error - decode it
			if (AllowErrors)
				return; // Any error is allowed

			if (Helpers.isOneOf(lastResponseCode, ExpectedResponses))
				return; // The given error is expected

			if (_isSuccessExpected())
			{
				System.out.println("TPM ERROR: " + lastResponseCode);
				throw new TpmException(lastResponseCode, rawResponseCode);
			}
			String expected = ExpectedResponses.length > 1 ? Arrays.toString(ExpectedResponses) : ExpectedResponses[0].toString();
			throw new TpmException("TPM returned unexpected error " + lastResponseCode + " instead of " + expected,
								   lastResponseCode);
		}
        else if (ExpectedResponses != null)
		{
			String expected = ExpectedResponses.length > 1 ? "s " + Arrays.toString(ExpectedResponses) + " were"
														   : " " + ExpectedResponses.toString() + " was";
			throw new TpmException("Error" + expected + " expected, " +
								   "but the TPM command " + command + " succeeded"); 
		}
		
		// This should be fine, but just to check
		if(respTag.toInt() != tag)
		{
			throw new TpmException("Unexpected response tag " + respTag);
		}

		// first the handle, if there are any
		// note that the response structure is fragmented, so we need to reconstruct it
		// in respParmBuf if there are handles
		OutByteBuf respParmBuf = new OutByteBuf();
		
		TPM_HANDLE outHandles[] = new TPM_HANDLE[outHandleCount];
		for(int j=0;j




© 2015 - 2024 Weber Informatics LLC | Privacy Policy