@ -330,13 +330,16 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
/*
* Internal kernel interface to transmit TPM commands
*/
ssize_t tpm_transmit ( struct tpm_chip * chip , const char * buf ,
size_t bufsiz )
ssize_t tpm_transmit ( struct tpm_chip * chip , const u8 * buf , size_t bufsiz ,
unsigned int flags )
{
ssize_t rc ;
u32 count , ordinal ;
unsigned long stop ;
if ( bufsiz < TPM_HEADER_SIZE )
return - EINVAL ;
if ( bufsiz > TPM_BUFSIZE )
bufsiz = TPM_BUFSIZE ;
@ -350,7 +353,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
return - E2BIG ;
}
mutex_lock ( & chip - > tpm_mutex ) ;
if ( ! ( flags & TPM_TRANSMIT_UNLOCKED ) )
mutex_lock ( & chip - > tpm_mutex ) ;
rc = chip - > ops - > send ( chip , ( u8 * ) buf , count ) ;
if ( rc < 0 ) {
@ -393,20 +397,21 @@ out_recv:
dev_err ( & chip - > dev ,
" tpm_transmit: tpm_recv: error %zd \n " , rc ) ;
out :
mutex_unlock ( & chip - > tpm_mutex ) ;
if ( ! ( flags & TPM_TRANSMIT_UNLOCKED ) )
mutex_unlock ( & chip - > tpm_mutex ) ;
return rc ;
}
# define TPM_DIGEST_SIZE 20
# define TPM_RET_CODE_IDX 6
ssize_t tpm_transmit_cmd ( struct tpm_chip * chip , void * cmd ,
int len , const char * desc )
ssize_t tpm_transmit_cmd ( struct tpm_chip * chip , const void * cmd ,
int len , unsigned int flags , const char * desc )
{
struct tpm_output_header * header ;
const struct tpm_output_header * header ;
int err ;
len = tpm_transmit ( chip , ( u8 * ) cmd , len ) ;
len = tpm_transmit ( chip , ( const u8 * ) cmd , len , flags ) ;
if ( len < 0 )
return len ;
else if ( len < TPM_HEADER_SIZE )
@ -453,26 +458,13 @@ ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
tpm_cmd . params . getcap_in . subcap_size = cpu_to_be32 ( 4 ) ;
tpm_cmd . params . getcap_in . subcap = subcap_id ;
}
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , desc ) ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
desc ) ;
if ( ! rc )
* cap = tpm_cmd . params . getcap_out . cap ;
return rc ;
}
void tpm_gen_interrupt ( struct tpm_chip * chip )
{
struct tpm_cmd_t tpm_cmd ;
ssize_t rc ;
tpm_cmd . header . in = tpm_getcap_header ;
tpm_cmd . params . getcap_in . cap = TPM_CAP_PROP ;
tpm_cmd . params . getcap_in . subcap_size = cpu_to_be32 ( 4 ) ;
tpm_cmd . params . getcap_in . subcap = TPM_CAP_PROP_TIS_TIMEOUT ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE ,
" attempting to determine the timeouts " ) ;
}
EXPORT_SYMBOL_GPL ( tpm_gen_interrupt ) ;
EXPORT_SYMBOL_GPL ( tpm_getcap ) ;
# define TPM_ORD_STARTUP cpu_to_be32(153)
# define TPM_ST_CLEAR cpu_to_be16(1)
@ -490,7 +482,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
start_cmd . header . in = tpm_startup_header ;
start_cmd . params . startup_in . startup_type = startup_type ;
return tpm_transmit_cmd ( chip , & start_cmd , TPM_INTERNAL_RESULT_SIZE ,
return tpm_transmit_cmd ( chip , & start_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
" attempting to start the TPM " ) ;
}
@ -521,7 +513,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
tpm_cmd . params . getcap_in . cap = TPM_CAP_PROP ;
tpm_cmd . params . getcap_in . subcap_size = cpu_to_be32 ( 4 ) ;
tpm_cmd . params . getcap_in . subcap = TPM_CAP_PROP_TIS_TIMEOUT ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , NULL ) ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
NULL ) ;
if ( rc = = TPM_ERR_INVALID_POSTINIT ) {
/* The TPM is not started, we are the first to talk to it.
@ -535,7 +528,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
tpm_cmd . params . getcap_in . subcap_size = cpu_to_be32 ( 4 ) ;
tpm_cmd . params . getcap_in . subcap = TPM_CAP_PROP_TIS_TIMEOUT ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE ,
NULL ) ;
0 , NULL ) ;
}
if ( rc ) {
dev_err ( & chip - > dev ,
@ -596,7 +589,7 @@ duration:
tpm_cmd . params . getcap_in . subcap_size = cpu_to_be32 ( 4 ) ;
tpm_cmd . params . getcap_in . subcap = TPM_CAP_PROP_TIS_DURATION ;
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE ,
rc = tpm_transmit_cmd ( chip , & tpm_cmd , TPM_INTERNAL_RESULT_SIZE , 0 ,
" attempting to determine the durations " ) ;
if ( rc )
return rc ;
@ -633,7 +626,7 @@ EXPORT_SYMBOL_GPL(tpm_get_timeouts);
# define TPM_ORD_CONTINUE_SELFTEST 83
# define CONTINUE_SELFTEST_RESULT_SIZE 10
static struct tpm_input_header continue_selftest_header = {
static const struct tpm_input_header continue_selftest_header = {
. tag = TPM_TAG_RQU_COMMAND ,
. length = cpu_to_be32 ( 10 ) ,
. ordinal = cpu_to_be32 ( TPM_ORD_CONTINUE_SELFTEST ) ,
@ -652,14 +645,14 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
struct tpm_cmd_t cmd ;
cmd . header . in = continue_selftest_header ;
rc = tpm_transmit_cmd ( chip , & cmd , CONTINUE_SELFTEST_RESULT_SIZE ,
rc = tpm_transmit_cmd ( chip , & cmd , CONTINUE_SELFTEST_RESULT_SIZE , 0 ,
" continue selftest " ) ;
return rc ;
}
# define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
# define READ_PCR_RESULT_SIZE 30
static struct tpm_input_header pcrread_header = {
static const struct tpm_input_header pcrread_header = {
. tag = TPM_TAG_RQU_COMMAND ,
. length = cpu_to_be32 ( 14 ) ,
. ordinal = TPM_ORDINAL_PCRREAD
@ -672,7 +665,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
cmd . header . in = pcrread_header ;
cmd . params . pcrread_in . pcr_idx = cpu_to_be32 ( pcr_idx ) ;
rc = tpm_transmit_cmd ( chip , & cmd , READ_PCR_RESULT_SIZE ,
rc = tpm_transmit_cmd ( chip , & cmd , READ_PCR_RESULT_SIZE , 0 ,
" attempting to read a pcr value " ) ;
if ( rc = = 0 )
@ -745,7 +738,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
*/
# define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
# define EXTEND_PCR_RESULT_SIZE 34
static struct tpm_input_header pcrextend_header = {
static const struct tpm_input_header pcrextend_header = {
. tag = TPM_TAG_RQU_COMMAND ,
. length = cpu_to_be32 ( 34 ) ,
. ordinal = TPM_ORD_PCR_EXTEND
@ -770,7 +763,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
cmd . header . in = pcrextend_header ;
cmd . params . pcrextend_in . pcr_idx = cpu_to_be32 ( pcr_idx ) ;
memcpy ( cmd . params . pcrextend_in . hash , hash , TPM_DIGEST_SIZE ) ;
rc = tpm_transmit_cmd ( chip , & cmd , EXTEND_PCR_RESULT_SIZE ,
rc = tpm_transmit_cmd ( chip , & cmd , EXTEND_PCR_RESULT_SIZE , 0 ,
" attempting extend a PCR value " ) ;
tpm_put_ops ( chip ) ;
@ -792,7 +785,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
unsigned int loops ;
unsigned int delay_msec = 100 ;
unsigned long duration ;
struct tpm_cmd_t cmd ;
u8 dummy [ TPM_DIGEST_SIZE ] ;
duration = tpm_calc_ordinal_duration ( chip , TPM_ORD_CONTINUE_SELFTEST ) ;
@ -807,9 +800,8 @@ int tpm_do_selftest(struct tpm_chip *chip)
do {
/* Attempt to read a PCR value */
cmd . header . in = pcrread_header ;
cmd . params . pcrread_in . pcr_idx = cpu_to_be32 ( 0 ) ;
rc = tpm_transmit ( chip , ( u8 * ) & cmd , READ_PCR_RESULT_SIZE ) ;
rc = tpm_pcr_read_dev ( chip , 0 , dummy ) ;
/* Some buggy TPMs will not respond to tpm_tis_ready() for
* around 300 ms while the self test is ongoing , keep trying
* until the self test duration expires . */
@ -824,7 +816,6 @@ int tpm_do_selftest(struct tpm_chip *chip)
if ( rc < TPM_HEADER_SIZE )
return - EFAULT ;
rc = be32_to_cpu ( cmd . header . out . return_code ) ;
if ( rc = = TPM_ERR_DISABLED | | rc = = TPM_ERR_DEACTIVATED ) {
dev_info ( & chip - > dev ,
" TPM is disabled/deactivated (0x%X) \n " , rc ) ;
@ -879,7 +870,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
if ( chip = = NULL )
return - ENODEV ;
rc = tpm_transmit_cmd ( chip , cmd , buflen , " attempting tpm_cmd " ) ;
rc = tpm_transmit_cmd ( chip , cmd , buflen , 0 , " attempting tpm_cmd " ) ;
tpm_put_ops ( chip ) ;
return rc ;
@ -949,7 +940,7 @@ EXPORT_SYMBOL_GPL(wait_for_tpm_stat);
# define TPM_ORD_SAVESTATE cpu_to_be32(152)
# define SAVESTATE_RESULT_SIZE 10
static struct tpm_input_header savestate_header = {
static const struct tpm_input_header savestate_header = {
. tag = TPM_TAG_RQU_COMMAND ,
. length = cpu_to_be32 ( 10 ) ,
. ordinal = TPM_ORD_SAVESTATE
@ -981,14 +972,15 @@ int tpm_pm_suspend(struct device *dev)
cmd . params . pcrextend_in . pcr_idx = cpu_to_be32 ( tpm_suspend_pcr ) ;
memcpy ( cmd . params . pcrextend_in . hash , dummy_hash ,
TPM_DIGEST_SIZE ) ;
rc = tpm_transmit_cmd ( chip , & cmd , EXTEND_PCR_RESULT_SIZE ,
rc = tpm_transmit_cmd ( chip , & cmd , EXTEND_PCR_RESULT_SIZE , 0 ,
" extending dummy pcr before suspend " ) ;
}
/* now do the actual savestate */
for ( try = 0 ; try < TPM_RETRY ; try + + ) {
cmd . header . in = savestate_header ;
rc = tpm_transmit_cmd ( chip , & cmd , SAVESTATE_RESULT_SIZE , NULL ) ;
rc = tpm_transmit_cmd ( chip , & cmd , SAVESTATE_RESULT_SIZE , 0 ,
NULL ) ;
/*
* If the TPM indicates that it is too busy to respond to
@ -1032,7 +1024,7 @@ int tpm_pm_resume(struct device *dev)
EXPORT_SYMBOL_GPL ( tpm_pm_resume ) ;
# define TPM_GETRANDOM_RESULT_SIZE 18
static struct tpm_input_header tpm_getrandom_header = {
static const struct tpm_input_header tpm_getrandom_header = {
. tag = TPM_TAG_RQU_COMMAND ,
. length = cpu_to_be32 ( 14 ) ,
. ordinal = TPM_ORD_GET_RANDOM
@ -1072,8 +1064,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
tpm_cmd . params . getrandom_in . num_bytes = cpu_to_be32 ( num_bytes ) ;
err = tpm_transmit_cmd ( chip , & tpm_cmd ,
TPM_GETRANDOM_RESULT_SIZE + num_bytes ,
" attempting get random " ) ;
TPM_GETRANDOM_RESULT_SIZE + num_bytes ,
0 , " attempting get random " ) ;
if ( err )
break ;