/********************************************************************************/
/*                                                                              */
/*                      NVRAM File Abstraction Layer                            */
/*                           Written by Ken Goldman                             */
/*                       Adapted to SWTPM by Stefan Berger                      */
/*                     IBM Thomas J. Watson Research Center                     */
/*                                                                              */
/* (c) Copyright IBM Corporation 2006, 2010, 2014, 2015.			*/
/*										*/
/* All rights reserved.								*/
/* 										*/
/* Redistribution and use in source and binary forms, with or without		*/
/* modification, are permitted provided that the following conditions are	*/
/* met:										*/
/* 										*/
/* Redistributions of source code must retain the above copyright notice,	*/
/* this list of conditions and the following disclaimer.			*/
/* 										*/
/* Redistributions in binary form must reproduce the above copyright		*/
/* notice, this list of conditions and the following disclaimer in the		*/
/* documentation and/or other materials provided with the distribution.		*/
/* 										*/
/* Neither the names of the IBM Corporation nor the names of its		*/
/* contributors may be used to endorse or promote products derived from		*/
/* this software without specific prior written permission.			*/
/* 										*/
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS		*/
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT		*/
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR	*/
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT		*/
/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,	*/
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT		*/
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,	*/
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY	*/
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT		*/
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE	*/
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.		*/
/********************************************************************************/

/* This module abstracts out all NVRAM read and write operations.

   This implementation uses standard, portable C files.

   The basic high level abstractions are:

        SWTPM_NVRAM_LoadData();
        SWTPM_NVRAM_StoreData();
        SWTPM_NVRAM_DeleteName();

   They take a 'name' that is mapped to a rooted file name.
*/

#include "config.h"

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <fcntl.h>

#include <libtpms/tpm_error.h>
#include <libtpms/tpm_memory.h>
#include <libtpms/tpm_nvfilename.h>
#include <libtpms/tpm_library.h>

#include <openssl/sha.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
# include <openssl/core_names.h>
#else
# include <openssl/hmac.h>
#endif

#if defined(__OpenBSD__)
 # define OPENSSL_OLD_API
#else
 #if OPENSSL_VERSION_NUMBER < 0x10100000
  #define OPENSSL_OLD_API
 #endif
#endif

#include "swtpm.h"
#include "swtpm_aes.h"
#include "swtpm_debug.h"
#include "swtpm_nvstore.h"
#include "swtpm_utils.h"
#include "key.h"
#include "logging.h"
#include "tpmstate.h"
#include "tpmlib.h"
#include "tlv.h"
#include "utils.h"
#include "compiler_dependencies.h"

/* local structures */
typedef struct {
    uint8_t  version;
    uint8_t  min_version; /* min. required version */
    uint16_t hdrsize;
    uint16_t flags;
    uint32_t totlen; /* length of the header and following data */
} __attribute__((packed)) blobheader;

#define BLOB_HEADER_VERSION 2

/* flags for blobheader */
#define BLOB_FLAG_ENCRYPTED              0x01
#define BLOB_FLAG_MIGRATION_ENCRYPTED    0x02  /* encrypted with migration key */
#define BLOB_FLAG_MIGRATION_DATA         0x04  /* migration data are available */
#define BLOB_FLAG_ENCRYPTED_256BIT_KEY   0x08  /* 256 bit file key was used */
#define BLOB_FLAG_MIGRATION_256BIT_KEY   0x10  /* 256 bit migration key was used */

typedef struct {
    enum encryption_mode data_encmode;
    TPM_SYMMETRIC_KEY_DATA symkey;
} encryptionkey ;

static encryptionkey filekey = {
    .symkey = {
        .userKeyLength = 0,
    },
};

static encryptionkey migrationkey = {
    .symkey = {
        .userKeyLength = 0,
    },
};

static uint32_t g_ivec_length;
static unsigned char *g_ivec;
static struct nvram_backend_ops *g_nvram_backend_ops;

/* local prototypes */

static TPM_RESULT SWTPM_NVRAM_EncryptData(const encryptionkey *key,
                                          tlv_data *td,
                                          size_t *td_len,
                                          uint16_t tag_encrypted_data,
                                          const unsigned char *decrypt_data,
                                          uint32_t decrypt_length,
                                          uint16_t tag_ivec);

static TPM_RESULT SWTPM_NVRAM_GetDecryptedData(const encryptionkey *key,
                                               unsigned char **decrypt_data,
                                               uint32_t *decrypt_length,
                                               const unsigned char *encrypt_data,
                                               uint32_t encrypt_length,
                                               uint16_t tag_decryped_data,
                                               uint16_t tag_data,
                                               uint8_t hdrversion,
                                               uint16_t tag_ivec,
                                               uint16_t hdrflags,
                                               uint16_t flag_256bitkey);

static TPM_RESULT SWTPM_NVRAM_PrependHeader(unsigned char **data,
                                            uint32_t *length,
                                            uint16_t flags);

static TPM_RESULT SWTPM_NVRAM_CheckHeader(unsigned char *data, uint32_t length,
                                          uint32_t *dataoffset,
                                          uint16_t *hdrflags,
                                          uint8_t *hdrversion,
                                          bool quiet);

/* SWTPM_NVRAM_Init() is called once at startup.  It does any NVRAM required initialization.

   This function sets some static variables that are used by all TPM's.
*/

TPM_RESULT SWTPM_NVRAM_Init(void)
{
    const char  *backend_uri;
    TPM_RESULT  rc = 0;
    TPM_DEBUG(" SWTPM_NVRAM_Init:\n");

    backend_uri = tpmstate_get_backend_uri();
    if (!backend_uri) {
        logprintf(STDERR_FILENO,
                  "SWTPM_NVRAM_Init: Missing backend URI.\n");
        rc = TPM_FAIL;
    } else if (strncmp(backend_uri, "dir://", 6) == 0) {
        g_nvram_backend_ops = &nvram_dir_ops;
    } else if (strncmp(backend_uri, "file://", 7) == 0) {
        g_nvram_backend_ops = &nvram_linear_ops;
    } else {
        logprintf(STDERR_FILENO,
                  "SWTPM_NVRAM_Init: Unsupported backend.\n");
        rc = TPM_FAIL;
    }

    if (rc == 0)
        rc = g_nvram_backend_ops->prepare(backend_uri);

    return rc;
}

void SWTPM_NVRAM_Shutdown(void)
{
    if (g_nvram_backend_ops)
        g_nvram_backend_ops->cleanup();
    memset(&filekey, 0, sizeof(filekey));
    memset(&migrationkey, 0, sizeof(migrationkey));
}

/* SWTPM_NVRAM_GetFilenameForName() constructs a file name from the name.
 * A temporary filename used to write to may be created. It should be rename()'d to
 * the non-temporary filename.
 */

TPM_RESULT
SWTPM_NVRAM_GetFilenameForName(char *filename,       /* output: filename */
                               size_t bufsize,
                               uint32_t tpm_number,
                               const char *name,     /* input: abstract name */
                               TPM_BOOL is_tempfile) /* input: is temporary file? */
{
    TPM_RESULT res = TPM_SUCCESS;
    int n;
    const char *suffix = "";

    TPM_DEBUG(" SWTPM_NVRAM_GetFilenameForName: For name %s\n", name);

    switch (tpmstate_get_version()) {
    case TPMLIB_TPM_VERSION_1_2:
        break;
    case TPMLIB_TPM_VERSION_2:
        suffix = "2";
        break;
    }

    if (is_tempfile) {
        n = snprintf(filename, bufsize, "TMP%s-%02lx.%s", suffix, (unsigned long)tpm_number, name);
    } else {
        n = snprintf(filename, bufsize, "tpm%s-%02lx.%s", suffix, (unsigned long)tpm_number, name);
    }
    if ((size_t)n > bufsize) {
        res = TPM_FAIL;
    }

    TPM_DEBUG("  SWTPM_NVRAM_GetFilenameForName: File name %s\n", filename);

    return res;
}


/* Load 'data' of 'length' from the 'name'.

   'data' must be freed after use.
   
   Returns
        0 on success.
        TPM_RETRY and NULL,0 on non-existent file (non-fatal, first time start up)
        TPM_FAIL on failure to load (fatal), since it should never occur
*/

TPM_RESULT
SWTPM_NVRAM_LoadData(unsigned char **data,     /* freed by caller */
                     uint32_t *length,
                     uint32_t tpm_number,
                     const char *name)
{
    TPM_RESULT    rc = 0;
    unsigned char *decrypt_data = NULL;
    uint32_t      decrypt_length;
    uint32_t      dataoffset = 0;
    uint8_t       hdrversion = 0;
    uint16_t      hdrflags;
    const char    *backend_uri = NULL;

    TPM_DEBUG(" SWTPM_NVRAM_LoadData: From file %s\n", name);
    *data = NULL;
    *length = 0;

    if (rc == 0) {
        backend_uri = tpmstate_get_backend_uri();
        rc = g_nvram_backend_ops->load(data, length, tpm_number, name,
                                       backend_uri);
    }

    /* this function needs to return the plain data -- no tlv headers */
    if (rc == 0) {
        rc = SWTPM_NVRAM_CheckHeader(*data, *length, &dataoffset,
                                      &hdrflags, &hdrversion, true);
        if (rc != 0)
            logprintf(STDERR_FILENO,
                      "SWTPM_NVRAM_LoadData: Error from SWTPM_NVRAM_CheckHeader "
                      "rc = %d\n", rc);
    }

    if (rc == 0) {
        rc = SWTPM_NVRAM_GetDecryptedData(&filekey,
                                          &decrypt_data, &decrypt_length,
                                          *data + dataoffset,
                                          *length - dataoffset,
                                          TAG_ENCRYPTED_DATA, TAG_DATA,
                                          hdrversion,
                                          TAG_IVEC_ENCRYPTED_DATA,
                                          hdrflags,
                                          BLOB_FLAG_ENCRYPTED_256BIT_KEY);
        TPM_DEBUG(" SWTPM_NVRAM_LoadData: SWTPM_NVRAM_GetDecryptedData rc = %d\n",
                  rc);
        if (rc != 0)
            logprintf(STDERR_FILENO,
                      "SWTPM_NVRAM_LoadData: Error from SWTPM_NVRAM_GetDecryptedData "
                      "rc = %d\n", rc);
    }

    free(*data);

    if (rc == 0) {
        TPM_DEBUG(" SWTPM_NVRAM_LoadData: Decrypted %u bytes of "
                  "data to %u bytes.\n",
                  *length, decrypt_length);
        *data = decrypt_data;
        *length = decrypt_length;
    } else {
        *data = NULL;
    }

    return rc;
}

/* SWTPM_NVRAM_StoreData stores 'data' of 'length' to the rooted 'filename'

   Returns
        0 on success
        TPM_FAIL for other fatal errors
*/

