};
/*
- * Comments used by the non-CUSE TPMs
+ * Commands used by the non-CUSE TPMs
+ *
+ * All messages container big-endian data.
+ *
+ * The return messages only contain the 'resp' part of the unions
+ * in the data structures above. Besides that the limits in the
+ * buffers above (ptm_hdata:u.req.data and ptm_get_state:u.resp.data
+ * and ptm_set_state:u.req.data) are 0xffffffff.
*/
enum {
CMD_GET_CAPABILITY = 1,
CMD_GET_TPMESTABLISHED,
CMD_SET_LOCALITY,
CMD_HASH_START,
- CMD_HASH_END = 8 ,
+ CMD_HASH_DATA,
+ CMD_HASH_END,
CMD_CANCEL_TPM_CMD,
- CMD_RESET_TPMESTABLISHED = 11,
+ CMD_STORE_VOLATILE,
+ CMD_RESET_TPMESTABLISHED,
CMD_STOP = 13,
CMD_GET_CONFIG,
};
+#include <stdio.h>
/*
* ctrlchannel.c -- control channel implementation
*
ptm_init *init_p;
ptm_reset_est *re;
ptm_getconfig *pgc;
+ ptm_hdata *data;
size_t out_len = 0;
TPM_RESULT res;
+ uint32_t remain;
if (fd < 0)
return -1;
PTM_CAP_GET_TPMESTABLISHED |
PTM_CAP_RESET_TPMESTABLISHED |
PTM_CAP_HASHING |
- PTM_CAP_CANCEL_TPM_CMD);
+ PTM_CAP_CANCEL_TPM_CMD |
+ PTM_CAP_STORE_VOLATILE);
out_len = sizeof(*ptm_caps);
break;
break;
+ case CMD_HASH_DATA:
+ if (!*tpm_running)
+ goto err_not_running;
+
+ data = (ptm_hdata *)&input.body;
+ remain = htobe32(data->u.req.length);
+ n -= sizeof(data->u.req.length);
+ /* n has the available number of bytes to hash */
+
+ while (true) {
+ res = TPM_IO_Hash_Data(data->u.req.data, n);
+ if (res)
+ break;
+ remain -= n;
+ if (!remain)
+ break;
+
+ n = read(fd, &data->u.req.data, sizeof(data->u.req.data));
+ if (n <= 0) {
+ res = TPM_IOERROR;
+ break;
+ }
+ }
+
+ data = (ptm_hdata *)&output.body;
+
+ data->u.resp.tpm_result = htobe32(res);
+ out_len = sizeof(data->u.resp.tpm_result);
+
+ break;
+
case CMD_HASH_END:
if (!*tpm_running)
goto err_not_running;
out_len = sizeof(ptm_res);
break;
+ case CMD_STORE_VOLATILE:
+ if (!*tpm_running)
+ goto err_not_running;
+
+ *res_p = htobe32(SWTPM_NVRAM_Store_Volatile());
+ out_len = sizeof(ptm_res);
+ break;
+
case CMD_GET_CONFIG:
pgc = (ptm_getconfig *)output.body;
default:
logprintf(STDERR_FILENO,
- "Error: Unknown command\n");
+ "Error: Unknown command: 0x%08x\n", be32toh(input.cmd));
*res_p = htobe32(TPM_BAD_ORDINAL);
out_len = sizeof(ptm_res);
sed -n '/^ /p' | \
tail -n1 > $RESP_PATH
res="$(cat $RESP_PATH)"
-exp=" 00 00 00 00 00 00 04 b7"
+exp=" 00 00 00 00 00 00 04 f7"
if [ "$res" != "$exp" ]; then
echo "Error: Unexpected response from CMD_GET_CAPABILITY:"
echo " actual : $res"
exit 1
fi
+# Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
+/bin/echo -en '\x00\x00\x00\x0a' >$CMD_PATH
+socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CLIENT:$SOCK_PATH 2>&1 | \
+ sed -n '/^ /p' | \
+ tail -n1 > $RESP_PATH
+res="$(cat $RESP_PATH)"
+exp=" 00 00 00 00"
+if [ "$res" != "$exp" ]; then
+ echo "Error: Unexpected response from CMD_STORE_VOLATILE:"
+ echo " actual : $res"
+ echo " expected: $exp"
+ exit 1
+fi
+
+if [ ! -r $TPMDIR/tpm-00.volatilestate ]; then
+ echo "Error: Socket TPM: Did not write volatile state file"
+ exit 1
+fi
+
# Send stop command to the TPM: CMD_STOP = 00 00 00 0d
echo -en '\x00\x00\x00\x0d' > $CMD_PATH
socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CONNECT:$SOCK_PATH 2>&1 | \
sed -n '/^ /p' | \
tail -n1 > $RESP_PATH
res="$(cat $RESP_PATH)"
-exp=" 00 00 00 00 00 00 04 b7"
+exp=" 00 00 00 00 00 00 04 f7"
if [ "$res" != "$exp" ]; then
echo "Error: Socket TPM: Unexpected response from CMD_GET_CAPABILITY:"
echo " actual : $res"
exit 1
fi
+# Save the volatile state: CMD_STORE_VOLATILE = 0x00 00 00 0a
+/bin/echo -en '\x00\x00\x00\x0a' >$CMD_PATH
+socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CLIENT:$SOCK_PATH 2>&1 | \
+ sed -n '/^ /p' | \
+ tail -n1 > $RESP_PATH
+res="$(cat $RESP_PATH)"
+exp=" 00 00 00 00"
+if [ "$res" != "$exp" ]; then
+ echo "Error: Socket TPM: Unexpected response from CMD_STORE_VOLATILE:"
+ echo " actual : $res"
+ echo " expected: $exp"
+ exit 1
+fi
+
+if [ ! -r $TPMDIR/tpm-00.volatilestate ]; then
+ echo "Error: Socket TPM: Did not write volatile state file"
+ exit 1
+fi
+
# 1. Send command to get TPM established flag: CMD_GET_TPMESTABLISHED = 00 00 00 04
echo -en '\x00\x00\x00\x04' > $CMD_PATH
cat $RESP_PATH
# 2. Send command to start HASH : CMD_HASH_START = 00 00 00 06
echo -en '\x00\x00\x00\x06' > $CMD_PATH
-cat $RESP_PATH
socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CONNECT:$SOCK_PATH 2>&1 | \
sed -n '/^ /p' | \
tail -n1 > $RESP_PATH
exit 1
fi
+# 2.1. Send command to hash data : CMD_HASH_DATA = 00 00 00 07 uint32(length) data
+# We send 0x100 null bytes
+echo -en '\x00\x00\x00\x07\x00\x00\x20\x00' > $CMD_PATH
+dd if=/dev/zero count=$((0x2000)) bs=1 >> $CMD_PATH 2>/dev/null
+socat -x -t10 FILE:$CMD_PATH,rdonly UNIX-CONNECT:$SOCK_PATH 2>&1 | \
+ sed -n '/^ /p' | \
+ tail -n1 > $RESP_PATH
+res="$(cat $RESP_PATH)"
+exp=" 00 00 00 00"
+if [ "$res" != "$exp" ]; then
+ echo "Error: Socket TPM: Unexpected response from sending CMD_HASH_DATA command:"
+ echo " actual : $res"
+ echo " expected: $exp"
+ exit 1
+fi
+
# 3. Send command to end HASH : CMD_HASH_END = 00 00 00 08
echo -en '\x00\x00\x00\x08' > $CMD_PATH
cat $RESP_PATH
exec 100<>/dev/tcp/localhost/65530
echo -en '\x00\xC1\x00\x00\x00\x0E\x00\x00\x00\x15\x00\x00\x00\x11' >&100
RES=$(cat <&100 | od -t x1 -A n | tr -d "\n")
-exp=' 00 c4 00 00 00 1e 00 00 00 00 31 a2 dc 4c 22 f9 c5 44 4a 41 62 5d 05 f9 58 98 e0 55 f7 50'
+exp=' 00 c4 00 00 00 1e 00 00 00 00 c4 e1 e1 c9 81 c0 cd b1 e0 43 df 97 20 72 f9 5d a9 ff 06 ff'
if [ "$RES" != "$exp" ]; then
echo "Error: (1) Did not get expected result from TPM_PCRRead(17)"
echo "expected: $exp"