Skip to content

Commit

Permalink
Bug 1315735 - TLS 1.3 draft 18 - Update to draft-18 key schedule and …
Browse files Browse the repository at this point in the history
…code point. r=mt

Reviewers: mt

Reviewed By: mt

Differential Revision: https://nss-dev.phacility.com/D138
  • Loading branch information
ekr committed Nov 7, 2016
1 parent 3c57ecb commit 184e9d4
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 55 deletions.
2 changes: 1 addition & 1 deletion gtests/ssl_gtest/libssl_internals.c
Expand Up @@ -138,7 +138,7 @@ PRBool SSLInt_CheckSecretsDestroyed(PRFileDesc *fd) {
}

CHECK_SECRET(currentSecret);
CHECK_SECRET(resumptionPsk);
CHECK_SECRET(resumptionMasterSecret);
CHECK_SECRET(dheSecret);
CHECK_SECRET(clientEarlyTrafficSecret);
CHECK_SECRET(clientHsTrafficSecret);
Expand Down
6 changes: 3 additions & 3 deletions lib/ssl/ssl3con.c
Expand Up @@ -12839,7 +12839,7 @@ ssl3_InitState(sslSocket *ss)
}

ss->ssl3.hs.currentSecret = NULL;
ss->ssl3.hs.resumptionPsk = NULL;
ss->ssl3.hs.resumptionMasterSecret = NULL;
ss->ssl3.hs.dheSecret = NULL;
ss->ssl3.hs.pskBinderKey = NULL;
ss->ssl3.hs.clientEarlyTrafficSecret = NULL;
Expand Down Expand Up @@ -13214,8 +13214,8 @@ ssl3_DestroySSL3Info(sslSocket *ss)
/* Destroy TLS 1.3 keys */
if (ss->ssl3.hs.currentSecret)
PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
if (ss->ssl3.hs.resumptionPsk)
PK11_FreeSymKey(ss->ssl3.hs.resumptionPsk);
if (ss->ssl3.hs.resumptionMasterSecret)
PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret);
if (ss->ssl3.hs.dheSecret)
PK11_FreeSymKey(ss->ssl3.hs.dheSecret);
if (ss->ssl3.hs.pskBinderKey)
Expand Down
2 changes: 1 addition & 1 deletion lib/ssl/ssl3prot.h
Expand Up @@ -18,7 +18,7 @@ typedef PRUint16 SSL3ProtocolVersion;
/* The TLS 1.3 draft version. Used to avoid negotiating
* between incompatible pre-standard TLS 1.3 drafts.
* TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
#define TLS_1_3_DRAFT_VERSION 17
#define TLS_1_3_DRAFT_VERSION 18

typedef PRUint16 ssl3CipherSuite;
/* The cipher suites are defined in sslproto.h */
Expand Down
4 changes: 2 additions & 2 deletions lib/ssl/sslimpl.h
Expand Up @@ -846,8 +846,8 @@ typedef struct SSL3HandshakeStateStr {

/* This group of values is used for TLS 1.3 and above */
PK11SymKey *currentSecret; /* The secret down the "left hand side"
* of the TLS 1.3 key schedule. */
PK11SymKey *resumptionPsk; /* The resumption PSK. */
* of the TLS 1.3 key schedule. */
PK11SymKey *resumptionMasterSecret; /* The resumption PSK. */
PK11SymKey *dheSecret; /* The (EC)DHE shared secret. */
PK11SymKey *pskBinderKey; /* Used to compute the PSK binder. */
PK11SymKey *clientEarlyTrafficSecret; /* The secret we use for 0-RTT. */
Expand Down
69 changes: 21 additions & 48 deletions lib/ssl/tls13con.c
Expand Up @@ -114,11 +114,7 @@ const char kHkdfLabelHandshakeTrafficSecret[] = "handshake traffic secret";
const char kHkdfLabelApplicationTrafficSecret[] = "application traffic secret";
const char kHkdfLabelFinishedSecret[] = "finished";
const char kHkdfLabelResumptionMasterSecret[] = "resumption master secret";
const char kHkdfLabelResumptionPsk[] = "resumption psk";
const char kHkdfLabelExporterMasterSecret[] = "exporter master secret";
const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data key expansion";
const char kHkdfPhaseHandshakeKeys[] = "handshake key expansion";
const char kHkdfPhaseApplicationDataKeys[] = "application data key expansion";
const char kHkdfPurposeKey[] = "key";
const char kHkdfPurposeIv[] = "iv";

Expand Down Expand Up @@ -605,10 +601,8 @@ static SECStatus
tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
{
PK11SymKey *wrapKey; /* wrapping key */
PK11SymKey *RMS = NULL;
SECItem wrappedMS = { siBuffer, NULL, 0 };
SSLHashType hashType;
SECStatus rv;

SSL_TRC(3, ("%d: TLS13[%d]: recovering static secret (%s)",
SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
Expand Down Expand Up @@ -651,41 +645,21 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;

/* unwrap the "master secret" which is actually RMS. */
RMS = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
NULL, &wrappedMS,
CKM_SSL3_MASTER_KEY_DERIVE,
CKA_DERIVE,
tls13_GetHashSizeForHash(hashType),
CKF_SIGN | CKF_VERIFY);
ss->ssl3.hs.resumptionMasterSecret = PK11_UnwrapSymKeyWithFlags(
wrapKey, sid->u.ssl3.masterWrapMech,
NULL, &wrappedMS,
CKM_SSL3_MASTER_KEY_DERIVE,
CKA_DERIVE,
tls13_GetHashSizeForHash(hashType),
CKF_SIGN | CKF_VERIFY);
PK11_FreeSymKey(wrapKey);
if (!RMS) {
if (!ss->ssl3.hs.resumptionMasterSecret) {
return SECFailure;
}

PRINT_KEY(50, (ss, "Recovered RMS", RMS));
/* Now compute resumption_psk.
*
* resumption_psk = HKDF-Expand-Label(resumption_secret,
* "resumption psk", "", L)
*/
rv = tls13_HkdfExpandLabel(RMS, hashType, NULL, 0,
kHkdfLabelResumptionPsk,
strlen(kHkdfLabelResumptionPsk),
tls13_GetHkdfMechanismForHash(hashType),
tls13_GetHashSizeForHash(hashType),
&ss->ssl3.hs.resumptionPsk);
if (rv != SECSuccess) {
goto loser;
}
PRINT_KEY(50, (ss, "Recovered RMS", ss->ssl3.hs.resumptionMasterSecret));

PK11_FreeSymKey(RMS);
return SECSuccess;

loser:
if (RMS) {
PK11_FreeSymKey(RMS);
}
return SECFailure;
}

/* Key Derivation Functions.
Expand Down Expand Up @@ -748,28 +722,23 @@ tls13_ComputeEarlySecrets(sslSocket *ss)
SSL_TRC(5, ("%d: TLS13[%d]: compute early secrets (%s)",
SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

/* Extract off the resumptionPsk (if present), else pass the NULL
* resumptionPsk which will be internally translated to zeroes. */

/* Extract off the resumptionMasterSecret (if present), else pass the NULL
* resumptionMasterSecret which will be internally translated to zeroes. */
PORT_Assert(!ss->ssl3.hs.currentSecret);
rv = tls13_HkdfExtract(NULL, ss->ssl3.hs.resumptionPsk,
rv = tls13_HkdfExtract(NULL, ss->ssl3.hs.resumptionMasterSecret,
tls13_GetHash(ss), &ss->ssl3.hs.currentSecret);
if (rv != SECSuccess) {
return SECFailure;
}

PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionPsk != NULL));
PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionMasterSecret != NULL));
if (ss->statelessResume) {
PRUint8 buf[1] = { 0 };
SSL3Hashes hashes;

PORT_Assert(ss->ssl3.hs.resumptionPsk);
if (!ss->ssl3.hs.resumptionPsk) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}

PK11_FreeSymKey(ss->ssl3.hs.resumptionPsk);
ss->ssl3.hs.resumptionPsk = NULL;
PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret);
ss->ssl3.hs.resumptionMasterSecret = NULL;

rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
hashes.u.raw, buf, 0);
Expand All @@ -786,7 +755,7 @@ tls13_ComputeEarlySecrets(sslSocket *ss)
return SECFailure;
}
} else {
PORT_Assert(!ss->ssl3.hs.resumptionPsk);
PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret);
}

return SECSuccess;
Expand Down Expand Up @@ -2619,6 +2588,10 @@ tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec,
ssl3KeyMaterial *target;
const char *phase;
SECStatus rv;
/* These labels are just used for debugging. */
const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data";
const char kHkdfPhaseHandshakeKeys[] = "handshake data";
const char kHkdfPhaseApplicationDataKeys[] = "application data";

if (ss->sec.isServer ^ (direction == CipherSpecWrite)) {
clientKey = PR_TRUE;
Expand Down

0 comments on commit 184e9d4

Please sign in to comment.