Nikos Mavrogiannopoulos wrote: > > This sounds pretty awkward decision because HMAC per record is full > (e.g. 160-bits on SHA-1), but the MAC on the handshake message > "signature" is truncated to 96-bits. Why wasn't the record MAC > truncated as well? In any case saving few bytes per handshake > is much less of value than saving few bytes per record. Was > there any other rationale for truncation? Are you wondering why the HMAC on the TLS data records is is sent in its full beauty, while the TLS Finished.verify_data is a truncated output of the PRF (which in the abstract definintion uses HMAC as the outermost function, but in the case of TLSv1.0 is actually the XOR of two different HMACs over half the secret). The reason might be about the "secret" input to the HMAC, which in case of the TLS data records is a derived traffic key, while in case of the Finished.verify_data, is the "master secret" of the session. That was, what I assume, the fear, based on the second part of this message from Dan Simon http://lists.w3.org/Archives/Public/ietf-tls/1996OctDec/0224.html and the second part of this message from Hugo Krawczyk http://lists.w3.org/Archives/Public/ietf-tls/1996OctDec/0231.html Since the TLSv1.0 finished message was defined based on the output of the TLS PRF (a function with indefinite output length), defining a truncation was inevitable. :) A Finished message of 20 bytes size would have required A(1) for SHA-1 and A(2) for MD5, a 16 bytes size would only have required A(1) from both, but truncated the P_SHA1() output by 32 bits while leaving the P_MD5() output in full. For 12 bytes size, both P_SHA1() and P_MD5() output is truncated (by 64 and 32 bits respectively), while still remaining in the "safe truncation" area of "no less than half the output size of the underlying hash function" (rfc-2104, section-5) for both MD5 and SHA-1. Recall how the TLS PRF is defined in TLSv1.0 (rfc-2246): http://tools.ietf.org/html/rfc2246#page-12 first as a generic TLS PRF: P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + HMAC_hash(secret, A(2) + seed) + HMAC_hash(secret, A(3) + seed) + ... Where + indicates concatenation. A() is defined as: A(0) = seed A(i) = HMAC_hash(secret, A(i-1)) Then as a specific PRF for use with TLSv1.0 (reused by TLSv1.1) http://tools.ietf.org/html/rfc2246#page-12 S1 and S2 are the two halves of the secret and each is the same length. S1 is taken from the first half of the secret, S2 from the second half. Their length is created by rounding up the length of the overall secret divided by two; thus, if the original secret is an odd number of bytes long, the last byte of S1 will be the same as the first byte of S2. L_S = length in bytes of secret; L_S1 = L_S2 = ceil(L_S / 2); The secret is partitioned into two halves (with the possibility of one shared byte) as described above, S1 taking the first L_S1 bytes and S2 the last L_S2 bytes. The [TLSv1.0] PRF is then defined as the result of mixing the two pseudorandom streams by exclusive-or'ing them together. PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed); and how it is used in the TLSv1.0 Finished message: http://tools.ietf.org/html/rfc2246#page-46 struct { opaque verify_data[12]; } Finished; verify_data PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages)) [0..11]; -Martin _______________________________________________ Ietf mailing list Ietf@xxxxxxxx https://www.ietf.org/mailman/listinfo/ietf