Skip to content

Commit

Permalink
Bug 1117022 - Implement draft-ietf-tls-session-hash [PKCS#11 part] r=…
Browse files Browse the repository at this point in the history
…rrelyea
  • Loading branch information
Richard Barnes committed Aug 24, 2015
1 parent c4d54fd commit 01c62df
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 7 deletions.
4 changes: 4 additions & 0 deletions lib/pk11wrap/pk11mech.c
Expand Up @@ -379,6 +379,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
case CKM_TLS_KEY_AND_MAC_DERIVE:
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
case CKM_SHA_1_HMAC:
case CKM_SHA_1_HMAC_GENERAL:
case CKM_SHA224_HMAC:
Expand Down Expand Up @@ -573,6 +575,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_TLS_MASTER_KEY_DERIVE:
case CKM_TLS_KEY_AND_MAC_DERIVE:
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
return CKM_SSL3_PRE_MASTER_KEY_GEN;
case CKM_SHA_1_HMAC:
case CKM_SHA_1_HMAC_GENERAL:
Expand Down
4 changes: 4 additions & 0 deletions lib/softoken/pkcs11.c
Expand Up @@ -474,6 +474,10 @@ static const struct mechanismList mechanisms[] = {
{CKM_TLS12_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
{CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256,
{48, 48, CKF_DERIVE}, PR_FALSE},
{CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
{48,128, CKF_DERIVE}, PR_FALSE},
{CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH,
{48,128, CKF_DERIVE}, PR_FALSE},
/* ---------------------- PBE Key Derivations ------------------------ */
{CKM_PBE_MD2_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
{CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
Expand Down
97 changes: 97 additions & 0 deletions lib/softoken/pkcs11c.c
Expand Up @@ -6136,6 +6136,103 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
break;
}

/* Extended master key derivation [draft-ietf-tls-session-hash] */
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
{
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
SSL3RSAPreMasterSecret *rsa_pms;
SECStatus status;
SECItem pms = { siBuffer, NULL, 0 };
SECItem seed = { siBuffer, NULL, 0 };
SECItem master = { siBuffer, NULL, 0 };

ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS*) pMechanism->pParameter;

/* First do the consistency checks */
att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
if ((att2 == NULL) ||
(*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET)) {
if (att2) sftk_FreeAttribute(att2);
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
break;
}
sftk_FreeAttribute(att2);
if (keyType != CKK_GENERIC_SECRET) {
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
break;
}
if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
break;
}
if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) &&
(att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}

/* Do the key derivation */
pms.data = (unsigned char*) att->attrib.pValue;
pms.len = att->attrib.ulValueLen;
seed.data = ems_params->pSessionHash;
seed.len = ems_params->ulSessionHashLen;
master.data = key_block;
master.len = SSL3_MASTER_SECRET_LENGTH;
if (ems_params-> prfHashMechanism == CKM_TLS_PRF) {
/*
* In this case, the session hash is the concatenation of SHA-1
* and MD5, so it should be 36 bytes long.
*/
if (seed.len != MD5_LENGTH + SHA1_LENGTH) {
crv = CKR_TEMPLATE_INCONSISTENT;
break;
}

status = TLS_PRF(&pms, "extended master secret",
&seed, &master, isFIPS);
} else {
tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
if (tlsPrfHash == HASH_AlgNULL) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}

const SECHashObject *hashObj = HASH_GetRawHashObject(tlsPrfHash);
if (seed.len != hashObj->length) {
crv = CKR_TEMPLATE_INCONSISTENT;
break;
}

status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
&seed, &master, isFIPS);
}

/* Reflect the version if required, and the input looks like a PMS */
if (ems_params->pVersion) {
if (att->attrib.ulValueLen != SSL3_PMS_LENGTH) {
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}

SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
/* don't leak more key material then necessary for SSL to work */
if ((sessKey == NULL) || sessKey->wasDerived) {
ems_params->pVersion->major = 0xff;
ems_params->pVersion->minor = 0xff;
} else {
ems_params->pVersion->major = rsa_pms->client_version[0];
ems_params->pVersion->minor = rsa_pms->client_version[1];
}
}

