Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encryption function random parameters are set at program init [TOB-ETHSTAKER-6] #238

Closed
remyroy opened this issue Nov 26, 2024 · 3 comments

Comments

@remyroy
Copy link
Member

remyroy commented Nov 26, 2024

Reported by Trail of Bits from their EthStaker Deposit CLI Security Assessment DRAFT report presented on October 8 2024. The description was updated on November 14 2024.

Description

The kdf_salt and aes_iv default parameters of the encrypt method are chosen at program initialization, rather than when the function is called. This means that duplicate calls to the function will produce the same kdf_salt and aes_iv values unless they are manually specified in the function call. This means, for example, that a call to new-mnemonic will produce multiple keystores with the same IV and salt values. This seriously weakens the encryption strength of these keystore files.

@classmethod
def encrypt(cls, *, secret: bytes, password: str, path: str = '',
            kdf_salt: bytes = randbits(256).to_bytes(32, 'big'),
            aes_iv: bytes = randbits(128).to_bytes(16, 'big')) -> 'Keystore':
    """
    Encrypt a secret (BLS SK) as an EIP 2335 Keystore.
    """
    keystore = cls()
    keystore.uuid = str(uuid4())
    keystore.crypto.kdf.params['salt'] = kdf_salt
    decryption_key = keystore.kdf(
        password=cls._process_password(password),
        **keystore.crypto.kdf.params
    )
    keystore.crypto.cipher.params['iv'] = aes_iv
    cipher = AES_128_CTR(key=decryption_key[:16], **keystore.crypto.cipher.params)
    keystore.crypto.cipher.message = cipher.encrypt(secret)
    keystore.crypto.checksum.message = SHA256(decryption_key[16:32] + keystore.crypto.cipher.message)
    keystore.pubkey = bls.SkToPk(int.from_bytes(secret, 'big')).hex()
    keystore.path = path
    return keystore

Recommendations

Short term, set these default parameter values to None. Add if statements in the function body to check if the value is None, and if so, assign a random value.

@remyroy
Copy link
Member Author

remyroy commented Nov 26, 2024

Fixed with private fork and this commit: 6a47170

@remyroy remyroy closed this as completed Nov 26, 2024
@jmcph4
Copy link

jmcph4 commented Nov 27, 2024

Reported by Trail of Bits from their EthStaker Deposit CLI Security Assessment DRAFT report presented on October 8 2024

Is this document public yet and if not is there intent to publish?

@remyroy
Copy link
Member Author

remyroy commented Nov 28, 2024

Is this document public yet and if not is there intent to publish?

The document will be published once the security assessment is completed in a few days. A link to the document will be added in the README.md file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants