0
$\begingroup$

I'm trying to decrypt a PCAP encrypted with TLS 1.2. I have the private key and Wireshark is able to decrypt the data so what I am doing should work but there is obviously something wrong. The cipher used is TLS_RSA_WITH_AES_256_GCM_SHA384 with no compression.

The first steps are to extract the random values from the client and server HELLOs.

client_rnd = extracted_from_client_hello()
server_rnd = extracted_from_server_hello()

client_server = client_rnd + server_rnd
server_client = server_rnd + client_rnd

My understanding of for TLS1.2 is to use SHA256 with the PRF to get a 48 byte master secret value.

master_secret = PRF("SHA256", "master secret", decrypted_pre_key, client_server, 48)

And then because the cipher is SHA384, use that during the key expansion.

params = PRF("SHA386", "key expansion", master_secret, server_client, 96)
//  0: client_key
// 32: server_key
// 64: client_nonce
// 68: server_nonce

And the resulting output gives us the needed keys and nonces.

I'm pretty confident my PRF function is correct. It's basically the code provided here: https://github.com/lowleveldesign/diagnostics-tools/tree/master/PRF

So, I get everything calculated and come to the FINISH message.

Type:      0x22
TLS1.2:    0x0303
EncLength: 0x28
DecLength: 0x28 - 0x8 - 0x10 = 0x10

Nonce            Encrypted Data                   Validation
447f2c386ab84dfa 3df84665fc155c814c2e5c25836a5a39 c498c6ca886632e97305bcb3d78f36f1

One point that is confusing is the nonce prepended to the encrypted data is not 0 which is what the RFC states (https://tools.ietf.org/html/rfc5246#section-6.1 ):

sequence number
  Each connection state contains a sequence number, which is
  maintained separately for read and write states.  The sequence
  number MUST be set to zero whenever a connection state is made the
  active state.  Sequence numbers are of type uint64 and may not
  exceed 2^64-1.  Sequence numbers do not wrap.  If a TLS
  implementation would need to wrap a sequence number, it must
  renegotiate instead.  A sequence number is incremented after each
  record: **specifically, the first record transmitted under a
  particular connection state MUST use sequence number 0.**

But each successive message is incremented so it definitely appears to be a sequence number.

Application Data 1
447f2c386ab84dfb ...
Application Data 2
447f2c386ab84dfc ...

Then because this is AES-GCM, I build the additional data and nonce arrays based on the values.

additional_data = [ 0x447f2c386ab84dfa, 0x22, 0x0303, 0x0010 ]  // 13 bytes
nonce = [ client_nonce, 0x447f2c386ab84dfa]  //12 bytes

Finally, I try to decrypt using BouncyCastle but it doesn't work. Throws a validation error. So some piece of this puzzle doesn't fit quite right and based on what I've read I can't seem to figure it out. What am I missing here?

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 53
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 49
            Version: TLS 1.2 (0x0303)
            Random: 10aa93806a64725df65f06b7351c107e1a6fb8fbfcc7698e…
            Session ID Length: 0
            Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
            Compression Method: null (0)
            Extensions Length: 9
            Extension: renegotiation_info (len=1)
            Extension: extended_master_secret (len=0)
    TLSv1.2 Record Layer: Handshake Protocol: Certificate
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 1536
        Handshake Protocol: Certificate
            Handshake Type: Certificate (11)
            Length: 1532
            Certificates Length: 1529
            Certificates (1529 bytes)
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 4
        Handshake Protocol: Server Hello Done
            Handshake Type: Server Hello Done (14)
            Length: 0

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 518
        Handshake Protocol: Client Key Exchange
            Handshake Type: Client Key Exchange (16)
            Length: 514
            RSA Encrypted PreMaster Secret
                Encrypted PreMaster length: 512
                Encrypted PreMaster: 96e8e60aea349bdc4bfd3de8a0f449c145a017328639a5bb...
    TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
        Content Type: Change Cipher Spec (20)
        Version: TLS 1.2 (0x0303)
        Length: 1
        Change Cipher Spec Message
    TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 40
        Handshake Protocol: Encrypted Handshake Message
           16
           0303
           0028
           2b4a00ec92c65a27675dfd9186fc67789f3ac...

Transport Layer Security
    TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
        Content Type: Change Cipher Spec (20)
        Version: TLS 1.2 (0x0303)
        Length: 1
        Change Cipher Spec Message
    TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 40
        Handshake Protocol: Encrypted Handshake Message
           16
           0303
           0028
           447f2c386ab84dfa3df84665fc155c814c2e...

Transport Layer Security
    TLSv1.2 Record Layer:
        Content Type: Application Data (23)
        Version: TLS 1.2 (0x0303)
        Length: 91
        Encrypted Application Data:
           17
           0303
           005b
           447f2c386ab84dfb75f0a2338c65f4f0cec7c8f...

EDIT As @poncho says, nonce != sequence_num so I changed the AeadParameters to reflect the sequence of the packet however, it is still not decrypting.

Parameters for first application data packet.
nonce = [ client_nonce, 0x447f2c386ab84dfb]  //12 bytes
additional_data = [ 0x0000000000000001, 0x23, 0x0303, 0x0043 ]  // 13 bytes
$\endgroup$
  • $\begingroup$ Did you see 0 as sequence number in the first record? GCM IV is recommended to be generated with counter/LFSR. A Counter is incremental, too. That should be the GCM nonce/IV. $\endgroup$ – kelalaka Jun 16 at 7:39
  • $\begingroup$ @kelalaka I don't. I've added the Wireshark printouts of the TLS setup and first application data message. $\endgroup$ – 0xdeadbeef Jun 16 at 14:19
  • 2
    $\begingroup$ nonce != sequence number. The RFC states that the sequence number (which is not explicitly transmitted) is initially 0. I don't see where the RFC places any requirements on the initial IV (which is the part of the initial nonce which is explicitly transmitted). $\endgroup$ – poncho Jun 16 at 15:03
  • $\begingroup$ Also, while you have listed the nonce as 12 bytes, what you have listed is only 8 bytes. That's the IV; the actual GCM nonce is that value concatenated with 4 bytes of 'keying data' (that is generated by the TLS KDF function in addition to the actual GCM key) $\endgroup$ – poncho Jun 16 at 19:57
  • $\begingroup$ @poncho it is 12 bytes. The client_nonce is the 4 byte keying data value. I just didn't show the actual value. $\endgroup$ – 0xdeadbeef Jun 16 at 20:20
2
$\begingroup$

You have enabled

Extension: extended_master_secret (len=0).

When the extended master secret extension is negotiated in a full handshake, the master_secret is computed as:

master_secret = PRF(pre_master_secret, "extended master secret",
                       session_hash)
                       [0..47];
| improve this answer | |
$\endgroup$
  • $\begingroup$ That was it. It now decrypts and validates. Thanks for pointing this out. $\endgroup$ – 0xdeadbeef Jun 17 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.