static TPM_RESULT
SWTPM_NVRAM_StoreData_Intern(const unsigned char *data,
                             uint32_t length,
                             uint32_t tpm_number,
                             const char *name,
                             TPM_BOOL encrypt         /* encrypt if key is set */)
{
    TPM_RESULT    rc = 0;
    unsigned char *filedata = NULL;
    uint32_t      filedata_length = 0;
    tlv_data      td[3];
    size_t        td_len = 0;
    uint16_t      flags = 0;
    const char    *backend_uri = NULL;

    TPM_DEBUG(" SWTPM_NVRAM_StoreData: To name %s\n", name);

    if (rc == 0) {
        if (encrypt && SWTPM_NVRAM_Has_FileKey()) {
            td_len = 3;
            rc = SWTPM_NVRAM_EncryptData(&filekey, &td[0], &td_len,
                                         TAG_ENCRYPTED_DATA, data, length,
                                         TAG_IVEC_ENCRYPTED_DATA);
            if (rc) {
                logprintf(STDERR_FILENO,
                          "SWTPM_NVRAM_EncryptData failed: 0x%02x\n", rc);
            } else {
                TPM_DEBUG("  SWTPM_NVRAM_StoreData: Encrypted %u bytes before "
                          "write, will write %u bytes\n", length,
                          td[0].tlv.length);
            }
            flags |= BLOB_FLAG_ENCRYPTED;
            if (SWTPM_NVRAM_FileKey_Size() == SWTPM_AES256_BLOCK_SIZE)
                flags |= BLOB_FLAG_ENCRYPTED_256BIT_KEY;
        } else {
            td_len = 1;
            td[0] = TLV_DATA_CONST(TAG_DATA, length, data);
        }
    }

    if (rc == 0)
        rc = tlv_data_append(&filedata, &filedata_length, td, td_len);

    if (rc == 0)
        rc = SWTPM_NVRAM_PrependHeader(&filedata, &filedata_length, flags);

    if (rc == 0) {
        backend_uri = tpmstate_get_backend_uri();
        rc = g_nvram_backend_ops->store(filedata, filedata_length, tpm_number, name,
                                        backend_uri);
    }

    tlv_data_free(td, td_len);
    free(filedata);

    TPM_DEBUG(" SWTPM_NVRAM_StoreData: rc=%d\n", rc);

    return rc;
}

TPM_RESULT SWTPM_NVRAM_StoreData(const unsigned char *data,
                                 uint32_t length,
                                 uint32_t tpm_number,
                                 const char *name)
{
    return SWTPM_NVRAM_StoreData_Intern(data, length, tpm_number, name, TRUE);
}

/* SWTPM_NVRAM_DeleteName() deletes the 'name' from NVRAM

   Returns:
        0 on success, or if the file does not exist and mustExist is FALSE
        TPM_FAIL if the file could not be removed, since this should never occur and there is
                no recovery

   NOTE: Not portable code, but supported by Linux and Windows
*/

TPM_RESULT SWTPM_NVRAM_DeleteName(uint32_t tpm_number,
                                  const char *name,
                                  TPM_BOOL mustExist)
{
    const char *backend_uri = NULL;
    backend_uri = tpmstate_get_backend_uri();

    return g_nvram_backend_ops->delete(tpm_number, name, mustExist,
                                       backend_uri);
}


TPM_RESULT SWTPM_NVRAM_Store_Volatile(void)
{
    TPM_RESULT     rc = 0;
    char           *name = TPM_VOLATILESTATE_NAME;
    uint32_t       tpm_number = 0;
    unsigned char  *buffer = NULL;
    uint32_t       buflen;

    TPM_DEBUG(" SWTPM_Store_Volatile: Name %s\n", name);
    if (rc == 0) {
        rc = TPMLIB_VolatileAll_Store(&buffer, &buflen);
    }
    if (rc == 0) {
        /* map name to the rooted filename */
        rc = SWTPM_NVRAM_StoreData(buffer, buflen, tpm_number, name);
    }

    free(buffer);

    return rc;
}

static TPM_RESULT
SWTPM_NVRAM_KeyParamCheck(uint32_t keylen,
                          enum encryption_mode encmode)
{
    TPM_RESULT rc = 0;

    if (keylen != SWTPM_AES128_BLOCK_SIZE &&
        keylen != SWTPM_AES256_BLOCK_SIZE) {
        rc = TPM_BAD_KEY_PROPERTY;
    }
    switch (encmode) {
    case ENCRYPTION_MODE_AES_CBC:
        break;
    case ENCRYPTION_MODE_UNKNOWN:
        rc = TPM_BAD_MODE;
    }

    return rc;
}

size_t SWTPM_NVRAM_FileKey_Size(void)
{
    return filekey.symkey.userKeyLength;
}

TPM_RESULT SWTPM_NVRAM_Set_FileKey(const unsigned char *key, uint32_t keylen,
                                   enum encryption_mode encmode)
{
    TPM_RESULT rc;

    rc = SWTPM_NVRAM_KeyParamCheck(keylen, encmode);

    if (rc == 0) {
        memcpy(filekey.symkey.userKey, key, keylen);
        filekey.symkey.userKeyLength = keylen;
        filekey.data_encmode = encmode;
    }

    return rc;
}

size_t SWTPM_NVRAM_MigrationKey_Size(void)
{
    return migrationkey.symkey.userKeyLength;
}

TPM_RESULT SWTPM_NVRAM_Set_MigrationKey(const unsigned char *key,
                                        uint32_t keylen,
                                        enum encryption_mode encmode)
{
    TPM_RESULT rc;

    rc = SWTPM_NVRAM_KeyParamCheck(keylen, encmode);

    if (rc == 0) {
        memcpy(migrationkey.symkey.userKey, key, keylen);
        migrationkey.symkey.userKeyLength = keylen;
        migrationkey.data_encmode = encmode;
    }

    return rc;
}

# if OPENSSL_VERSION_NUMBER >= 0x30000000L

