tss.TpmBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of TSS.Java Show documentation
Show all versions of TSS.Java Show documentation
A TPM 2.0 access library written in Java
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