tpm2-software / tpm2-pytss

Python bindings for TSS
https://tpm2-pytss.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
63 stars 45 forks source link

ESAPI.hash would fails on too big input #239

Open gaetanww opened 2 years ago

gaetanww commented 2 years ago

If data is bigger than lib.MAX_BUFFER_SIZE the TPM should send error. Is it worth catching it before in python code?

Might be worth considering a higher level hash function taht handles the hash sequences if data input is too big.

For example:

def hash_all(
        self,
        data: Union[TPM2B_MAX_DIGEST_BUFFER, bytes, str],
        hash_alg: TPM2_ALG,
        hierarchy: ESYS_TR = ESYS_TR.OWNER,
        session1: ESYS_TR = ESYS_TR.NONE,
        session2: ESYS_TR = ESYS_TR.NONE,
        session3: ESYS_TR = ESYS_TR.NONE,
    ) -> Tuple[TPM2B_DIGEST, TPMT_TK_HASHCHECK]:
        data = data.encode() if isinstance(data, str) else data
        maxi = lib.MAX_BUFFER_SIZE
        # data is small enough
        if isinstance(data, TPM2B_MAX_BUFFER) or data.len() <= maxi:
            return self.hash(data, hash_alg, hierarchy, session1, session2, session3)
        handle = self.hash_sequence_start(
            b'', hash_alg, session1, session2, session3)

        # data is too big
        for chunk in [data[i:i+maxi] for i in range(0, len(data), maxi)]:
            self.sequence_update(handle, chunk, session1, session2, session3)
        return self.sequence_complete(handle, b'', hierarchy, session1, session2, session3)
whooo commented 2 years ago

Does it silently fail for you? or what happens?

gaetanww commented 2 years ago

No, my bad, it's caught by the TPM2B_MAX_BUFFER initializer:

initializer bytes is too long for 'uint8_t[1024]' (got 2048 characters)

However, do you think the ESAPI could benefit from that sort of abstracted hash function? I also have an abstracted signing function that handles generates and use a tpm hash ticket for restricted signing keys.

whooo commented 2 years ago

Sorry, I misread.

The bigger question is how much extra functionality we want to add I guess. And adding something that behaves like pythons hashlib might be better, so wrapping something around hash and HMAC sequences, so for example:

hashseq = ectx.hashseq(TPM2_ALG.SHA256, b"initial data")
hashseq.update(b"more data")
digest, ticket = hashseq.digest()
williamcroberts commented 2 years ago

No, it's not good to handle it in the python code, because policies generated may need to know how many commands were executed. So we don't want to automate this in the direct calls. However, we could have an option to the call to keep sending it if its set and default it to false.