static int SWTPM_HMAC(unsigned char *md, unsigned int *md_len,
                      const void *key, int key_len,
                      const unsigned char *in, uint32_t in_length,
                      const unsigned char *ivec, uint32_t ivec_length)
{
    OSSL_PARAM params[2];
    EVP_MAC_CTX *ctx;
    EVP_MAC *hmac;
    size_t outl;
    int ret = 0;

    hmac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL);
    if (!hmac)
        return 0;

    ctx = EVP_MAC_CTX_new(hmac);
    if (!ctx)
        goto err;

    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
                                                 "sha256", 0);
    params[1] = OSSL_PARAM_construct_end();

    if (!EVP_MAC_init(ctx, key, key_len, params) ||
        !EVP_MAC_update(ctx, in, in_length))
        goto err;

    if (ivec &&
        !EVP_MAC_update(ctx, ivec, ivec_length))
        goto err;

    if (!EVP_MAC_final(ctx, md, &outl, *md_len))
        goto err;
    *md_len = outl;

    ret = 1;

err:
    EVP_MAC_CTX_free(ctx);
    EVP_MAC_free(hmac);

    return ret;
}

#else

static int SWTPM_HMAC(unsigned char *md, unsigned int *md_len,
                      const void *key, int key_len,
                      const unsigned char *in, uint32_t in_length,
                      const unsigned char *ivec, uint32_t ivec_length)
{
    int ret = 0;

#if defined OPENSSL_OLD_API
    HMAC_CTX sctx, *ctx = &sctx;

    HMAC_CTX_init(ctx);
#else
    HMAC_CTX *ctx = HMAC_CTX_new();

    if (!ctx)
        return 0;
#endif


    if (!HMAC_Init_ex(ctx, key, key_len, EVP_sha256(), NULL) ||
        !HMAC_Update(ctx, in, in_length))
        goto err;

    if (ivec &&
        !HMAC_Update(ctx, ivec, ivec_length))
        goto err;

    if (!HMAC_Final(ctx, md, md_len))
        goto err;

    ret = 1;

err:
#if defined OPENSSL_OLD_API
    HMAC_CTX_cleanup(ctx);
#else
    HMAC_CTX_free(ctx);
#endif

    return ret;
}
#endif /* if OPENSSL_VERSION_NUMBER >= 0x30000000L */

/*
 * SWTPM_RollAndSetGlobalIvec: Create an IV for the AES CBC algorithm to use
 *                             Create it with a random number every time.
 *                             and leave the pointer to the data in @td.
 *
 * @td: pointer to tlv_data to get pointer to the random data
 * @tag_ivec: tag for the IV tlv header
 * @ivec_length: number of bytes needed for the ivec
 */
static TPM_RESULT SWTPM_RollAndSetGlobalIvec(tlv_data *td,
                                             uint16_t tag_ivec,
                                             uint32_t ivec_length)
{
    unsigned char data[16]; /* do not initialize */
    unsigned char hashbuf[SHA256_DIGEST_LENGTH];
    void *p;

    if (g_ivec_length < ivec_length) {
        p = realloc(g_ivec, ivec_length);
        if (!p) {
            *td = TLV_DATA_CONST(tag_ivec, 0, NULL);

            logprintf(STDOUT_FILENO,
                      "Could not allocate %u bytes.\n", ivec_length);
            return TPM_FAIL;
        }
        g_ivec = p;
        g_ivec_length = ivec_length;
    }

    if (RAND_bytes(g_ivec, g_ivec_length) != 1) {
        /* random data from stack to the rescue */
        SHA256(g_ivec, g_ivec_length, hashbuf);
        SHA256(data, sizeof(data), hashbuf);
        memcpy(g_ivec, hashbuf,
               g_ivec_length < sizeof(hashbuf)
                   ? g_ivec_length
                   : sizeof(hashbuf));
    }

    *td = TLV_DATA_CONST(tag_ivec, g_ivec_length, g_ivec);

    return 0;
}

/*
 * SWTPM_GetIvec: Get the encryption IV from the data stream. If none is
 *                found a NULL pointer is set in *ivec, otherwise a pointer
 *                to the beginning of the IV and its length are returned.
 */
static void SWTPM_GetIvec(const unsigned char *data, uint32_t length,
                          const unsigned char **ivec, uint32_t *ivec_length,
                          uint16_t tag)
{
    tlv_data td;

    if (!tlv_data_find_tag(data, length, tag, &td)) {
        *ivec = NULL;
    } else {
        *ivec = td.u.const_ptr;
        *ivec_length = td.tlv.length;
    }
}

/*
 * SWTPM_CalcHMAC
 *
 * @in: input buffer to calculate HMAC on
 * @in_length: length of input buffer
 * @td: pointer to a tlv_data structure to receive the result with the
 *      tag, length, and pointer to an allocated buffer holding the HMAC
 * @tpm_symmetric_key_token: symmetric key
 * @ivec: the IV for AES CBC
 * @ivec_length: the length of the IV
 *
 * Calculate an HMAC on the input buffer with payload and create an output
 * buffer with the HMAC
 */
static TPM_RESULT
SWTPM_CalcHMAC(const unsigned char *in, uint32_t in_length,
               tlv_data *td,
               const TPM_SYMMETRIC_KEY_DATA *tpm_symmetric_key_token,
               const unsigned char *ivec, uint32_t ivec_length)
{
    TPM_RESULT rc = 0;
    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned int md_len = sizeof(md);
    unsigned char *buffer = NULL;

    if (!SWTPM_HMAC(md, &md_len,
                    tpm_symmetric_key_token->userKey,
                    tpm_symmetric_key_token->userKeyLength,
                    in, in_length, ivec, ivec_length)) {
        logprintf(STDOUT_FILENO, "HMAC calculation failed.\n");
        return TPM_FAIL;
    }

    buffer = malloc(md_len);

    if (buffer) {
        *td = TLV_DATA(TAG_HMAC, md_len, buffer);
        memcpy(buffer, md, md_len);
    } else {
       logprintf(STDOUT_FILENO,
                 "Could not allocate %u bytes.\n", md_len);
       rc = TPM_FAIL;
    }

    return rc;
}

