TLS 1.0 - Calculating the Completed MAC Address

I am having trouble calculating the MAC of the finished message. RFC gives the formula

HMAC_hash (MAC_write_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment));

But tlsCompressed (tlsplaintext in this case, because compression is not used) does not contain version information: (hex dump)

14 00 00 0c 2c 93 e6 c5 d1 cb 44 12 bd a0 f9 2d

the first byte is tlsplaintext.type followed by the length of uint24.
Full message with MAC addition and pre-encryption

1400000c2c93e6c5d1cb4412bda0f92dbc175a02daab04c6096da8d4736e7c3d251381b10b

I tried to calculate hmac with the following parameters (corresponding to rfc), but it does not work:

uint64 seq_num  
uint8  tlsplaintext.type  
uint8  tlsplaintext.version_major  
uint8  tlscompressed.version_minor  
uint16 tlsplaintext.length  
opaque tlsplaintext.fragment

uint24 . .
hmac_hash() , . verify_data . , , 0.
, MAC ?

+4
1

Forge ( JS TLS 1.0):

HMAC:

var hmac_sha1 = function(key, seqNum, record) {
    /* MAC is computed like so:
    HMAC_hash(
      key, seqNum +
        TLSCompressed.type +
        TLSCompressed.version +
        TLSCompressed.length +
        TLSCompressed.fragment)
    */
    var hmac = forge.hmac.create();
    hmac.start('SHA1', key);
    var b = forge.util.createBuffer();
    b.putInt32(seqNum[0]);
    b.putInt32(seqNum[1]);
    b.putByte(record.type);
    b.putByte(record.version.major);
    b.putByte(record.version.minor);
    b.putInt16(record.length);
    b.putBytes(record.fragment.bytes());
    hmac.update(b.getBytes());
    return hmac.digest().getBytes();
};

, :

tls.createFinished = function(c) {
    // generate verify_data
    var b = forge.util.createBuffer();
    b.putBuffer(c.session.md5.digest());
    b.putBuffer(c.session.sha1.digest());

    // TODO: determine prf function and verify length for TLS 1.2
    var client = (c.entity === tls.ConnectionEnd.client);
    var sp = c.session.sp;
    var vdl = 12;
    var prf = prf_TLS1;
    var label = client ? 'client finished' : 'server finished';
    b = prf(sp.master_secret, label, b.getBytes(), vdl);

    // build record fragment
    var rval = forge.util.createBuffer();
    rval.putByte(tls.HandshakeType.finished);
    rval.putInt24(b.length());
    rval.putBuffer(b);
    return rval;
};

. , , , :

 // rewind to get full bytes for message so it can be manually
 // digested below (special case for Finished messages because they
 // must be digested *after* handling as opposed to all others)

, - ?

1

, TLSPlainText. TLSPlainText "" TLS. "" "" , . :

struct {
    ContentType type;
    ProtocolVersion version;
    uint16 length;
    opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

. - . 22. :

struct {
    HandshakeType msg_type;
    uint24 length;
    body
} Handshake;

"" / , "". Finished (HandshakeType 20), :

struct {
    opaque verify_data[12];
} Finished;

Finished, Handshake, , , TLS- (TLSPlainText). / - :

struct {
    ContentType type=22;
    ProtocolVersion version=<major, minor>;
    uint16 length=<length of fragment>;
    opaque fragment=<struct {
        HandshakeType msg_type=20;
        uint24 length=<length of finished message>;
        body=<struct {
          opaque verify_data[12]>;
        } Finished>
    } Handshake>
} TLSPlainText;

. , ( ). . MAC, , . ( , -) . , , , , , .

, , MAC Finished, , TLSPlainText ( , ). TLSPlainText, , , . HMAC, , . HMAC ( 0) . , , HMAC, .

, , , , , .

+3

Source: https://habr.com/ru/post/1540125/


All Articles