Exemple #1
0
static SECStatus
ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp)
{   SECStatus	      rv;
    PK11SymKey *    ms = NULL;
    SECItem         params = {siBuffer, NULL, 0};
    CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
    unsigned char   rand[SSL3_RANDOM_LENGTH];
    CK_VERSION      pms_version;
    CK_MECHANISM_TYPE master_derive;
    CK_MECHANISM_TYPE key_derive;
    CK_FLAGS          keyFlags;
    
    if (pms == NULL)
	return(SECFailure);

    PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH);

    if (isTLS) {
	if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
	else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
	key_derive    = CKM_TLS_KEY_AND_MAC_DERIVE;
	keyFlags      = CKF_SIGN | CKF_VERIFY;
    } else {
	if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH;
	else master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
	key_derive    = CKM_SSL3_KEY_AND_MAC_DERIVE;
	keyFlags      = 0;
    }

    master_params.pVersion                     = &pms_version;
    master_params.RandomInfo.pClientRandom     = rand;
    master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
    master_params.RandomInfo.pServerRandom     = rand;
    master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;

    params.data = (unsigned char *) &master_params;
    params.len  = sizeof master_params;

    ms = PK11_DeriveWithFlags(pms, master_derive, &params, key_derive,
			      CKA_DERIVE, 0, keyFlags);
    if (ms == NULL)
	return(SECFailure);

    rv = PK11_ExtractKeyValue(ms);
    *pcbp = (rv == SECSuccess);
    PK11_FreeSymKey(ms);
    
    return(rv);

}
Exemple #2
0
SECStatus
tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash,
                      const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
                      const char *label, unsigned int labelLen,
                      CK_MECHANISM_TYPE algorithm, unsigned int keySize,
                      PK11SymKey **keyp)
{
    CK_NSS_HKDFParams params;
    SECItem paramsi = { siBuffer, NULL, 0 };
    /* Size of info array needs to be big enough to hold the maximum Prefix,
     * Label, plus HandshakeHash. If it's ever to small, the code will abort.
     */
    PRUint8 info[256];
    PRUint8 *ptr = info;
    unsigned int infoLen;
    PK11SymKey *derived;
    const char *kLabelPrefix = "TLS 1.3, ";
    const unsigned int kLabelPrefixLen = strlen(kLabelPrefix);

    if (handshakeHash) {
        PORT_Assert(handshakeHashLen == kTlsHkdfInfo[baseHash].hashSize * 2);
    } else {
        PORT_Assert(!handshakeHashLen);
    }

    /*
     *  [draft-ietf-tls-tls13-11] Section 7.1:
     *
     *  HKDF-Expand-Label(Secret, Label, HashValue, Length) =
     *       HKDF-Expand(Secret, HkdfLabel, Length)
     *
     *  Where HkdfLabel is specified as:
     *
     *  struct HkdfLabel {
     *    uint16 length;
     *    opaque label<9..255>;
     *    opaque hash_value<0..255>;
     *  };
     *
     *  Where:
     *  - HkdfLabel.length is Length
     *  - HkdfLabel.hash_value is HashValue.
     *  - HkdfLabel.label is "TLS 1.3, " + Label
     *
     */
    infoLen = 2 + 1 + kLabelPrefixLen + labelLen + 1 + handshakeHashLen;
    if (infoLen > sizeof(info)) {
        PORT_Assert(0);
        goto abort;
    }

    ptr = tls13_EncodeUintX(keySize, 2, ptr);
    ptr = tls13_EncodeUintX(labelLen + kLabelPrefixLen, 1, ptr);
    PORT_Memcpy(ptr, kLabelPrefix, kLabelPrefixLen);
    ptr += kLabelPrefixLen;
    PORT_Memcpy(ptr, label, labelLen);
    ptr += labelLen;
    ptr = tls13_EncodeUintX(handshakeHashLen, 1, ptr);
    if (handshakeHash) {
        PORT_Memcpy(ptr, handshakeHash, handshakeHashLen);
        ptr += handshakeHashLen;
    }
    PORT_Assert((ptr - info) == infoLen);

    params.bExtract = CK_FALSE;
    params.bExpand = CK_TRUE;
    params.pInfo = info;
    params.ulInfoLen = infoLen;
    paramsi.data = (unsigned char *)&params;
    paramsi.len = sizeof(params);

    derived = PK11_DeriveWithFlags(prk, kTlsHkdfInfo[baseHash].pkcs11Mech,
                                   &paramsi, algorithm,
                                   CKA_DERIVE, keySize,
                                   CKF_SIGN | CKF_VERIFY);
    if (!derived)
        return SECFailure;

    *keyp = derived;

#ifdef TRACE
    if (ssl_trace >= 10) {
        /* Make sure the label is null terminated. */
        char labelStr[100];
        PORT_Memcpy(labelStr, label, labelLen);
        labelStr[labelLen] = 0;
        SSL_TRC(50, ("HKDF Expand: label=[TLS 1.3, ] + '%s',requested length=%d",
                     labelStr, keySize));
    }
    PRINT_KEY(50, (NULL, "PRK", prk));
    PRINT_BUF(50, (NULL, "Hash", handshakeHash, handshakeHashLen));
    PRINT_BUF(50, (NULL, "Info", info, infoLen));
    PRINT_KEY(50, (NULL, "Derived key", derived));
#endif

    return SECSuccess;

abort:
    PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
    return SECFailure;
}