tpm2-software / tpm2-tools

The source repository for the Trusted Platform Module (TPM2.0) tools
https://tpm2-software.github.io
721 stars 379 forks source link

tpm2_nvdefine, tpm2_nvwrite, tpm2_nvread using a C program. #3263

Open visyuvi opened 1 year ago

visyuvi commented 1 year ago

Hi @williamcroberts ,

I want to create nvram index, write into and read from my tpm's nvram using a C program that calls these functions. I don't want to use any system calls or popen. Can you help me do that ?

Thanks!

visyuvi commented 1 year ago

hi @williamcroberts, You provided code for tpm2_getrandom as below (https://github.com/tpm2-software/tpm2-tools/issues/1971 )

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <tss2/tss2_esys.h>
#include <tss2/tss2_fapi.h>
#include <tss2/tss2_rc.h>

void random_fapi(void) {

    FAPI_CONTEXT  *context = NULL;
    TSS2_RC rc = Fapi_Initialize(
        &context,
        NULL);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "Fapi_Initialize: %s\n", Tss2_RC_Decode(rc));
        exit(1);
    }

    /*
     * This is typically done once via the tpm2-tools tool: tss2_provision
     *
     * So this may fail, because it's already been provisioned. SO just log a warning
     * and plod ahead....
     */
    rc = Fapi_Provision(context, NULL, NULL, NULL);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "WARN: Fapi_Provision: %s\n", Tss2_RC_Decode(rc));
    }

    uint8_t *bytes = NULL;
    rc = Fapi_GetRandom(context, 8, &bytes);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "Fapi_GetRandom: %s\n", Tss2_RC_Decode(rc));
        exit(1);
    }

    size_t i;
    for (i = 0; i < sizeof(bytes); i++) {
        printf("%02x", bytes[i]);
    }
    printf("\n");

    Fapi_Free(bytes);

    Fapi_Finalize(&context);
}

void random_esys(void) {

    ESYS_CONTEXT *context = NULL;
    TSS2_RC rc = Esys_Initialize(&context, NULL, NULL);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "Esys_Initialize: %s\n", Tss2_RC_Decode(rc));
        exit(1);
    }

    TPM2B_DIGEST *bytes = NULL;
    rc = Esys_GetRandom(context,
            ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
            8, &bytes);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "Esys_GetRandom: %s\n", Tss2_RC_Decode(rc));
        exit(1);
    }

    size_t i;
    for (i = 0; i < bytes->size; i++) {
        printf("%02x", bytes->buffer[i]);
    }
    printf("\n");

    Esys_Free(bytes);

    Esys_Finalize(&context);
}

int main(int argc, char *argv[]) {

    if (argc == 1 || strcmp(argv[1], "esapi")) {
        random_esys();
    }

    if (argc == 1 || strcmp(argv[1], "fapi")) {
        random_fapi();
    }

    return 0;
}

Can you provide similar code for nvram creation, writing into it and reading from it ? Or atleast guide me to write the C program

williamcroberts commented 1 year ago

I can't, but dig around in the test code and I would ask on the mailing list

JuergenReppSIT commented 1 year ago

You can check the tss integration test: https://github.com/tpm2-software/tpm2-tss/blob/master/test/integration/esys-nv-ram-ordinary-index.int.c

visyuvi commented 1 year ago

I can't, but dig around in the test code and I would ask on the mailing list

Could you please do that and let me know thanks!

visyuvi commented 1 year ago

You can check the tss integration test: https://github.com/tpm2-software/tpm2-tss/blob/master/test/integration/esys-nv-ram-ordinary-index.int.c

Thanks @JuergenReppSIT ! I wanted to try out this test. So I thought of writing the main function in it and call the test_invoke_esys function, but it expects this pointer variable - ESYS_CONTEXT * esys_context

What do I initialize "esys_context" to before passing to test_invoke_esys function ? I am not sure about the flow. Kindly revert! Thanks!

visyuvi commented 1 year ago

Hi @williamcroberts , @JuergenReppSIT !!

JuergenReppSIT commented 1 year ago

@visyuvi The integration test should just be an example how the functions Esys_NV_DefineSpace, Esys_NV_Read, Esys_NV_Write, and Esys_NV_UndefineSpace. You can't call the function test_invoke_esys from your main. This file did include interal esys files which are not available for your main program. For the FAPI functions there is also an integration test for the nv ram usage: https://github.com/tpm2-software/tpm2-tss/blob/master/test/integration/fapi-nv-ordinary.int.c

visyuvi commented 1 year ago

@JuergenReppSIT How can I run this test ? It has no main function. As you are aware I wanted to perform the three functions (nv define,write and read) using a standalone C program having a main function.

Appreciate your help! Thanks!

JuergenReppSIT commented 1 year ago

@visyuvi This test is executed when you run make check in the tss source directory after the sources have been compiled. In the test files you can check how the needed functions are used and you can create your main program based on these patterns.

visyuvi commented 1 year ago

Ok I will check. Thanks once again!