Commit 3d6811b6 authored by Franziskus Kiefer's avatar Franziskus Kiefer

Bug 1347975 - use bytes for curve parameter definitions, r=ttaubert

--HG--
extra : rebase_source : 905a759b7370c382cd122b986fe7f3bdd3ed7ec4
parent 3df657f3
...@@ -26,70 +26,6 @@ ...@@ -26,70 +26,6 @@
#include "pkcs11f.h" #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 (*op_func)(void *, void *, void *);
typedef SECStatus (*pk11_op_func)(CK_SESSION_HANDLE, 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, ...@@ -374,30 +310,6 @@ PKCS11_Verify(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *hKey,
return SECSuccess; 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. /* Performs basic tests of elliptic curve cryptography over prime fields.
* If tests fail, then it prints an error message, aborts, and returns an * If tests fail, then it prints an error message, aborts, and returns an
* error code. Otherwise, returns 0. */ * error code. Otherwise, returns 0. */
...@@ -423,7 +335,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads) ...@@ -423,7 +335,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
ecParams.data = NULL; ecParams.data = NULL;
ecParams.len = 0; ecParams.len = 0;
rv = ecName2params(curve, &ecParams); rv = SECU_ecName2params(curve, &ecParams);
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto cleanup; goto cleanup;
} }
...@@ -542,9 +454,9 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads, ...@@ -542,9 +454,9 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
unsigned char sigData[256]; unsigned char sigData[256];
unsigned char digestData[20]; unsigned char digestData[20];
double signRate, deriveRate = 0; double signRate, deriveRate = 0;
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
PLArenaPool *arena; PLArenaPool *arena;
SECItem ecEncodedParams = { siBuffer, NULL, 0 };
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) { if (!arena) {
...@@ -556,28 +468,11 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads, ...@@ -556,28 +468,11 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
return SECFailure; return SECFailure;
} }
ecParams.name = curve; rv = SECU_ecName2params(curve, &ecEncodedParams);
ecParams.type = ec_params_named; if (rv != SECSuccess) {
ecParams.curveOID.data = NULL; goto cleanup;
ecParams.curveOID.len = 0; }
ecParams.curve.seed.data = NULL; EC_FillParams(arena, &ecEncodedParams, &ecParams);
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;
PORT_Memset(digestData, 0xa5, sizeof(digestData)); PORT_Memset(digestData, 0xa5, sizeof(digestData));
digest.data = digestData; digest.data = digestData;
...@@ -618,6 +513,7 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads, ...@@ -618,6 +513,7 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
} }
cleanup: cleanup:
SECITEM_FreeItem(&ecEncodedParams, PR_FALSE);
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE); PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
return rv; return rv;
......
...@@ -88,26 +88,19 @@ ectest_ecdh_kat(ECDH_KAT *kat) ...@@ -88,26 +88,19 @@ ectest_ecdh_kat(ECDH_KAT *kat)
SECItem answer = { siBuffer, NULL, 0 }; SECItem answer = { siBuffer, NULL, 0 };
SECItem answer2 = { siBuffer, NULL, 0 }; SECItem answer2 = { siBuffer, NULL, 0 };
SECItem derived = { siBuffer, NULL, 0 }; SECItem derived = { siBuffer, NULL, 0 };
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; SECItem ecEncodedParams = { siBuffer, NULL, 0 };
int i; int i;
rv = init_params(&ecParams, curve, &arena, kat->fieldType); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (rv != SECSuccess) { if (!arena) {
return rv; return SECFailure;
} }
SECU_HexString2SECItem(arena, &ecParams.fieldID.u.prime, ecCurve_map[curve]->irr); rv = SECU_ecName2params(curve, &ecEncodedParams);
SECU_HexString2SECItem(arena, &ecParams.curve.a, ecCurve_map[curve]->curvea); if (rv != SECSuccess) {
SECU_HexString2SECItem(arena, &ecParams.curve.b, ecCurve_map[curve]->curveb); goto cleanup;
genenc[0] = '0'; }
genenc[1] = '4'; EC_FillParams(arena, &ecEncodedParams, &ecParams);
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);
if (kat->our_pubhex) { if (kat->our_pubhex) {
SECU_HexString2SECItem(arena, &answer, kat->our_pubhex); SECU_HexString2SECItem(arena, &answer, kat->our_pubhex);
...@@ -161,6 +154,7 @@ ectest_ecdh_kat(ECDH_KAT *kat) ...@@ -161,6 +154,7 @@ ectest_ecdh_kat(ECDH_KAT *kat)
} }
cleanup: cleanup:
SECITEM_FreeItem(&ecEncodedParams, PR_FALSE);
PORT_FreeArena(arena, PR_FALSE); PORT_FreeArena(arena, PR_FALSE);
if (ecPriv) { if (ecPriv) {
PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE); PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
......
...@@ -774,3 +774,93 @@ SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) ...@@ -774,3 +774,93 @@ SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
return item; 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 @@ ...@@ -13,6 +13,7 @@
#include "base64.h" #include "base64.h"
#include "secasn1.h" #include "secasn1.h"
#include "secder.h" #include "secder.h"
#include "ecl-exp.h"
#include <stdio.h> #include <stdio.h>
#ifdef SECUTIL_NEW #ifdef SECUTIL_NEW
...@@ -86,6 +87,8 @@ SECU_SECItemHexStringToBinary(SECItem *srcdest); ...@@ -86,6 +87,8 @@ SECU_SECItemHexStringToBinary(SECItem *srcdest);
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
const char *str); const char *str);
extern SECStatus SECU_ecName2params(ECCurveName curve, SECItem *params);
/* /*
* *
* Utilities for parsing security tools command lines * Utilities for parsing security tools command lines
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "basicutil.h" #include "basicutil.h"
#include "sslerr.h" #include "sslerr.h"
#include "sslt.h" #include "sslt.h"
#include "blapi.h"
#define SEC_CT_PRIVATE_KEY "private-key" #define SEC_CT_PRIVATE_KEY "private-key"
#define SEC_CT_PUBLIC_KEY "public-key" #define SEC_CT_PUBLIC_KEY "public-key"
...@@ -402,11 +403,6 @@ SECStatus ...@@ -402,11 +403,6 @@ SECStatus
SECU_ParseSSLVersionRangeString(const char *input, SECU_ParseSSLVersionRangeString(const char *input,
const SSLVersionRange defaultVersionRange, const SSLVersionRange defaultVersionRange,
SSLVersionRange *vrange); 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, SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
unsigned int *enabledGroupsCount); unsigned int *enabledGroupsCount);
......
...@@ -22,57 +22,6 @@ ...@@ -22,57 +22,6 @@
if (SECSuccess != (rv = func)) \ if (SECSuccess != (rv = func)) \
goto cleanup 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 /* Copy all of the fields from srcParams into dstParams
*/ */
SECStatus SECStatus
...@@ -120,12 +69,10 @@ cleanup: ...@@ -120,12 +69,10 @@ cleanup:
} }
static SECStatus 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; SECStatus rv = SECFailure;
const ECCurveParams *curveParams; const ECCurveBytes *curveParams;
/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
goto cleanup; goto cleanup;
...@@ -134,26 +81,19 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) ...@@ -134,26 +81,19 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
CHECK_OK(curveParams); CHECK_OK(curveParams);
params->fieldID.size = curveParams->size; params->fieldID.size = curveParams->size;
params->fieldID.type = field_type; params->fieldID.type = field_type;
if (field_type == ec_field_GFp || if (field_type != ec_field_GFp && field_type != ec_field_plain) {
field_type == ec_field_plain) { return SECFailure;
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
curveParams->irr));
} else {
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
curveParams->irr));
} }
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a, params->fieldID.u.prime.len = curveParams->scalarSize;
curveParams->curvea)); params->fieldID.u.prime.data = (unsigned char *)curveParams->irr;
CHECK_OK(hexString2SECItem(params->arena, &params->curve.b, params->curve.a.len = curveParams->scalarSize;
curveParams->curveb)); params->curve.a.data = (unsigned char *)curveParams->curvea;
genenc[0] = '0'; params->curve.b.len = curveParams->scalarSize;
genenc[1] = '4'; params->curve.b.data = (unsigned char *)curveParams->curveb;
genenc[2] = '\0'; params->base.len = curveParams->pointSize;
strcat(genenc, curveParams->genx); params->base.data = (unsigned char *)curveParams->base;
strcat(genenc, curveParams->geny); params->order.len = curveParams->scalarSize;
CHECK_OK(hexString2SECItem(params->arena, &params->base, genenc)); params->order.data = (unsigned char *)curveParams->order;
CHECK_OK(hexString2SECItem(params->arena, &params->order,
curveParams->order));
params->cofactor = curveParams->cofactor; params->cofactor = curveParams->cofactor;
rv = SECSuccess; rv = SECSuccess;
...@@ -216,29 +156,30 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, ...@@ -216,29 +156,30 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
/* Populate params for prime256v1 aka secp256r1 /* Populate params for prime256v1 aka secp256r1
* (the NIST P-256 curve) * (the NIST P-256 curve)
*/ */
CHECK_SEC_OK(gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp, CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_X9_62_PRIME_256V1,
params)); ec_field_GFp, params));
break; break;
case SEC_OID_SECG_EC_SECP384R1: case SEC_OID_SECG_EC_SECP384R1:
/* Populate params for secp384r1 /* Populate params for secp384r1
* (the NIST P-384 curve) * (the NIST P-384 curve)
*/ */
CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_384R1,
params)); ec_field_GFp, params));
break; break;
case SEC_OID_SECG_EC_SECP521R1: case SEC_OID_SECG_EC_SECP521R1:
/* Populate params for secp521r1 /* Populate params for secp521r1
* (the NIST P-521 curve) * (the NIST P-521 curve)
*/ */
CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_521R1,
params)); ec_field_GFp, params));
break; break;
case SEC_OID_CURVE25519: case SEC_OID_CURVE25519:
/* Populate params for 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; break;
default: default:
...@@ -296,16 +237,20 @@ int ...@@ -296,16 +237,20 @@ int
EC_GetPointSize(const ECParams *params) EC_GetPointSize(const ECParams *params)
{ {
ECCurveName name = params->name; ECCurveName name = params->name;
const ECCurveParams *curveParams; const ECCurveBytes *curveParams;
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) || if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) ||
((curveParams = ecCurve_map[name]) == NULL)) { ((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 */ * and a point compression indicator byte */
int sizeInBytes = (params->fieldID.size + 7) / 8; int sizeInBytes = (params->fieldID.size + 7) / 8;
return sizeInBytes * 2 + 1; return sizeInBytes * 2 + 1;
} }
return curveParams->pointSize; if (name == ECCurve25519) {
/* Only X here */
return curveParams->scalarSize;
}
return curveParams->pointSize - 1;
} }
#endif /* NSS_DISABLE_ECC */ #endif /* NSS_DISABLE_ECC */
This diff is collapsed.
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef FREEBL_NO_DEPEND
#include "../stubs.h"
#endif
#include "mpi.h" #include "mpi.h"
#include "mplogic.h" #include "mplogic.h"
#include "ecl.h" #include "ecl.h"
#include "ecl-priv.h" #include "ecl-priv.h"
#include "ecp.h" #include "ecp.h"
#include "ecl-curve.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -128,37 +133,16 @@ CLEANUP: ...@@ -128,37 +133,16 @@ CLEANUP:
return group; return group;
} }
/* Construct ECGroup from hex parameters and name, if any. Called by /* Construct an ECGroup. */
* ECGroup_fromHex and ECGroup_fromName. */
ECGroup * ECGroup *
ecgroup_fromNameAndHex(const ECCurveName name, construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
const ECCurveParams *params) mp_int curveb, mp_int genx, mp_int geny, mp_int order,
int cofactor, ECField field, const char *text)
{ {
mp_int irr, curvea, curveb, genx, geny, order;
int bits; int bits;
ECGroup *group = NULL; ECGroup *group = NULL;
mp_err res = MP_OKAY; mp_err res = MP_OKAY;
/* initialize values */
MP_DIGITS(&irr) = 0;
MP_DIGITS(&curvea) = 0;
MP_DIGITS(&curveb) = 0;
MP_DIGITS(&genx) = 0;
MP_DIGITS(&geny) = 0;
MP_DIGITS(&order) = 0;
MP_CHECKOK(mp_init(&irr));
MP_CHECKOK(mp_init(&curvea));
MP_CHECKOK(mp_init(&curveb));
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));
/* determine number of bits */ /* determine number of bits */
bits = mpl_significant_bits(&irr) - 1; bits = mpl_significant_bits(&irr) - 1;
if (bits < MP_OKAY) { if (bits < MP_OKAY) {
...@@ -167,12 +151,12 @@ ecgroup_fromNameAndHex(const ECCurveName name, ...@@ -167,12 +151,12 @@ ecgroup_fromNameAndHex(const ECCurveName name,
} }
/* determine which optimizations (if any) to use */ /* determine which optimizations (if any) to use */
if (params->field == ECField_GFp) { if (field == ECField_GFp) {
switch (name) { switch (name) {
case ECCurve_SECG_PRIME_256R1: case ECCurve_SECG_PRIME_256R1:
group = group =
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
&order, params->cofactor); &order, cofactor);
if (group == NULL) { if (group == NULL) {
res = MP_UNDEF; res = MP_UNDEF;
goto CLEANUP; goto CLEANUP;
...@@ -183,7 +167,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, ...@@ -183,7 +167,7 @@ ecgroup_fromNameAndHex(const ECCurveName name,
case ECCurve_SECG_PRIME_521R1: case ECCurve_SECG_PRIME_521R1:
group = group =
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
&order, params->cofactor); &order, cofactor);
if (group == NULL) { if (group == NULL) {
res = MP_UNDEF; res = MP_UNDEF;
goto CLEANUP; goto CLEANUP;
...@@ -194,7 +178,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, ...@@ -194,7 +178,7 @@ ecgroup_fromNameAndHex(const ECCurveName name,
/* use generic arithmetic */ /* use generic arithmetic */
group = group =
ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
&order, params->cofactor); &order, cofactor);
if (group == NULL) { if (group == NULL) {
res = MP_UNDEF; res = MP_UNDEF;
goto CLEANUP; goto CLEANUP;
...@@ -206,13 +190,53 @@ ecgroup_fromNameAndHex(const ECCurveName name, ...@@ -206,13 +190,53 @@ ecgroup_fromNameAndHex(const ECCurveName name,
} }