/*
 * SWTPM_CheckHMAC:
 *
 * @hmac: tlv_data with pointer to hmac bytes
 * @encrypted_data: tlv_data with pointer to encrypted data bytes
 * @tpm_symmetric_key_token: symmetric key
 * @ivec: the IV for AES CBC
 * @ivec_length: the length of the IV
 *
 * Verify the HMAC given the expected @hmac and the @tpm_symmetric_key_token
 * to calculate the HMAC over the @encrypted_data.
 */
static TPM_RESULT
SWTPM_CheckHMAC(tlv_data *hmac, tlv_data *encrypted_data,
                const TPM_SYMMETRIC_KEY_DATA *tpm_symmetric_key_token,
                const unsigned char *ivec, uint32_t ivec_length)
{
    const unsigned char *data;
    uint32_t data_length;
    unsigned int md_len;
    unsigned char md[EVP_MAX_MD_SIZE];

    md_len = EVP_MD_size(EVP_sha256());
    if (md_len > hmac->tlv.length) {
        logprintf(STDOUT_FILENO, "Insufficient bytes for CheckHMAC()\n");
        return TPM_FAIL;
    }

    data = encrypted_data->u.ptr;
    data_length = encrypted_data->tlv.length;

    if (!SWTPM_HMAC(md, &md_len,
                    tpm_symmetric_key_token->userKey,
                    tpm_symmetric_key_token->userKeyLength,
                    data, data_length, ivec, ivec_length)) {
        logprintf(STDOUT_FILENO, "HMAC() call failed.\n");
        return TPM_FAIL;
    }

    if (memcmp(hmac->u.ptr, md, md_len)) {
        logprintf(STDOUT_FILENO, "Verification of HMAC failed. "
                  "Data integrity is compromised\n");
        /* TPM_DECRYPT_ERROR indicates (to libtpms) that something
           exists but we have the wrong key. */
        return TPM_DECRYPT_ERROR;
    }

    return TPM_SUCCESS;
}

/*
 * SWTPM_CheckHash:
 *
 * @in: input buffer
 * @in_length: input buffer length
 * @out: output buffer
 * @out_length: output buffer length
 */
static TPM_RESULT
SWTPM_CheckHash(const unsigned char *in, uint32_t in_length,
                unsigned char **out, uint32_t *out_length)
{
    TPM_RESULT rc = 0;
    unsigned char *dest = NULL;
    unsigned char hashbuf[SHA256_DIGEST_LENGTH];
    const unsigned char *data = &in[sizeof(hashbuf)];
    uint32_t data_length = in_length - sizeof(hashbuf);

    /* hash the data */
    SHA256(data, data_length, hashbuf);

    if (memcmp(in, hashbuf, sizeof(hashbuf))) {
        logprintf(STDOUT_FILENO, "Verification of hash failed. "
                  "Data integrity is compromised\n");
        rc = TPM_FAIL;
    }

    if (rc == 0) {
        dest = malloc(data_length);
        if (dest) {
            *out = dest;
            *out_length = data_length;
            memcpy(dest, data, data_length);
        } else {
            logprintf(STDOUT_FILENO,
                      "Could not allocated %u bytes.\n", data_length);
            rc = TPM_FAIL;
        }
    }

    return rc;
}

static TPM_RESULT
SWTPM_NVRAM_EncryptData(const encryptionkey *key,
                        struct tlv_data *td, /* must provide 2 array members */
                        size_t *td_len,
                        uint16_t tag_encrypted_data,
                        const unsigned char *data, uint32_t length,
                        uint16_t tag_ivec)
{
    TPM_RESULT rc = 0;
    TPM_RESULT irc;
    unsigned char *tmp_data = NULL;
    uint32_t tmp_length = 0;

    *td_len = 0;

    if (key->symkey.userKeyLength > 0) {
        switch (key->data_encmode) {
        case ENCRYPTION_MODE_UNKNOWN:
            rc = TPM_BAD_MODE;
            break;
        case ENCRYPTION_MODE_AES_CBC:
            irc = SWTPM_RollAndSetGlobalIvec(&td[2], tag_ivec,
                                             key->symkey.userKeyLength);
            rc = SWTPM_SymmetricKeyData_Encrypt(&tmp_data, &tmp_length,
                                                data, length, &key->symkey,
                                                td[2].u.const_ptr,
                                                td[2].tlv.length);
            if (rc)
                 break;

            rc = SWTPM_CalcHMAC(tmp_data, tmp_length, &td[1], &key->symkey,
                                td[2].u.const_ptr, td[2].tlv.length);
            if (rc == 0) {
                td[0] = TLV_DATA(tag_encrypted_data, tmp_length, tmp_data);
                /* in case we couldn't get an IV */
                *td_len = (irc == 0) ? 3 : 2;
                tmp_data = NULL;
            }
            break;
        }
    }

    if (rc)
        tlv_data_free(td, *td_len);

    free(tmp_data);

    return rc;
}

