summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWan-Teh Chang <wtc@google.com>2013-08-20 15:29:22 -0700
committerWan-Teh Chang <wtc@google.com>2013-08-20 15:29:22 -0700
commita6ce93968a505344a40616ec346d3d78ac206e83 (patch)
tree708728012cf81971a11309b99ee3f407c7a8f16a
parent81cd4f570d6bbc0d886c070d87a5bca289a25082 (diff)
downloadnss-hg-a6ce93968a505344a40616ec346d3d78ac206e83.tar.gz
Bug 880543: Make the AES-GCM cipher suites work in DTLS, by moving the
ssl3_BuildRecordPseudoHeader calls to where the isDTLS boolean is available. Make the three MAC-related fields of the SSLCipherSuiteInfo structure report reasonable values for AEAD ciphers, which don't use a MAC. r=sleevi.
-rw-r--r--lib/ssl/dtlscon.c7
-rw-r--r--lib/ssl/ssl3con.c193
-rw-r--r--lib/ssl/sslimpl.h6
-rw-r--r--lib/ssl/sslinfo.c9
-rw-r--r--lib/ssl/sslt.h6
5 files changed, 91 insertions, 130 deletions
diff --git a/lib/ssl/dtlscon.c b/lib/ssl/dtlscon.c
index e86ae01dd..78371e62a 100644
--- a/lib/ssl/dtlscon.c
+++ b/lib/ssl/dtlscon.c
@@ -30,13 +30,6 @@ static const PRUint16 COMMON_MTU_VALUES[] = {
/* List copied from ssl3con.c:cipherSuites */
static const ssl3CipherSuite nonDTLSSuites[] = {
- /* XXX Make AES-GCM work with DTLS. */
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-#endif /* NSS_ENABLE_ECC */
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_RSA_WITH_AES_128_GCM_SHA256,
#ifdef NSS_ENABLE_ECC
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index 870a19869..2b4a4f6d2 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -71,9 +71,8 @@ static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt,
unsigned char *out, int *outlen, int maxout,
const unsigned char *in, int inlen,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num);
+ const unsigned char *additionalData,
+ int additionalDataLen);
#endif
#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
@@ -381,10 +380,10 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
{SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},
{SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips},
- {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_null, kea_dhe_rsa},
- {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_null, kea_rsa},
- {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_null, kea_ecdhe_rsa},
- {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_null, kea_ecdhe_ecdsa},
+ {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa},
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa},
#ifdef NSS_ENABLE_ECC
{TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa},
@@ -453,22 +452,25 @@ static const SSLCipher2Mech alg2Mech[] = {
/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
};
-#define mmech_null (CK_MECHANISM_TYPE)0x80000000L
+#define mmech_invalid (CK_MECHANISM_TYPE)0x80000000L
#define mmech_md5 CKM_SSL3_MD5_MAC
#define mmech_sha CKM_SSL3_SHA1_MAC
#define mmech_md5_hmac CKM_MD5_HMAC
#define mmech_sha_hmac CKM_SHA_1_HMAC
#define mmech_sha256_hmac CKM_SHA256_HMAC
+#define mmech_sha384_hmac CKM_SHA384_HMAC
+#define mmech_sha512_hmac CKM_SHA512_HMAC
static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
/* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */
/* mac mmech pad_size mac_size */
- { mac_null, mmech_null, 0, 0 },
+ { mac_null, mmech_invalid, 0, 0 },
{ mac_md5, mmech_md5, 48, MD5_LENGTH },
{ mac_sha, mmech_sha, 40, SHA1_LENGTH},
{hmac_md5, mmech_md5_hmac, 0, MD5_LENGTH },
{hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH},
{hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH},
+ { mac_aead, mmech_invalid, 0, 0 },
};
/* indexed by SSL3BulkCipher */
@@ -1751,8 +1753,18 @@ ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
return param;
}
-/* ssl3_BuildRecordPseudoHeader writes the TLS pseudo-header (the data which
- * is included in the MAC) to |out| and returns its length. */
+/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data
+ * which is included in the MAC or AEAD additional data) to |out| and returns
+ * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
+ * definition of the AEAD additional data.
+ *
+ * TLS pseudo-header includes the record's version field, SSL's doesn't. Which
+ * pseudo-header defintiion to use should be decided based on the version of
+ * the protocol that was negotiated when the cipher spec became current, NOT
+ * based on the version value in the record itself, and the decision is passed
+ * to this function as the |includesVersion| argument. But, the |version|
+ * argument should be the record's version value.
+ */
static unsigned int
ssl3_BuildRecordPseudoHeader(unsigned char *out,
SSL3SequenceNumber seq_num,
@@ -1803,29 +1815,18 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
int maxout,
const unsigned char *in,
int inlen,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num)
+ const unsigned char *additionalData,
+ int additionalDataLen)
{
SECItem param;
SECStatus rv = SECFailure;
unsigned char nonce[12];
- unsigned char additionalData[13];
- unsigned int additionalDataLen;
unsigned int uOutLen;
CK_GCM_PARAMS gcmParams;
static const int tagSize = 16;
static const int explicitNonceLen = 8;
- /* See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
- * definition of the AEAD additional data. */
- additionalDataLen = ssl3_BuildRecordPseudoHeader(
- additionalData, seq_num, type, PR_TRUE /* includes version */,
- version, PR_FALSE /* not DTLS */,
- inlen - (doDecrypt ? explicitNonceLen + tagSize : 0));
- PORT_Assert(additionalDataLen <= sizeof(additionalData));
-
/* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
* nonce is formed. */
memcpy(nonce, keys->write_iv, 4);
@@ -1852,7 +1853,7 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
param.len = sizeof(gcmParams);
gcmParams.pIv = nonce;
gcmParams.ulIvLen = sizeof(nonce);
- gcmParams.pAAD = additionalData;
+ gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */
gcmParams.ulAADLen = additionalDataLen;
gcmParams.ulTagBits = tagSize * 8;
@@ -1877,14 +1878,11 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
int maxout,
const unsigned char *in,
int inlen,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num)
+ const unsigned char *additionalData,
+ int additionalDataLen)
{
SECStatus rv = SECFailure;
unsigned char nonce[12];
- unsigned char additionalData[13];
- unsigned int additionalDataLen;
unsigned int uOutLen;
AESContext *cx;
CK_GCM_PARAMS gcmParams;
@@ -1892,14 +1890,6 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
static const int tagSize = 16;
static const int explicitNonceLen = 8;
- /* See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the
- * definition of the AEAD additional data. */
- additionalDataLen = ssl3_BuildRecordPseudoHeader(
- additionalData, seq_num, type, PR_TRUE /* includes version */,
- version, PR_FALSE /* not DTLS */,
- inlen - (doDecrypt ? explicitNonceLen + tagSize : 0));
- PORT_Assert(additionalDataLen <= sizeof(additionalData));
-
/* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
* nonce is formed. */
PORT_Assert(keys->write_iv_item.len == 4);
@@ -1928,7 +1918,7 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
gcmParams.pIv = nonce;
gcmParams.ulIvLen = sizeof(nonce);
- gcmParams.pAAD = additionalData;
+ gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */
gcmParams.ulAADLen = additionalDataLen;
gcmParams.ulTagBits = tagSize * 8;
@@ -2229,10 +2219,8 @@ static SECStatus
ssl3_ComputeRecordMAC(
ssl3CipherSpec * spec,
PRBool useServerMacKey,
- PRBool isDTLS,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
+ const unsigned char *header,
+ unsigned int headerLen,
const SSL3Opaque * input,
int inputLength,
unsigned char * outbuf,
@@ -2240,22 +2228,8 @@ ssl3_ComputeRecordMAC(
{
const ssl3MACDef * mac_def;
SECStatus rv;
- PRBool isTLS;
- unsigned int tempLen;
- unsigned char temp[MAX_MAC_LENGTH];
-
- /* TLS MAC includes the record's version field, SSL's doesn't.
- ** We decide which MAC defintiion to use based on the version of
- ** the protocol that was negotiated when the spec became current,
- ** NOT based on the version value in the record itself.
- ** But, we use the record's version value in the computation.
- */
- isTLS = spec->version > SSL_LIBRARY_VERSION_3_0;
- tempLen = ssl3_BuildRecordPseudoHeader(temp, seq_num, type, isTLS,
- version, isDTLS, inputLength);
- PORT_Assert(tempLen <= sizeof(temp));
- PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
+ PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen));
PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));
mac_def = spec->mac_def;
@@ -2300,7 +2274,10 @@ ssl3_ComputeRecordMAC(
return SECFailure;
}
- if (!isTLS) {
+ if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
+ unsigned int tempLen;
+ unsigned char temp[MAX_MAC_LENGTH];
+
/* compute "inner" part of SSL3 MAC */
hashObj->begin(write_mac_context);
if (useServerMacKey)
@@ -2312,7 +2289,7 @@ ssl3_ComputeRecordMAC(
spec->client.write_mac_key_item.data,
spec->client.write_mac_key_item.len);
hashObj->update(write_mac_context, mac_pad_1, pad_bytes);
- hashObj->update(write_mac_context, temp, tempLen);
+ hashObj->update(write_mac_context, header, headerLen);
hashObj->update(write_mac_context, input, inputLength);
hashObj->end(write_mac_context, temp, &tempLen, sizeof temp);
@@ -2343,7 +2320,7 @@ ssl3_ComputeRecordMAC(
}
if (rv == SECSuccess) {
HMAC_Begin(cx);
- HMAC_Update(cx, temp, tempLen);
+ HMAC_Update(cx, header, headerLen);
HMAC_Update(cx, input, inputLength);
rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size);
HMAC_Destroy(cx, PR_FALSE);
@@ -2357,7 +2334,7 @@ ssl3_ComputeRecordMAC(
(useServerMacKey ? spec->server.write_mac_context
: spec->client.write_mac_context);
rv = PK11_DigestBegin(mac_context);
- rv |= PK11_DigestOp(mac_context, temp, tempLen);
+ rv |= PK11_DigestOp(mac_context, header, headerLen);
rv |= PK11_DigestOp(mac_context, input, inputLength);
rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
}
@@ -2383,10 +2360,8 @@ static SECStatus
ssl3_ComputeRecordMACConstantTime(
ssl3CipherSpec * spec,
PRBool useServerMacKey,
- PRBool isDTLS,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
+ const unsigned char *header,
+ unsigned int headerLen,
const SSL3Opaque * input,
int inputLen,
int originalLen,
@@ -2397,9 +2372,7 @@ ssl3_ComputeRecordMACConstantTime(
CK_NSS_MAC_CONSTANT_TIME_PARAMS params;
SECItem param, inputItem, outputItem;
SECStatus rv;
- unsigned char header[13];
PK11SymKey * key;
- int recordLength;
PORT_Assert(inputLen >= spec->mac_size);
PORT_Assert(originalLen >= inputLen);
@@ -2415,42 +2388,15 @@ ssl3_ComputeRecordMACConstantTime(
return SECSuccess;
}
- header[0] = (unsigned char)(seq_num.high >> 24);
- header[1] = (unsigned char)(seq_num.high >> 16);
- header[2] = (unsigned char)(seq_num.high >> 8);
- header[3] = (unsigned char)(seq_num.high >> 0);
- header[4] = (unsigned char)(seq_num.low >> 24);
- header[5] = (unsigned char)(seq_num.low >> 16);
- header[6] = (unsigned char)(seq_num.low >> 8);
- header[7] = (unsigned char)(seq_num.low >> 0);
- header[8] = type;
-
macType = CKM_NSS_HMAC_CONSTANT_TIME;
- recordLength = inputLen - spec->mac_size;
if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
- header[9] = recordLength >> 8;
- header[10] = recordLength;
- params.ulHeaderLen = 11;
- } else {
- if (isDTLS) {
- SSL3ProtocolVersion dtls_version;
-
- dtls_version = dtls_TLSVersionToDTLSVersion(version);
- header[9] = dtls_version >> 8;
- header[10] = dtls_version;
- } else {
- header[9] = version >> 8;
- header[10] = version;
- }
- header[11] = recordLength >> 8;
- header[12] = recordLength;
- params.ulHeaderLen = 13;
}
params.macAlg = spec->mac_def->mmech;
params.ulBodyTotalLen = originalLen;
- params.pHeader = header;
+ params.pHeader = (unsigned char *) header; /* const cast */
+ params.ulHeaderLen = headerLen;
param.data = (unsigned char*) &params;
param.len = sizeof(params);
@@ -2490,9 +2436,8 @@ fallback:
/* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
* length already. */
inputLen -= spec->mac_size;
- return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type,
- version, seq_num, input, inputLen,
- outbuf, outLen);
+ return ssl3_ComputeRecordMAC(spec, useServerMacKey, header, headerLen,
+ input, inputLen, outbuf, outLen);
}
static PRBool
@@ -2541,6 +2486,8 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
PRUint16 headerLen;
int ivLen = 0;
int cipherBytes = 0;
+ unsigned char pseudoHeader[13];
+ unsigned int pseudoHeaderLen;
cipher_def = cwSpec->cipher_def;
headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
@@ -2586,6 +2533,11 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
contentLen = outlen;
}
+ pseudoHeaderLen = ssl3_BuildRecordPseudoHeader(
+ pseudoHeader, cwSpec->write_seq_num, type,
+ cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version,
+ isDTLS, contentLen);
+ PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader));
if (cipher_def->type == type_aead) {
const int nonceLen = cipher_def->explicit_nonce_size;
const int tagLen = cipher_def->tag_size;
@@ -2603,7 +2555,7 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
&cipherBytes, /* out len */
wrBuf->space - headerLen, /* max out */
pIn, contentLen, /* input */
- type, cwSpec->version, cwSpec->write_seq_num);
+ pseudoHeader, pseudoHeaderLen);
if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
@@ -2612,8 +2564,8 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
/*
* Add the MAC
*/
- rv = ssl3_ComputeRecordMAC( cwSpec, isServer, isDTLS,
- type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
+ rv = ssl3_ComputeRecordMAC(cwSpec, isServer,
+ pseudoHeader, pseudoHeaderLen, pIn, contentLen,
wrBuf->buf + headerLen + ivLen + contentLen, &macLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
@@ -10907,6 +10859,8 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
unsigned int originalLen = 0;
unsigned int good;
unsigned int minLength;
+ unsigned char header[13];
+ unsigned int headerLen;
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
@@ -11060,6 +11014,17 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
rType = cText->type;
if (cipher_def->type == type_aead) {
+ /* XXX For many AEAD ciphers, the plaintext is shorter than the
+ * ciphertext by a fixed byte count, but it is not true in general.
+ * Each AEAD cipher should provide a function that returns the
+ * plaintext length for a given ciphertext. */
+ unsigned int decryptedLen =
+ cText->buf->len - cipher_def->explicit_nonce_size -
+ cipher_def->tag_size;
+ headerLen = ssl3_BuildRecordPseudoHeader(
+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+ rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen);
+ PORT_Assert(headerLen <= sizeof(header));
rv = crSpec->aead(
ss->sec.isServer ? &crSpec->client : &crSpec->server,
PR_TRUE, /* do decrypt */
@@ -11068,9 +11033,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
plaintext->space, /* maxout */
cText->buf->buf, /* in */
cText->buf->len, /* inlen */
- rType, /* record type */
- cText->version,
- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num);
+ header, headerLen);
if (rv != SECSuccess) {
good = 0;
}
@@ -11097,7 +11060,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
const unsigned int blockSize = cipher_def->block_size;
const unsigned int macSize = crSpec->mac_size;
- if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) {
+ if (!isTLS) {
good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
plaintext, blockSize, macSize));
} else {
@@ -11107,11 +11070,14 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
}
/* compute the MAC */
+ headerLen = ssl3_BuildRecordPseudoHeader(
+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+ rType, isTLS, cText->version, IS_DTLS(ss),
+ plaintext->len - crSpec->mac_size);
+ PORT_Assert(headerLen <= sizeof(header));
if (cipher_def->type == type_block) {
rv = ssl3_ComputeRecordMACConstantTime(
- crSpec, (PRBool)(!ss->sec.isServer),
- IS_DTLS(ss), rType, cText->version,
- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+ crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
plaintext->buf, plaintext->len, originalLen,
hash, &hashBytes);
@@ -11129,11 +11095,8 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
plaintext->len -= crSpec->mac_size;
rv = ssl3_ComputeRecordMAC(
- crSpec, (PRBool)(!ss->sec.isServer),
- IS_DTLS(ss), rType, cText->version,
- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- plaintext->buf, plaintext->len,
- hash, &hashBytes);
+ crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
+ plaintext->buf, plaintext->len, hash, &hashBytes);
/* We can read the MAC directly from the record because its location
* is public when a stream cipher is used. */
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index bf12e6b0b..0387dddf5 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -62,6 +62,7 @@ typedef SSLSignType SSL3SignType;
#define hmac_md5 ssl_hmac_md5
#define hmac_sha ssl_hmac_sha
#define hmac_sha256 ssl_hmac_sha256
+#define mac_aead ssl_mac_aead
#define SET_ERROR_CODE /* reminder */
#define SEND_ALERT /* reminder */
@@ -515,9 +516,8 @@ typedef SECStatus (*SSLAEADCipher)(
int maxout,
const unsigned char *in,
int inlen,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seqnum);
+ const unsigned char *additionalData,
+ int additionalDataLen);
typedef SECStatus (*SSLCompressor)(void * context,
unsigned char * out,
int * outlen,
diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c
index 2b9c81cc1..291d9cf28 100644
--- a/lib/ssl/sslinfo.c
+++ b/lib/ssl/sslinfo.c
@@ -128,6 +128,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
#define B_40 128, 40, 40
#define B_0 0, 0, 0
+#define M_AEAD_128 "AEAD", ssl_mac_aead, 128
#define M_SHA256 "SHA256", ssl_hmac_sha256, 256
#define M_SHA "SHA1", ssl_mac_sha, 160
#define M_MD5 "MD5", ssl_mac_md5, 128
@@ -135,7 +136,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
static const SSLCipherSuiteInfo suiteInfo[] = {
/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
-{0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_NULL, 1, 0, 0, },
+{0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
@@ -150,7 +151,7 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
-{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_NULL, 1, 0, 0, },
+{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
{0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
@@ -180,8 +181,8 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
#ifdef NSS_ENABLE_ECC
/* ECC cipher suites */
-{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_NULL, 1, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_NULL, 1, 0, 0, },
+{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
+{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
index 51162ad99..6b9362934 100644
--- a/lib/ssl/sslt.h
+++ b/lib/ssl/sslt.h
@@ -90,7 +90,8 @@ typedef enum {
ssl_mac_sha = 2,
ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */
ssl_hmac_sha = 4, /* TLS HMAC version of mac_sha */
- ssl_hmac_sha256 = 5
+ ssl_hmac_sha256 = 5,
+ ssl_mac_aead = 6
} SSLMACAlgorithm;
typedef enum {
@@ -146,6 +147,9 @@ typedef struct SSLCipherSuiteInfoStr {
PRUint16 effectiveKeyBits;
/* MAC info */
+ /* AEAD ciphers don't have a MAC. For an AEAD cipher, macAlgorithmName
+ * is "AEAD", macAlgorithm is ssl_mac_aead, and macBits is the length in
+ * bits of the authentication tag. */
const char * macAlgorithmName;
SSLMACAlgorithm macAlgorithm;
PRUint16 macBits;