From 8ce50494c74db0ecfe3b09ea41b84ba4a2eb09c3 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Sat, 15 Sep 2018 14:03:50 -0400 Subject: [PATCH] swtpm: Check the size of the user's key against expected size Use the flags in the header to check the size of the provided key(s) against the one(s) from the user. There are the state and migration keys, each has a different flag in the header if a 256bit key was used. We display an error about the mismatching key size against expected size if the given key is of the wrong size. Signed-off-by: Stefan Berger --- src/swtpm/swtpm_nvfile.c | 45 +++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/swtpm/swtpm_nvfile.c b/src/swtpm/swtpm_nvfile.c index 9663e96e..debf6f5d 100644 --- a/src/swtpm/swtpm_nvfile.c +++ b/src/swtpm/swtpm_nvfile.c @@ -150,7 +150,9 @@ static TPM_RESULT SWTPM_NVRAM_GetDecryptedData(const encryptionkey *key, uint16_t tag_decryped_data, uint16_t tag_data, uint8_t hdrversion, - uint16_t tag_ivec); + uint16_t tag_ivec, + uint16_t hdrflags, + uint16_t flag_256bitkey); static TPM_RESULT SWTPM_NVRAM_PrependHeader(unsigned char **data, uint32_t *length, @@ -423,13 +425,15 @@ SWTPM_NVRAM_LoadData(unsigned char **data, /* freed by caller */ *length - dataoffset, TAG_ENCRYPTED_DATA, TAG_DATA, hdrversion, - TAG_IVEC_ENCRYPTED_DATA); - TPM_DEBUG(" SWTPM_NVRAM_LoadData: SWTPM_NVRAM_DecryptData rc = %d\n", + 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: Decrypting the NVRAM data " - "failed rc = %d\n", rc); + "SWTPM_NVRAM_LoadData: Error from SWTPM_NVRAM_GetDecryptedData " + "rc = %d\n", rc); if (rc == 0) { TPM_DEBUG(" SWTPM_NVRAM_LoadData: Decrypted %u bytes of " @@ -1035,7 +1039,8 @@ SWTPM_NVRAM_DecryptData(const encryptionkey *key, const unsigned char *data, uint32_t length, uint16_t tag_encrypted_data, uint8_t hdrversion, - uint16_t tag_ivec) + uint16_t tag_ivec, uint16_t hdrflags, + uint16_t flag_256bitkey) { TPM_RESULT rc = 0; unsigned char *tmp_data = NULL; @@ -1043,6 +1048,7 @@ SWTPM_NVRAM_DecryptData(const encryptionkey *key, 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) { @@ -1063,6 +1069,16 @@ SWTPM_NVRAM_DecryptData(const encryptionkey *key, } 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])) { @@ -1157,6 +1173,9 @@ SWTPM_NVRAM_GetPlainData(unsigned char **plain, uint32_t *plain_length, * 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, @@ -1167,13 +1186,16 @@ SWTPM_NVRAM_GetDecryptedData(const encryptionkey *key, uint16_t tag_encrypted_data, uint16_t tag_data, uint8_t hdrversion, - uint16_t tag_ivec) + 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); + hdrversion, tag_ivec, hdrflags, + flag_256bitkey); } return SWTPM_NVRAM_GetPlainData(decrypt_data, decrypt_length, data, length, tag_data, hdrversion); @@ -1414,7 +1436,8 @@ TPM_RESULT SWTPM_NVRAM_SetStateBlob(unsigned char *data, &data[dataoffset], length - dataoffset, TAG_ENCRYPTED_MIGRATION_DATA, hdrversion, - TAG_IVEC_ENCRYPTED_MIGRATION_DATA); + 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; " @@ -1442,10 +1465,12 @@ TPM_RESULT SWTPM_NVRAM_SetStateBlob(unsigned char *data, 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); + hdrversion, TAG_IVEC_ENCRYPTED_DATA, + hdrflags, BLOB_FLAG_ENCRYPTED_256BIT_KEY); if (res) { logprintf(STDERR_FILENO, "Decrypting the %s blob with the state key "