mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 1345368 - land NSS d621b1e53054, r=me
--HG-- extra : rebase_source : 3030e2bdde664359d725bda01379c858492b7686
This commit is contained in:
parent
45004a3e56
commit
5a25c3f857
@ -1 +1 @@
|
||||
37ccb22f8e51
|
||||
d621b1e53054
|
||||
|
@ -26,70 +26,6 @@
|
||||
|
||||
#include "pkcs11f.h"
|
||||
|
||||
/* mapping between ECCurveName enum and pointers to ECCurveParams */
|
||||
static SECOidTag ecCurve_oid_map[] = {
|
||||
SEC_OID_UNKNOWN, /* ECCurve_noName */
|
||||
SEC_OID_ANSIX962_EC_PRIME192V1, /* ECCurve_NIST_P192 */
|
||||
SEC_OID_SECG_EC_SECP224R1, /* ECCurve_NIST_P224 */
|
||||
SEC_OID_ANSIX962_EC_PRIME256V1, /* ECCurve_NIST_P256 */
|
||||
SEC_OID_SECG_EC_SECP384R1, /* ECCurve_NIST_P384 */
|
||||
SEC_OID_SECG_EC_SECP521R1, /* ECCurve_NIST_P521 */
|
||||
SEC_OID_SECG_EC_SECT163K1, /* ECCurve_NIST_K163 */
|
||||
SEC_OID_SECG_EC_SECT163R1, /* ECCurve_NIST_B163 */
|
||||
SEC_OID_SECG_EC_SECT233K1, /* ECCurve_NIST_K233 */
|
||||
SEC_OID_SECG_EC_SECT233R1, /* ECCurve_NIST_B233 */
|
||||
SEC_OID_SECG_EC_SECT283K1, /* ECCurve_NIST_K283 */
|
||||
SEC_OID_SECG_EC_SECT283R1, /* ECCurve_NIST_B283 */
|
||||
SEC_OID_SECG_EC_SECT409K1, /* ECCurve_NIST_K409 */
|
||||
SEC_OID_SECG_EC_SECT409R1, /* ECCurve_NIST_B409 */
|
||||
SEC_OID_SECG_EC_SECT571K1, /* ECCurve_NIST_K571 */
|
||||
SEC_OID_SECG_EC_SECT571R1, /* ECCurve_NIST_B571 */
|
||||
SEC_OID_ANSIX962_EC_PRIME192V2,
|
||||
SEC_OID_ANSIX962_EC_PRIME192V3,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V1,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V2,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V2,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB176V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V2,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB208W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V2,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB272W1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB304W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB359V1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB368W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB431R1,
|
||||
SEC_OID_SECG_EC_SECP112R1,
|
||||
SEC_OID_SECG_EC_SECP112R2,
|
||||
SEC_OID_SECG_EC_SECP128R1,
|
||||
SEC_OID_SECG_EC_SECP128R2,
|
||||
SEC_OID_SECG_EC_SECP160K1,
|
||||
SEC_OID_SECG_EC_SECP160R1,
|
||||
SEC_OID_SECG_EC_SECP160R2,
|
||||
SEC_OID_SECG_EC_SECP192K1,
|
||||
SEC_OID_SECG_EC_SECP224K1,
|
||||
SEC_OID_SECG_EC_SECP256K1,
|
||||
SEC_OID_SECG_EC_SECT113R1,
|
||||
SEC_OID_SECG_EC_SECT113R2,
|
||||
SEC_OID_SECG_EC_SECT131R1,
|
||||
SEC_OID_SECG_EC_SECT131R2,
|
||||
SEC_OID_SECG_EC_SECT163R1,
|
||||
SEC_OID_SECG_EC_SECT193R1,
|
||||
SEC_OID_SECG_EC_SECT193R2,
|
||||
SEC_OID_SECG_EC_SECT239K1,
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_1 */
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_8 */
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_9 */
|
||||
SEC_OID_CURVE25519,
|
||||
SEC_OID_UNKNOWN /* ECCurve_pastLastCurve */
|
||||
};
|
||||
|
||||
typedef SECStatus (*op_func)(void *, void *, void *);
|
||||
typedef SECStatus (*pk11_op_func)(CK_SESSION_HANDLE, void *, void *, void *);
|
||||
|
||||
@ -374,30 +310,6 @@ PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ecName2params(ECCurveName curve, SECKEYECParams *params)
|
||||
{
|
||||
SECOidData *oidData = NULL;
|
||||
|
||||
if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve) ||
|
||||
((oidData = SECOID_FindOIDByTag(ecCurve_oid_map[curve])) == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECITEM_AllocItem(NULL, params, (2 + oidData->oid.len));
|
||||
/*
|
||||
* params->data needs to contain the ASN encoding of an object ID (OID)
|
||||
* representing the named curve. The actual OID is in
|
||||
* oidData->oid.data so we simply prepend 0x06 and OID length
|
||||
*/
|
||||
params->data[0] = SEC_ASN1_OBJECT_ID;
|
||||
params->data[1] = oidData->oid.len;
|
||||
memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Performs basic tests of elliptic curve cryptography over prime fields.
|
||||
* If tests fail, then it prints an error message, aborts, and returns an
|
||||
* error code. Otherwise, returns 0. */
|
||||
@ -423,7 +335,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
|
||||
|
||||
ecParams.data = NULL;
|
||||
ecParams.len = 0;
|
||||
rv = ecName2params(curve, &ecParams);
|
||||
rv = SECU_ecName2params(curve, &ecParams);
|
||||
if (rv != SECSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -542,9 +454,9 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
|
||||
unsigned char sigData[256];
|
||||
unsigned char digestData[20];
|
||||
double signRate, deriveRate = 0;
|
||||
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
|
||||
SECStatus rv = SECFailure;
|
||||
PLArenaPool *arena;
|
||||
SECItem ecEncodedParams = { siBuffer, NULL, 0 };
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
@ -556,28 +468,11 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ecParams.name = curve;
|
||||
ecParams.type = ec_params_named;
|
||||
ecParams.curveOID.data = NULL;
|
||||
ecParams.curveOID.len = 0;
|
||||
ecParams.curve.seed.data = NULL;
|
||||
ecParams.curve.seed.len = 0;
|
||||
ecParams.DEREncoding.data = NULL;
|
||||
ecParams.DEREncoding.len = 0;
|
||||
|
||||
ecParams.fieldID.size = ecCurve_map[curve]->size;
|
||||
ecParams.fieldID.type = fieldType;
|
||||
SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
|
||||
SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
|
||||
SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
|
||||
genenc[0] = '0';
|
||||
genenc[1] = '4';
|
||||
genenc[2] = '\0';
|
||||
strcat(genenc, ecCurve_map[curve]->genx);
|
||||
strcat(genenc, ecCurve_map[curve]->geny);
|
||||
SECU_HexString2SECItem(arena, &ecParams.base, genenc);
|
||||
SECU_HexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
|
||||
ecParams.cofactor = ecCurve_map[curve]->cofactor;
|
||||
rv = SECU_ecName2params(curve, &ecEncodedParams);
|
||||
if (rv != SECSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
EC_FillParams(arena, &ecEncodedParams, &ecParams);
|
||||
|
||||
PORT_Memset(digestData, 0xa5, sizeof(digestData));
|
||||
digest.data = digestData;
|
||||
@ -618,6 +513,7 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
|
||||
}
|
||||
|
||||
cleanup:
|
||||
SECITEM_FreeItem(&ecEncodedParams, PR_FALSE);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
|
||||
return rv;
|
||||
|
@ -88,26 +88,19 @@ ectest_ecdh_kat(ECDH_KAT *kat)
|
||||
SECItem answer = { siBuffer, NULL, 0 };
|
||||
SECItem answer2 = { siBuffer, NULL, 0 };
|
||||
SECItem derived = { siBuffer, NULL, 0 };
|
||||
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
|
||||
SECItem ecEncodedParams = { siBuffer, NULL, 0 };
|
||||
int i;
|
||||
|
||||
rv = init_params(&ecParams, curve, &arena, kat->fieldType);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr);
|
||||
SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea);
|
||||
SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb);
|
||||
genenc[0] = '0';
|
||||
genenc[1] = '4';
|
||||
genenc[2] = '\0';
|
||||
PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->genx));
|
||||
PORT_Assert(PR_ARRAY_SIZE(genenc) >= PORT_Strlen(ecCurve_map[curve]->geny));
|
||||
strcat(genenc, ecCurve_map[curve]->genx);
|
||||
strcat(genenc, ecCurve_map[curve]->geny);
|
||||
SECU_HexString2SECItem(arena, &ecParams.base, genenc);
|
||||
SECU_HexString2SECItem(arena, &ecParams.order, ecCurve_map[curve]->order);
|
||||
rv = SECU_ecName2params(curve, &ecEncodedParams);
|
||||
if (rv != SECSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
EC_FillParams(arena, &ecEncodedParams, &ecParams);
|
||||
|
||||
if (kat->our_pubhex) {
|
||||
SECU_HexString2SECItem(arena, &answer, kat->our_pubhex);
|
||||
@ -161,6 +154,7 @@ ectest_ecdh_kat(ECDH_KAT *kat)
|
||||
}
|
||||
|
||||
cleanup:
|
||||
SECITEM_FreeItem(&ecEncodedParams, PR_FALSE);
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
if (ecPriv) {
|
||||
PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
|
||||
|
@ -774,3 +774,93 @@ SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/* mapping between ECCurveName enum and SECOidTags */
|
||||
static SECOidTag ecCurve_oid_map[] = {
|
||||
SEC_OID_UNKNOWN, /* ECCurve_noName */
|
||||
SEC_OID_ANSIX962_EC_PRIME192V1, /* ECCurve_NIST_P192 */
|
||||
SEC_OID_SECG_EC_SECP224R1, /* ECCurve_NIST_P224 */
|
||||
SEC_OID_ANSIX962_EC_PRIME256V1, /* ECCurve_NIST_P256 */
|
||||
SEC_OID_SECG_EC_SECP384R1, /* ECCurve_NIST_P384 */
|
||||
SEC_OID_SECG_EC_SECP521R1, /* ECCurve_NIST_P521 */
|
||||
SEC_OID_SECG_EC_SECT163K1, /* ECCurve_NIST_K163 */
|
||||
SEC_OID_SECG_EC_SECT163R1, /* ECCurve_NIST_B163 */
|
||||
SEC_OID_SECG_EC_SECT233K1, /* ECCurve_NIST_K233 */
|
||||
SEC_OID_SECG_EC_SECT233R1, /* ECCurve_NIST_B233 */
|
||||
SEC_OID_SECG_EC_SECT283K1, /* ECCurve_NIST_K283 */
|
||||
SEC_OID_SECG_EC_SECT283R1, /* ECCurve_NIST_B283 */
|
||||
SEC_OID_SECG_EC_SECT409K1, /* ECCurve_NIST_K409 */
|
||||
SEC_OID_SECG_EC_SECT409R1, /* ECCurve_NIST_B409 */
|
||||
SEC_OID_SECG_EC_SECT571K1, /* ECCurve_NIST_K571 */
|
||||
SEC_OID_SECG_EC_SECT571R1, /* ECCurve_NIST_B571 */
|
||||
SEC_OID_ANSIX962_EC_PRIME192V2,
|
||||
SEC_OID_ANSIX962_EC_PRIME192V3,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V1,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V2,
|
||||
SEC_OID_ANSIX962_EC_PRIME239V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V2,
|
||||
SEC_OID_ANSIX962_EC_C2PNB163V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB176V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V2,
|
||||
SEC_OID_ANSIX962_EC_C2TNB191V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB208W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V2,
|
||||
SEC_OID_ANSIX962_EC_C2TNB239V3,
|
||||
SEC_OID_ANSIX962_EC_C2PNB272W1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB304W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB359V1,
|
||||
SEC_OID_ANSIX962_EC_C2PNB368W1,
|
||||
SEC_OID_ANSIX962_EC_C2TNB431R1,
|
||||
SEC_OID_SECG_EC_SECP112R1,
|
||||
SEC_OID_SECG_EC_SECP112R2,
|
||||
SEC_OID_SECG_EC_SECP128R1,
|
||||
SEC_OID_SECG_EC_SECP128R2,
|
||||
SEC_OID_SECG_EC_SECP160K1,
|
||||
SEC_OID_SECG_EC_SECP160R1,
|
||||
SEC_OID_SECG_EC_SECP160R2,
|
||||
SEC_OID_SECG_EC_SECP192K1,
|
||||
SEC_OID_SECG_EC_SECP224K1,
|
||||
SEC_OID_SECG_EC_SECP256K1,
|
||||
SEC_OID_SECG_EC_SECT113R1,
|
||||
SEC_OID_SECG_EC_SECT113R2,
|
||||
SEC_OID_SECG_EC_SECT131R1,
|
||||
SEC_OID_SECG_EC_SECT131R2,
|
||||
SEC_OID_SECG_EC_SECT163R1,
|
||||
SEC_OID_SECG_EC_SECT193R1,
|
||||
SEC_OID_SECG_EC_SECT193R2,
|
||||
SEC_OID_SECG_EC_SECT239K1,
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_1 */
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_8 */
|
||||
SEC_OID_UNKNOWN, /* ECCurve_WTLS_9 */
|
||||
SEC_OID_CURVE25519,
|
||||
SEC_OID_UNKNOWN /* ECCurve_pastLastCurve */
|
||||
};
|
||||
|
||||
SECStatus
|
||||
SECU_ecName2params(ECCurveName curve, SECItem *params)
|
||||
{
|
||||
SECOidData *oidData = NULL;
|
||||
|
||||
if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve) ||
|
||||
((oidData = SECOID_FindOIDByTag(ecCurve_oid_map[curve])) == NULL)) {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (SECITEM_AllocItem(NULL, params, (2 + oidData->oid.len)) == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
/*
|
||||
* params->data needs to contain the ASN encoding of an object ID (OID)
|
||||
* representing the named curve. The actual OID is in
|
||||
* oidData->oid.data so we simply prepend 0x06 and OID length
|
||||
*/
|
||||
params->data[0] = SEC_ASN1_OBJECT_ID;
|
||||
params->data[1] = oidData->oid.len;
|
||||
memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "base64.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include "ecl-exp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SECUTIL_NEW
|
||||
@ -86,6 +87,8 @@ SECU_SECItemHexStringToBinary(SECItem *srcdest);
|
||||
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
|
||||
const char *str);
|
||||
|
||||
extern SECStatus SECU_ecName2params(ECCurveName curve, SECItem *params);
|
||||
|
||||
/*
|
||||
*
|
||||
* Utilities for parsing security tools command lines
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "basicutil.h"
|
||||
#include "sslerr.h"
|
||||
#include "sslt.h"
|
||||
#include "blapi.h"
|
||||
|
||||
#define SEC_CT_PRIVATE_KEY "private-key"
|
||||
#define SEC_CT_PUBLIC_KEY "public-key"
|
||||
@ -402,11 +403,6 @@ SECStatus
|
||||
SECU_ParseSSLVersionRangeString(const char *input,
|
||||
const SSLVersionRange defaultVersionRange,
|
||||
SSLVersionRange *vrange);
|
||||
/*
|
||||
** Read a hex string into a SecItem.
|
||||
*/
|
||||
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
|
||||
const char *str);
|
||||
|
||||
SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount);
|
||||
|
@ -10,3 +10,4 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -33,15 +33,8 @@ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus rv = ssl3_InitState(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = ssl3_RestartHandshakeHashes(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
ssl3_InitState(ss);
|
||||
ssl3_RestartHandshakeHashes(ss);
|
||||
|
||||
// Ensure we don't overrun hs.client_random.
|
||||
rnd_len = PR_MIN(SSL3_RANDOM_LENGTH, rnd_len);
|
||||
@ -66,11 +59,11 @@ void SSLInt_ClearSessionTicketKey() { ssl_ResetSessionTicketKeys(); }
|
||||
|
||||
SECStatus SSLInt_SetMTU(PRFileDesc *fd, PRUint16 mtu) {
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (ss) {
|
||||
ss->ssl3.mtu = mtu;
|
||||
return SECSuccess;
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
return SECFailure;
|
||||
ss->ssl3.mtu = mtu;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd) {
|
||||
@ -194,7 +187,9 @@ SECStatus SSLInt_Set0RttAlpn(PRFileDesc *fd, PRUint8 *data, unsigned int len) {
|
||||
if (ss->xtnData.nextProto.data) {
|
||||
SECITEM_FreeItem(&ss->xtnData.nextProto, PR_FALSE);
|
||||
}
|
||||
if (!SECITEM_AllocItem(NULL, &ss->xtnData.nextProto, len)) return SECFailure;
|
||||
if (!SECITEM_AllocItem(NULL, &ss->xtnData.nextProto, len)) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(ss->xtnData.nextProto.data, data, len);
|
||||
|
||||
return SECSuccess;
|
||||
@ -251,6 +246,7 @@ SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (to >= (1ULL << 48)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
@ -262,6 +258,7 @@ SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to) {
|
||||
* scrub the entire structure on the assumption that the new sequence number
|
||||
* is far enough past the last received sequence number. */
|
||||
if (to <= spec->recvdRecords.right + DTLS_RECVD_RECORDS_WINDOW) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
dtls_RecordSetRecvd(&spec->recvdRecords, to);
|
||||
@ -279,6 +276,7 @@ SECStatus SSLInt_AdvanceWriteSeqNum(PRFileDesc *fd, PRUint64 to) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (to >= (1ULL << 48)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
@ -364,10 +362,36 @@ SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result) {
|
||||
}
|
||||
|
||||
*result = ss->ssl3.hs.shortHeaders;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void SSLInt_SetTicketLifetime(uint32_t lifetime) {
|
||||
ssl_ticket_lifetime = lifetime;
|
||||
}
|
||||
|
||||
void SSLInt_SetMaxEarlyDataSize(uint32_t size) {
|
||||
ssl_max_early_data_size = size;
|
||||
}
|
||||
|
||||
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) {
|
||||
sslSocket *ss;
|
||||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* This only works when resuming. */
|
||||
if (!ss->statelessResume) {
|
||||
PORT_SetError(SEC_INTERNAL_ONLY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Modifying both specs allows this to be used on either peer. */
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
ss->ssl3.crSpec->earlyDataRemaining = size;
|
||||
ss->ssl3.cwSpec->earlyDataRemaining = size;
|
||||
ssl_ReleaseSpecWriteLock(ss);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -50,5 +50,7 @@ unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec);
|
||||
SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd);
|
||||
SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result);
|
||||
void SSLInt_SetTicketLifetime(uint32_t lifetime);
|
||||
void SSLInt_SetMaxEarlyDataSize(uint32_t size);
|
||||
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size);
|
||||
|
||||
#endif // ndef libssl_internals_h_
|
||||
|
@ -282,4 +282,110 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) {
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckEarlyDataLimit(const std::shared_ptr<TlsAgent>& agent,
|
||||
size_t expected_size) {
|
||||
SSLPreliminaryChannelInfo preinfo;
|
||||
SECStatus rv =
|
||||
SSL_GetPreliminaryChannelInfo(agent->ssl_fd(), &preinfo, sizeof(preinfo));
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(expected_size, static_cast<size_t>(preinfo.maxEarlyDataSize));
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, SendTooMuchEarlyData) {
|
||||
const char* big_message = "0123456789abcdef";
|
||||
const size_t short_size = strlen(big_message) - 1;
|
||||
const PRInt32 short_length = static_cast<PRInt32>(short_size);
|
||||
SSLInt_SetMaxEarlyDataSize(static_cast<PRUint32>(short_size));
|
||||
SetupForZeroRtt();
|
||||
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->SetExpectedAlertSentCount(1);
|
||||
server_->SetExpectedAlertReceivedCount(1);
|
||||
|
||||
client_->Handshake();
|
||||
CheckEarlyDataLimit(client_, short_size);
|
||||
|
||||
PRInt32 sent;
|
||||
// Writing more than the limit will succeed in TLS, but fail in DTLS.
|
||||
if (mode_ == STREAM) {
|
||||
sent = PR_Write(client_->ssl_fd(), big_message,
|
||||
static_cast<PRInt32>(strlen(big_message)));
|
||||
} else {
|
||||
sent = PR_Write(client_->ssl_fd(), big_message,
|
||||
static_cast<PRInt32>(strlen(big_message)));
|
||||
EXPECT_GE(0, sent);
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
// Try an exact-sized write now.
|
||||
sent = PR_Write(client_->ssl_fd(), big_message, short_length);
|
||||
}
|
||||
EXPECT_EQ(short_length, sent);
|
||||
|
||||
// Even a single octet write should now fail.
|
||||
sent = PR_Write(client_->ssl_fd(), big_message, 1);
|
||||
EXPECT_GE(0, sent);
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
// Process the ClientHello and read 0-RTT.
|
||||
server_->Handshake();
|
||||
CheckEarlyDataLimit(server_, short_size);
|
||||
|
||||
std::vector<uint8_t> buf(short_size + 1);
|
||||
PRInt32 read = PR_Read(server_->ssl_fd(), buf.data(), buf.capacity());
|
||||
EXPECT_EQ(short_length, read);
|
||||
EXPECT_EQ(0, memcmp(big_message, buf.data(), short_size));
|
||||
|
||||
// Second read fails.
|
||||
read = PR_Read(server_->ssl_fd(), buf.data(), buf.capacity());
|
||||
EXPECT_EQ(SECFailure, read);
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
Handshake();
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) {
|
||||
const size_t limit = 5;
|
||||
SSLInt_SetMaxEarlyDataSize(limit);
|
||||
SetupForZeroRtt();
|
||||
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
|
||||
client_->Handshake(); // Send ClientHello
|
||||
CheckEarlyDataLimit(client_, limit);
|
||||
|
||||
// Lift the limit on the client.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSLInt_SetSocketMaxEarlyDataSize(client_->ssl_fd(), 1000));
|
||||
|
||||
// Send message
|
||||
const char* message = "0123456789abcdef";
|
||||
const PRInt32 message_len = static_cast<PRInt32>(strlen(message));
|
||||
EXPECT_EQ(message_len, PR_Write(client_->ssl_fd(), message, message_len));
|
||||
|
||||
server_->Handshake(); // Process ClientHello, send server flight.
|
||||
server_->Handshake(); // Just to make sure that we don't read ahead.
|
||||
CheckEarlyDataLimit(server_, limit);
|
||||
|
||||
// Attempt to read early data.
|
||||
std::vector<uint8_t> buf(strlen(message) + 1);
|
||||
EXPECT_GT(0, PR_Read(server_->ssl_fd(), buf.data(), buf.capacity()));
|
||||
if (mode_ == STREAM) {
|
||||
// This error isn't fatal for DTLS.
|
||||
server_->CheckErrorCode(SSL_ERROR_TOO_MUCH_EARLY_DATA);
|
||||
}
|
||||
|
||||
client_->Handshake(); // Process the handshake.
|
||||
client_->Handshake(); // Process the alert.
|
||||
if (mode_ == STREAM) {
|
||||
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
@ -175,6 +175,7 @@ void TlsConnectTestBase::SetUp() {
|
||||
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
||||
SSLInt_ClearSessionTicketKey();
|
||||
SSLInt_SetTicketLifetime(30);
|
||||
SSLInt_SetMaxEarlyDataSize(1024);
|
||||
ClearStats();
|
||||
Init();
|
||||
}
|
||||
|
@ -22,57 +22,6 @@
|
||||
if (SECSuccess != (rv = func)) \
|
||||
goto cleanup
|
||||
|
||||
/*
|
||||
* Initializes a SECItem from a hexadecimal string
|
||||
*
|
||||
* Warning: This function ignores leading 00's, so any leading 00's
|
||||
* in the hexadecimal string must be optional.
|
||||
*/
|
||||
static SECItem *
|
||||
hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
int byteval = 0;
|
||||
int tmp = PORT_Strlen(str);
|
||||
|
||||
PORT_Assert(arena);
|
||||
PORT_Assert(item);
|
||||
|
||||
if ((tmp % 2) != 0)
|
||||
return NULL;
|
||||
|
||||
/* skip leading 00's unless the hex string is "00" */
|
||||
while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
|
||||
str += 2;
|
||||
tmp -= 2;
|
||||
}
|
||||
|
||||
item->data = (unsigned char *)PORT_ArenaAlloc(arena, tmp / 2);
|
||||
if (item->data == NULL)
|
||||
return NULL;
|
||||
item->len = tmp / 2;
|
||||
|
||||
while (str[i]) {
|
||||
if ((str[i] >= '0') && (str[i] <= '9'))
|
||||
tmp = str[i] - '0';
|
||||
else if ((str[i] >= 'a') && (str[i] <= 'f'))
|
||||
tmp = str[i] - 'a' + 10;
|
||||
else if ((str[i] >= 'A') && (str[i] <= 'F'))
|
||||
tmp = str[i] - 'A' + 10;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
byteval = byteval * 16 + tmp;
|
||||
if ((i % 2) != 0) {
|
||||
item->data[i / 2] = byteval;
|
||||
byteval = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/* Copy all of the fields from srcParams into dstParams
|
||||
*/
|
||||
SECStatus
|
||||
@ -120,12 +69,10 @@ cleanup:
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
|
||||
gf_populate_params_bytes(ECCurveName name, ECFieldType field_type, ECParams *params)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
const ECCurveParams *curveParams;
|
||||
/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
|
||||
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
|
||||
const ECCurveBytes *curveParams;
|
||||
|
||||
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
|
||||
goto cleanup;
|
||||
@ -134,26 +81,19 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
|
||||
CHECK_OK(curveParams);
|
||||
params->fieldID.size = curveParams->size;
|
||||
params->fieldID.type = field_type;
|
||||
if (field_type == ec_field_GFp ||
|
||||
field_type == ec_field_plain) {
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime,
|
||||
curveParams->irr));
|
||||
} else {
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly,
|
||||
curveParams->irr));
|
||||
if (field_type != ec_field_GFp && field_type != ec_field_plain) {
|
||||
return SECFailure;
|
||||
}
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a,
|
||||
curveParams->curvea));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b,
|
||||
curveParams->curveb));
|
||||
genenc[0] = '0';
|
||||
genenc[1] = '4';
|
||||
genenc[2] = '\0';
|
||||
strcat(genenc, curveParams->genx);
|
||||
strcat(genenc, curveParams->geny);
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, genenc));
|
||||
CHECK_OK(hexString2SECItem(params->arena, ¶ms->order,
|
||||
curveParams->order));
|
||||
params->fieldID.u.prime.len = curveParams->scalarSize;
|
||||
params->fieldID.u.prime.data = (unsigned char *)curveParams->irr;
|
||||
params->curve.a.len = curveParams->scalarSize;
|
||||
params->curve.a.data = (unsigned char *)curveParams->curvea;
|
||||
params->curve.b.len = curveParams->scalarSize;
|
||||
params->curve.b.data = (unsigned char *)curveParams->curveb;
|
||||
params->base.len = curveParams->pointSize;
|
||||
params->base.data = (unsigned char *)curveParams->base;
|
||||
params->order.len = curveParams->scalarSize;
|
||||
params->order.data = (unsigned char *)curveParams->order;
|
||||
params->cofactor = curveParams->cofactor;
|
||||
|
||||
rv = SECSuccess;
|
||||
@ -216,29 +156,30 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
|
||||
/* Populate params for prime256v1 aka secp256r1
|
||||
* (the NIST P-256 curve)
|
||||
*/
|
||||
CHECK_SEC_OK(gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
|
||||
params));
|
||||
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_X9_62_PRIME_256V1,
|
||||
ec_field_GFp, params));
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP384R1:
|
||||
/* Populate params for secp384r1
|
||||
* (the NIST P-384 curve)
|
||||
*/
|
||||
CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
|
||||
params));
|
||||
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_384R1,
|
||||
ec_field_GFp, params));
|
||||
break;
|
||||
|
||||
case SEC_OID_SECG_EC_SECP521R1:
|
||||
/* Populate params for secp521r1
|
||||
* (the NIST P-521 curve)
|
||||
*/
|
||||
CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
|
||||
params));
|
||||
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_521R1,
|
||||
ec_field_GFp, params));
|
||||
break;
|
||||
|
||||
case SEC_OID_CURVE25519:
|
||||
/* Populate params for Curve25519 */
|
||||
CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params));
|
||||
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519, ec_field_plain,
|
||||
params));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -296,16 +237,20 @@ int
|
||||
EC_GetPointSize(const ECParams *params)
|
||||
{
|
||||
ECCurveName name = params->name;
|
||||
const ECCurveParams *curveParams;
|
||||
const ECCurveBytes *curveParams;
|
||||
|
||||
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) ||
|
||||
((curveParams = ecCurve_map[name]) == NULL)) {
|
||||
/* unknown curve, calculate point size from params. assume standard curves with 2 points
|
||||
/* unknown curve, calculate point size from params. assume standard curves with 2 points
|
||||
* and a point compression indicator byte */
|
||||
int sizeInBytes = (params->fieldID.size + 7) / 8;
|
||||
return sizeInBytes * 2 + 1;
|
||||
}
|
||||
return curveParams->pointSize;
|
||||
if (name == ECCurve25519) {
|
||||
/* Only X here */
|
||||
return curveParams->scalarSize;
|
||||
}
|
||||
return curveParams->pointSize - 1;
|
||||
}
|
||||
|
||||
#endif /* NSS_DISABLE_ECC */
|
||||
|
@ -3,6 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ecl-exp.h"
|
||||
#include "eclt.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __ecl_curve_h_
|
||||
@ -12,52 +13,201 @@
|
||||
#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
|
||||
#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
|
||||
|
||||
static const ECCurveParams ecCurve_NIST_P256 = {
|
||||
static const PRUint8 irr256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b256[32] =
|
||||
{ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
|
||||
0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
|
||||
0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B };
|
||||
static const PRUint8 x256[32] =
|
||||
{ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 };
|
||||
static const PRUint8 y256[32] =
|
||||
{ 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
static const PRUint8 order256[32] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
|
||||
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 };
|
||||
static const PRUint8 base256[66] =
|
||||
{ 0x04, 0x00,
|
||||
0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
|
||||
0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
|
||||
0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
|
||||
0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A,
|
||||
0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE,
|
||||
0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 };
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P256 = {
|
||||
"NIST-P256", ECField_GFp, 256,
|
||||
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
|
||||
"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
|
||||
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
|
||||
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
|
||||
1, 128, 65, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
irr256, a256, b256, x256, y256, order256, base256,
|
||||
1, 128, 66, 32,
|
||||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const ECCurveParams ecCurve_NIST_P384 = {
|
||||
static const PRUint8 irr384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b384[48] =
|
||||
{ 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
|
||||
0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
|
||||
0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
|
||||
0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF };
|
||||
static const PRUint8 x384[48] =
|
||||
{ 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 };
|
||||
static const PRUint8 y384[48] =
|
||||
{ 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
static const PRUint8 order384[48] =
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
|
||||
0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 };
|
||||
static const PRUint8 base384[98] =
|
||||
{ 0x04, 0x00,
|
||||
0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
|
||||
0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
|
||||
0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
|
||||
0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
|
||||
0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF,
|
||||
0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
|
||||
0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
|
||||
0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F };
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P384 = {
|
||||
"NIST-P384", ECField_GFp, 384,
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
|
||||
"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
|
||||
"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
|
||||
"3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
|
||||
1, 192, 97, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
irr384, a384, b384, x384, y384, order384, base384,
|
||||
1, 192, 98, 48,
|
||||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const ECCurveParams ecCurve_NIST_P521 = {
|
||||
static const PRUint8 irr521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const PRUint8 a521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
|
||||
static const PRUint8 b521[66] =
|
||||
{ 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
|
||||
0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
|
||||
0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
|
||||
0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
|
||||
0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
|
||||
0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 };
|
||||
static const PRUint8 x521[66] =
|
||||
{ 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 };
|
||||
static const PRUint8 y521[66] =
|
||||
{ 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 };
|
||||
static const PRUint8 order521[66] =
|
||||
{ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
|
||||
0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
|
||||
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
|
||||
0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 };
|
||||
static const PRUint8 base521[134] =
|
||||
{
|
||||
0x04, 0x00,
|
||||
0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
|
||||
0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
|
||||
0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
|
||||
0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
|
||||
0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
|
||||
0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
|
||||
0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A,
|
||||
0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B,
|
||||
0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE,
|
||||
0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
|
||||
0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE,
|
||||
0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50
|
||||
};
|
||||
|
||||
static const ECCurveBytes ecCurve_NIST_P521 = {
|
||||
"NIST-P521", ECField_GFp, 521,
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
"0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
|
||||
"00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
|
||||
"011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
|
||||
"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
|
||||
1, 256, 133, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
irr521, a521, b521, x521, y521, order521, base521,
|
||||
1, 256, 134, 66,
|
||||
KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
static const ECCurveParams ecCurve25519 = {
|
||||
static const PRUint8 irr25519[32] =
|
||||
{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f };
|
||||
static const PRUint8 a25519[32] =
|
||||
{ 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 b25519[32] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const PRUint8 x25519[32] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 };
|
||||
static const PRUint8 y25519[32] =
|
||||
{ 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20 };
|
||||
static const PRUint8 order25519[32] =
|
||||
{ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
|
||||
0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
|
||||
static const PRUint8 base25519[66] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||||
0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d,
|
||||
0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0,
|
||||
0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20, 0x00, 0x04 };
|
||||
|
||||
static const ECCurveBytes ecCurve_25519 = {
|
||||
"Curve25519", ECField_GFp, 255,
|
||||
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
|
||||
"076D06",
|
||||
"00",
|
||||
"0900000000000000000000000000000000000000000000000000000000000000",
|
||||
"20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9",
|
||||
"1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed",
|
||||
8, 128, 32, KU_KEY_AGREEMENT
|
||||
irr25519, a25519, b25519, x25519, y25519, order25519, base25519,
|
||||
8, 128, 66, 32,
|
||||
KU_KEY_AGREEMENT
|
||||
};
|
||||
|
||||
/* mapping between ECCurveName enum and pointers to ECCurveParams */
|
||||
static const ECCurveParams *ecCurve_map[] = {
|
||||
static const ECCurveBytes *ecCurve_map[] = {
|
||||
NULL, /* ECCurve_noName */
|
||||
NULL, /* ECCurve_NIST_P192 */
|
||||
NULL, /* ECCurve_NIST_P224 */
|
||||
@ -116,7 +266,7 @@ static const ECCurveParams *ecCurve_map[] = {
|
||||
NULL, /* ECCurve_WTLS_1 */
|
||||
NULL, /* ECCurve_WTLS_8 */
|
||||
NULL, /* ECCurve_WTLS_9 */
|
||||
&ecCurve25519, /* ECCurve25519 */
|
||||
&ecCurve_25519, /* ECCurve25519 */
|
||||
NULL /* ECCurve_pastLastCurve */
|
||||
};
|
||||
|
||||
|
@ -246,12 +246,5 @@ mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
|
||||
/* Optimized point multiplication */
|
||||
mp_err ec_group_set_gfp256_32(ECGroup *group, ECCurveName name);
|
||||
|
||||
/* Optimized floating-point arithmetic */
|
||||
#ifdef ECL_USE_FP
|
||||
mp_err ec_group_set_secp160r1_fp(ECGroup *group);
|
||||
mp_err ec_group_set_nistp192_fp(ECGroup *group);
|
||||
mp_err ec_group_set_nistp224_fp(ECGroup *group);
|
||||
#endif
|
||||
|
||||
SECStatus ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p);
|
||||
#endif /* __ecl_priv_h_ */
|
||||
|
@ -2,11 +2,16 @@
|
||||
* 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/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "../stubs.h"
|
||||
#endif
|
||||
|
||||
#include "mpi.h"
|
||||
#include "mplogic.h"
|
||||
#include "ecl.h"
|
||||
#include "ecl-priv.h"
|
||||
#include "ecp.h"
|
||||
#include "ecl-curve.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -128,14 +133,84 @@ CLEANUP:
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Construct ECGroup from hex parameters and name, if any. Called by
|
||||
* ECGroup_fromHex and ECGroup_fromName. */
|
||||
/* Construct an ECGroup. */
|
||||
ECGroup *
|
||||
ecgroup_fromNameAndHex(const ECCurveName name,
|
||||
const ECCurveParams *params)
|
||||
construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
|
||||
mp_int curveb, mp_int genx, mp_int geny, mp_int order,
|
||||
int cofactor, ECField field, const char *text)
|
||||
{
|
||||
int bits;
|
||||
ECGroup *group = NULL;
|
||||
mp_err res = MP_OKAY;
|
||||
|
||||
/* determine number of bits */
|
||||
bits = mpl_significant_bits(&irr) - 1;
|
||||
if (bits < MP_OKAY) {
|
||||
res = bits;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* determine which optimizations (if any) to use */
|
||||
if (field == ECField_GFp) {
|
||||
switch (name) {
|
||||
case ECCurve_SECG_PRIME_256R1:
|
||||
group =
|
||||
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
MP_CHECKOK(ec_group_set_gfp256(group, name));
|
||||
MP_CHECKOK(ec_group_set_gfp256_32(group, name));
|
||||
break;
|
||||
case ECCurve_SECG_PRIME_521R1:
|
||||
group =
|
||||
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
MP_CHECKOK(ec_group_set_gfp521(group, name));
|
||||
break;
|
||||
default:
|
||||
/* use generic arithmetic */
|
||||
group =
|
||||
ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* set name, if any */
|
||||
if ((group != NULL) && (text != NULL)) {
|
||||
group->text = strdup(text);
|
||||
if (group->text == NULL) {
|
||||
res = MP_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
if (group && res != MP_OKAY) {
|
||||
ECGroup_free(group);
|
||||
return NULL;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Construct ECGroup from parameters and name, if any. */
|
||||
ECGroup *
|
||||
ecgroup_fromName(const ECCurveName name,
|
||||
const ECCurveBytes *params)
|
||||
{
|
||||
mp_int irr, curvea, curveb, genx, geny, order;
|
||||
int bits;
|
||||
ECGroup *group = NULL;
|
||||
mp_err res = MP_OKAY;
|
||||
|
||||
@ -152,66 +227,15 @@ ecgroup_fromNameAndHex(const ECCurveName name,
|
||||
MP_CHECKOK(mp_init(&genx));
|
||||
MP_CHECKOK(mp_init(&geny));
|
||||
MP_CHECKOK(mp_init(&order));
|
||||
MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
|
||||
MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
|
||||
MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
|
||||
MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
|
||||
MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
|
||||
MP_CHECKOK(mp_read_radix(&order, params->order, 16));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&irr, params->irr, params->scalarSize));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&curvea, params->curvea, params->scalarSize));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&curveb, params->curveb, params->scalarSize));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&genx, params->genx, params->scalarSize));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&geny, params->geny, params->scalarSize));
|
||||
MP_CHECKOK(mp_read_unsigned_octets(&order, params->order, params->scalarSize));
|
||||
|
||||
/* determine number of bits */
|
||||
bits = mpl_significant_bits(&irr) - 1;
|
||||
if (bits < MP_OKAY) {
|
||||
res = bits;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* determine which optimizations (if any) to use */
|
||||
if (params->field == ECField_GFp) {
|
||||
switch (name) {
|
||||
case ECCurve_SECG_PRIME_256R1:
|
||||
group =
|
||||
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, params->cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
MP_CHECKOK(ec_group_set_gfp256(group, name));
|
||||
MP_CHECKOK(ec_group_set_gfp256_32(group, name));
|
||||
break;
|
||||
case ECCurve_SECG_PRIME_521R1:
|
||||
group =
|
||||
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, params->cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
MP_CHECKOK(ec_group_set_gfp521(group, name));
|
||||
break;
|
||||
default:
|
||||
/* use generic arithmetic */
|
||||
group =
|
||||
ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
|
||||
&order, params->cofactor);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* set name, if any */
|
||||
if ((group != NULL) && (params->text != NULL)) {
|
||||
group->text = strdup(params->text);
|
||||
if (group->text == NULL) {
|
||||
res = MP_MEM;
|
||||
}
|
||||
}
|
||||
group = construct_ecgroup(name, irr, curvea, curveb, genx, geny, order,
|
||||
params->cofactor, params->field, params->text);
|
||||
|
||||
CLEANUP:
|
||||
mp_clear(&irr);
|
||||
@ -220,18 +244,23 @@ CLEANUP:
|
||||
mp_clear(&genx);
|
||||
mp_clear(&geny);
|
||||
mp_clear(&order);
|
||||
if (res != MP_OKAY) {
|
||||
if (group && res != MP_OKAY) {
|
||||
ECGroup_free(group);
|
||||
return NULL;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Construct ECGroup from hexadecimal representations of parameters. */
|
||||
ECGroup *
|
||||
ECGroup_fromHex(const ECCurveParams *params)
|
||||
/* Construct ECCurveBytes from an ECCurveName */
|
||||
const ECCurveBytes *
|
||||
ec_GetNamedCurveParams(const ECCurveName name)
|
||||
{
|
||||
return ecgroup_fromNameAndHex(ECCurve_noName, params);
|
||||
if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
|
||||
(ecCurve_map[name] == NULL)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return ecCurve_map[name];
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct ECGroup from named parameters. */
|
||||
@ -239,25 +268,26 @@ ECGroup *
|
||||
ECGroup_fromName(const ECCurveName name)
|
||||
{
|
||||
ECGroup *group = NULL;
|
||||
ECCurveParams *params = NULL;
|
||||
const ECCurveBytes *params = NULL;
|
||||
mp_err res = MP_OKAY;
|
||||
|
||||
params = EC_GetNamedCurveParams(name);
|
||||
/* This doesn't work with Curve25519 but it's not necessary to. */
|
||||
PORT_Assert(name != ECCurve25519);
|
||||
|
||||
params = ec_GetNamedCurveParams(name);
|
||||
if (params == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* construct actual group */
|
||||
group = ecgroup_fromNameAndHex(name, params);
|
||||
group = ecgroup_fromName(name, params);
|
||||
if (group == NULL) {
|
||||
res = MP_UNDEF;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
EC_FreeCurveParams(params);
|
||||
if (res != MP_OKAY) {
|
||||
if (group && res != MP_OKAY) {
|
||||
ECGroup_free(group);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -11,28 +11,17 @@
|
||||
#include "blapi.h"
|
||||
#include "ecl-exp.h"
|
||||
#include "mpi.h"
|
||||
#include "eclt.h"
|
||||
|
||||
struct ECGroupStr;
|
||||
typedef struct ECGroupStr ECGroup;
|
||||
|
||||
/* Construct ECGroup from hexadecimal representations of parameters. */
|
||||
ECGroup *ECGroup_fromHex(const ECCurveParams *params);
|
||||
|
||||
/* Construct ECGroup from named parameters. */
|
||||
ECGroup *ECGroup_fromName(const ECCurveName name);
|
||||
|
||||
/* Free an allocated ECGroup. */
|
||||
void ECGroup_free(ECGroup *group);
|
||||
|
||||
/* Construct ECCurveParams from an ECCurveName */
|
||||
ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name);
|
||||
|
||||
/* Duplicates an ECCurveParams */
|
||||
ECCurveParams *ECCurveParams_dup(const ECCurveParams *params);
|
||||
|
||||
/* Free an allocated ECCurveParams */
|
||||
void EC_FreeCurveParams(ECCurveParams *params);
|
||||
|
||||
/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
|
||||
* y). If x, y = NULL, then P is assumed to be the generator (base point)
|
||||
* of the group of points on the elliptic curve. Input and output values
|
||||
|
@ -1,93 +0,0 @@
|
||||
/* 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 "ecl.h"
|
||||
#include "ecl-curve.h"
|
||||
#include "ecl-priv.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CHECK(func) \
|
||||
if ((func) == NULL) { \
|
||||
res = 0; \
|
||||
goto CLEANUP; \
|
||||
}
|
||||
|
||||
/* Duplicates an ECCurveParams */
|
||||
ECCurveParams *
|
||||
ECCurveParams_dup(const ECCurveParams *params)
|
||||
{
|
||||
int res = 1;
|
||||
ECCurveParams *ret = NULL;
|
||||
|
||||
CHECK(ret = (ECCurveParams *)calloc(1, sizeof(ECCurveParams)));
|
||||
if (params->text != NULL) {
|
||||
CHECK(ret->text = strdup(params->text));
|
||||
}
|
||||
ret->field = params->field;
|
||||
ret->size = params->size;
|
||||
if (params->irr != NULL) {
|
||||
CHECK(ret->irr = strdup(params->irr));
|
||||
}
|
||||
if (params->curvea != NULL) {
|
||||
CHECK(ret->curvea = strdup(params->curvea));
|
||||
}
|
||||
if (params->curveb != NULL) {
|
||||
CHECK(ret->curveb = strdup(params->curveb));
|
||||
}
|
||||
if (params->genx != NULL) {
|
||||
CHECK(ret->genx = strdup(params->genx));
|
||||
}
|
||||
if (params->geny != NULL) {
|
||||
CHECK(ret->geny = strdup(params->geny));
|
||||
}
|
||||
if (params->order != NULL) {
|
||||
CHECK(ret->order = strdup(params->order));
|
||||
}
|
||||
ret->cofactor = params->cofactor;
|
||||
|
||||
CLEANUP:
|
||||
if (res != 1) {
|
||||
EC_FreeCurveParams(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef CHECK
|
||||
|
||||
/* Construct ECCurveParams from an ECCurveName */
|
||||
ECCurveParams *
|
||||
EC_GetNamedCurveParams(const ECCurveName name)
|
||||
{
|
||||
if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
|
||||
(ecCurve_map[name] == NULL)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return ECCurveParams_dup(ecCurve_map[name]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the memory allocated (if any) to an ECCurveParams object. */
|
||||
void
|
||||
EC_FreeCurveParams(ECCurveParams *params)
|
||||
{
|
||||
if (params == NULL)
|
||||
return;
|
||||
if (params->text != NULL)
|
||||
free(params->text);
|
||||
if (params->irr != NULL)
|
||||
free(params->irr);
|
||||
if (params->curvea != NULL)
|
||||
free(params->curvea);
|
||||
if (params->curveb != NULL)
|
||||
free(params->curveb);
|
||||
if (params->genx != NULL)
|
||||
free(params->genx);
|
||||
if (params->geny != NULL)
|
||||
free(params->geny);
|
||||
if (params->order != NULL)
|
||||
free(params->order);
|
||||
free(params);
|
||||
}
|
30
security/nss/lib/freebl/ecl/eclt.h
Normal file
30
security/nss/lib/freebl/ecl/eclt.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* 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/. */
|
||||
|
||||
/* This header holds ECC types and must not be exported publicly. */
|
||||
|
||||
#ifndef __eclt_h_
|
||||
#define __eclt_h_
|
||||
|
||||
/* byte encoding of curve parameters */
|
||||
struct ECCurveBytesStr {
|
||||
char *text;
|
||||
ECField field;
|
||||
size_t size;
|
||||
const PRUint8 *irr;
|
||||
const PRUint8 *curvea;
|
||||
const PRUint8 *curveb;
|
||||
const PRUint8 *genx;
|
||||
const PRUint8 *geny;
|
||||
const PRUint8 *order;
|
||||
const PRUint8 *base;
|
||||
int cofactor;
|
||||
int security;
|
||||
size_t pointSize;
|
||||
size_t scalarSize;
|
||||
unsigned int usage;
|
||||
};
|
||||
typedef struct ECCurveBytesStr ECCurveBytes;
|
||||
|
||||
#endif /* __ecl_h_ */
|
@ -33,6 +33,7 @@
|
||||
'ec.h',
|
||||
'ecl/ecl-curve.h',
|
||||
'ecl/ecl.h',
|
||||
'ecl/eclt.h',
|
||||
'hmacct.h',
|
||||
'secmpi.h',
|
||||
'secrng.h'
|
||||
|
@ -21,7 +21,6 @@
|
||||
'ecdecode.c',
|
||||
'ecl/ec_naf.c',
|
||||
'ecl/ecl.c',
|
||||
'ecl/ecl_curve.c',
|
||||
'ecl/ecl_gf.c',
|
||||
'ecl/ecl_mult.c',
|
||||
'ecl/ecp_25519.c',
|
||||
|
@ -94,6 +94,7 @@ PRIVATE_EXPORTS = \
|
||||
ec.h \
|
||||
ecl.h \
|
||||
ecl-curve.h \
|
||||
eclt.h \
|
||||
$(NULL)
|
||||
|
||||
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
|
||||
@ -102,7 +103,7 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c
|
||||
|
||||
ECL_HDRS = ecl-exp.h ecl.h ecp.h ecl-priv.h
|
||||
ifndef NSS_DISABLE_ECC
|
||||
ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
|
||||
ECL_SRCS = ecl.c ecl_mult.c ecl_gf.c \
|
||||
ecp_aff.c ecp_jac.c ecp_mont.c \
|
||||
ec_naf.c ecp_jm.c ecp_256.c ecp_384.c ecp_521.c \
|
||||
ecp_256_32.c ecp_25519.c
|
||||
|
@ -508,3 +508,6 @@ ER3(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES, (SSL_ERROR_BASE + 159),
|
||||
|
||||
ER3(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA, (SSL_ERROR_BASE + 160),
|
||||
"SSL got a pre-TLS 1.3 version even though we sent early data.")
|
||||
|
||||
ER3(SSL_ERROR_TOO_MUCH_EARLY_DATA, (SSL_ERROR_BASE + 161),
|
||||
"SSL received more early data than permitted.")
|
||||
|
@ -2726,10 +2726,7 @@ ssl3_SendRecord(sslSocket *ss,
|
||||
** trying to send an alert.
|
||||
*/
|
||||
PR_ASSERT(type == content_alert);
|
||||
rv = ssl3_InitState(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure; /* ssl3_InitState has set the error code. */
|
||||
}
|
||||
ssl3_InitState(ss);
|
||||
}
|
||||
|
||||
/* check for Token Presence */
|
||||
@ -2935,6 +2932,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
|
||||
ssl_GetXmitBufLock(ss);
|
||||
}
|
||||
toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
|
||||
|
||||
/*
|
||||
* Note that the 0 epoch is OK because flags will never require
|
||||
* its use, as guaranteed by the PORT_Assert above.
|
||||
@ -4101,11 +4099,9 @@ ssl3_InitHandshakeHashes(sslSocket *ss)
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
void
|
||||
ssl3_RestartHandshakeHashes(sslSocket *ss)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: reset handshake hashes",
|
||||
SSL_GETPID(), ss->fd));
|
||||
ss->ssl3.hs.hashType = handshake_hash_unknown;
|
||||
@ -4118,7 +4114,6 @@ ssl3_RestartHandshakeHashes(sslSocket *ss)
|
||||
PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
|
||||
ss->ssl3.hs.sha = NULL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5024,15 +5019,8 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
|
||||
if (ss->ssl3.hs.helloRetry) {
|
||||
PORT_Assert(type == client_hello_retry);
|
||||
} else {
|
||||
rv = ssl3_InitState(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv; /* ssl3_InitState has set the error code. */
|
||||
}
|
||||
|
||||
rv = ssl3_RestartHandshakeHashes(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
ssl3_InitState(ss);
|
||||
ssl3_RestartHandshakeHashes(ss);
|
||||
}
|
||||
|
||||
/* These must be reset every handshake. */
|
||||
@ -9164,16 +9152,8 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length,
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = ssl3_InitState(ss);
|
||||
if (rv != SECSuccess) {
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
return rv; /* ssl3_InitState has set the error code. */
|
||||
}
|
||||
rv = ssl3_RestartHandshakeHashes(ss);
|
||||
if (rv != SECSuccess) {
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
return rv;
|
||||
}
|
||||
ssl3_InitState(ss);
|
||||
ssl3_RestartHandshakeHashes(ss);
|
||||
|
||||
if (ss->ssl3.hs.ws != wait_client_hello) {
|
||||
desc = unexpected_message;
|
||||
@ -11795,10 +11775,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
|
||||
/* Start new handshake hashes when we start a new handshake. Unless this is
|
||||
* TLS 1.3 and we sent a HelloRetryRequest. */
|
||||
if (ss->ssl3.hs.msg_type == client_hello && !ss->ssl3.hs.helloRetry) {
|
||||
rv = ssl3_RestartHandshakeHashes(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
ssl3_RestartHandshakeHashes(ss);
|
||||
}
|
||||
/* We should not include hello_request and hello_verify_request messages
|
||||
* in the handshake hashes */
|
||||
@ -12590,11 +12567,8 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
|
||||
if (!ss->ssl3.initialized) {
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
rv = ssl3_InitState(ss);
|
||||
ssl3_InitState(ss);
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv; /* ssl3_InitState has set the error code. */
|
||||
}
|
||||
}
|
||||
|
||||
/* check for Token Presence */
|
||||
@ -12913,16 +12887,14 @@ ssl3_InitCipherSpec(ssl3CipherSpec *spec)
|
||||
** ssl3_HandleRecord()
|
||||
**
|
||||
** This function should perhaps acquire and release the SpecWriteLock.
|
||||
**
|
||||
**
|
||||
*/
|
||||
SECStatus
|
||||
void
|
||||
ssl3_InitState(sslSocket *ss)
|
||||
{
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
|
||||
if (ss->ssl3.initialized)
|
||||
return SECSuccess; /* Function should be idempotent */
|
||||
return; /* Function should be idempotent */
|
||||
|
||||
ss->ssl3.policy = SSL_ALLOWED;
|
||||
|
||||
@ -12977,7 +12949,6 @@ ssl3_InitState(sslSocket *ss)
|
||||
ssl_FilterSupportedGroups(ss);
|
||||
|
||||
ss->ssl3.initialized = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* record the export policy for this cipher suite */
|
||||
|
@ -878,7 +878,7 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
||||
}
|
||||
|
||||
PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */
|
||||
#define TLS_EX_SESS_TICKET_VERSION (0x0103)
|
||||
#define TLS_EX_SESS_TICKET_VERSION (0x0104)
|
||||
|
||||
/*
|
||||
* Called from ssl3_SendNewSessionTicket, tls13_SendNewSessionTicket
|
||||
@ -1003,7 +1003,8 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
||||
+ 1 /* extendedMasterSecretUsed */
|
||||
+ sizeof(ticket->ticket_lifetime_hint) /* ticket lifetime hint */
|
||||
+ sizeof(ticket->flags) /* ticket flags */
|
||||
+ 1 + alpnSelection.len; /* npn value + length field. */
|
||||
+ 1 + alpnSelection.len /* npn value + length field. */
|
||||
+ 4; /* maxEarlyData */
|
||||
#ifdef UNSAFE_FUZZER_MODE
|
||||
padding_length = 0;
|
||||
#else
|
||||
@ -1152,6 +1153,10 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = ssl3_AppendNumberToItem(&plaintext, ssl_max_early_data_size, 4);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
PORT_Assert(plaintext.len == padding_length);
|
||||
for (i = 0; i < padding_length; i++)
|
||||
plaintext.data[i] = (unsigned char)padding_length;
|
||||
@ -1608,6 +1613,12 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
||||
goto no_ticket;
|
||||
}
|
||||
|
||||
rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &buffer_len);
|
||||
if (rv != SECSuccess) {
|
||||
goto no_ticket;
|
||||
}
|
||||
parsed_session_ticket->maxEarlyData = temp;
|
||||
|
||||
#ifndef UNSAFE_FUZZER_MODE
|
||||
/* Done parsing. Check that all bytes have been consumed. */
|
||||
if (buffer_len != padding_length) {
|
||||
@ -1642,6 +1653,8 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
||||
&extension_data) != SECSuccess)
|
||||
goto no_ticket;
|
||||
sid->u.ssl3.locked.sessionTicket.flags = parsed_session_ticket->flags;
|
||||
sid->u.ssl3.locked.sessionTicket.max_early_data_size =
|
||||
parsed_session_ticket->maxEarlyData;
|
||||
|
||||
if (parsed_session_ticket->ms_length >
|
||||
sizeof(sid->u.ssl3.keys.wrapped_master_secret))
|
||||
|
@ -245,6 +245,7 @@ typedef enum {
|
||||
SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 158),
|
||||
SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 159),
|
||||
SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA = (SSL_ERROR_BASE + 160),
|
||||
SSL_ERROR_TOO_MUCH_EARLY_DATA = (SSL_ERROR_BASE + 161),
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
@ -504,6 +504,9 @@ struct ssl3CipherSpecStr {
|
||||
SECItem msItem;
|
||||
DTLSEpoch epoch;
|
||||
DTLSRecvdRecords recvdRecords;
|
||||
/* The number of 0-RTT bytes that can be sent or received in TLS 1.3. This
|
||||
* will be zero for everything but 0-RTT. */
|
||||
PRUint32 earlyDataRemaining;
|
||||
|
||||
PRUint8 refCt;
|
||||
const char *phase;
|
||||
@ -1013,6 +1016,7 @@ typedef struct SessionTicketStr {
|
||||
PRUint32 flags;
|
||||
SECItem srvName; /* negotiated server name */
|
||||
SECItem alpnSelection;
|
||||
PRUint32 maxEarlyData;
|
||||
} SessionTicket;
|
||||
|
||||
/*
|
||||
@ -1231,6 +1235,7 @@ extern FILE *ssl_trace_iob;
|
||||
extern FILE *ssl_keylog_iob;
|
||||
extern PRUint32 ssl3_sid_timeout;
|
||||
extern PRUint32 ssl_ticket_lifetime;
|
||||
extern PRUint32 ssl_max_early_data_size;
|
||||
|
||||
extern const char *const ssl3_cipherName[];
|
||||
|
||||
@ -1350,8 +1355,8 @@ extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
|
||||
|
||||
extern SECStatus ssl3_ConstrainRangeByPolicy(void);
|
||||
|
||||
extern SECStatus ssl3_InitState(sslSocket *ss);
|
||||
extern SECStatus ssl3_RestartHandshakeHashes(sslSocket *ss);
|
||||
extern void ssl3_InitState(sslSocket *ss);
|
||||
extern void ssl3_RestartHandshakeHashes(sslSocket *ss);
|
||||
extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
|
||||
const unsigned char *b,
|
||||
unsigned int l);
|
||||
|
@ -141,8 +141,19 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
|
||||
inf.protocolVersion = ss->version;
|
||||
inf.cipherSuite = ss->ssl3.hs.cipher_suite;
|
||||
inf.canSendEarlyData = !ss->sec.isServer &&
|
||||
(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) &&
|
||||
!ss->firstHsDone;
|
||||
(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
|
||||
/* We shouldn't be able to send early data if the handshake is done. */
|
||||
PORT_Assert(!ss->firstHsDone || !inf.canSendEarlyData);
|
||||
|
||||
if (ss->sec.ci.sid &&
|
||||
(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted)) {
|
||||
inf.maxEarlyDataSize =
|
||||
ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
|
||||
} else {
|
||||
inf.maxEarlyDataSize = 0;
|
||||
}
|
||||
|
||||
memcpy(info, &inf, inf.length);
|
||||
return SECSuccess;
|
||||
|
@ -884,6 +884,7 @@ int
|
||||
ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
{
|
||||
int rv = 0;
|
||||
PRBool zeroRtt = PR_FALSE;
|
||||
|
||||
SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
|
||||
SSL_GETPID(), ss->fd, len));
|
||||
@ -923,19 +924,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
* Case 2: TLS 1.3 0-RTT
|
||||
*/
|
||||
if (!ss->firstHsDone) {
|
||||
PRBool falseStart = PR_FALSE;
|
||||
PRBool allowEarlySend = PR_FALSE;
|
||||
|
||||
ssl_Get1stHandshakeLock(ss);
|
||||
if (ss->opt.enableFalseStart ||
|
||||
(ss->opt.enable0RttData && !ss->sec.isServer)) {
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
/* The client can sometimes send before the handshake is fully
|
||||
* complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
|
||||
falseStart = ss->ssl3.hs.canFalseStart ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
|
||||
zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
|
||||
allowEarlySend = ss->ssl3.hs.canFalseStart || zeroRtt;
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
}
|
||||
if (!falseStart && ss->handshake) {
|
||||
if (!allowEarlySend && ss->handshake) {
|
||||
rv = ssl_Do1stHandshake(ss);
|
||||
}
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
@ -945,6 +947,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (zeroRtt) {
|
||||
/* There's a limit to the number of early data octets we can send.
|
||||
*
|
||||
* Note that taking this lock doesn't prevent the cipher specs from
|
||||
* being changed out between here and when records are ultimately
|
||||
* encrypted. The only effect of that is to occasionally do an
|
||||
* unnecessary short write when data is identified as 0-RTT here but
|
||||
* 1-RTT later.
|
||||
*/
|
||||
ssl_GetSpecReadLock(ss);
|
||||
len = tls13_LimitEarlyData(ss, content_application_data, len);
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
}
|
||||
|
||||
/* Check for zero length writes after we do housekeeping so we make forward
|
||||
* progress.
|
||||
*/
|
||||
@ -959,19 +975,6 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!ss->firstHsDone) {
|
||||
#ifdef DEBUG
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
PORT_Assert(!ss->sec.isServer &&
|
||||
(ss->ssl3.hs.canFalseStart ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
|
||||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted));
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
#endif
|
||||
SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
|
||||
SSL_GETPID(), ss->fd));
|
||||
}
|
||||
|
||||
ssl_GetXmitBufLock(ss);
|
||||
rv = ssl3_SendApplicationData(ss, buf, len, flags);
|
||||
ssl_ReleaseXmitBufLock(ss);
|
||||
|
@ -304,6 +304,15 @@ typedef struct SSLPreliminaryChannelInfoStr {
|
||||
*/
|
||||
PRBool canSendEarlyData;
|
||||
|
||||
/* The following fields were added in NSS 3.31. */
|
||||
/* The number of early data octets that a client is permitted to send on
|
||||
* this connection. The value will be zero if the connection was not
|
||||
* resumed or early data is not permitted. For a client, this value only
|
||||
* has meaning if |canSendEarlyData| is true. For a server, this indicates
|
||||
* the value that was advertised in the session ticket that was used to
|
||||
* resume this session. */
|
||||
PRUint32 maxEarlyDataSize;
|
||||
|
||||
/* When adding new fields to this structure, please document the
|
||||
* NSS version in which they were added. */
|
||||
} SSLPreliminaryChannelInfo;
|
||||
|
@ -2769,6 +2769,11 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
|
||||
dtls_InitRecvdRecords(&spec->recvdRecords);
|
||||
}
|
||||
|
||||
if (type == TrafficKeyEarlyApplicationData) {
|
||||
spec->earlyDataRemaining =
|
||||
ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
|
||||
}
|
||||
|
||||
/* Now that we've set almost everything up, finally cut over. */
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
tls13_CipherSpecRelease(*specp); /* May delete old cipher. */
|
||||
@ -3775,7 +3780,7 @@ tls13_SendClientSecondRound(sslSocket *ss)
|
||||
* } NewSessionTicket;
|
||||
*/
|
||||
|
||||
#define MAX_EARLY_DATA_SIZE (2 << 16) /* Arbitrary limit. */
|
||||
PRUint32 ssl_max_early_data_size = (2 << 16); /* Arbitrary limit. */
|
||||
|
||||
SECStatus
|
||||
tls13_SendNewSessionTicket(sslSocket *ss)
|
||||
@ -3845,7 +3850,7 @@ tls13_SendNewSessionTicket(sslSocket *ss)
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
rv = ssl3_AppendHandshakeNumber(ss, MAX_EARLY_DATA_SIZE, 4);
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ssl_max_early_data_size, 4);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
}
|
||||
@ -4089,6 +4094,28 @@ tls13_FormatAdditionalData(PRUint8 *aad, unsigned int length,
|
||||
PORT_Assert((ptr - aad) == length);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
tls13_LimitEarlyData(sslSocket *ss, SSL3ContentType type, PRInt32 toSend)
|
||||
{
|
||||
PRInt32 reduced;
|
||||
|
||||
PORT_Assert(type == content_application_data);
|
||||
PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
PORT_Assert(!ss->firstHsDone);
|
||||
if (ss->ssl3.cwSpec->epoch != TrafficKeyEarlyApplicationData) {
|
||||
return toSend;
|
||||
}
|
||||
|
||||
if (IS_DTLS(ss) && toSend > ss->ssl3.cwSpec->earlyDataRemaining) {
|
||||
/* Don't split application data records in DTLS. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
reduced = PR_MIN(toSend, ss->ssl3.cwSpec->earlyDataRemaining);
|
||||
ss->ssl3.cwSpec->earlyDataRemaining -= reduced;
|
||||
return reduced;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
tls13_ProtectRecord(sslSocket *ss,
|
||||
ssl3CipherSpec *cwSpec,
|
||||
@ -4240,6 +4267,17 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext
|
||||
cText->type = plaintext->buf[plaintext->len - 1];
|
||||
--plaintext->len;
|
||||
|
||||
/* Check that we haven't received too much 0-RTT data. */
|
||||
if (crSpec->epoch == TrafficKeyEarlyApplicationData &&
|
||||
cText->type == content_application_data) {
|
||||
if (plaintext->len > crSpec->earlyDataRemaining) {
|
||||
*alert = unexpected_message;
|
||||
PORT_SetError(SSL_ERROR_TOO_MUCH_EARLY_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
crSpec->earlyDataRemaining -= plaintext->len;
|
||||
}
|
||||
|
||||
SSL_TRC(10,
|
||||
("%d: TLS13[%d]: %s received record of length=%d type=%d",
|
||||
SSL_GETPID(), ss->fd, SSL_ROLE(ss),
|
||||
|
@ -45,6 +45,7 @@ void tls13_FatalError(sslSocket *ss, PRErrorCode prError,
|
||||
SSL3AlertDescription desc);
|
||||
SECStatus tls13_SetupClientHello(sslSocket *ss);
|
||||
SECStatus tls13_MaybeDo0RTTHandshake(sslSocket *ss);
|
||||
PRInt32 tls13_LimitEarlyData(sslSocket *ss, SSL3ContentType type, PRInt32 toSend);
|
||||
PRBool tls13_AllowPskCipher(const sslSocket *ss,
|
||||
const ssl3CipherSuiteDef *cipher_def);
|
||||
PRBool tls13_PskSuiteEnabled(sslSocket *ss);
|
||||
|
Loading…
Reference in New Issue
Block a user