static TPM_RESULT
SWTPM_NVRAM_DecryptData(const encryptionkey *key,
                        unsigned char **decrypt_data, uint32_t *decrypt_length,
                        const unsigned char *data, uint32_t length,
                        uint16_t tag_encrypted_data,
                        uint8_t hdrversion,
                        uint16_t tag_ivec, uint16_t hdrflags,
                        uint16_t flag_256bitkey)
{
    TPM_RESULT rc = 0;
    unsigned char *tmp_data = NULL;
    uint32_t tmp_length = 0;
    tlv_data td[2];
    const unsigned char *ivec = NULL;
    uint32_t ivec_length = 0;
    size_t keylen;

    if (key->symkey.userKeyLength > 0) {
        switch (key->data_encmode) {
        case ENCRYPTION_MODE_UNKNOWN:
            rc = TPM_BAD_MODE;
            break;
        case ENCRYPTION_MODE_AES_CBC:
            switch (hdrversion) {
            case 1:
                rc = SWTPM_SymmetricKeyData_Decrypt(&tmp_data,
                                                    &tmp_length,
                                                    data, length,
                                                    &key->symkey,
                                                    NULL, 0);
                if (rc == 0) {
                    rc = SWTPM_CheckHash(tmp_data, tmp_length,
                                         decrypt_data, decrypt_length);
                }
            break;
            case 2:
                keylen = (hdrflags & flag_256bitkey)
                          ? SWTPM_AES256_BLOCK_SIZE : SWTPM_AES128_BLOCK_SIZE;
                if (keylen != key->symkey.userKeyLength) {
                    logprintf(STDERR_FILENO,
                              "Wrong decryption key. Need %zu bit key.\n",
                              keylen * 8);
                    rc = TPM_BAD_KEY_PROPERTY;
                    break;
                }

                if (!tlv_data_find_tag(data, length, TAG_HMAC, &td[0]) ||
                    !tlv_data_find_tag(data, length, tag_encrypted_data,
                                       &td[1])) {
                    logprintf(STDERR_FILENO,
                              "Could not find HMAC or encrypted data (tag %u) "
                              "in byte stream.\n", tag_encrypted_data);
                    rc = TPM_FAIL;
                    break;
                }
                /* get the IV, if there is one */
                SWTPM_GetIvec(data, length, &ivec, &ivec_length, tag_ivec);

                rc = SWTPM_CheckHMAC(&td[0], &td[1], &key->symkey,
                                     ivec, ivec_length);
                if (rc == 0) {
                    rc = SWTPM_SymmetricKeyData_Decrypt(decrypt_data,
                                                        decrypt_length,
                                                        td[1].u.const_ptr,
                                                        td[1].tlv.length,
                                                        &key->symkey,
                                                        ivec, ivec_length);
                }
            break;
            default:
                rc = TPM_FAIL;
            }
            free(tmp_data);
        }
    }

    return rc;
}

static TPM_RESULT
SWTPM_NVRAM_GetPlainData(unsigned char **plain, uint32_t *plain_length,
                         const unsigned char *data, uint32_t length,
                         uint16_t tag_data,
                         uint8_t hdrversion)
{
    TPM_RESULT rc = 0;
    tlv_data td[1];

    switch (hdrversion) {
    case 1:
        *plain = malloc(length);
        if (*plain) {
            memcpy(*plain, data, length);
            *plain_length = length;
        } else {
            logprintf(STDERR_FILENO,
                      "Could not allocate %u bytes.\n", length);
            rc = TPM_FAIL;
        }
    break;

    case 2:
        if (!tlv_data_find_tag(data, length, tag_data, &td[0])) {
            logprintf(STDERR_FILENO,
                      "Could not find plain data in byte stream.\n");
            rc = TPM_FAIL;
            break;
        }
        *plain = malloc(td->tlv.length);
        if (*plain) {
            memcpy(*plain, td->u.const_ptr, td->tlv.length);
            *plain_length = td->tlv.length;
        } else {
            logprintf(STDERR_FILENO,
                      "Could not allocate %u bytes.\n", td->tlv.length);
            rc = TPM_FAIL;
        }
    break;
    }

    return rc;
}

/*
 * SWTPM_NVRAM_GetDecryptedData: Get the decrytped data either by just returning
 *                               the data if they were not encrypted or by
 *                               actually decrypting them if there is a key.
 *                               The plain data is returned, meaning any TLV
 *                               header has been removed.
 * @key: the encryption key, may be NULL
 * @decrypt_data: pointer to a pointer for the result
 * @decrypt_length: the length of the returned data
 * @data: input data
 * @length: length of the input data
 * @tag_encrypted_data: the tag the encrypted data is stored with
 * @tag_data: the tag the plain data is stored with
 * @hdrversion: the version found in the header that determines in what
 *              format the data is stored; tag-length-value is the format
 *              in v2
 * @tag_ivec: the tag for finding the IV
 * @hdrflags: the flags from the header
 * @flag_256bitkey: the flag in the header to check whether we expect a
 *                  256 bit key; different flag for migration and state key
 */
static TPM_RESULT
SWTPM_NVRAM_GetDecryptedData(const encryptionkey *key,
                             unsigned char **decrypt_data,
                             uint32_t *decrypt_length,
                             const unsigned char *data,
                             uint32_t length,
                             uint16_t tag_encrypted_data,
                             uint16_t tag_data,
                             uint8_t hdrversion,
                             uint16_t tag_ivec,
                             uint16_t hdrflags,
                             uint16_t flag_256bitkey)
{
    if (key && key->symkey.userKeyLength > 0) {
        /* we assume the data are encrypted when there's a key given */
        return SWTPM_NVRAM_DecryptData(key, decrypt_data, decrypt_length,
                                       data, length, tag_encrypted_data,
                                       hdrversion, tag_ivec, hdrflags,
                                       flag_256bitkey);
    }
    return SWTPM_NVRAM_GetPlainData(decrypt_data, decrypt_length,
                                    data, length, tag_data, hdrversion);
}

/*
 * Prepend a header in front of the state blob
 */
static TPM_RESULT
SWTPM_NVRAM_PrependHeader(unsigned char **data, uint32_t *length,
                          uint16_t flags)
{
    unsigned char *out = NULL;
    uint32_t out_len = sizeof(blobheader) + *length;
    blobheader bh = {
        .version = BLOB_HEADER_VERSION,
        .min_version = 1,
        .hdrsize = htons(sizeof(bh)),
        .flags = htons(flags),
        .totlen = htonl(out_len),
    };
    TPM_RESULT res;

    out = malloc(out_len);
    if (!out) {
        logprintf(STDERR_FILENO,
                  "Could not allocate %u bytes.\n", out_len);
        res = TPM_FAIL;
        goto error;
    }

    memcpy(out, &bh, sizeof(bh));
    memcpy(&out[sizeof(bh)], *data, *length);

    free(*data);

    *data = out;
    *length = out_len;

    return TPM_SUCCESS;

 error:
    free(*data);
    *data = NULL;
    *length = 0;

    return res;
}


static TPM_RESULT
SWTPM_NVRAM_CheckHeader(unsigned char *data, uint32_t length,
                        uint32_t *dataoffset, uint16_t *hdrflags,
                        uint8_t *hdrversion, bool quiet)
{
    blobheader *bh = (blobheader *)data;
    uint16_t hdrsize;

    if (length < sizeof(bh)) {
        if (!quiet)
            logprintf(STDERR_FILENO,
                      "not enough bytes for header: %u\n", length);
        return TPM_BAD_PARAMETER;
    }

    if (ntohl(bh->totlen) != length) {
        if (!quiet)
            logprintf(STDERR_FILENO,
                      "broken header: bh->totlen %u != %u\n",
                      htonl(bh->totlen), length);
        return TPM_BAD_PARAMETER;
    }

    if (bh->min_version > BLOB_HEADER_VERSION) {
        if (!quiet)
            logprintf(STDERR_FILENO,
                      "Minimum required version for the blob is %d, we "
                      "only support version %d\n", bh->min_version,
                      BLOB_HEADER_VERSION);
        return TPM_BAD_VERSION;
    }

    hdrsize = ntohs(bh->hdrsize);
    if (hdrsize != sizeof(blobheader)) {
        logprintf(STDERR_FILENO,
                  "bad header size: %u != %zu\n",
                  hdrsize, sizeof(blobheader));
        return TPM_BAD_DATASIZE;
    }

    *hdrversion = bh->version;
    *dataoffset = hdrsize;
    *hdrflags = ntohs(bh->flags);

    return TPM_SUCCESS;
}

/*
 * Get the state blob with the current name; read it from the filesystem.
 * Decrypt it if the caller asks for it and if a key is set. Return
 * whether it's still encrypyted.
 */
TPM_RESULT SWTPM_NVRAM_GetStateBlob(unsigned char **data,
                                    uint32_t *length,
                                    uint32_t tpm_number,
                                    const char *name,
                                    TPM_BOOL decrypt,
                                    TPM_BOOL *is_encrypted)
{
    TPM_RESULT res;
    uint16_t flags = 0;
    tlv_data td[3];
    size_t td_len;
    unsigned char *plain = NULL, *buffer = NULL;
    uint32_t plain_len, buffer_len = 0;

    *data = NULL;
    *length = 0;

    res = SWTPM_NVRAM_LoadData(&plain, &plain_len, tpm_number, name);
    if (res)
        return res;

    /* @plain contains unencrypted data without tlv headers */

    /* if the user doesn't want decryption and there's a file key, we need to
       encrypt the data */
    if (!decrypt && SWTPM_NVRAM_Has_FileKey()) {
        td_len = 3;
        res = SWTPM_NVRAM_EncryptData(&filekey, &td[0], &td_len,
                                      TAG_ENCRYPTED_DATA, plain, plain_len,
                                      TAG_IVEC_ENCRYPTED_DATA);
        if (res)
            goto err_exit;

        *is_encrypted = TRUE;
        if (SWTPM_NVRAM_FileKey_Size() == SWTPM_AES256_BLOCK_SIZE)
            flags |= BLOB_FLAG_ENCRYPTED_256BIT_KEY;
    } else {
        *is_encrypted = FALSE;
        td[0] = TLV_DATA(TAG_DATA, plain_len, plain);
        plain = NULL;
        td_len = 1;
    }

    res = tlv_data_append(&buffer, &buffer_len, td, td_len);
    if (res)
        goto err_exit;

    tlv_data_free(td, td_len);

    /* @buffer contains tlv data */

    if (SWTPM_NVRAM_Has_MigrationKey()) {
        /* we have to encrypt it now with the migration key */
        flags |= BLOB_FLAG_MIGRATION_ENCRYPTED;
        if (SWTPM_NVRAM_MigrationKey_Size() == SWTPM_AES256_BLOCK_SIZE)
             flags |= BLOB_FLAG_MIGRATION_256BIT_KEY;

        td_len = 3;
        res = SWTPM_NVRAM_EncryptData(&migrationkey, &td[0], &td_len,
                                      TAG_ENCRYPTED_MIGRATION_DATA,
                                      buffer, buffer_len,
                                      TAG_IVEC_ENCRYPTED_MIGRATION_DATA);
        if (res)
            goto err_exit;
    } else {
        td[0] = TLV_DATA(TAG_MIGRATION_DATA, buffer_len, buffer);
        buffer = NULL;
        td_len = 1;
    }
    flags |= BLOB_FLAG_MIGRATION_DATA;

    res = tlv_data_append(data, length, td, td_len);
    if (res)
        goto err_exit;

    /* put the header in clear text */
    if (*is_encrypted)
        flags |= BLOB_FLAG_ENCRYPTED;

    res = SWTPM_NVRAM_PrependHeader(data, length, flags);

err_exit:
    tlv_data_free(td, td_len);
    free(buffer);
    free(plain);

    return res;
}

/*
 * Set the state blob with the given name; the caller tells us if
 * the blob is encrypted; if it is encrypted, it will be written
 * into the file as-is, otherwise it will be encrypted if a key is set.
 */
