Search code examples
csslopensslpublic-key-exchange

Premaster secret and master key in OpenSSL


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.


Solution

  • 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;
       }