Как продолжать подписывать данные с помощью TPM, не получая ответа на блокировку?

Я использую TSS.net для запуска некоторых тестов на симуляторе Microsoft TPM. Я могу успешно создать ключ подписи, но могу подписать этим ключом только дважды. При третьей попытке подписать я получаю ответ Lockout.

Как продолжить подписывать данные этим ключом, не получая ответа Lockout?

Шаги воспроизведения

После запуска симулятора я запускаю этот метод один раз:

public void ReproStep1()
{
    Tpm2Device tpmDevice = new TcpTpmDevice("127.0.0.1", 2321);

    tpmDevice.Connect();

    var tpm = new Tpm2(tpmDevice);

    tpmDevice.PowerCycle();
    tpm.Startup(Su.Clear);

    var ownerAuth = new AuthValue();

    var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm
        ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key
        ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable 
        ObjectAttr.SensitiveDataOrigin,
        null, // No policy
        new RsaParms(new SymDefObject(),
            new SchemeRsassa(TpmAlgId.Sha256), 2048, 0),
        new Tpm2bPublicKeyRsa());

    var keyAuth = new byte[] {1, 2, 3};

    TpmPublic keyPublic;
    CreationData creationData;
    TkCreation creationTicket;
    byte[] creationHash;

    TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
        TpmRh.Owner, // In the owner-hierarchy
        new SensitiveCreate(keyAuth, null), // With this auth-value
        keyTemplate, // Describes key
        null, // Extra data for creation ticket
        new PcrSelection[0], // Non-PCR-bound
        out keyPublic, // PubKey and attributes
        out creationData, out creationHash, out creationTicket); // Not used here

    Console.WriteLine("New public key\n" + keyPublic.ToString());

    TpmHandle persistentHandle = TpmHandle.Persistent(0x5000);

    //Get rid of the stored key (if there is one)
    tpm._AllowErrors().EvictControl(TpmRh.Owner, persistentHandle, persistentHandle);

    //Store the key in NV memory
    tpm.EvictControl(TpmRh.Owner, keyHandle, persistentHandle);
}

Затем я могу запустить следующий метод только дважды, прежде чем получить ответ Lockout от симулятора TPM:

public void ReproStep2()
{
    Tpm2Device tpmDevice = new TcpTpmDevice("127.0.0.1", 2321);

    tpmDevice.Connect();

    var tpm = new Tpm2(tpmDevice);

    var keyAuth = new byte[] {1, 2, 3};

    tpmDevice.PowerCycle();
    tpm.Startup(Su.Clear); //Is this appropriate?

    byte[] message = Encoding.Unicode.GetBytes("ABC");
    TpmHash digestToSign = TpmHash.FromData(TpmAlgId.Sha256, message);

    var persistentHandle = TpmHandle.Persistent(0x5000);

    var signature = tpm[keyAuth].Sign(persistentHandle, // Handle of signing key
        digestToSign, // Data to sign
        null, // Use key's scheme
        TpmHashCheck.Null()) as SignatureRsassa;

    Console.WriteLine("Signature: " + BitConverter.ToString(signature.sig));

    tpm.Dispose();
}

person RQDQ    schedule 04.06.2019    source источник


Ответы (1)


Ах. Оказывается, что неполное отключение TPM имеет последствия для механизма предотвращения атаки по словарю. Добавив это в конце шага 2, я смог вызывать tpm.Sign(...) много раз:

tpm.Shutdown(Su.Clear);
person RQDQ    schedule 04.06.2019