diff --git a/README.md b/README.md index 18d78dc..9d3616c 100644 --- a/README.md +++ b/README.md @@ -52,26 +52,30 @@ For getting an overview of the possible commands, run ./eltt2 -h Some options require the TPM to be in a specific state. This state is shown in brackets ("[]") behind each command line option in the list below: -\[u\]: started +\[-\]: none
+\[*\]: the TPM platform hierarchy authorization value is not set (i.e., empty buffer)
+\[l\]: the required PCR bank is allocated
+\[u\]: started
To get the TPM into the required state, call ELTT2 with the corresponding commands ("x" for a state means that whether this state is required or not depends on the actual command or the command parameters sent eventually to the TPM). Command line option | Explanation | Precondition --- | --- | --- - -a \[hash algorithm\] \ | Hash Sequence SHA-1/SHA-256 \[default: SHA-1\] | \[u\] + -a \[hash algorithm\] \ | Hash Sequence SHA-1/256/384 \[default: SHA-1\] | \[u\] -A \ | Hash Sequence SHA-256 | \[u\] -b \ | Enter your own TPM command | \[u\] -c | Read Clock | \[u\] -d \ | Shutdown | \[u\] - -e \[hash algorithm\] \ \ | PCR Extend SHA-1/SHA-256 \[default: SHA-1\] | \[u\] - -E \ \ | PCR Extend SHA-256 | \[u\] + -e \[hash algorithm\] \ \ | PCR Extend SHA-1/256/384 \[default: SHA-1\] | \[u\], \[l\] + -E \ \ | PCR Extend SHA-256 | \[u\], \[l\] -g | Get fixed capability values | \[u\] -v | Get variable capability values | \[u\] -G \ | Get Random | \[u\] -h | Help | \[-\] - -r \[hash algorithm\] \ | PCR Read SHA-1/SHA-256 \[default: SHA-1\] | \[u\] - -R \ | PCR Read SHA-256 | \[u\] - -s \[hash algorithm\] \ | Hash SHA-1/SHA-256 \[default: SHA-1\] | \[u\] + -l \ | PCR Allocate SHA-1/256/384 | \[u\], \[*\] + -r \[hash algorithm\] \ | PCR Read SHA-1/256/384 \[default: SHA-1\] | \[u\], \[l\] + -R \ | PCR Read SHA-256 | \[u\], \[l\] + -s \[hash algorithm\] \ | Hash SHA-1/256/384 \[default: SHA-1\] | \[u\] -S \ | Hash SHA-256 | \[u\] -t \ | Self Test | \[u\] -T | Get Test Result | \[u\] @@ -82,11 +86,12 @@ To get the TPM into the required state, call ELTT2 with the corresponding comman Additional information: -a:
-With the "-a" command you can hash given data with the SHA-1/SHA-256 hash algorithm. This hash sequence sends 3 commands [start, update, complete] to the TPM and allows to hash an arbitrary amount of data. For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
+With the "-a" command you can hash given data with the SHA-1/256/384 hash algorithm. This hash sequence sends 3 commands [start, update, complete] to the TPM and allows to hash an arbitrary amount of data. For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
./eltt2 -a 41624364 Hash given data with SHA-1 hash algorithm.
or
./eltt2 -a sha1 41624364 Hash given data with SHA-1 hash algorithm.
./eltt2 -a sha256 41624364 Hash given data with SHA-256 hash algorithm.
+./eltt2 -a sha384 41624364 Hash given data with SHA-384 hash algorithm.
-A:
With the "-A" command you can hash given data with the SHA-256 hash algorithm. This hash sequence sends 3 commands [start, update, complete] to the TPM and allows to hash an arbitrary amount of data. For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
@@ -107,11 +112,12 @@ or
./eltt2 -d state send a TPM2_Shutdown command with shutdown type STATE to the TPM.
-e:
- With the "-e" command you can extend bytes in the selected PCR with SHA-1/SHA-256. To do so, you have to enter the index of PCR in hexadecimal that you like to extend and the digest you want to extend the selected PCR with. Note that you can only extend PCRs with index 0 to 16 and PCR 23 and that the digest must have a length of 20/32 bytes (will be padded with 0 if necessary). The TPM then builds an SHA-1/SHA-256 hash over the PCR data in the selected PCR and the digest you provided and writes the result back to the selected PCR. For example, use the following command to extend PCR 23 (0x17) with the byte sequence {0x41, 0x62, 0x43, 0x64, 0x00, ... (will be filled with 0x00)}:
+ With the "-e" command you can extend bytes in the selected PCR with SHA-1/256/384. To do so, you have to enter the index of PCR in hexadecimal that you like to extend and the digest you want to extend the selected PCR with. Note that you can only extend PCRs with index 0 to 16 and PCR 23 and that the digest must have a length of 20/32/48 bytes (will be padded with 0 if necessary). The TPM then builds an SHA-1/256/384 hash over the PCR data in the selected PCR and the digest you provided and writes the result back to the selected PCR. For example, use the following command to extend PCR 23 (0x17) with the byte sequence {0x41, 0x62, 0x43, 0x64, 0x00, ... (will be filled with 0x00)}:
./eltt2 -e 17 41624364 Extend bytes in PCR 23 with SHA-1.
or
./eltt2 -e sha1 17 41624364 Extend bytes in PCR 23 with SHA-1.
./eltt2 -e sha256 17 41624364 Extend bytes in PCR 23 with SHA-256.
+./eltt2 -e sha384 17 41624364 Extend bytes in PCR 23 with SHA-384.
-E:
With the "-E" command you can extend bytes in the selected PCR with SHA-256. To do so, you have to enter the index of PCR in hexadecimal that you like to extend and the digest you want to extend the selected PCR with. Note that you can only extend PCRs with index 0 to 16 and PCR 23 and that the digest must have a length of 32 bytes (will be padded with 0 if necessary). The TPM then builds an SHA-256 hash over the PCR data in the selected PCR and the digest you provided and writes the result back to the selected PCR. For example, use the following command to extend PCR 23 (0x17) with the byte sequence {0x41, 0x62, 0x43, 0x64, 0x00, ... (will be filled with 0x00)}:
@@ -127,23 +133,31 @@ With the "-v" command you can read the TPM's variable properties. With the "-G" command you can get a given amount of random bytes. Note that you can only request a maximum amount of 32 random bytes at once. For example, use the following command to get 20 (0x14) random bytes:
./eltt2 -G 14 +-l:
+With the "-l" command you can allocate the SHA-1/256/384 PCR bank. Take note of two things. Firstly, the command requires a platform authorization value and it is set to an empty buffer; hence the command cannot be used if the TPM platform authorization value is set (e.g., by UEFI). Secondly, when the command is executed successfully a TPM reset has to follow for it to take effect. For example, use the following command to allocate a PCR bank:
+./eltt2 -l sha1 Allocate SHA-1 PCR bank.
+./eltt2 -l sha256 Allocate SHA-256 PCR bank.
+./eltt2 -l sha384 Allocate SHA-384 PCR bank.
+ -r:
-With the "-r" command you can read data from a selected SHA-1/SHA-256 PCR. For example, use the following command to read data from PCR 23 (0x17):
+With the "-r" command you can read data from a selected SHA-1/256/384 PCR. For example, use the following command to read data from PCR 23 (0x17):
./eltt2 -r 17 Read data from SHA-1 PCR 23.
or
./eltt2 -r sha1 17 Read data from SHA-1 PCR 23.
./eltt2 -r sha256 17 Read data from SHA-256 PCR 23.
+./eltt2 -r sha384 17 Read data from SHA-384 PCR 23.
-R:
With the "-R" command you can read data from a selected SHA-256 PCR. For example, use the following command to read data from PCR 23 (0x17):
./eltt2 -R 17 -s:
-With the "-s" command you can hash given data with the SHA-1/SHA-256 hash algorithm. This command only allows a limited amount of data to be hashed (depending on the TPM's maximum input buffer size). For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
+With the "-s" command you can hash given data with the SHA-1/256/384 hash algorithm. This command only allows a limited amount of data to be hashed (depending on the TPM's maximum input buffer size). For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
./eltt2 -s 41624364 Hash given data with SHA-1 hash algorithm.
or
./eltt2 -s sha1 41624364 Hash given data with SHA-1 hash algorithm.
./eltt2 -s sha256 41624364 Hash given data with SHA-256 hash algorithm.
+./eltt2 -s sha384 41624364 Hash given data with SHA-384 hash algorithm.
-S:
With the "-S" command you can hash given data with the SHA-256 hash algorithm. This command only allows a limited amount of data to be hashed (depending on the TPM input buffer size). For example, use the following command to hash the byte sequence {0x41, 0x62, 0x43, 0x64}:
diff --git a/README.txt b/README.txt index 39f4173..9643321 100644 --- a/README.txt +++ b/README.txt @@ -98,6 +98,9 @@ Contents: Some options require the TPM to be in a specific state. This state is shown in brackets ("[]") behind each command line option in the list below: + [-]: none + [*]: the TPM platform hierarchy authorization value is not set (i.e., empty buffer) + [l]: the required PCR bank is allocated [u]: started To get the TPM into the required state, call ELTT2 with the corresponding @@ -108,7 +111,7 @@ Contents: Command line options: Preconditions: - -a [hash algorithm] : Hash Sequence SHA-1/SHA-256 [default: SHA-1] [u] + -a [hash algorithm] : Hash Sequence SHA-1/256/384 [default: SHA-1] [u] -A : Hash Sequence SHA-256 [u] @@ -118,9 +121,9 @@ Contents: -d : Shutdown [u] - -e [hash algorithm] : PCR Extend SHA-1/SHA-256 [default: SHA-1] [u] + -e [hash algorithm] : PCR Extend SHA-1/256/384 [default: SHA-1] [u], [l] - -E : PCR Extend SHA-256 [u] + -E : PCR Extend SHA-256 [u], [l] -g: Get fixed capability values [u] @@ -130,9 +133,11 @@ Contents: -h: Help [-] - -r [hash algorithm] : PCR Read SHA-1/SHA-256 [default: SHA-1] [u] + -l : PCR Allocate SHA-1/256/384 [u], [*] - -R : PCR Read SHA-256 [u] + -r [hash algorithm] : PCR Read SHA-1/256/384 [default: SHA-1] [u], [l] + + -R : PCR Read SHA-256 [u], [l] -s [hash algorithm] : Hash SHA-1/SHA256 [default: SHA-1] [u] @@ -150,7 +155,7 @@ Contents: Additional information: -a: - With the "-a" command you can hash given data with the SHA-1/SHA-256 hash + With the "-a" command you can hash given data with the SHA-1/256/384 hash algorithm. This hash sequence sends 3 commands [start, update, complete] to the TPM and allows to hash an arbitrary amount of data. For example, use the following command to hash the byte sequence {0x41, @@ -188,12 +193,12 @@ Contents: the TPM. -e: - With the "-e" command you can extend bytes in the selected PCR with SHA-1/SHA-256. + With the "-e" command you can extend bytes in the selected PCR with SHA-1/256/384. To do so, you have to enter the index of PCR in hexadecimal that you like to extend and the digest you want to extend the selected PCR with. Note that you can only extend PCRs with index 0 to 16 and PCR 23 and that the digest - must have a length of 20/32 bytes (will be padded with 0 if necessary). - The TPM then builds an SHA-1/SHA-256 hash over the PCR data in the selected PCR + must have a length of 20/32/48 bytes (will be padded with 0 if necessary). + The TPM then builds an SHA-1/256/384 hash over the PCR data in the selected PCR and the digest you provided and writes the result back to the selected PCR. For example, use the following command to extend PCR 23 (0x17) with the byte sequence {0x41, 0x62, 0x43, 0x64, 0x00, ... (will be filled with 0x00)}: @@ -226,8 +231,20 @@ Contents: For example, use the following command to get 20 (0x14) random bytes: ./eltt2 -G 14 + -l: + With the "-l" command you can allocate the SHA-1/256/384 PCR bank. + Take note of two things. Firstly, the command requires a platform + authorization value and it is set to an empty buffer; hence the command + cannot be used if the TPM platform authorization value is set (e.g., by UEFI). + Secondly, when the command is executed successfully a TPM reset has to + follow for it to take effect. For example, use the following command to + allocate a PCR bank: + ./eltt2 -l sha1 Allocate SHA-1 PCR bank. + ./eltt2 -l sha256 Allocate SHA-256 PCR bank. + ./eltt2 -l sha384 Allocate SHA-384 PCR bank. + -r: - With the "-r" command you can read data from a selected SHA-1/SHA-256 PCR. + With the "-r" command you can read data from a selected SHA-1/256/384 PCR. For example, use the following command to read data from PCR 23 (0x17): ./eltt2 -r 17 Read data from SHA-1 PCR 23. or @@ -240,7 +257,7 @@ Contents: ./eltt2 -R 17 -s: - With the "-s" command you can hash given data with the SHA-1/SHA-256 hash + With the "-s" command you can hash given data with the SHA-1/256/384 hash algorithm. This command only allows a limited amount of data to be hashed (depending on the TPM's maximum input buffer size). For example, use the following command to hash the byte sequence {0x41, diff --git a/eltt2.c b/eltt2.c index 128f090..2c70776 100644 --- a/eltt2.c +++ b/eltt2.c @@ -82,11 +82,11 @@ int main(int argc, char **argv) opterr = 0; // Disable getopt error messages in case of unknown parameters; we want to use our own error messages. // Loop through parameters with getopt. - while (-1 != (option = getopt(argc, argv, "cgvhTa:A:b:d:e:E:G:r:R:s:S:t:u:z:"))) + while (-1 != (option = getopt(argc, argv, "cgvhTa:A:b:d:e:E:G:l:r:R:s:S:t:u:z:"))) { switch (option) { - case 'a': // TPM2_HashSequenceStart SHA-1 + case 'a': // TPM2_HashSequenceStart SHA-1/256/384 case 'A': // TPM2_HashSequenceStart SHA-256 HASH_ALG_PARSER('a', 3); @@ -128,7 +128,7 @@ int main(int argc, char **argv) } break; - case 'e': // PCR_Extend SHA-1 + case 'e': // PCR_Extend SHA-1/256/384 case 'E': // PCR_Extend SHA-256 if (4 > argc) { @@ -147,10 +147,14 @@ int main(int argc, char **argv) { input_bytes_size = sizeof(tpm2_pcr_extend) + TPM_SHA1_DIGEST_SIZE; } - else + else if (ALG_SHA256 == hash_algo) { input_bytes_size = sizeof(tpm2_pcr_extend) + TPM_SHA256_DIGEST_SIZE; } + else + { + input_bytes_size = sizeof(tpm2_pcr_extend) + TPM_SHA384_DIGEST_SIZE; + } input_bytes = malloc(input_bytes_size); MALLOC_ERROR_CHECK(input_bytes); memset(input_bytes, 0, input_bytes_size); @@ -196,7 +200,24 @@ int main(int argc, char **argv) no_transmission = 1; break; - case 'r': // PCR_Read SHA-1 + case 'l': // PCR_Allocate SHA-1/256/384 + HASH_ALG_PARSER('l', -1); + + // Allocate the input buffer for pcr_read and tpmtool_transmit. + input_bytes_size = sizeof(tpm2_pcr_allocate); + input_bytes = malloc(input_bytes_size); + MALLOC_ERROR_CHECK(input_bytes); + memset(input_bytes, 0, input_bytes_size); + + // Create PCR_Allocate TPM request. + ret_val = pcr_allocate(input_bytes, hash_algo); + RET_VAL_CHECK(ret_val); + + // Send bytes to TPM. + ret_val = tpmtool_transmit(input_bytes, input_bytes_size, tpm_response_buf, &tpm_response_buf_size); + break; + + case 'r': // PCR_Read SHA-1/256/384 case 'R': // PCR_Read SHA-256 HASH_ALG_PARSER('r', 3); @@ -214,7 +235,7 @@ int main(int argc, char **argv) ret_val = tpmtool_transmit(input_bytes, input_bytes_size, tpm_response_buf, &tpm_response_buf_size); break; - case 's': // Hash SHA-1 + case 's': // Hash SHA-1/256/384 case 'S': // Hash SHA-256 HASH_ALG_PARSER('s', 3); @@ -289,7 +310,7 @@ int main(int argc, char **argv) default: if ('a' == optopt || 'A' == optopt || 'b' == optopt || 'e' == optopt || 'E' == optopt || 'G' == optopt || - 'r' == optopt || 'R' == optopt || 's' == optopt || 'S' == optopt || 'z' == optopt) + 'l' == optopt || 'r' == optopt || 'R' == optopt || 's' == optopt || 'S' == optopt || 'z' == optopt) { // Error output if arguments are missing. fprintf(stderr, "Option '-%c' requires additional arguments. Use '-h' for more information.\n", optopt); @@ -724,8 +745,8 @@ static int print_response_buf(uint8_t *response_buf, size_t resp_size, uint32_t static void print_help() { - printf("'-a [hash algorithm] ': Hash Sequence SHA-1/SHA-256 [default: SHA-1]\n"); - printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256'\n"); + printf("'-a [hash algorithm] ': Hash Sequence SHA-1/256/384 [default: SHA-1]\n"); + printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256', 'sha384'\n"); printf(" Data bytes: Enter a byte sequence like '0F56...' for {0x0f, 0x56, ...}\n"); printf("'-A ': Hash Sequence SHA-256\n"); printf(" -> Data bytes: Enter a byte sequence like '0F56...' for {0x0f, 0x56, ...}\n"); @@ -734,8 +755,8 @@ static void print_help() printf("'-c': Read Clock\n"); printf("'-d ': Shutdown\n"); printf(" -> Shutdown types: clear [default], state\n"); - printf("'-e [hash algorithm] ': PCR Extend SHA-1/SHA-256 [default: SHA-1]\n"); - printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256'\n"); + printf("'-e [hash algorithm] ': PCR Extend SHA-1/256/384 [default: SHA-1]\n"); + printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256', 'sha384'\n"); printf(" PCR index: Enter the PCR index in hex like '17' for 0x17\n"); printf(" PCR digest: Enter the value to extend the PCR with in hex like '0f56...' for {0x0f, 0x56, ...}\n"); printf("'-E ': PCR Extend SHA-256\n"); @@ -746,13 +767,15 @@ static void print_help() printf("'-G ': Get Random\n"); printf(" -> Enter desired number of random bytes in hex like '20' for 0x20 (=32 bytes, maximum)\n"); printf("'-h': Help\n"); - printf("'-r [hash algorithm] ': PCR Read SHA-1/SHA-256 [default: SHA-1]\n"); - printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256'\n"); + printf("'-l ': PCR allocate SHA-1/256/384\n"); + printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256', 'sha384'\n"); + printf("'-r [hash algorithm] ': PCR Read SHA-1/256/384 [default: SHA-1]\n"); + printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256', 'sha384'\n"); printf(" PCR index: Enter PCR number in hex like '17' for 0x17\n"); printf("'-R ': PCR Read SHA-256\n"); printf(" -> PCR index: Enter PCR number in hex like '17' for 0x17\n"); - printf("'-s [hash algorithm] ': Hash SHA-1/SHA-256 [default: SHA-1]\n"); - printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256'\n"); + printf("'-s [hash algorithm] ': Hash SHA-1/256/384 [default: SHA-1]\n"); + printf(" -> Hash algorithm: Enter hash algorithm like 'sha1', 'sha256', 'sha384'\n"); printf(" Data bytes: Enter a byte sequence like '0F56...' for {0x0f, 0x56, ...}\n"); printf("'-S ': Hash SHA-256\n"); printf(" -> Data bytes: Enter a byte sequence like '0F56...' for {0x0f, 0x56, ...}\n"); @@ -761,7 +784,7 @@ static void print_help() printf("'-T': Get Test Result\n"); printf("'-u ': Startup\n"); printf(" -> Startup types: clear [default], state\n"); - printf("'-z ': PCR Reset SHA-1 and SHA-256\n"); + printf("'-z ': PCR Reset SHA-1, SHA-256, and SHA-384\n"); printf(" -> PCR index: Enter PCR number in hex like '17' for 0x17\n"); } @@ -1270,11 +1293,16 @@ static int create_hash(char *data_string, hash_algo_enum hash_algo, uint8_t *has tpm_hash_alg = sha1_alg; printf("\nTPM2_Hash of '%s' with SHA-1:\n", data_string); } - else + else if (ALG_SHA256 == hash_algo) { tpm_hash_alg = sha256_alg; printf("\nTPM2_Hash of '%s' with SHA-256:\n", data_string); } + else + { + tpm_hash_alg = sha384_alg; + printf("\nTPM2_Hash of '%s' with SHA-384:\n", data_string); + } offset = TPM_CMD_SIZE_OFFSET; ret_val = int_to_bytearray(sizeof(tpm2_hash) + data_string_size, sizeof(uint32_t), hash_cmd_buf + offset); @@ -1344,11 +1372,16 @@ static int create_hash_sequence(char *data_string, hash_algo_enum hash_algo, uin printf("\nTPM2_HashSequenceStart of '%s' with SHA-1:\n", data_string); memcpy(tpm2_hash_sequence_start + 12, sha1_alg, sizeof(sha1_alg)); } - else + else if (ALG_SHA256 == hash_algo) { printf("\nTPM2_HashSequenceStart of '%s' with SHA-256:\n", data_string); memcpy(tpm2_hash_sequence_start + 12, sha256_alg, sizeof(sha256_alg)); } + else + { + printf("\nTPM2_HashSequenceStart of '%s' with SHA-384:\n", data_string); + memcpy(tpm2_hash_sequence_start + 12, sha384_alg, sizeof(sha384_alg)); + } // Send the TPM2_HashSequenceStart command to the TPM. ret_val = tpmtool_transmit(tpm2_hash_sequence_start, sizeof(tpm2_hash_sequence_start), tpm_response_buf, tpm_response_buf_size); @@ -1490,13 +1523,6 @@ static int pcr_extend(char *pcr_index_str, char *pcr_digest_str, uint8_t *pcr_cm memset(pcr_cmd_buf, 0, pcr_cmd_buf_size); - if (ALG_SHA1 != hash_algo && ALG_SHA256 != hash_algo) - { - ret_val = EINVAL; - fprintf(stderr, "Bad parameter. Option argument must be 'e' or 'E'.\n"); - break; - } - // Check and convert the command line input (PCR index) to bytes. if (1 != strlen(pcr_index_str) / HEX_BYTE_STRING_LENGTH + strlen(pcr_index_str) % HEX_BYTE_STRING_LENGTH) { @@ -1527,6 +1553,12 @@ static int pcr_extend(char *pcr_index_str, char *pcr_digest_str, uint8_t *pcr_cm fprintf(stderr, "Bad option. Maximum SHA-256 PCR digest size is 32 byte (64 characters), but you entered %u byte.\n", pcr_digest_size); break; } + if (ALG_SHA384 == hash_algo && TPM_SHA384_DIGEST_SIZE < pcr_digest_size) + { + ret_val = ERR_BAD_CMD; + fprintf(stderr, "Bad option. Maximum SHA-384 PCR digest size is 48 byte (96 characters), but you entered %u byte.\n", pcr_digest_size); + break; + } // Copy basic command bytes. memcpy(pcr_cmd_buf, tpm2_pcr_extend, sizeof(tpm2_pcr_extend)); @@ -1551,6 +1583,12 @@ static int pcr_extend(char *pcr_index_str, char *pcr_digest_str, uint8_t *pcr_cm memcpy(pcr_cmd_buf + 31, sha256_alg, sizeof(sha256_alg)); printf("Extend PCR %i (SHA-256) with digest { ", pcr_index); } + else if (ALG_SHA384 == hash_algo) + { + pcr_cmd_buf[5] = sizeof(tpm2_pcr_extend) + TPM_SHA384_DIGEST_SIZE; + memcpy(pcr_cmd_buf + 31, sha384_alg, sizeof(sha384_alg)); + printf("Extend PCR %i (SHA-384) with digest { ", pcr_index); + } print_response_buf(pcr_cmd_buf, pcr_cmd_buf_size, sizeof(tpm2_pcr_extend), PRINT_RESPONSE_CLEAR); printf("}:\n"); } while (0); @@ -1558,6 +1596,46 @@ static int pcr_extend(char *pcr_index_str, char *pcr_digest_str, uint8_t *pcr_cm return ret_val; } +static int pcr_allocate(uint8_t *pcr_cmd_buf, hash_algo_enum hash_algo) +{ + int ret_val = EXIT_SUCCESS; // Return value. + unsigned char set[] = {0xFF, 0xFF, 0xFF}; + unsigned char clear[] = {0x00, 0x00, 0x00}; + + do + { + NULL_POINTER_CHECK(pcr_cmd_buf); + + // Copy basic command bytes. + memcpy(pcr_cmd_buf, tpm2_pcr_allocate, sizeof(tpm2_pcr_allocate)); + + // Set hash algorithm depending on user input option at the correct byte index in the command byte stream. + if (ALG_SHA1 == hash_algo) + { + memcpy(pcr_cmd_buf + 34, set, sizeof(set)); + memcpy(pcr_cmd_buf + 40, clear, sizeof(clear)); + memcpy(pcr_cmd_buf + 46, clear, sizeof(clear)); + printf("PCR allocate SHA-1 bank\n"); + } + else if (ALG_SHA256 == hash_algo) + { + memcpy(pcr_cmd_buf + 34, clear, sizeof(clear)); + memcpy(pcr_cmd_buf + 40, set, sizeof(set)); + memcpy(pcr_cmd_buf + 46, clear, sizeof(clear)); + printf("PCR allocate SHA-256 bank\n"); + } + else if (ALG_SHA384 == hash_algo) + { + memcpy(pcr_cmd_buf + 34, clear, sizeof(clear)); + memcpy(pcr_cmd_buf + 40, clear, sizeof(clear)); + memcpy(pcr_cmd_buf + 46, set, sizeof(set)); + printf("PCR allocate SHA-384 bank\n"); + } + } while (0); + + return ret_val; +} + static int pcr_read(char *pcr_index_str, uint8_t *pcr_cmd_buf, hash_algo_enum hash_algo) { int ret_val = EXIT_SUCCESS; // Return value. @@ -1613,6 +1691,11 @@ static int pcr_read(char *pcr_index_str, uint8_t *pcr_cmd_buf, hash_algo_enum ha memcpy(pcr_cmd_buf + 14, sha256_alg, sizeof(sha256_alg)); printf("Read PCR %i (SHA-256):\n", pcr_index); } + else if (ALG_SHA384 == hash_algo) + { + memcpy(pcr_cmd_buf + 14, sha384_alg, sizeof(sha384_alg)); + printf("Read PCR %i (SHA-384):\n", pcr_index); + } } while (0); return ret_val; @@ -1652,7 +1735,7 @@ static int pcr_reset(char *pcr_index_str, uint8_t *pcr_cmd_buf) // Store pcr_index at the correct byte index in the command byte stream. pcr_cmd_buf[13] = pcr_index; - printf("Reset PCR %i (SHA-1 and SHA-256):\n", pcr_index); + printf("Reset PCR %i (SHA-1, SHA-256, and SHA-384):\n", pcr_index); } while (0); return ret_val; diff --git a/eltt2.h b/eltt2.h index 6e7ca36..12d7a79 100644 --- a/eltt2.h +++ b/eltt2.h @@ -80,6 +80,7 @@ #define ERR_BAD_CMD -2 ///< Error code for a bad command line argument or option. #define TPM_SHA1_DIGEST_SIZE 20 ///< For all SHA-1 operations the digest's size is always 20 bytes. #define TPM_SHA256_DIGEST_SIZE 32 ///< For all SHA-256 operations the digest's size is always 32 bytes. +#define TPM_SHA384_DIGEST_SIZE 48 ///< For all SHA-384 operations the digest's size is always 48 bytes. #define TPM_CMD_HEADER_SIZE 10 ///< The size of a standard TPM command header is 10 bytes. #define TPM_CMD_SIZE_OFFSET 2 ///< The offset of a TPM command's size value is 2 bytes. #define HEX_BYTE_STRING_LENGTH 2 ///< A byte can be represented by two hexadecimal characters. @@ -142,13 +143,20 @@ { \ hash_algo = ALG_SHA256; \ } \ + else if (0 == strcasecmp(optarg, "sha384")) \ + { \ + hash_algo = ALG_SHA384; \ + } \ else \ { \ ret_val = ERR_BAD_CMD; \ fprintf(stderr, "Unknown option. Use '-h' for more information.\n"); \ break; \ } \ - optarg = argv[optind++]; \ + if (argc > optind) \ + { \ + optarg = argv[optind++]; \ + } \ } \ } \ else \ @@ -164,6 +172,7 @@ typedef enum hash_algo_enum ALG_NULL, ALG_SHA1, ALG_SHA256, + ALG_SHA384, } hash_algo_enum; //-------------"Methods"------------- @@ -215,7 +224,8 @@ static int int_to_bytearray(uint64_t input, uint32_t input_size, uint8_t *output * @param [in] *pcr_digest_str User input string of value to extend the selected PCR with. * @param [out] *pcr_cmd_buf Return buffer for the complete command. Must be allocated by caller. * @param [in] *pcr_cmd_buf_size Size of memory allocated at pcr_cmd_buf in bytes. - * @param [in] hash_algo Set to ALG_SHA1 for extending with SHA-1 and to ALG_SHA256 for SHA-256. + * @param [in] hash_algo Set to ALG_SHA1 for extending with SHA-1, + ALG_SHA256 for SHA-256, and ALG_SHA384 for SHA-384. * @return One of the listed return codes. * @retval EINVAL In case of a NULL pointer or an invalid option. * @retval EXIT_SUCCESS In case of success. @@ -225,11 +235,24 @@ static int int_to_bytearray(uint64_t input, uint32_t input_size, uint8_t *output */ static int pcr_extend(char *pcr_index_str, char *pcr_digest_str, uint8_t *pcr_cmd_buf, size_t pcr_cmd_buf_size, hash_algo_enum hash_algo); +/** + * @brief Create the PCR_Allocate command. + * @param [out] *pcr_cmd_buf Return buffer for the complete command. + * @param [in] hash_algo Set to ALG_SHA1 to allocate SHA-1, + ALG_SHA256 for SHA-256, and ALG_SHA384 for SHA-384. + * @return One of the listed return codes. + * @retval EINVAL In case of a NULL pointer or an invalid option. + * @retval EXIT_SUCCESS In case of success. + * @date 2022/05/09 + */ +static int pcr_allocate(uint8_t *pcr_cmd_buf, hash_algo_enum hash_algo); + /** * @brief Create the PCR_Read command. * @param [in] *pcr_index_str User input string for PCR index. * @param [out] *pcr_cmd_buf Return buffer for the complete command. - * @param [in] hash_algo Set to ALG_SHA1 for reading with SHA-1 and to ALG_SHA256 for SHA-256. + * @param [in] hash_algo Set to ALG_SHA1 for reading with SHA-1, + ALG_SHA256 for SHA-256, and ALG_SHA384 for SHA-384. * @return One of the listed return codes. * @retval EINVAL In case of a NULL pointer or an invalid option. * @retval EXIT_SUCCESS In case of success. @@ -355,7 +378,8 @@ static int get_random(char *data_length_string, uint8_t *response_buf); /** * @brief Create the simple hash command. * @param [in] *data_string User input string of data to be hashed. - * @param [in] hash_algo Set to ALG_SHA1 for hashing with SHA-1 and to ALG_SHA256 for SHA-256. + * @param [in] hash_algo Set to ALG_SHA1 for hashing with SHA-1, + ALG_SHA256 for SHA-256, and ALG_SHA384 for SHA-384. * @param [out] *hash_cmd_buf Return buffer for the complete command. * @param [in] hash_cmd_buf_size Return buffer size. * @return One of the listed return codes. @@ -370,7 +394,8 @@ static int create_hash(char *data_string, hash_algo_enum hash_algo, uint8_t *has /** * @brief Create and transmit a sequence of TPM commands for hashing larger amounts of data. * @param [in] *data_string User input string of data to be hashed. - * @param [in] hash_algo Set to ALG_SHA1 for hashing with SHA-1 and to ALG_SHA256 for SHA-256. + * @param [in] hash_algo Set to ALG_SHA1 for hashing with SHA-1, + ALG_SHA256 for SHA-256, and ALG_SHA384 for SHA-384. * @param [out] *tpm_response_buf TPM response. * @param [out] *tpm_response_buf_size Size of tpm_response_buf. * @return One of the listed return codes or the error code stored in the global errno system variable. @@ -538,11 +563,37 @@ static const uint8_t sha256_alg[] = { 0x00, 0x0B // command for sha256 alg }; +static const uint8_t sha384_alg[] = { + 0x00, 0x0C // command for sha384 alg +}; + static const uint8_t tpm_cc_hash_hierarchy[] = { 0x40, 0x00, 0x00, 0x07 // hierarchy of the ticket (TPM_RH_NULL) }; //PCR_Command +static const uint8_t tpm2_pcr_allocate[] = { + 0x80, 0x02, // TPM_ST_SESSIONS + 0x00, 0x00, 0x00, 0x31, // commandSize + 0x00, 0x00, 0x01, 0x2B, // TPM_CC_PCR_Allocate + 0x40, 0x00, 0x00, 0x0C, // TPM_RH_PLATFORM + 0x00, 0x00, // authSize (NULL Password) + // null (indicate a NULL Password) + 0x00, 0x09, // authSize (password authorization session) + 0x40, 0x00, 0x00, 0x09, // TPM_RS_PW (indicate a password authorization session) + 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, // count (TPML_PCR_SELECTION) + 0x00, 0x04, // hash (TPMS_PCR_SELECTION; SHA-1) + 0x03, // sizeofSelect (TPMS_PCR_SELECTION) + 0x00, 0x00, 0x00, // pcrSelect (TPMS_PCR_SELECTION; will be set later) + 0x00, 0x0B, // hash (TPMS_PCR_SELECTION; SHA-256) + 0x03, // sizeofSelect (TPMS_PCR_SELECTION) + 0x00, 0x00, 0x00, // pcrSelect (TPMS_PCR_SELECTION; will be set later) + 0x00, 0x0C, // hash (TPMS_PCR_SELECTION; SHA-384) + 0x03, // sizeofSelect (TPMS_PCR_SELECTION) + 0x00, 0x00, 0x00 // pcrSelect (TPMS_PCR_SELECTION; will be set later) +}; + static const uint8_t tpm2_pcr_read[] = { 0x80, 0x01, // TPM_ST_NO_SESSIONS 0x00, 0x00, 0x00, 0x14, // commandSize