TPM_RESULT SWTPM_NVRAM_SetStateBlob(unsigned char *data,
                                    uint32_t length,
                                    TPM_BOOL is_encrypted,
                                    uint32_t tpm_number SWTPM_ATTR_UNUSED,
                                    uint32_t blobtype)
{
    TPM_RESULT res;
    uint32_t dataoffset;
    unsigned char *plain = NULL, *mig_decrypt = NULL;
    uint32_t plain_len = 0, mig_decrypt_len = 0;
    uint16_t hdrflags;
    enum TPMLIB_StateType st = tpmlib_blobtype_to_statetype(blobtype);
    const char *blobname = tpmlib_get_blobname(blobtype);
    uint8_t hdrversion;

    if (st == 0) {
        logprintf(STDERR_FILENO,
                  "Unknown blob type %u\n", blobtype);
        return TPM_BAD_PARAMETER;
    }

    if (length == 0)
        return TPMLIB_SetState(st, NULL, 0);

    res = SWTPM_NVRAM_CheckHeader(data, length, &dataoffset, &hdrflags,
                                  &hdrversion, false);
    if (res != TPM_SUCCESS)
        return res;

    if (length - dataoffset == 0)
        return TPMLIB_SetState(st, NULL, 0);

    /*
     * We allow setting of blobs that were not encrypted before;
     * we just will not decrypt them even if the migration key is
     * set. This allows to 'upgrade' to encryption. 'Downgrading'
     * will not be possible once a migration key was used.
     */
    if ((hdrflags & BLOB_FLAG_MIGRATION_ENCRYPTED)) {
        /*
         * we first need to decrypt the data with the migration key
         */
        if (!SWTPM_NVRAM_Has_MigrationKey()) {
            logprintf(STDERR_FILENO,
                      "Missing migration key to decrypt %s\n", blobname);
            return TPM_KEYNOTFOUND;
        }

        res = SWTPM_NVRAM_DecryptData(&migrationkey,
                                      &mig_decrypt, &mig_decrypt_len,
                                      &data[dataoffset], length - dataoffset,
                                      TAG_ENCRYPTED_MIGRATION_DATA,
                                      hdrversion,
                                      TAG_IVEC_ENCRYPTED_MIGRATION_DATA,
                                      hdrflags, BLOB_FLAG_MIGRATION_256BIT_KEY);
        if (res) {
            logprintf(STDERR_FILENO,
                      "Decrypting the %s blob with the migration key failed; "
                      "res = %d\n", blobname, res);
            return res;
        }
    } else {
        res = SWTPM_NVRAM_GetPlainData(&mig_decrypt, &mig_decrypt_len,
                                       &data[dataoffset], length - dataoffset,
                                       TAG_MIGRATION_DATA,
                                       hdrversion);
        if (res)
            return res;
    }

    /*
     * Migration key has decrytped the data; if they are still encrypted
     * with the state encryption key, we need to decrypt them using that
     * key now.
     */
    if (is_encrypted || (hdrflags & BLOB_FLAG_ENCRYPTED)) {
        if (!SWTPM_NVRAM_Has_FileKey()) {
            logprintf(STDERR_FILENO,
                      "Missing state key to decrypt %s\n", blobname);
            res = TPM_KEYNOTFOUND;
            goto cleanup;
        }

        res = SWTPM_NVRAM_DecryptData(&filekey, &plain, &plain_len,
                                      mig_decrypt, mig_decrypt_len,
                                      TAG_ENCRYPTED_DATA,
                                      hdrversion, TAG_IVEC_ENCRYPTED_DATA,
                                      hdrflags, BLOB_FLAG_ENCRYPTED_256BIT_KEY);
        if (res) {
            logprintf(STDERR_FILENO,
                      "Decrypting the %s blob with the state key "
                      "failed; res = %d\n", blobname, res);
            goto cleanup;
        }
    } else {
        res = SWTPM_NVRAM_GetPlainData(&plain, &plain_len,
                                       mig_decrypt, mig_decrypt_len,
                                       TAG_DATA,
                                       hdrversion);
        if (res)
            goto cleanup;
    }

    /* SetState will make a copy of the buffer */
    res = TPMLIB_SetState(st, plain, plain_len);

    free(plain);

cleanup:
    free(mig_decrypt);

    return res;
}

/* Example JSON output:
 *  { "type": "swtpm",
 *    "states": [ "permall", "volatilestate", "savestate" ]
 *  }
 */
int SWTPM_NVRAM_PrintJson(void)
{
    TPM_RESULT rc = 0;
    const char *backend_uri;
    const char *states[] = {
        TPM_PERMANENT_ALL_NAME,
        TPM_VOLATILESTATE_NAME,
        TPM_SAVESTATE_NAME,
    };
    char state_str[200] = "";
    size_t i, n, o, blobsize;
    int ret = -1;

    rc = SWTPM_NVRAM_Init();
    if (rc == 0) {
        o = 0;
        backend_uri = tpmstate_get_backend_uri();

        for (i = 0; i < ARRAY_LEN(states); i++) {
            rc = g_nvram_backend_ops->check_state(backend_uri, states[i],
                                                  &blobsize);
            if (rc == TPM_SUCCESS) {
                n = snprintf(&state_str[o], sizeof(state_str) - o,
                             "%s {\"name\": \"%s\", \"size\": %zu}",
                             (o > 0) ? "," : "",
                             states[i], blobsize);
                if (n >= sizeof(state_str) - o)
                    goto exit;
                o += n;
            } else if (rc != TPM_RETRY) {
                /* Error other than ENOENT */
                goto exit;
            }
        }
        printf("{ \"type\": \"swtpm\", \"states\": [%s%s] }",
               state_str,  (o > 0) ? " ": "");
        ret = 0;
    }

exit:
    return ret;
}
