Not exactly a direct answer, but the comment section is too limited, so...
I might be blind (a sleepless night can do that for you) but that document describes a situation where you don't want nor need a Diffie-Hellman key exchange. In fact, it doesn't add anything to the security of the whole thing.
If both sides already have a shared secret (password
in this case), and that secret is not known to the malicious adversary (Mallory in this case), then why would you go through all that trouble in the first place? After all, DHKE is used to share a secret over an insecure channel, if you have already done that you have no use for DHKE*. You can simply derive a symmetric key out of that secret and be quite confident that nobody can MITM you unless they get a hold of the said password
. In pseudo-code, a straight-forward example:
a:
password = 54321
kdfParams = [salt, iterations, other] // depends on the KDF, some or all may be random
secretKey = KDF(password, kdfParams)
data = ENCRYPT(secretKey, "Hello, Bob!")
a->b (data, kdfParams)
m:
b->m<-a (data, kdfParams)
// Doesn't know the password and have no use for the publically transmitted kdfParams
// Can derive the secretKey only through brute-force,
// so choose your KDF and password carefully
b:
b<-a (data, kdfParams)
password = 54321
secretKey = KDF(password, kdfParams)
data = DECRYPT(secretKey, data) // << "Hello, Bob!"
Works the other way around as well.
Of course, if Mallory somehow finds out the password
, the whole hell breaks loose, but the referenced document doesn't help with that either. If you are worried about forward and backward secrecy, you can use the secretKey
to HMAC the public part of the DHKE to thwart any MITM attacks and have a fresh sessionKey
for encryption each time.
To conclude, the explained 'method' is no explanation at all and the author either doesn't understand what DHKE is used for, or I need to get some sleep.
* in this particular example, CodesInChaos raises a valid point on general usefulness of DHKE.