blob: af7c90f772d70c7b36c1e37c888851ba0c46b67d [file] [log] [blame]
/* Software-based Mobile Trusted Module (MTM) Emulator
* Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This module is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* $Id$
*/
#include "mtm_structures.h"
#include "mtm_marshalling.h"
#include "mtm_data.h"
#include "tpm/tpm_data.h"
#include "tpm/tpm_commands.h"
static inline TPM_RESULT return_UINT32(UINT32 *respSize, BYTE **resp, UINT32 value)
{
UINT32 len = *respSize = 4;
BYTE *ptr = *resp = tpm_malloc(*respSize);
if (ptr == NULL || tpm_marshal_UINT32(&ptr, &len, value)) {
tpm_free(*resp);
return TPM_FAIL;
}
return TPM_SUCCESS;
}
static inline TPM_RESULT return_BOOL(UINT32 *respSize, BYTE **resp, BOOL value)
{
UINT32 len = *respSize = 1;
BYTE *ptr = *resp = tpm_malloc(*respSize);
if (ptr == NULL || tpm_marshal_BOOL(&ptr, &len, value)) {
tpm_free(*resp);
return TPM_FAIL;
}
return TPM_SUCCESS;
}
#define return_BYTE return_BOOL
static TPM_RESULT cap_ord(UINT32 subCapSize, BYTE *subCap,
UINT32 *respSize, BYTE **resp)
{
TPM_COMMAND_CODE ord;
if (tpm_unmarshal_TPM_COMMAND_CODE(&subCap, &subCapSize, &ord))
return TPM_BAD_MODE;
switch (ord) {
case MTM_ORD_InstallRIM:
case MTM_ORD_LoadVerificationKey:
case MTM_ORD_LoadVerificationRootKeyDisable:
case MTM_ORD_VerifyRIMCert:
case MTM_ORD_VerifyRIMCertAndExtend:
case MTM_ORD_IncrementBootstrapCounter:
case MTM_ORD_SetVerifiedPCRSelection:
return return_BOOL(respSize, resp, TRUE);
default:
return return_BOOL(respSize, resp, FALSE);
}
}
static TPM_RESULT cap_mtm_permanent_data(UINT32 subCapSize, BYTE *subCap,
UINT32 *respSize, BYTE **resp)
{
UINT32 subCapVal, len;
BYTE* ptr;
/* unmarshal subCap */
if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &subCapVal) != 0)
return TPM_BAD_PARAMETER;
switch (subCapVal) {
case 1:
return TPM_FAIL;
break;
case 2:
*respSize = len = sizeof_TPM_PCR_SELECTION(mtmData.permanent.data.verifiedPCRs);
*resp = ptr = tpm_malloc(*respSize);
if (*resp == NULL
|| tpm_marshal_TPM_PCR_SELECTION(&ptr, &len, &mtmData.permanent.data.verifiedPCRs)) {
tpm_free(*resp);
return TPM_FAIL;
}
case 3:
return return_UINT32(respSize, resp,
tpmData.permanent.data.counters[MTM_COUNTER_SELECT_BOOTSTRAP].counter);
case 4:
return return_UINT32(respSize, resp, mtmData.permanent.data.counterRimProtectId);
case 5:
return return_UINT32(respSize, resp, mtmData.permanent.data.counterStorageProtectId);
case 6:
return return_BYTE(respSize, resp, mtmData.permanent.data.specMajor);
case 7:
return return_BYTE(respSize, resp, mtmData.permanent.data.specMinor);
case 8:
return return_BYTE(respSize, resp, mtmData.permanent.data.loadVerificationKeyMethods);
default:
return TPM_BAD_PARAMETER;
}
return TPM_SUCCESS;
}
TPM_RESULT MTM_GetCapability(TPM_CAPABILITY_AREA capArea, UINT32 subCapSize,
BYTE *subCap, UINT32 *respSize, BYTE **resp)
{
info("MTM_GetCapability()");
switch (capArea) {
case TPM_CAP_ORD:
debug("[MTM_CAP_ORD]");
TPM_RESULT res = cap_ord(subCapSize, subCap, respSize, resp);
if (res == TPM_SUCCESS && resp[0] == FALSE) {
res = TPM_GetCapability(capArea, subCapSize, subCap, respSize, resp);
}
return res;
case TPM_CAP_MTM_PERMANENT_DATA:
debug("[TPM_CAP_MTM_PERMANENT_DATA]");
return cap_mtm_permanent_data(subCapSize, subCap, respSize, resp);
default:
return TPM_GetCapability(capArea, subCapSize, subCap, respSize, resp);
}
}