dcsimg
Results 1 to 5 of 5
  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    576

    Resolved [RESOLVED] Help finding Agreed Secret

    In my ongoing attempt to implement ECC (Elliptical Curve Cryptography) in TLS 1.2, I have run into a roadblock that I can't seem to get around.

    Background:
    To use ECDHE (Elliptical Curve Diffie-Hellman Ephemoral), one uses an internally generated Private Key and a Public Key from the other end to create a 32 byte Agreed (or Shared) Secret. This Secret is then combined with the 32 Byte Client Random and 32 byte Server Random to produce a 48 byte Master Secret from which the various Symmetric keys for the exchange are created.

    Problem:
    CNG (Cryptography Next Generation) is capable of producing the Agreed Secret, but it appears that the only way of recovering it is as a hashed value using:
    Code:
    BCryptDeriveKey(hAgreedSecret, StrPtr(BCRYPT_KDF_HASH), VarPtr(ParameterList), VarPtr(bAgreedSecret(0)), cbAgreedSecret, cbAgreedSecret, 0)
    The second parameter can also be BCRYPT_KDF_HMAC or BCRYPT_KDF_TLS_PRF. BCRYPT_KDF_HMAC is an HMAC Hash, and I have tried using BCRYPT_KDF_TLS_PRF. In theory, it produces a 48 byte variable that should be the Master Secret, but unfortunately it is different value every time I run it with the identical input parameters. To be of any use to TLS, both ends must be able to generate the same Master Secret.

    I started all this trying to figure out why I could not connect to a foreign server. RFC5903 provided sample data to verify the key generation. I hashed the Agreed Secret that RFC5903 said I should get, and that hash compared to the results of the call above. So I know that it is calculating the Agreed Secret correctly, but a hash of it however is useless to me. I found where the raw Agreed Secret is stored in memory, but it looks like it has been encrypted. I also located the Private Key and the Public Key in memory, but they also look like they are encrypted in the same manner.

    Does anyone know what the operating system uses to encrypt this information?

    J.A. Coutts

  2. #2
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    612

    Re: Help finding Agreed Secret

    What HMAC algortihm are you/your system using? SHA-256 is default according to NIST.

    <clip>
    TLS 1.2 also declares that "New cipher suites MUST explicitly specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a stronger standard hash function", which means that the hash functions used at handshakeing should be SHA-256 at least.

    3.HMAC at protecting record
    For the HMAC operations used to protect record data, the hash funtion is defined by cipher suites. For example, the HMAC's hash function of cipher suite TLS_RSA_WITH_NULL_MD5 is MD5.

    From TLS 1.2, new cipher suites may define their own MAC constructions except the default HMAC. TLS 1.2 defines five MAC algorithms, from the literal, it is straight forward to know the hash function used.
    ◦null
    ◦hmac_md5
    ◦hmac_sha1
    ◦hmac_sha256
    ◦hmac_sha384
    ◦hmac_sha512
    </clip>

    as what comes to sha512...

    https://support.microsoft.com/en-us/kb/2973337

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    576

    Re: Help finding Agreed Secret

    Quote Originally Posted by Tech99 View Post
    What HMAC algortihm are you/your system using? SHA-256 is default according to NIST.
    According to RFC5246 "In this section, we define one PRF, based on HMAC. This PRF with the SHA-256 hash function is used for all cipher suites defined in this document and in TLS documents published prior to this document when TLS 1.2 is negotiated. New cipher suites MUST explicitly specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a stronger standard hash function". Although I did test the call using an HMAC hash and SHA256, what I really need is a "NoHash" function. I have pretty much given up on MD5 and SHA1, although the mandatory Suite for TLS 1.2 is TLS_RSA_WITH_AES_128_CBC_SHA. I need the raw Agreed Secret without it being hashed in order to input to my own PRF.

    In desperation, I tried BCRYPT_KDF_TLS_PRF, specifying SHA256 and TLS 1.2. For reasons unknown (to me), I could not get a consistent output with fixed input parameters.

    J.A. Coutts

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    576

    Re: Help finding Agreed Secret

    I know this thread is old, but it has taken me this long to figure it out. The pointer to the Agreed Secret is located at offset 12 of the Agreed Secret handle. At that pointer location, the Raw Agreed Secret starts at offset 16.
    Code:
        'Generate the agreed secret
        lRet = BCryptSecretAgreement(hPrivKey, hPubKey, hAgreedSecret, 0)
        If lRet <> 0 Then
            ReDim bAgreedSecret(0)
            bAgreedSecret(0) = 10
            GoTo ReleaseHandles
        Else
            lPntr = PeekW(hAgreedSecret + 12) + 16
            KeyLen = KeyLen / 8
            ReDim bAgreedSecret(KeyLen - 1)
            CopyMemory bAgreedSecret(0), ByVal lPntr, KeyLen
            GoTo ReleaseHandles
        End If
    Using the key values provided by RFC 5903 produces:

    14 00 00 00 43 45 53 4D 20 00 00 00 20 00 00 00
    D6 84 0F 6B 42 F6 ED AF D1 31 16 E0 E1 25 65 20
    2F EF 8E 9E CE 7D CE 03 81 24 64 D0 4B 94 42 DE

    The complete code is available here:
    http://www.vbforums.com/showthread.p...an-(ECDH)-Demo

    J.A. Coutts

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    576

    Re: [RESOLVED] Help finding Agreed Secret

    This one just doesn't seem to go away. After incorporating my newfound Raw AgreedSecret into an application, I discovered that it does not work on Win 10. Investigating further, it looks like Microsoft moved the storage location for the AgreedSecret. For 256 bit:
    Code:
    Win 8.1 (0x5C6548)
    14 00 00 00 43 45 53 4D 20 00 00 00 20 00 00 00 
    D6 84 0F 6B 42 F6 ED AF D1 31 16 E0 E1 25 65 20 
    2F EF 8E 9E CE 7D CE 03 81 24 64 D0 4B 94 42 DE 
    71 E3 7B CA 8C D6 C5 FC F3 F7 78 4E F4 1B 00 80 
    59 3C 11 0B 70 37 79 52 90 09 86 0D EC 9C D2 BC 
    95 0D F1 6D 0D 33 9B E1 08 72 3D BC DC DD 9D 70 
    
    Win 10 (0x4FDA88)
    30 02 00 00 43 45 53 4D 07 00 03 00 20 00 00 00 
    20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    The header is still there (slightly modified), but the key itself is gone. I suspect that it has been encrypted, stored elsewhere, and the memory released. The 07 00 03 00 (0x00030007) appears to be an index of some sort.
    256 bit
    43 45 53 4D 07 00 03 00 20 00 00 00 20 00 00 00
    384 bit
    43 45 53 4D 08 00 03 00 30 00 00 00 30 00 00 00
    521 bit
    43 45 53 4D 09 00 03 00 42 00 00 00 42 00 00 00

    The length of the 521 bit key seems a bit odd, since it does not use a full byte count. Anyway, while searching for the answer to this dilemma, I found at least a dozen others asking the same question. Why doesn't Microsoft make the Raw AgreedSecret available? Doing so restricts the use of CNG in many ECC applications. Any help would be appreciated.

    J.A. Coutts

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width