tpm2-software/tpm2-tss

Is there a good method to delete or disable algorithms?

Closed this issue ยท 7 comments

I want to disable or remove the RSA algorithm in TSS, but there are too many files related to RSA, and manually commenting out each one is too cumbersome. Is there a good method to delete or disable algorithms?

Short answer: no, there is no easy/convenient way.

Long answer: it depends on what you want to achieve. I will assume that you want to remove RSA functionally, but don't care about code size. It's actually quite complex because there is no singular place where RSA (or algorithms in general) are managed/controlled.

You could try to control the key creation functions. That is, for a handful of TPM commands, you unmarshal e.g. the publicArea and verify that the .type member is not RSA. I think the most important contenders are CreatePrimary, Create, CreateLoaded, LoadExternal, Import (but there might be more). If you forget any function that is able to introduce an RSA key into the TPM, you have not removed RSA. If there is already a RSA key in the TPM, you also didn't remove RSA. Keep in mind that parameter encryption is a thing and that there are multiple library levels: SAPI, ESAPI and FAPI.

A more low-level and radical way would be thin out marshaling and simply remove mashalling for types with RSA in the name. This would surely break things higher up and result in pretty nasty errors (and potentially crashes), but it's also more foolproof. Again, RSA might sneak in via parameter encryption and blob types like TPM2B_PUBLIC, so make sure to have a look at those.

See:

grep -rne 'RSA' --include='*.c' src/tss2-mu

I found some code in AlgorithmCap.c in IBM TPM2 provided by Microsoft

#include "Tpm.h"
typedef struct
{
    TPM_ALG_ID          algID;
    TPMA_ALGORITHM      attributes;
} ALGORITHM;
static const ALGORITHM    s_algorithms[] =
    {
	// The entries in this table need to be in ascending order but the table doesn't
	// need to be full (gaps are allowed). One day, a tool might exist to fill in the
	// table from the TPM_ALG description
#if ALG_RSA
	//{TPM_ALG_RSA,           TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
#endif
#if ALG_TDES
	{TPM_ALG_TDES,          TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
#endif
#if ALG_SHA1
	//{TPM_ALG_SHA1,          TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
#endif
	//{TPM_ALG_HMAC,          TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 1, 0, 0, 0)},
#if ALG_AES
	//{TPM_ALG_AES,           TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
#endif
......

I found that by commenting the tpm2_getcap algorithms command to find out the algorithm supported by the TPM, the corresponding encryption algorithm in the next tpm2_getcap algorithms will disappear, and the tpm2_getcap algorithms query is the encryption algorithm supported by the TPM, is it possible to make the TPM not support the RSA encryption algorithm in this way? I don't know if my understanding is correct, can you give me a judgment?

Good idea, but I suspect that will not work. Applications will expect RSA to be present because it is a mandatory algorithms according to the PCClient Spec:

https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p05p_r14_pub.pdf#%5B%7B%22num%22%3A69%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C33%2C533%2C0%5D

Of course you might want to "remove" the RSA algorithm id when an application queries for it. However, you should not trust that an application will query for it in the first place.

"So what is the purpose of this masking? Does it simply hide the content I masked when calling tpm2_getcap algorithms, or can those masked algorithms still be called when the user actively invokes them?"

My business is very simple, I just don't want users to call some encryption algorithms. Can you give me some suggestions in this regard? For example, I just want users to encrypt with the few encryption algorithms I want

So what is the purpose of this masking

The general thought is of course that applications can query which algorithms supported. But firstly, the TPM reports those, so you would need to manipulate those as a man in the middle. And more importantly, even if RSA is not listed there (either because it was actually not supported or because you manipulate the traffic), most applications will not care.

[...] or can those masked algorithms still be called when the user actively invokes them?"

They can and most probably will continue to try using RSA. Again, a PCClient compliant TPM must support RSA.

My business is very simple

Yes, but the solution to your problem is not.

You should reconsider if you want to remove RSA in the first place. Your users will expect it to be there and probably curse if it is not. Btw: the reason why RSA is mandatory is because it is a well-established and secure algorithm.

I gave you two approaches already: firstly trying to return an error if someone wants to create/load an RSA key or alternatively remove RSA types/marshalling alltogether from the TSS. It's going to be a lot of work, though. The TSS is not built for your use-case.

Also, please remember, the rsa and ecc algorithms are often carried around in union data types.
If you remove the rsa part, then the data type size will change.
This would not only be a break in API but also in ABI.

Thus, programs compiled against an rsa-enabled tpm2-tss would not run correctly with an rsa-disabled tpm2-tss.

Thus, we cannot remove it. Only way would be to add safeguards. We have this for SHA1, which is considered weak (as a configure switch). There is no plan to do it for rsa though.