CALG_SCHANNEL_MASTER_HASH

The master hash is created from the master key just prior to deriving the bulk encryption keys, via a call to CPCreateHash:

CPCreateHash(hProv, CALG_SCHANNEL_MASTER_HASH, 
             hMasterKey, 0, &hMasterHash);
 

The master hash should not maintain a reference to the master key. All relevant data associated with the master key should be copied over to the master hash object.

Depending on the protocol, the CSP should perform the following operations within the CPCreateHash function.

PCT1

All key derivation operations are done within the CPDeriveKey function.

SSL2

The "key block" from which the session keys are created should probably be created within this function. This key block is later used to create the respective session keys by the CPDeriveKey function. See the SSL 2 specification for a description of this key generation.

SSL 3.0

The key generated via CPGenKey (or CPImportKey) is not the master key, but a "pre-master key." See the SSL 3.0 specification. The "pre-master key" is used to generate the master key, via the following formula:

master_secret =
       MD5(pre_master_secret + SHA('A' + pre_master_secret +
           ClientHello.random + ServerHello.random)) +
       MD5(pre_master_secret + SHA('BB' + pre_master_secret +
           ClientHello.random + ServerHello.random)) +
       MD5(pre_master_secret + SHA('CCC' + pre_master_secret +
           ClientHello.random + ServerHello.random));

Note  The master key, not the "pre-master key," is hashed via CPHashSessionKey.

The "key block" from which the session keys are created should probably be created within this function. This key block is later used to create the respective session keys by the CPDeriveKey function. For details, see the SSL 3.0 specification. This is done via the following formula:

key_block =
       MD5(master_secret + SHA('A' + master_secret +
                               ServerHello.random +
                               ClientHello.random)) +
       MD5(master_secret + SHA('BB' + master_secret +
                               ServerHello.random +
                               ClientHello.random)) +
       MD5(master_secret + SHA('CCC' + master_secret +
                               ServerHello.random +
                               ClientHello.random)) + [...];
 

TLS 1.0

The key generated via CPGenKey (or CPImportKey) is not the master key, but a "pre-master key." See the TLS 1.0 specification. The "pre-master key" is used to generate the master key, via the following formula:

master_secret = PRF(pre_master_secret, "master secret",
              ClientHello.random + ServerHello.random) [0..47];
 

The "key block" from which the session keys are created should probably be created within this function. This key block is later used to create the respective session keys by the CPDeriveKey function. This is done via the following formula:

key_block = PRF(SecurityParameters.master_secret,
                         "key expansion",
                         SecurityParameters.server_random +
                         SecurityParameters.client_random);