< GitHub73> [bitcoin] accraze opened pull request #7747: [docs] added depends cross compile info (master...depends-build-docs) https://github.com/bitcoin/bitcoin/pull/7747
< jonasschnelli> gmaxwell: good point with including the ciphersuite into the KDF to avoid a weak-ciphersuite-attack. Haven't thought about that!
< jonasschnelli> gmaxwell: you said "Personally I'd just suggest dropping the negoation;". I guess you mean only the ciphersuite-negotiation? Not the whole ECDH?
< gmaxwell> nor did the authors of dozens of other protocols that didn't. I am not so smart, lots of people have failed here before, and I'm only repeating their mistakes.
< gmaxwell> jonasschnelli: right.
< jonasschnelli> gmaxwell: you said: " (also, you're going to need a 256 bit session ID for later auth, and two 512 bit keys for the authenticated encryption);" I don't understand that. I'm only aware of two 256bit keys for both directions ECDH.
< jonasschnelli> I don't see a need for a auth session id.
< jonasschnelli> Because I assume the encryption negotiation followed by a auth identity pubkey check will keep the authentication withing the encryption session?
< sipa> jonasschnelli: you'll need a session id to sign when doing identity checking
< gmaxwell> the authentication must bind the session or varrious kinds of MITM identity proxying attacks turn up.
< sipa> sure, you could sign one of the encryption keys or the ECDH output directly, but it's generally better to separate them
< jonasschnelli> sipa: Ah. So during the encryption negotiation both side produce a 256bit session id and the other party needs to sign that (together with the pubkey) to ensure a link between the auth and the enc?
< sipa> jonasschnelli: auth is an overloaded term; do you mean MAC or identity verification?
< jonasschnelli> identity verification. sry.
< gmaxwell> jonasschnelli: right thats what the session ID is for.
< jonasschnelli> So the session ID can be transported unencrypted during ECDH nego.?
< jonasschnelli> no... wait.
< gmaxwell> the session ID is just a result of the ECDH.
< sipa> jonasschnelli: the session ID never ever transported
< sipa> not encrypted, not unencrypted
< jonasschnelli> hmm...
< gmaxwell> The ECDH runs, and the result is a session ID and a set of keys for the encryption/mac.
< gmaxwell> And the session ID can (optionally) be authenticated.
< jonasschnelli> so the ECDH calculated point could be the session ID, then run a KDF, get the sym. cipher key?
< sipa> jonasschnelli: ECDH output is used as seed for a PRNG; from that PRNG you read session id, IV, encryption keys, ... whatever you need
< jonasschnelli> And to verify identity (identity auth) the requesting peer needs to sign the ECDH calculated point (or a PRNG result from that seed) with his pre-shared idendity pubkey?
< sipa> yes
< gmaxwell> you never use the ECDH value directly. They'd sign the session ID. (a PRNG result)
< jonasschnelli> Okay. Got it!
< jonasschnelli> Wasn't aware of the possibility to use the ECDH point as seed.
< gmaxwell> The PRNG input should include the ECDH along with all the 'session context' e.g. any paramter negoiation that was sent.
< gmaxwell> (I recommend including one of the public keys in the KDF, to avoid the gratitious loss of entropy; but this is a minor thing)
< jonasschnelli> And probably the ciphersuite (if we keep this).
< sipa> jonasschnelli: i think it makes sense to have ciphersuite versions
< sipa> and just have one currently
< jonasschnelli> Yes. I also reserved it for future changes.
< sipa> negotiation is hard, and general trend is moving away from it
< sipa> instead just have version numbers of the protocol, and each version has one fixed set of ciphers
< gmaxwell> sipa: I'm not sure this is better though! consider, if you merely do that, how do you guard against downgrade attacks-- I guess only by supporting just a single version?
< gmaxwell> otherwise, what you need to do is have the protocol commit to whatever versions were offered.
< jonasschnelli> Okay. I'll update the BIP and write more specification about the negotiation, session ID, KDF
< jonasschnelli> pbkdf2?
< sipa> for KDF you could use rfc6979 (slow!), just a simple SHA256 of ECDH together with a counter, chacha20, or maybe SHAKE (sha3 variant with arbitrary length output)
< sipa> i like sha3 because it has such large state, so you can put a lot of context in without limiting entropy
< sipa> the pb in pbkdf stands for password based :)
< gmaxwell> jonasschnelli: another thing your spec is missing is rekeying. The chacha20/poly must be rekeyed periodically.
< jonasschnelli> ^^
< gmaxwell> pbkdf2 is intentionally slow, not a requirement here.
< sipa> gmaxwell: my assumption was that you'd do another encinit session occasionally within the encrypted channel
< gmaxwell> I don't know if you noticed but I suggested that authentication could be done in a way combined with rekeying which would have some very nice properties.
< jonasschnelli> So... rekey = re-negotiate the whole ECDH secret every x minutes/hours?
< sipa> every gigabyte
< sipa> though having time limits is good too
< jonasschnelli> an right. would something speak against sipas idea of re-key within the current enc session?
< jonasschnelli> Would probably make the implementation simpler.
< jonasschnelli> (different message formats)
< sipa> jonasschnelli: gmaxwell's identity check idea would also automatically result in a rekey
< gmaxwell> I suggested that to auth, the auth requester send X H(sessionid,server_pubkey), and if the server knows the pubkey for X, she responds with a message saying that she is changing her encryption key, and changes to H(old_encryption_key, server_pubkey) as the new one.. and in the newly encrypted segment she tranmits the signature that proves she knows the secret.
< gmaxwell> This has a nice properity that if the server pubkey is kept secret; the confidentiality of past communications is preserved even if ECC is broken.
< gmaxwell> And it also proves that the servers identity key has remained online, if that procedure is used for each rekeying in the future.
< jonasschnelli> gmaxwell: H(old_encryption_key, server_pubkey) <--- "old_encryption_key" would be the KDF derived symmetric key?
< gmaxwell> Yes.
< jonasschnelli> And... right. That would be required "in both directions"...
< gmaxwell> My thought on that is that even when you don't have an identity you're expecting everyone could just support using the generator (private key 1).. so even without a known identity the same protocol would always be used... good for QA and for traffic analysis resistance.
< jonasschnelli> gmaxwell: and a re-keying without identity auth? new ECDH nego., new session id, but sym. key could be H(old_encryption_key, new_encryption_key)?
< gmaxwell> yes it could be there is no need to redo ECDH, just a waste of CPU time.
< jonasschnelli> but how would you create a new shared secret? Using a counter on both sides?
< gmaxwell> H(old_key) is sufficient.
< jonasschnelli> ah.. okay. I see. Just hash the hash, ...
< gmaxwell> for forward security reasons you don't want to be forced to keep the old keys around... they should be destroyed as soon as they're not in use.
< jonasschnelli> How would the other peer know when it is time to re-key. Probably requested by the responding peer with a new message type.
< jonasschnelli> s/./?
< gmaxwell> by sending a message in the channel, "everything that follows will be the next key"
< jonasschnelli> right. That makes sense.
< gmaxwell> and my earlier suggestion was to make the auth do this so that the pubkey could be used as a symmetric secret in the rekeying.
< jonasschnelli> And I suppose the identity auth also needs a timeout (probably time instead of consumed bandwith).
< gmaxwell> forward secrecy also wants a timeout, so something like 1 hour or 1GB whichever comes first.
< gmaxwell> not that our need for forward secrecy is so great, but if we're going to do something might as well do it right.
< jonasschnelli> Okay... Let me update the BIP. I think this iterative improvement approach might lead to something we can use (at least use it for later improvments).
< GitHub145> [bitcoin] mruddy opened pull request #7748: test and regtest mempool: not require standard, non-mandatory, input script verification flags (master...nonstandard-sighash) https://github.com/bitcoin/bitcoin/pull/7748
< GitHub135> [bitcoin] sipa opened pull request #7749: Enforce expected outbound services (master...checkservices) https://github.com/bitcoin/bitcoin/pull/7749