Expand Up
@@ -56,7 +56,24 @@ struct tpm_sign_ctx {
char * outFilePath ;
BYTE * msg ;
UINT16 length ;
TSS2_SYS_CONTEXT * sapi_context ;
char * contextKeyFile ;
char * inMsgFileName ;
struct {
UINT8 k : 1 ;
UINT8 P : 1 ;
UINT8 g : 1 ;
UINT8 m : 1 ;
UINT8 t : 1 ;
UINT8 s : 1 ;
UINT8 c : 1 ;
UINT8 unused : 1 ;
} flags ;
};
tpm_sign_ctx ctx = {
.msg = NULL ,
.sessionData = TPMS_AUTH_COMMAND_INIT (TPM_RS_PW ),
.halg = TPM_ALG_SHA1 ,
};
static bool get_key_type (TSS2_SYS_CONTEXT * sapi_context , TPMI_DH_OBJECT objectHandle ,
Expand All
@@ -69,7 +86,7 @@ static bool get_key_type(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT objectHa
};
TSS2_SYS_RSP_AUTHS sessions_data_out = {
1 ,
required_argument ,
& session_data_out_array [0 ]
};
Expand Down
Expand Up
@@ -120,7 +137,7 @@ static bool set_scheme(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT keyHandle,
return true;
}
static bool sign_and_save (tpm_sign_ctx * ctx ) {
static bool sign_and_save (TSS2_SYS_CONTEXT * sapi_context ) {
TPM2B_DIGEST digest = TPM2B_TYPE_INIT (TPM2B_DIGEST , buffer );
Expand All
@@ -133,174 +150,56 @@ static bool sign_and_save(tpm_sign_ctx *ctx) {
TPMS_AUTH_COMMAND * session_data_array [1 ];
TPMS_AUTH_RESPONSE * session_data_out_array [1 ];
session_data_array [0 ] = & ctx -> sessionData ;
session_data_array [0 ] = & ctx . sessionData ;
sessions_data .cmdAuths = & session_data_array [0 ];
session_data_out_array [0 ] = & session_data_out ;
sessions_data_out .rspAuths = & session_data_out_array [0 ];
sessions_data_out .rspAuthsCount = 1 ;
sessions_data .cmdAuthsCount = 1 ;
int rc = tpm_hash_compute_data (ctx -> sapi_context , ctx -> halg , TPM_RH_NULL ,
ctx -> msg , ctx -> length , & digest , NULL );
int rc = tpm_hash_compute_data (sapi_context , ctx . halg , TPM_RH_NULL ,
ctx . msg , ctx . length , & digest , NULL );
if (rc ) {
LOG_ERR ("Compute message hash failed!" );
return false;
}
// printf("\ndigest(hex type):\n ");
// UINT16 i;
// for (i = 0; i < digest.t.size; i++)
// printf("%02x ", digest.t.buffer[i]);
// printf("\n");
bool result = set_scheme (ctx -> sapi_context , ctx -> keyHandle , ctx -> halg , & in_scheme );
bool result = set_scheme (sapi_context , ctx .keyHandle , ctx .halg , & in_scheme );
if (!result ) {
return false;
}
TPM_RC rval = Tss2_Sys_Sign (ctx -> sapi_context , ctx -> keyHandle ,
& sessions_data , & digest , & in_scheme , & ctx -> validation , & signature ,
TPM_RC rval = Tss2_Sys_Sign (sapi_context , ctx . keyHandle ,
& sessions_data , & digest , & in_scheme , & ctx . validation , & signature ,
& sessions_data_out );
if (rval != TPM_RC_SUCCESS ) {
LOG_ERR ("Sys_Sign failed, error code: 0x%x" , rval );
return false;
}
/* TODO fix serialization */
return files_save_bytes_to_file (ctx -> outFilePath , (UINT8 * ) & signature ,
return files_save_bytes_to_file (ctx . outFilePath , (UINT8 * ) & signature ,
sizeof (signature ));
}
static bool init (int argc , char * argv [], tpm_sign_ctx * ctx ) {
static const char * optstring = "k:P:g:m:t:s:c:S:" ;
static const struct option long_options [] = {
{"keyHandle" ,1 ,NULL ,'k' },
{"pwdk" ,1 ,NULL ,'P' },
{"halg" ,1 ,NULL ,'g' },
{"msg" ,1 ,NULL ,'m' },
{"sig" ,1 ,NULL ,'s' },
{"ticket" ,1 ,NULL ,'t' },
{"keyContext" ,1 ,NULL ,'c' },
{"input-session-handle" ,1 ,NULL , 'S' },
{0 ,0 ,0 ,0 }
};
if (argc == 1 ) {
showArgMismatch (argv [0 ]);
return false;
}
union {
struct {
UINT8 k : 1 ;
UINT8 P : 1 ;
UINT8 g : 1 ;
UINT8 m : 1 ;
UINT8 t : 1 ;
UINT8 s : 1 ;
UINT8 c : 1 ;
UINT8 unused : 1 ;
};
UINT8 all ;
} flags = { .all = 0 };
int opt ;
char * contextKeyFile = NULL ;
char * inMsgFileName = NULL ;
while ((opt = getopt_long (argc , argv , optstring , long_options , NULL )) != -1 ) {
switch (opt ) {
case 'k' : {
bool result = tpm2_util_string_to_uint32 (optarg , & ctx -> keyHandle );
if (!result ) {
LOG_ERR ("Could not format key handle to number, got: \"%s\"" ,
optarg );
return false;
}
flags .k = 1 ;
}
break ;
case 'P' : {
bool result = tpm2_password_util_from_optarg (optarg , & ctx -> sessionData .hmac );
if (!result ) {
LOG_ERR ("Invalid key password, got\"%s\"" , optarg );
return false;
}
flags .P = 1 ;
}
break ;
case 'g' : {
ctx -> halg = tpm2_alg_util_from_optarg (optarg );
if (ctx -> halg == TPM_ALG_ERROR ) {
LOG_ERR ("Could not convert to number or lookup algorithm, got: \"%s\"" ,
optarg );
return false;
}
flags .g = 1 ;
}
break ;
case 'm' :
inMsgFileName = optarg ;
flags .m = 1 ;
break ;
case 't' : {
UINT16 size = sizeof (ctx -> validation );
bool result = files_load_bytes_from_path (optarg , (UINT8 * ) & ctx -> validation ,
& size );
if (!result ) {
return false;
}
flags .t = 1 ;
}
break ;
case 's' : {
bool result = files_does_file_exist (optarg );
if (result ) {
return false;
}
ctx -> outFilePath = optarg ;
flags .s = 1 ;
}
break ;
case 'c' :
contextKeyFile = optarg ;
flags .c = 1 ;
break ;
case 'S' :
if (!tpm2_util_string_to_uint32 (optarg , & ctx -> sessionData .sessionHandle )) {
LOG_ERR ("Could not convert session handle to number, got: \"%s\"" ,
optarg );
return false;
}
break ;
case ':' :
LOG_ERR ("Argument %c needs a value!" , optopt );
return false;
case '?' :
LOG_ERR ("Unknown Argument: %c" , optopt );
return false;
default :
LOG_ERR ("?? getopt returned character code 0%o ??" , opt );
return false;
}
}
static bool init (TSS2_SYS_CONTEXT * sapi_context ) {
if (!((flags .k || flags .c ) && flags .m && flags .s )) {
if (!((ctx . flags .k || ctx . flags .c ) && ctx . flags .m && ctx . flags .s )) {
LOG_ERR ("Expected options (k or c) and m and s" );
return false;
}
if (!flags .t ) {
ctx -> validation .tag = TPM_ST_HASHCHECK ;
ctx -> validation .hierarchy = TPM_RH_NULL ;
if (!ctx . flags .t ) {
ctx . validation .tag = TPM_ST_HASHCHECK ;
ctx . validation .hierarchy = TPM_RH_NULL ;
}
/*
* load tpm context from a file if -c is provided
*/
if (flags .c ) {
bool result = files_load_tpm_context_from_file (ctx -> sapi_context , & ctx -> keyHandle ,
contextKeyFile );
if (ctx . flags .c ) {
bool result = files_load_tpm_context_from_file (sapi_context , & ctx . keyHandle ,
ctx . contextKeyFile );
if (!result ) {
return false;
}
Expand All
@@ -310,12 +209,12 @@ static bool init(int argc, char *argv[], tpm_sign_ctx *ctx) {
* Process the msg file
*/
unsigned long file_size ;
bool result = files_get_file_size_path (inMsgFileName , & file_size );
bool result = files_get_file_size_path (ctx . inMsgFileName , & file_size );
if (!result ) {
return false;
}
if (file_size == 0 ) {
LOG_ERR ("The message file \"%s\" is empty!" , inMsgFileName );
LOG_ERR ("The message file \"%s\" is empty!" , ctx . inMsgFileName );
return false;
}
Expand All
@@ -326,46 +225,126 @@ static bool init(int argc, char *argv[], tpm_sign_ctx *ctx) {
return false;
}
ctx -> msg = (BYTE * ) calloc (1 , file_size );
if (!ctx -> msg ) {
ctx . msg = (BYTE * ) calloc (required_argument , file_size );
if (!ctx . msg ) {
LOG_ERR ("oom" );
return false;
}
ctx -> length = file_size ;
result = files_load_bytes_from_path (inMsgFileName , ctx -> msg , & ctx -> length );
ctx . length = file_size ;
result = files_load_bytes_from_path (ctx . inMsgFileName , ctx . msg , & ctx . length );
if (!result ) {
free (ctx -> msg );
free (ctx . msg );
return false;
}
return true;
}
int execute_tool (int argc , char * argv [], char * envp [], common_opts_t * opts ,
TSS2_SYS_CONTEXT * sapi_context ) {
static bool on_option (char key , char * value ) {
/* opts and envp are unused, avoid compiler warning */
(void )opts ;
(void ) envp ;
UNUSED (value );
tpm_sign_ctx ctx = {
.msg = NULL ,
.sessionData = TPMS_AUTH_COMMAND_EMPTY_INIT ,
.halg = TPM_ALG_SHA1 ,
.keyHandle = 0 ,
.validation = TPMT_TK_HASHCHECK_EMPTY_INIT ,
.sapi_context = sapi_context
switch (key ) {
case 'k' : {
bool result = tpm2_util_string_to_uint32 (value , & ctx .keyHandle );
if (!result ) {
LOG_ERR ("Could not format key handle to number, got: \"%s\"" ,
optarg );
return false;
}
ctx .flags .k = 1 ;
}
break ;
case 'P' : {
bool result = tpm2_password_util_from_optarg (value , & ctx .sessionData .hmac );
if (!result ) {
LOG_ERR ("Invalid key password, got\"%s\"" , optarg );
return false;
}
ctx .flags .P = 1 ;
}
break ;
case 'g' : {
ctx .halg = tpm2_alg_util_from_optarg (optarg );
if (ctx .halg == TPM_ALG_ERROR ) {
LOG_ERR ("Could not convert to number or lookup algorithm, got: \"%s\"" ,
optarg );
return false;
}
ctx .flags .g = 1 ;
}
break ;
case 'm' :
ctx .inMsgFileName = optarg ;
ctx .flags .m = 1 ;
break ;
case 't' : {
UINT16 size = sizeof (ctx .validation );
bool result = files_load_bytes_from_path (value , (UINT8 * ) & ctx .validation ,
& size );
if (!result ) {
return false;
}
ctx .flags .t = 1 ;
}
break ;
case 's' : {
bool result = files_does_file_exist (optarg );
if (result ) {
return false;
}
ctx .outFilePath = optarg ;
ctx .flags .s = 1 ;
}
break ;
case 'c' :
ctx .contextKeyFile = optarg ;
ctx .flags .c = 1 ;
break ;
case 'S' :
if (!tpm2_util_string_to_uint32 (value , & ctx .sessionData .sessionHandle )) {
LOG_ERR ("Could not convert session handle to number, got: \"%s\"" ,
optarg );
return false;
}
break ;
/* no default */
}
return true;
}
bool tpm2_tool_onstart (tpm2_options * * opts ) {
static const struct option topts [] = {
{"keyHandle" , required_argument , NULL , 'k' },
{"pwdk" , required_argument , NULL , 'P' },
{"halg" , required_argument , NULL , 'g' },
{"msg" , required_argument , NULL , 'm' },
{"sig" , required_argument , NULL , 's' },
{"ticket" , required_argument , NULL , 't' },
{"keyContext" , required_argument , NULL , 'c' },
{"input-session-handle" , required_argument ,NULL , 'S' },
{ NULL }
};
ctx .sessionData .sessionHandle = TPM_RS_PW ;
* opts = tpm2_options_new ("k:P:g:m:t:s:c:S:" , ARRAY_LEN (topts ), topts ,
on_option , NULL );
return * opts != NULL ;
}
int tpm2_tool_onrun (TSS2_SYS_CONTEXT * sapi_context , tpm2_option_flags flags ) {
UNUSED (flags );
bool result = init (argc , argv , & ctx );
bool result = init (sapi_context );
if (!result ) {
return 1 ;
}
result = sign_and_save (& ctx );
result = sign_and_save (sapi_context );
free (ctx .msg );
Expand Down