summaryrefslogtreecommitdiff
path: root/lib/ssl
diff options
context:
space:
mode:
authorMartin Thomson <martin.thomson@gmail.com>2019-02-17 15:27:05 -0800
committerMartin Thomson <martin.thomson@gmail.com>2019-02-17 15:27:05 -0800
commit2dbd47b4ca0042f90f592693142540720796aea2 (patch)
tree61d3f7999985382d5461505b023c51e0f2d6444a /lib/ssl
parentb20f40ec7247150b407182a6d5d0c52739e36e29 (diff)
downloadnss-hg-2dbd47b4ca0042f90f592693142540720796aea2.tar.gz
Bug 1528175 - Expose an AEAD function, r=ekr
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/manifest.mn1
-rw-r--r--lib/ssl/ssl.gyp1
-rw-r--r--lib/ssl/ssl3con.c63
-rw-r--r--lib/ssl/sslexp.h51
-rw-r--r--lib/ssl/sslimpl.h21
-rw-r--r--lib/ssl/sslprimitive.c188
-rw-r--r--lib/ssl/sslsock.c4
-rw-r--r--lib/ssl/sslspec.h16
-rw-r--r--lib/ssl/tls13con.c88
-rw-r--r--lib/ssl/tls13con.h6
-rw-r--r--lib/ssl/tls13esni.c4
-rw-r--r--lib/ssl/tls13esni.h4
-rw-r--r--lib/ssl/tls13exthandle.c4
13 files changed, 358 insertions, 93 deletions
diff --git a/lib/ssl/manifest.mn b/lib/ssl/manifest.mn
index fe9470bd0..201a01049 100644
--- a/lib/ssl/manifest.mn
+++ b/lib/ssl/manifest.mn
@@ -55,6 +55,7 @@ CSRCS = \
tls13replay.c \
sslcert.c \
sslgrp.c \
+ sslprimitive.c \
tls13esni.c \
$(NULL)
diff --git a/lib/ssl/ssl.gyp b/lib/ssl/ssl.gyp
index 2e28f6775..235f752d5 100644
--- a/lib/ssl/ssl.gyp
+++ b/lib/ssl/ssl.gyp
@@ -35,6 +35,7 @@
'sslinit.c',
'sslmutex.c',
'sslnonce.c',
+ 'sslprimitive.c',
'sslreveal.c',
'sslsecur.c',
'sslsnce.c',
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index b5b047228..da609fb06 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -553,10 +553,9 @@ SSL_AtomicIncrementLong(long *x)
}
}
-static PRBool
-ssl3_CipherSuiteAllowedForVersionRange(
- ssl3CipherSuite cipherSuite,
- const SSLVersionRange *vrange)
+PRBool
+ssl3_CipherSuiteAllowedForVersionRange(ssl3CipherSuite cipherSuite,
+ const SSLVersionRange *vrange)
{
switch (cipherSuite) {
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
@@ -912,8 +911,8 @@ count_cipher_suites(sslSocket *ss, PRUint8 policy)
* Null compression, mac and encryption functions
*/
SECStatus
-Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
- const unsigned char *input, int inputLen)
+Null_Cipher(void *ctx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen)
{
if (inputLen > maxOutputLen) {
*outputLen = 0; /* Match PK11_CipherOp in setting outputLen */
@@ -1554,15 +1553,15 @@ ssl3_BuildRecordPseudoHeader(DTLSEpoch epoch,
}
static SECStatus
-ssl3_AESGCM(ssl3KeyMaterial *keys,
+ssl3_AESGCM(const ssl3KeyMaterial *keys,
PRBool doDecrypt,
unsigned char *out,
- int *outlen,
- int maxout,
+ unsigned int *outlen,
+ unsigned int maxout,
const unsigned char *in,
- int inlen,
+ unsigned int inlen,
const unsigned char *additionalData,
- int additionalDataLen)
+ unsigned int additionalDataLen)
{
SECItem param;
SECStatus rv = SECFailure;
@@ -1616,11 +1615,11 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
}
static SECStatus
-ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
+ssl3_ChaCha20Poly1305(const ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, unsigned int *outlen, unsigned int maxout,
+ const unsigned char *in, unsigned int inlen,
const unsigned char *additionalData,
- int additionalDataLen)
+ unsigned int additionalDataLen)
{
size_t i;
SECItem param;
@@ -2012,7 +2011,7 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
unsigned int ivLen = 0;
unsigned char pseudoHeaderBuf[13];
sslBuffer pseudoHeader = SSL_BUFFER(pseudoHeaderBuf);
- int len;
+ unsigned int len;
if (cwSpec->cipherDef->type == type_block &&
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
@@ -2130,15 +2129,15 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
memmove(SSL_BUFFER_NEXT(wrBuf) + p1Len, pIn + p1Len, oddLen);
}
if (p1Len > 0) {
- int cipherBytesPart1 = -1;
+ unsigned int cipherBytesPart1 = 0;
rv = cwSpec->cipher(cwSpec->cipherContext,
SSL_BUFFER_NEXT(wrBuf), /* output */
&cipherBytesPart1, /* actual outlen */
p1Len, /* max outlen */
pIn,
p1Len); /* input, and inputlen */
- PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int)p1Len);
- if (rv != SECSuccess || cipherBytesPart1 != (int)p1Len) {
+ PORT_Assert(rv == SECSuccess && cipherBytesPart1 == p1Len);
+ if (rv != SECSuccess || cipherBytesPart1 != p1Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
@@ -2146,15 +2145,15 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
PORT_Assert(rv == SECSuccess);
}
if (p2Len > 0) {
- int cipherBytesPart2 = -1;
+ unsigned int cipherBytesPart2 = 0;
rv = cwSpec->cipher(cwSpec->cipherContext,
SSL_BUFFER_NEXT(wrBuf),
&cipherBytesPart2, /* output and actual outLen */
p2Len, /* max outlen */
SSL_BUFFER_NEXT(wrBuf),
p2Len); /* input and inputLen*/
- PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int)p2Len);
- if (rv != SECSuccess || cipherBytesPart2 != (int)p2Len) {
+ PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
+ if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
@@ -2241,7 +2240,7 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSLContentType ct,
#ifdef UNSAFE_FUZZER_MODE
{
- int len;
+ unsigned int len;
rv = Null_Cipher(NULL, SSL_BUFFER_NEXT(wrBuf), &len,
SSL_BUFFER_SPACE(wrBuf), pIn, contentLen);
if (rv != SECSuccess) {
@@ -12200,7 +12199,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
* discard it before decrypting the rest.
*/
PRUint8 iv[MAX_IV_LENGTH];
- int decoded;
+ unsigned int decoded;
ivLen = cipher_def->iv_size;
if (ivLen < 8 || ivLen > sizeof(iv)) {
@@ -12248,12 +12247,12 @@ ssl3_UnprotectRecord(sslSocket *ss,
rType, isTLS, rVersion, IS_DTLS(ss), decryptedLen, &header);
PORT_Assert(rv == SECSuccess);
rv = spec->aead(&spec->keyMaterial,
- PR_TRUE, /* do decrypt */
- plaintext->buf, /* out */
- (int *)&plaintext->len, /* outlen */
- plaintext->space, /* maxout */
- cText->buf->buf, /* in */
- cText->buf->len, /* inlen */
+ PR_TRUE, /* do decrypt */
+ plaintext->buf, /* out */
+ &plaintext->len, /* outlen */
+ plaintext->space, /* maxout */
+ cText->buf->buf, /* in */
+ cText->buf->len, /* inlen */
SSL_BUFFER_BASE(&header), SSL_BUFFER_LEN(&header));
if (rv != SECSuccess) {
good = 0;
@@ -12266,7 +12265,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
/* decrypt from cText buf to plaintext. */
rv = spec->cipher(
- spec->cipherContext, plaintext->buf, (int *)&plaintext->len,
+ spec->cipherContext, plaintext->buf, &plaintext->len,
plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
if (rv != SECSuccess) {
goto decrypt_loser;
@@ -12548,7 +12547,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText)
rv = SECFailure;
} else {
#ifdef UNSAFE_FUZZER_MODE
- rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
+ rv = Null_Cipher(NULL, plaintext->buf, &plaintext->len,
plaintext->space, cText->buf->buf, cText->buf->len);
#else
/* IMPORTANT: Unprotect functions MUST NOT send alerts
diff --git a/lib/ssl/sslexp.h b/lib/ssl/sslexp.h
index 8f4720cdc..447547d2f 100644
--- a/lib/ssl/sslexp.h
+++ b/lib/ssl/sslexp.h
@@ -626,6 +626,57 @@ typedef SECStatus(PR_CALLBACK *SSLRecordWriteCallback)(
PRUint16 * _writeEpoch), \
(fd, readEpoch, writeEpoch))
+/*
+ * The following AEAD functions expose an AEAD primitive that uses a ciphersuite
+ * to set parameters. The ciphersuite determines the Hash function used by
+ * HKDF, the AEAD function, and the size of key and IV. Only TLS 1.3
+ * ciphersuites can be used.
+ *
+ * The key and IV are generated using the TLS KDF with a custom label. That is
+ * HKDF-Expand-Label(secret, labelPrefix + " key" or " iv", "", L).
+ *
+ * The encrypt and decrypt functions use a nonce construction identical to that
+ * used in TLS. The lower bits of the IV are XORed with the 64-bit counter to
+ * produce the nonce. Otherwise, this is an AEAD interface similar to that
+ * described in RFC 5116.
+ */
+typedef struct SSLAeadContextStr SSLAeadContext;
+
+#define SSL_MakeAead(secret, cipherSuite, labelPrefix, labelPrefixLen, ctx) \
+ SSL_EXPERIMENTAL_API("SSL_MakeAead", \
+ (PK11SymKey * _secret, PRUint16 _cipherSuite, \
+ const char *_labelPrefix, \
+ unsigned int _labelPrefixLen, \
+ SSLAeadContext **_ctx), \
+ (secret, cipherSuite, labelPrefix, labelPrefixLen, ctx))
+
+#define SSL_AeadEncrypt(ctx, counter, aad, aadLen, in, inLen, \
+ output, outputLen, maxOutputLen) \
+ SSL_EXPERIMENTAL_API("SSL_AeadEncrypt", \
+ (const SSLAeadContext *_ctx, PRUint64 _counter, \
+ const PRUint8 *_aad, unsigned int _aadLen, \
+ const PRUint8 *_in, unsigned int _inLen, \
+ PRUint8 *_out, unsigned int *_outLen, \
+ unsigned int _maxOut), \
+ (ctx, counter, aad, aadLen, in, inLen, \
+ output, outputLen, maxOutputLen))
+
+#define SSL_AeadDecrypt(ctx, counter, aad, aadLen, in, inLen, \
+ output, outputLen, maxOutputLen) \
+ SSL_EXPERIMENTAL_API("SSL_AeadDecrypt", \
+ (const SSLAeadContext *_ctx, PRUint64 _counter, \
+ const PRUint8 *_aad, unsigned int _aadLen, \
+ const PRUint8 *_in, unsigned int _inLen, \
+ PRUint8 *_output, unsigned int *_outLen, \
+ unsigned int _maxOut), \
+ (ctx, counter, aad, aadLen, in, inLen, \
+ output, outputLen, maxOutputLen))
+
+#define SSL_DestroyAead(ctx) \
+ SSL_EXPERIMENTAL_API("SSL_DestroyAead", \
+ (SSLAeadContext * _ctx), \
+ (ctx))
+
/* Deprecated experimental APIs */
#define SSL_UseAltServerHelloType(fd, enable) SSL_DEPRECATED_EXPERIMENTAL_API
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index d1bc69478..68abbdfa1 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -1209,9 +1209,9 @@ extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
extern SECStatus ssl3_ConstrainRangeByPolicy(void);
extern SECStatus ssl3_InitState(sslSocket *ss);
-extern SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
- int maxOutputLen, const unsigned char *input,
- int inputLen);
+extern SECStatus Null_Cipher(void *ctx, unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen, const unsigned char *input,
+ unsigned int inputLen);
extern void ssl3_RestartHandshakeHashes(sslSocket *ss);
extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
const unsigned char *b,
@@ -1663,6 +1663,8 @@ SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid,
const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
const ssl3CipherSuiteCfg *ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite,
const ssl3CipherSuiteCfg *suites);
+PRBool ssl3_CipherSuiteAllowedForVersionRange(ssl3CipherSuite cipherSuite,
+ const SSLVersionRange *vrange);
SECStatus ssl3_SelectServerCert(sslSocket *ss);
SECStatus ssl_PickSignatureScheme(sslSocket *ss,
@@ -1758,6 +1760,19 @@ SECStatus SSLExp_GetCurrentEpoch(PRFileDesc *fd, PRUint16 *readEpoch,
#define SSLResumptionTokenVersion 2
+SECStatus SSLExp_MakeAead(PK11SymKey *secret, PRUint16 cipherSuite,
+ const char *labelPrefix, unsigned int labelPrefixLen,
+ SSLAeadContext **ctx);
+SECStatus SSLExp_DestroyAead(SSLAeadContext *ctx);
+SECStatus SSLExp_AeadEncrypt(const SSLAeadContext *ctx, PRUint64 counter,
+ const PRUint8 *aad, unsigned int aadLen,
+ const PRUint8 *plaintext, unsigned int plaintextLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxOut);
+SECStatus SSLExp_AeadDecrypt(const SSLAeadContext *ctx, PRUint64 counter,
+ const PRUint8 *aad, unsigned int aadLen,
+ const PRUint8 *plaintext, unsigned int plaintextLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxOut);
+
SEC_END_PROTOS
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
diff --git a/lib/ssl/sslprimitive.c b/lib/ssl/sslprimitive.c
new file mode 100644
index 000000000..72caf962f
--- /dev/null
+++ b/lib/ssl/sslprimitive.c
@@ -0,0 +1,188 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * SSL Primitives: Public HKDF and AEAD Functions
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "keyhi.h"
+#include "pk11pub.h"
+#include "sechash.h"
+#include "ssl.h"
+#include "sslexp.h"
+#include "sslerr.h"
+#include "sslproto.h"
+
+#include "sslimpl.h"
+#include "tls13con.h"
+#include "tls13hkdf.h"
+
+struct SSLAeadContextStr {
+ CK_MECHANISM_TYPE mech;
+ ssl3KeyMaterial keys;
+};
+
+SECStatus
+SSLExp_MakeAead(PK11SymKey *secret, PRUint16 cipherSuite,
+ const char *labelPrefix, unsigned int labelPrefixLen,
+ SSLAeadContext **ctx)
+{
+ SSLAeadContext *out = NULL;
+ char label[255]; // Maximum length label.
+ static const char *const keySuffix = "key";
+ static const char *const ivSuffix = "iv";
+
+ PORT_Assert(strlen(keySuffix) >= strlen(ivSuffix));
+ if (secret == NULL || ctx == NULL ||
+ (labelPrefix == NULL && labelPrefixLen > 0) ||
+ labelPrefixLen + strlen(keySuffix) > sizeof(label)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+
+ // Lookup and check the suite.
+ SSLVersionRange tls13 = { SSL_LIBRARY_VERSION_TLS_1_3,
+ SSL_LIBRARY_VERSION_TLS_1_3 };
+ if (!ssl3_CipherSuiteAllowedForVersionRange(cipherSuite, &tls13)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ const ssl3CipherSuiteDef *suiteDef = ssl_LookupCipherSuiteDef(cipherSuite);
+ const ssl3BulkCipherDef *cipher = ssl_GetBulkCipherDef(suiteDef);
+ if (cipher->type != type_aead) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ SSLHashType hash = suiteDef->prf_hash;
+
+ out = PORT_ZNew(SSLAeadContext);
+ if (out == NULL) {
+ goto loser;
+ }
+ out->mech = ssl3_Alg2Mech(cipher->calg);
+
+ memcpy(label, labelPrefix, labelPrefixLen);
+ memcpy(label + labelPrefixLen, ivSuffix, strlen(ivSuffix));
+ unsigned int labelLen = labelPrefixLen + strlen(ivSuffix);
+ unsigned int ivLen = cipher->iv_size + cipher->explicit_nonce_size;
+ SECStatus rv = tls13_HkdfExpandLabelRaw(secret, hash,
+ NULL, 0, // Handshake hash.
+ label, labelLen,
+ out->keys.iv, ivLen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ memcpy(label + labelPrefixLen, keySuffix, strlen(keySuffix));
+ labelLen = labelPrefixLen + strlen(keySuffix);
+ rv = tls13_HkdfExpandLabel(secret, hash,
+ NULL, 0, // Handshake hash.
+ label, labelLen,
+ out->mech, cipher->key_size, &out->keys.key);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ *ctx = out;
+ return SECSuccess;
+
+loser:
+ SSLExp_DestroyAead(out);
+ return SECFailure;
+}
+
+SECStatus
+SSLExp_DestroyAead(SSLAeadContext *ctx)
+{
+ if (!ctx) {
+ return SECSuccess;
+ }
+
+ PK11_FreeSymKey(ctx->keys.key);
+ PORT_ZFree(ctx, sizeof(*ctx));
+ return SECSuccess;
+}
+
+/* Bug 1529440 exists to refactor this and the other AEAD uses. */
+static SECStatus
+ssl_AeadInner(const SSLAeadContext *ctx, PRBool decrypt, PRUint64 counter,
+ const PRUint8 *aad, unsigned int aadLen,
+ const PRUint8 *plaintext, unsigned int plaintextLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxOut)
+{
+ if (ctx == NULL || (aad == NULL && aadLen > 0) || plaintext == NULL ||
+ out == NULL || outLen == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ // Setup the nonce.
+ PRUint8 nonce[12] = { 0 };
+ sslBuffer nonceBuf = SSL_BUFFER_FIXED(nonce + sizeof(nonce) - sizeof(counter),
+ sizeof(counter));
+ SECStatus rv = sslBuffer_AppendNumber(&nonceBuf, counter, sizeof(counter));
+ if (rv != SECSuccess) {
+ PORT_Assert(0);
+ return SECFailure;
+ }
+ for (int i = 0; i < sizeof(nonce); ++i) {
+ nonce[i] ^= ctx->keys.iv[i];
+ }
+
+ // Build AEAD parameters.
+ CK_GCM_PARAMS gcmParams = { 0 };
+ CK_NSS_AEAD_PARAMS aeadParams = { 0 };
+ unsigned char *params;
+ unsigned int paramsLen;
+ switch (ctx->mech) {
+ case CKM_AES_GCM:
+ gcmParams.pIv = nonce;
+ gcmParams.ulIvLen = sizeof(nonce);
+ gcmParams.pAAD = (unsigned char *)aad; // const cast :(
+ gcmParams.ulAADLen = aadLen;
+ gcmParams.ulTagBits = 128; // GCM measures in bits.
+ params = (unsigned char *)&gcmParams;
+ paramsLen = sizeof(gcmParams);
+ break;
+
+ case CKM_NSS_CHACHA20_POLY1305:
+ aeadParams.pNonce = nonce;
+ aeadParams.ulNonceLen = sizeof(nonce);
+ aeadParams.pAAD = (unsigned char *)aad; // const cast :(
+ aeadParams.ulAADLen = aadLen;
+ aeadParams.ulTagLen = 16; // AEAD measures in octets.
+ params = (unsigned char *)&aeadParams;
+ paramsLen = sizeof(aeadParams);
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ return tls13_AEAD(&ctx->keys, decrypt, out, outLen, maxOut,
+ plaintext, plaintextLen, ctx->mech, params, paramsLen);
+}
+
+SECStatus
+SSLExp_AeadEncrypt(const SSLAeadContext *ctx, PRUint64 counter,
+ const PRUint8 *aad, unsigned int aadLen,
+ const PRUint8 *plaintext, unsigned int plaintextLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxOut)
+{
+ // false == encrypt
+ return ssl_AeadInner(ctx, PR_FALSE, counter, aad, aadLen,
+ plaintext, plaintextLen, out, outLen, maxOut);
+}
+
+SECStatus
+SSLExp_AeadDecrypt(const SSLAeadContext *ctx, PRUint64 counter,
+ const PRUint8 *aad, unsigned int aadLen,
+ const PRUint8 *plaintext, unsigned int plaintextLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxOut)
+{
+ // true == decrypt
+ return ssl_AeadInner(ctx, PR_TRUE, counter, aad, aadLen,
+ plaintext, plaintextLen, out, outLen, maxOut);
+}
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
index b8b75dc9c..2904ccddb 100644
--- a/lib/ssl/sslsock.c
+++ b/lib/ssl/sslsock.c
@@ -4041,6 +4041,9 @@ struct {
void *function;
} ssl_experimental_functions[] = {
#ifndef SSL_DISABLE_EXPERIMENTAL_API
+ EXP(AeadDecrypt),
+ EXP(AeadEncrypt),
+ EXP(DestroyAead),
EXP(DestroyResumptionTokenInfo),
EXP(EnableESNI),
EXP(EncodeESNIKeys),
@@ -4050,6 +4053,7 @@ struct {
EXP(HelloRetryRequestCallback),
EXP(InstallExtensionHooks),
EXP(KeyUpdate),
+ EXP(MakeAead),
EXP(RecordLayerData),
EXP(RecordLayerWriteCallback),
EXP(SecretCallback),
diff --git a/lib/ssl/sslspec.h b/lib/ssl/sslspec.h
index 967e35862..ca9ef540f 100644
--- a/lib/ssl/sslspec.h
+++ b/lib/ssl/sslspec.h
@@ -101,20 +101,20 @@ typedef struct {
typedef SECStatus (*SSLCipher)(void *context,
unsigned char *out,
- int *outlen,
- int maxout,
+ unsigned int *outlen,
+ unsigned int maxout,
const unsigned char *in,
- int inlen);
+ unsigned int inlen);
typedef SECStatus (*SSLAEADCipher)(
- ssl3KeyMaterial *keys,
+ const ssl3KeyMaterial *keys,
PRBool doDecrypt,
unsigned char *out,
- int *outlen,
- int maxout,
+ unsigned int *outlen,
+ unsigned int maxout,
const unsigned char *in,
- int inlen,
+ unsigned int inlen,
const unsigned char *additionalData,
- int additionalDataLen);
+ unsigned int additionalDataLen);
/* The DTLS anti-replay window in number of packets. Defined here because we
* need it in the cipher spec. Note that this is a ring buffer but left and
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
index 5daa48951..5e028727b 100644
--- a/lib/ssl/tls13con.c
+++ b/lib/ssl/tls13con.c
@@ -28,18 +28,24 @@
static SECStatus tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
SSLSecretDirection install,
PRBool deleteSecret);
-static SECStatus tls13_AESGCM(
- ssl3KeyMaterial *keys,
- PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
- const unsigned char *additionalData, int additionalDataLen);
-static SECStatus tls13_ChaCha20Poly1305(
- ssl3KeyMaterial *keys,
- PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
- const unsigned char *additionalData, int additionalDataLen);
+static SECStatus tls13_AESGCM(const ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out,
+ unsigned int *outlen,
+ unsigned int maxout,
+ const unsigned char *in,
+ unsigned int inlen,
+ const unsigned char *additionalData,
+ unsigned int additionalDataLen);
+static SECStatus tls13_ChaCha20Poly1305(const ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out,
+ unsigned int *outlen,
+ unsigned int maxout,
+ const unsigned char *in,
+ unsigned int inlen,
+ const unsigned char *additionalData,
+ unsigned int additionalDataLen);
static SECStatus tls13_SendServerHelloSequence(sslSocket *ss);
static SECStatus tls13_SendEncryptedExtensions(sslSocket *ss);
static void tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group);
@@ -293,7 +299,7 @@ tls13_GetHashSize(const sslSocket *ss)
return tls13_GetHashSizeForHash(tls13_GetHash(ss));
}
-static CK_MECHANISM_TYPE
+CK_MECHANISM_TYPE
tls13_GetHkdfMechanismForHash(SSLHashType hash)
{
switch (hash) {
@@ -3711,7 +3717,7 @@ tls13_DestroyEarlyData(PRCList *list)
* See RFC 5288 and https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04#section-2
*/
static void
-tls13_WriteNonce(ssl3KeyMaterial *keys,
+tls13_WriteNonce(const ssl3KeyMaterial *keys,
const unsigned char *seqNumBuf, unsigned int seqNumLen,
unsigned char *nonce, unsigned int nonceLen)
{
@@ -3734,41 +3740,35 @@ tls13_WriteNonce(ssl3KeyMaterial *keys,
* a sequence number. In TLS 1.3 there is no additional data so this value is
* just the encoded sequence number.
*/
-static SECStatus
-tls13_AEAD(ssl3KeyMaterial *keys, PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
+SECStatus
+tls13_AEAD(const ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, unsigned int *outlen, unsigned int maxout,
+ const unsigned char *in, unsigned int inlen,
CK_MECHANISM_TYPE mechanism,
unsigned char *aeadParams, unsigned int aeadParamLength)
{
- SECStatus rv;
- unsigned int uOutLen = 0;
SECItem param = {
siBuffer, aeadParams, aeadParamLength
};
if (doDecrypt) {
- rv = PK11_Decrypt(keys->key, mechanism, &param,
- out, &uOutLen, maxout, in, inlen);
- } else {
- rv = PK11_Encrypt(keys->key, mechanism, &param,
- out, &uOutLen, maxout, in, inlen);
+ return PK11_Decrypt(keys->key, mechanism, &param,
+ out, outlen, maxout, in, inlen);
}
- *outlen = (int)uOutLen;
-
- return rv;
+ return PK11_Encrypt(keys->key, mechanism, &param,
+ out, outlen, maxout, in, inlen);
}
static SECStatus
-tls13_AESGCM(ssl3KeyMaterial *keys,
+tls13_AESGCM(const ssl3KeyMaterial *keys,
PRBool doDecrypt,
unsigned char *out,
- int *outlen,
- int maxout,
+ unsigned int *outlen,
+ unsigned int maxout,
const unsigned char *in,
- int inlen,
+ unsigned int inlen,
const unsigned char *additionalData,
- int additionalDataLen)
+ unsigned int additionalDataLen)
{
CK_GCM_PARAMS gcmParams;
unsigned char nonce[12];
@@ -3789,11 +3789,11 @@ tls13_AESGCM(ssl3KeyMaterial *keys,
}
static SECStatus
-tls13_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
+tls13_ChaCha20Poly1305(const ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, unsigned int *outlen, unsigned int maxout,
+ const unsigned char *in, unsigned int inlen,
const unsigned char *additionalData,
- int additionalDataLen)
+ unsigned int additionalDataLen)
{
CK_NSS_AEAD_PARAMS aeadParams;
unsigned char nonce[12];
@@ -5145,7 +5145,7 @@ tls13_ProtectRecord(sslSocket *ss,
PRBool needsLength;
PRUint8 aad[21];
unsigned int aadLen;
- int len;
+ unsigned int len;
PORT_Assert(cipher_def->type == type_aead);
@@ -5266,12 +5266,12 @@ tls13_UnprotectRecord(sslSocket *ss,
return SECFailure;
}
rv = spec->aead(&spec->keyMaterial,
- PR_TRUE, /* do decrypt */
- plaintext->buf, /* out */
- (int *)&plaintext->len, /* outlen */
- plaintext->space, /* maxout */
- cText->buf->buf, /* in */
- cText->buf->len, /* inlen */
+ PR_TRUE, /* do decrypt */
+ plaintext->buf, /* out */
+ &plaintext->len, /* outlen */
+ plaintext->space, /* maxout */
+ cText->buf->buf, /* in */
+ cText->buf->len, /* inlen */
aad, aadLen);
if (rv != SECSuccess) {
SSL_TRC(3,
diff --git a/lib/ssl/tls13con.h b/lib/ssl/tls13con.h
index f6f52511d..4b3bb321e 100644
--- a/lib/ssl/tls13con.h
+++ b/lib/ssl/tls13con.h
@@ -52,6 +52,7 @@ SSLHashType tls13_GetHash(const sslSocket *ss);
unsigned int tls13_GetHashSizeForHash(SSLHashType hash);
unsigned int tls13_GetHashSize(const sslSocket *ss);
CK_MECHANISM_TYPE tls13_GetHkdfMechanism(sslSocket *ss);
+CK_MECHANISM_TYPE tls13_GetHkdfMechanismForHash(SSLHashType hash);
SECStatus tls13_ComputeHash(sslSocket *ss, SSL3Hashes *hashes,
const PRUint8 *buf, unsigned int len);
SECStatus tls13_ComputeHandshakeHashes(sslSocket *ss,
@@ -130,6 +131,11 @@ SECStatus tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request,
SECStatus SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate);
PRBool tls13_MaybeTls13(sslSocket *ss);
SSLAEADCipher tls13_GetAead(const ssl3BulkCipherDef *cipherDef);
+SECStatus tls13_AEAD(const ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, unsigned int *outlen, unsigned int maxout,
+ const unsigned char *in, unsigned int inlen,
+ CK_MECHANISM_TYPE mechanism,
+ unsigned char *aeadParams, unsigned int aeadParamLength);
void tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec);
SECStatus SSLExp_SendCertificateRequest(PRFileDesc *fd);
diff --git a/lib/ssl/tls13esni.c b/lib/ssl/tls13esni.c
index e2328769b..13b70de79 100644
--- a/lib/ssl/tls13esni.c
+++ b/lib/ssl/tls13esni.c
@@ -721,8 +721,8 @@ tls13_ServerGetEsniAEAD(const sslSocket *ss, PRUint64 suite,
}
SECStatus
-tls13_ServerDecryptEsniXtn(const sslSocket *ss, PRUint8 *in, unsigned int inLen,
- PRUint8 *out, int *outLen, int maxLen)
+tls13_ServerDecryptEsniXtn(const sslSocket *ss, const PRUint8 *in, unsigned int inLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxLen)
{
sslReader rdr = SSL_READER(in, inLen);
PRUint64 suite;
diff --git a/lib/ssl/tls13esni.h b/lib/ssl/tls13esni.h
index 6c52c9952..0fb12d25e 100644
--- a/lib/ssl/tls13esni.h
+++ b/lib/ssl/tls13esni.h
@@ -45,7 +45,7 @@ SECStatus tls13_ComputeESNIKeys(const sslSocket *ss,
SECStatus tls13_FormatEsniAADInput(sslBuffer *aadInput,
PRUint8 *keyShare, unsigned int keyShareLen);
-SECStatus tls13_ServerDecryptEsniXtn(const sslSocket *ss, PRUint8 *in, unsigned int inLen,
- PRUint8 *out, int *outLen, int maxLen);
+SECStatus tls13_ServerDecryptEsniXtn(const sslSocket *ss, const PRUint8 *in, unsigned int inLen,
+ PRUint8 *out, unsigned int *outLen, unsigned int maxLen);
#endif
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
index 5ecc2e796..9def16d41 100644
--- a/lib/ssl/tls13exthandle.c
+++ b/lib/ssl/tls13exthandle.c
@@ -1140,7 +1140,7 @@ tls13_ClientSendEsniXtn(const sslSocket *ss, TLSExtensionData *xtnData,
ssl3KeyMaterial keyMat;
SSLAEADCipher aead;
PRUint8 outBuf[1024];
- int outLen;
+ unsigned int outLen;
unsigned int sniStart;
unsigned int sniLen;
sslBuffer aadInput = SSL_BUFFER_EMPTY;
@@ -1294,7 +1294,7 @@ tls13_ServerHandleEsniXtn(const sslSocket *ss, TLSExtensionData *xtnData,
{
sslReadBuffer buf;
PRUint8 *plainText = NULL;
- int ptLen;
+ unsigned int ptLen;
SECStatus rv;
/* If we are doing < TLS 1.3, then ignore this. */