/* Store the results */
crv = sftk_forceAttribute(key, CKA_VALUE, key_block,
SSL3_MASTER_SECRET_LENGTH);
break;
}

case CKM_TLS12_KEY_AND_MAC_DERIVE:
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
case CKM_TLS_KEY_AND_MAC_DERIVE:
Expand Down
43 changes: 36 additions & 7 deletions lib/util/pkcs11n.h
Expand Up @@ -28,7 +28,7 @@

/*
* NSS-defined object classes
*
*
*/
#define CKO_NSS (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NSS)

Expand Down Expand Up @@ -164,7 +164,7 @@
#define CKM_NSS_JPAKE_ROUND1_SHA512 (CKM_NSS + 10)

/* J-PAKE round 2 key derivation mechanisms.
*
*
* Required template attributes: CKA_NSS_JPAKE_PEERID
* Input key type: CKK_NSS_JPAKE_ROUND1
* Output key type: CKK_NSS_JPAKE_ROUND2
Expand All @@ -176,14 +176,14 @@
#define CKM_NSS_JPAKE_ROUND2_SHA384 (CKM_NSS + 13)
#define CKM_NSS_JPAKE_ROUND2_SHA512 (CKM_NSS + 14)

/* J-PAKE final key material derivation mechanisms
/* J-PAKE final key material derivation mechanisms
*
* Input key type: CKK_NSS_JPAKE_ROUND2
* Output key type: CKK_GENERIC_SECRET
* Output key class: CKO_SECRET_KEY
* Parameter type: CK_NSS_JPAKEFinalParams
*
* You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
* You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
* to get a key with uniformly distributed bits.
*/
#define CKM_NSS_JPAKE_FINAL_SHA1 (CKM_NSS + 15)
Expand Down Expand Up @@ -214,6 +214,10 @@
#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 (CKM_NSS + 23)
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)

/* TLS extended master secret derivation */
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26)

/*
* HISTORICAL:
* Do not attempt to use these. They are only used by NETSCAPE's internal
Expand Down Expand Up @@ -292,7 +296,7 @@ typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {

/* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms.
See RFC 5869.
bExtract: If set, HKDF-Extract will be applied to the input key. If
the optional salt is given, it is used; otherwise, the salt is
set to a sequence of zeros equal in length to the HMAC output.
Expand All @@ -317,6 +321,31 @@ typedef struct CK_NSS_HKDFParams {
CK_ULONG ulInfoLen;
} CK_NSS_HKDFParams;

/*
* Parameter for the TLS extended master secret key derivation mechanisms:
*
* * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE
* * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH
*
* For the TLS 1.2 PRF, the prfHashMechanism parameter determines the hash
* function used. For earlier versions of the PRF, set the prfHashMechanism
* value to CKM_TLS_PRF.
*
* The session hash input is expected to be the output of the same hash
* function as the PRF uses (as required by draft-ietf-tls-session-hash). So
* the ulSessionHashLen member must be equal the output length of the hash
* function specified by the prfHashMechanism member (or, for pre-TLS 1.2 PRF,
* the length of concatenated MD5 and SHA-1 digests).
*
*/
typedef struct CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS {
CK_MECHANISM_TYPE prfHashMechanism;
CK_BYTE_PTR pSessionHash;
CK_ULONG ulSessionHashLen;
CK_VERSION_PTR pVersion;
} CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS;


/*
* Trust info
*
Expand All @@ -341,7 +370,7 @@ typedef CK_ULONG CK_TRUST;
#define CKT_NSS_NOT_TRUSTED (CKT_NSS + 10)
#define CKT_NSS_TRUST_UNKNOWN (CKT_NSS + 5) /* default */

/*
/*
* These may well remain NSS-specific; I'm only using them
* to cache resolution data.
*/
Expand Down Expand Up @@ -452,7 +481,7 @@ typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated
#define SECMOD_MODULE_DB_FUNCTION_FIND 0
#define SECMOD_MODULE_DB_FUNCTION_ADD 1
#define SECMOD_MODULE_DB_FUNCTION_DEL 2
#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
char *parameters, void *moduleSpec);

Expand Down

0 comments on commit 01c62df

Please sign in to comment.