1

I have following values:

  1. client-random bytes
  2. server-random bytes
  3. pre-master secret

I don't want to use features like SSL , SSL_CTX etc. What I want is, just I have three numbers, I want to calculate master-number from them.

How do I calculate master-key in c using OpenSSL? Is there any function in OpenSSL C library for PRF specified in RFCs?

Thank You.

jww
  • 97,681
  • 90
  • 411
  • 885
harihardik
  • 494
  • 1
  • 5
  • 15

1 Answers1

3
JKJS
    int master_secret(unsigned char *dest,int len,unsigned char *pre_master_secret,int pms_len,unsigned char *label,unsigned char *seed,int seed_len)
    {/*dest :where master secret will be stored
      len   :desired length of master secret
      pre_master_secret :given pre-master secret
      pms_len   :length of given pre-master secret
      label :given label to be fed to PRF
      seed  :given seed to be fed to PRF
      seed_len  :length of given seed

      finally,our function is analogus to RFC-2246 PRF definition:PRF(secret,label,seed)
      where,    secret=pre-master secret
            label=label
            seed=seed
    */
    EVP_MD *md5,*sha;
    md5=EVP_md5();
    sha=EVP_sha();

    int i=0,j,position;

    int half_secret_len=pms_len/2+pms_len%2;

    unsigned char md5_secret[half_secret_len];  //first half of the pre-master secret, analogus to S1 in RFC-2246
    for(i=0;i<pms_len/2+pms_len%2;i++)
      md5_secret[i]=pre_master_secret[i];

    unsigned char sha_secret[half_secret_len];  //second half of the pre-master secret, analogus to S2 in RFC-2246

    for(i=pms_len/2,j=i;i<pms_len;i++)
      sha_secret[i-j]=pre_master_secret[i];

    int iter_md5=len/16+(len%16?1:0);
    int iter_sha=len/20+(len%20?1:0);
    unsigned char h_md5[iter_md5*16];   //output of P_MD5(S1, label + seed) in RFC-2246
    unsigned char h_sha[iter_sha*20];   //output of P_MD5(S1, label + seed) in RFC-2246

    int actual_seed_len=strlen(label)+seed_len;
    unsigned char actual_seed[actual_seed_len];     //label+seed concatenation

    for(i=0;i<strlen(label);i++)
      actual_seed[i]=label[i];
    for(j=i;i<sizeof(actual_seed);i++)
      actual_seed[i]=seed[i-j];

    unsigned char temp_md5[16];     //A(0),A(1),A(2),... in RFC-2246
    unsigned char temp_sha[20];

    HMAC(md5,md5_secret,half_secret_len,actual_seed,actual_seed_len,temp_md5,NULL); //calculating A(0) for md5
    HMAC(sha,sha_secret,half_secret_len,actual_seed,actual_seed_len,temp_sha,NULL); //calculating A(0) for sha

    int temp_md5_seed_len=16+actual_seed_len;
    unsigned char md5_seed[temp_md5_seed_len];  //A(i)+seed to be fed to HMAC function according to RFC-2246
    for(i=16,j=i;i<temp_md5_seed_len;i++)
      md5_seed[i]=actual_seed[i-j];

    //calculating P_MD5()
    for(i=0;i<iter_md5;i++)
    {
        position=i*16;
        for(j=0;j<16;j++)
        md5_seed[j]=temp_md5[j];
        HMAC(md5,md5_secret,half_secret_len,md5_seed,temp_md5_seed_len,temp_md5,NULL);
        for(j=0;j<16;j++)
        h_md5[position+j]=temp_md5[j];
    }

    int temp_sha_seed_len=20+actual_seed_len;
    unsigned char sha_seed[temp_sha_seed_len];  //A(i)+seed to be fed to HMAC function according to RFC-2246
    for(i=20,j=i;i<temp_sha_seed_len;i++)
      sha_seed[i]=actual_seed[i-j];

    //calculating P_SHA()
    for(i=0;i<iter_sha;i++)
    {
        position=i*20;
        for(j=0;j<20;j++)
        sha_seed[j]=temp_sha[j];
        HMAC(sha,sha_secret,half_secret_len,sha_seed,temp_sha_seed_len,temp_sha,NULL);
        for(j=0;j<20;j++)
        h_sha[position+j]=temp_sha[j];
    }

    //PRF()=P_MD5() XOR P_SHA()
    for(i=0;i<len;i++)
      dest[i]=h_md5[i]^h_sha[i];

    return 1;
   }
Noam Rathaus
  • 5,405
  • 2
  • 28
  • 37
harihardik
  • 494
  • 1
  • 5
  • 15
  • There is a mistake here in the code, it doesn't work correctly, the output doesn't generate correctly – Noam Rathaus Dec 30 '14 at 09:05
  • Example Secret : Label : Seed, 248707237b320de123f9350fecaf6af51751a18a46ac0c4a536511ff222a6b441c84a83e5a0c6568fe685609b09d9f52 : key expansion : 460c1a2d1ad5d21c9f6640f8eeea14bd9adf709953e0338497a20771d3c1c84c54a250ef925a3ab9bb184b0ed36d2f675b350302d14f31159e54f6691a3309d5 – Noam Rathaus Dec 30 '14 at 09:05
  • Should return 1 13b727658ac91adf54f6b1540cf5b53b 2 395bd882f49690894b00d243ce6dfd71 3 59b0443b5ecec0476894ffd8c054edcf 4 3ce9f7db40663f497c182c76d121a8a1 5 0ec24bc46fca9cd36d612589c5481761 6 f38b1fe0dd6439970250a390ddbe0a97 7 e3befbd4129d7d2c29dcbf250afb347d 8 054346551095217ded77d80d91200330 9 26d6358a7c9b1c9d 1 2 3 4 5 6 7 8 – Noam Rathaus Dec 30 '14 at 09:05
  • 1
    But doesn't... The problem is in the A(n) calculation, A(n) is A(n) = HMAC_MD5(Secret, A(n-1)) and not the code found here which reuses the seed – Noam Rathaus Dec 30 '14 at 09:07
  • 1
    In addition the use of EVP_sha() rather than EVP_sha1() causes the calculation to be incorrect – Noam Rathaus Dec 30 '14 at 09:27