Last Call Review of draft-zimmermann-avt-zrtp-
I have reviewed this document as part of the security directorate's
ongoing effort to review all IETF documents being processed by the
IESG. These comments were written primarily for the benefit of the
security area directors. Document editors and WG chairs should treat
these comments just like any other last call comments.
This draft defines a Diffie-Hellman based key exchange to generate
a session key to use with SRTP. It prevents a man-in-the-middle attack
against the Diffie-Hellman key exchange without requiring traditional
authentication. It does not require use of a PKI.
There are three things I think the ADs should take a look at: having
the protocol resist a small sub-group attack, use of the "auxsecret", and
the hashing mishmash. All are described below.
The MitM attack is thwarted by using a short authentication string (SAS)
that is presented to users on each side of the ZRTP exchange to be read
and verbally compared.
An immediate concern with such an approach is that it might enable a
small sub-group attack against the Diffie-Hellman exchange that would
be undetectable by verification of the SAS. An attacker could take an
element of small order, f, and create pvi' = pvi^f modp and
pvr' = pvr^f mod p and the shared secret, DHResult', would be confined to
the small group. The SAS would verbally verify and the two parties would
continue unaware of the attack. But the DH shared secret is subsequently
used (indirectly) in a hash which fixes it and exposes it to the MitM,
which can run through the values in the small sub-group to determine
DHResult' and then attack the SRTP connection.
The draft specifies support for a Diffie-Hellman domain parameter set
using a safe prime (from RFC 3526) which would prevent such an attack
but it seems that the protocol should be secure in and of itself and not
rely on external safeguards. I recommend sections 18.104.22.168 and 22.214.171.124
define an additional processing step to ensure pvi and pvr are not in
a small sub-group. For a safe-prime this can be viewed as a "belt and
suspenders" approach, but I don't see why ZRTP couldn't be used in the
future with other domain parameter sets which may not be based on safe
primes and therefore such a check would be vital.
The draft has a clever shared secret state matching algorithm to use
secrets from a cache of state associated with a peer. One of these is
called "auxsecret", as described in section 4.3.1:
"the auxsecret shared secret may be manually provisioned in other
application-specific ways that are out-of-band, such as computed from
a hashed pass phrase by prior agreement between the two parties. Or
it may be a family key used by an institution that the two parties both
If one does not have an "auxsecret" configured a random value is used in
its field during the ZRTP exchange. If one does have an "auxsecret" though
it does not appear to change.
Traffic analysis, therefore, would tell an attacker whether an
"auxsecret" is being used or not. If one is, an off-line dictionary attack
might be possible if the "auxsecret" is being used per section 4.3.1 (if
it is a "family key used by an institution" then every member of the
institution would use the same "auxsecret" and that could also be easily
I recommend that the "auxsecret" be updated in the cache in section
4.6.1 so that it is different with a subsequent run of the protocol. If
that logistically isn't possible then perhaps hash rs1 or rs2 with it
in 4.3.1 to produce "auxsecretIDi" and "auxsecretIDr". Since there is a
matching algorithm for r1 and r2 then it might be necessary to have two
"auxsecretIDi" and two "auxsecretIDr", one hashed with r1 and one with
r2. The cost is a little extra space but the benefit seems worth it.
There is a confusing mix of hashing, HMACing, and KDFing. In section
126.96.36.199 a secret value s0 is derived using the KDF technique from
SP800-56A, which is not of the keyed variety, it just uses a hash function
in counter mode. But if a preshared key is used then section 188.8.131.52
derives s0 with an HMAC-based KDF based on SP800-108. This value, s0,
is then used to derive the SRTP session key, the SAS, and various
encryption and integrity protection keys using the HMAC-based, SP800-108
version of a KDF. When a session is terminated all keys are destroyed
except ZRTPSess which is replace by a hash of itself. But it was
originally derived by a keyed KDF. This seems unnecessarily complex and
would make this protocol very difficult to analyze.
There has been much discussion on the CFRG list about how the output
of a hash function is too structured to use the key to an HMAC (see
Hugo Krawczyk's HKDF draft). Whether the SP800-56A hash-style KDF is
good or whether the SP800-108 keyed HMAC-style KDF is good is a debate
for another forum but I think this draft should choose one and stick to
it. Keys derived from a hash function should not be used as keys to
an HMAC and keys derived from an HMAC-based KDF should not be replaced
with a simple hash of themselves.
* sections 184.108.40.206 and 220.127.116.11 mention the "width of the DH prime".
How about "bit-length of the DH prime" instead?
* section 18.104.22.168 mentions ECDH but then goes on to specify the
finite field (MODP) version of the exchange. I suggest adding an
example of ECDH in 22.214.171.124 and 126.96.36.199.