Skip to content

Side channels and padding oracle #9

@randombit

Description

@randombit

Apologies if these are already known to you, but I didn't see anything in the docs or comments about this.

In (

public func modular_pow<T : BinaryInteger>(_ base : T, _ exponent : T, _ mod : T) -> T
) you implement modular exponentiation using square-and-multiply. However this leaks the bits of the exponent (which in RSA and DH are secrets) to a timing or side channel attack. Also the reductions are implemented using Knuth's Algorithm D, which probably leak information about the inputs.

In ECDSA signature https://github.com/nsc/SwiftTLS/blob/master/SwiftTLS/Sources/Crypto/ECDSA.swift#L72 you must invert the k nonce modulo the group order during ECDSA signature. This is done using extended Euclidean algorithm (

public func modular_inverse<T : BinaryInteger>(_ x : T, _ y : T, mod : T) -> T
) which is known to leak information due to input dependent branches. The most common solution to this is to use Fermat's little theorem to compute the inverse (for any prime p and any x < p, x^{p-2} mod p == x^-1 mod p)

Decoding for PKCS1v1.5 ciphertexts exits early if the first bytes of padding are incorrect.

if paddedData[0] != 0 || paddedData[1] != 2 {
which creates a padding oracle.

Similarly, when the PKCS1v1.5 ciphertext is decrypted, the server returns an error immediately

preMasterSecret = try rsa.decrypt(encryptedPreMasterSecret)
which creates a padding oracle that doesn't even require a side channel to execute since an attacker knows the PKCSv1.5 ciphertext padding was valid iff the server does not abort the connection. The correct way to handle this is to first generate a random 48 byte premaster, then RSA decrypt, then if the RSA ciphertext was invalid carry on using the randomized premaster. Then there is no oracle for an attacker to use.

HTH

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions