Implement TPMLIB_GetInfo() to for example get TPM spec. info

The EK certificates need information about the TPM specification that was
implemented. The best place to get the information from seems the TPM itself.
So we implement a function TPMLIB_GetInfo() to allow to query for the TPM
specification information and possibly other information in the future.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
Stefan Berger 2018-04-23 06:29:04 -04:00
parent aef3e6fd6b
commit 70547a758b
9 changed files with 281 additions and 1 deletions

View File

@ -93,6 +93,12 @@ enum TPMLIB_TPMProperty {
TPM_RESULT TPMLIB_GetTPMProperty(enum TPMLIB_TPMProperty prop, int *result);
enum TPMLIB_InfoFlags {
TPMLIB_INFO_TPMSPECIFICATION = 1,
};
char *TPMLIB_GetInfo(enum TPMLIB_InfoFlags flags);
struct libtpms_callbacks {
int sizeOfStruct;
TPM_RESULT (*tpm_nvram_init)(void);

View File

@ -93,6 +93,12 @@ enum TPMLIB_TPMProperty {
TPM_RESULT TPMLIB_GetTPMProperty(enum TPMLIB_TPMProperty prop, int *result);
enum TPMLIB_InfoFlags {
TPMLIB_INFO_TPMSPECIFICATION = 1,
};
char *TPMLIB_GetInfo(enum TPMLIB_InfoFlags flags);
struct libtpms_callbacks {
int sizeOfStruct;
TPM_RESULT (*tpm_nvram_init)(void);

View File

@ -9,6 +9,7 @@ man3_PODS = \
TPM_IO_Hash_Start.pod \
TPM_IO_TpmEstablished_Get.pod \
TPMLIB_DecodeBlob.pod \
TPMLIB_GetInfo.pod \
TPMLIB_GetTPMProperty.pod \
TPMLIB_GetVersion.pod \
TPMLIB_MainInit.pod \
@ -33,6 +34,7 @@ man3_MANS += \
TPM_IO_Hash_Start.3 \
TPM_IO_TpmEstablished_Get.3 \
TPMLIB_DecodeBlob.3 \
TPMLIB_GetInfo.3 \
TPMLIB_GetTPMProperty.3 \
TPMLIB_GetVersion.3 \
TPMLIB_MainInit.3 \

170
man/man3/TPMLIB_GetInfo.3 Normal file
View File

@ -0,0 +1,170 @@
.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.31)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "TPMLIB_GetInfo 3"
.TH TPMLIB_GetInfo 3 "2018-04-23" "libtpms" ""
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
TPMLIB_GetInfo \- Get Information about the TPM implementation
.SH "LIBRARY"
.IX Header "LIBRARY"
\&\s-1TPM\s0 library (libtpms, \-ltpms)
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
\&\fB#include <libtpms/tpm_library.h\fR>
.PP
\&\fBchar *TPMLIB_GetInfo(TPMLIB_InfoFlags flags);\fR
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
The \fB\f(BITPMLIB_GetInfo()\fB\fR function allows to query for \s-1TPM\s0 implementation
specifics and get a \s-1JSON\s0 string in return. Which data is to be returned
can be specified in the flags parameter that may be a logical 'or' concatenation
of flags. If passed flags are not supported, nothing is returned . If a 0 is
passed in, an empty \s-1JSON\s0 Object '{}' is returned.
.PP
The following flags are defined and return \s-1JSON\s0 objects as shown:
.IP "\fB\s-1TPMLIB_INFO_TPMSPECIFICATION\s0\fR" 4
.IX Item "TPMLIB_INFO_TPMSPECIFICATION"
{\*(L"TPMSpecification\*(R":{\*(L"family\*(R":\*(L"1.2\*(R",\*(L"level\*(R":2,\*(L"revision\*(R":116}}
.SH "RETURN VALUE"
.IX Header "RETURN VALUE"
This function returns a \s-1JSON\s0 string on success and a \s-1NULL\s0 pointer if a memory
allocation failure occurred.
.PP
The caller must \fIfree()\fR the returned string.
.SH "SEE ALSO"
.IX Header "SEE ALSO"

View File

@ -0,0 +1,42 @@
=head1 NAME
TPMLIB_GetInfo - Get Information about the TPM implementation
=head1 LIBRARY
TPM library (libtpms, -ltpms)
=head1 SYNOPSIS
B<#include <libtpms/tpm_library.h>>
B<char *TPMLIB_GetInfo(TPMLIB_InfoFlags flags);>
=head1 DESCRIPTION
The B<TPMLIB_GetInfo()> function allows to query for TPM implementation
specifics and get a JSON string in return. Which data is to be returned
can be specified in the flags parameter that may be a logical 'or' concatenation
of flags. If passed flags are not supported, nothing is returned . If a 0 is
passed in, an empty JSON Object '{}' is returned.
The following flags are defined and return JSON objects as shown:
=over 4
=item B<TPMLIB_INFO_TPMSPECIFICATION>
{"TPMSpecification":{"family":"1.2","level":2,"revision":116}}
=back
=head1 RETURN VALUE
This function returns a JSON string on success and a NULL pointer if a memory
allocation failure occurred.
The caller must free() the returned string.
=head1 SEE ALSO
=cut

View File

@ -23,7 +23,8 @@ LIBTPMS_0.5.1 {
LIBTPMS_0.6.0 {
global:
TPMLIB_SetBufferSize;
TPMLIB_GetInfo;
TPMLIB_SetBufferSize;
TPMLIB_SetDebugFD;
TPMLIB_SetDebugLevel;
TPMLIB_SetDebugPrefix;

View File

@ -145,6 +145,11 @@ TPM_RESULT TPMLIB_GetTPMProperty(enum TPMLIB_TPMProperty prop,
return TPM_SUCCESS;
}
char *TPMLIB_GetInfo(enum TPMLIB_InfoFlags flags)
{
return tpm_iface[0]->GetInfo(flags);
}
TPM_RESULT TPM_IO_Hash_Start(void)
{
return tpm_iface[0]->HashStart();

View File

@ -60,6 +60,7 @@ struct tpm_interface {
TPM_RESULT (*VolatileAllStore)(unsigned char **buffer, uint32_t *buflen);
TPM_RESULT (*GetTPMProperty)(enum TPMLIB_TPMProperty prop,
int *result);
char *(*GetInfo)(enum TPMLIB_InfoFlags flags);
TPM_RESULT (*TpmEstablishedGet)(TPM_BOOL *tpmEstablished);
TPM_RESULT (*HashStart)(void);
TPM_RESULT (*HashData)(const unsigned char *data,

View File

@ -38,9 +38,11 @@
#include <config.h>
#define _GNU_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tpm12/tpm_debug.h"
#include "tpm_error.h"
@ -167,6 +169,50 @@ TPM_RESULT TPM12_GetTPMProperty(enum TPMLIB_TPMProperty prop,
return TPM_SUCCESS;
}
/*
* TPM12_GetInfo:
*
* @flags: logical or of flags that query for information
*
* Return a JSON document with contents queried for by the user's passed flags
*/
char *TPM12_GetInfo(enum TPMLIB_InfoFlags flags)
{
const char *tpmspec =
"\"TPMSpecification\":{"
"\"family\":\"1.2\","
"\"level\":2,"
"\"revision\":116"
"}";
char *fmt = NULL, *buffer;
if (!(buffer = strdup("{%s%s}")))
return NULL;
if ((flags & TPMLIB_INFO_TPMSPECIFICATION)) {
fmt = buffer;
buffer = NULL;
if (asprintf(&buffer, fmt, tpmspec, "%s%s") < 0)
goto error;
free(fmt);
}
/* nothing else to add */
fmt = buffer;
buffer = NULL;
if (asprintf(&buffer, fmt, "","") < 0)
goto error;
free(fmt);
return buffer;
error:
free(fmt);
free(buffer);
return NULL;
}
static uint32_t tpm12_buffersize = TPM_BUFFER_MAX;
uint32_t TPM12_SetBufferSize(uint32_t wanted_size,
@ -239,6 +285,7 @@ const struct tpm_interface TPM12Interface = {
.Process = TPM12_Process,
.VolatileAllStore = TPM12_VolatileAllStore,
.GetTPMProperty = TPM12_GetTPMProperty,
.GetInfo = TPM12_GetInfo,
.TpmEstablishedGet = TPM12_IO_TpmEstablished_Get,
.HashStart = TPM12_IO_Hash_Start,
.HashData = TPM12_IO_Hash_Data,