Commit 878c48cf authored by Franziskus Kiefer's avatar Franziskus Kiefer

Backed out changeset 703f8f3f2379 (needs additional fixes)

parent 6c570154
......@@ -2830,7 +2830,7 @@ print_td:
ECPrivateKey *key = (ECPrivateKey *)info->params.asymk.privKey;
ECCurveName curveName = key->ecParams.name;
fprintf(stdout, "%12s",
ecCurve_mapB[curveName] ? ecCurve_mapB[curveName]->text : "Unsupported curve");
ecCurve_map[curveName] ? ecCurve_map[curveName]->text : "Unsupported curve");
}
break;
#endif
......
......@@ -9,7 +9,6 @@
#include "basicutil.h"
#include "pkcs11.h"
#include "nspr.h"
#include "secutil.h"
#include <stdio.h>
#define __PASTE(x, y) x##y
......@@ -27,6 +26,70 @@
#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 *);
......@@ -311,6 +374,30 @@ 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. */
......@@ -336,7 +423,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
ecParams.data = NULL;
ecParams.len = 0;
rv = SECU_ecName2params(curve, &ecParams);
rv = ecName2params(curve, &ecParams);
if (rv != SECSuccess) {
goto cleanup;
}
......@@ -387,7 +474,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
lock = PR_NewLock();
if (ecCurve_mapB[curve]->usage & KU_KEY_AGREEMENT) {
if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT) {
rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Derive, "ECDH_Derive",
&ecPriv, &mech, NULL, iterations, numThreads,
lock, session, 0, &deriveRate);
......@@ -396,7 +483,7 @@ ectest_curve_pkcs11(ECCurveName curve, int iterations, int numThreads)
}
}
if (ecCurve_mapB[curve]->usage & KU_DIGITAL_SIGNATURE) {
if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE) {
rv = M_TimeOperation(PKCS11Thread, (op_func)PKCS11_Sign, "ECDSA_Sign",
(void *)&ecPriv, &sig, &digest, iterations, numThreads,
lock, session, 1, &signRate);
......@@ -455,9 +542,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) {
......@@ -469,11 +556,28 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
return SECFailure;
}
rv = SECU_ecName2params(curve, &ecEncodedParams);
if (rv != SECSuccess) {
goto cleanup;
}
EC_FillParams(arena, &ecEncodedParams, &ecParams);
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;
PORT_Memset(digestData, 0xa5, sizeof(digestData));
digest.data = digestData;
......@@ -488,7 +592,7 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
ecPub.ecParams = ecParams;
ecPub.publicValue = ecPriv->publicValue;
if (ecCurve_mapB[curve]->usage & KU_KEY_AGREEMENT) {
if (ecCurve_map[curve]->usage & KU_KEY_AGREEMENT) {
rv = M_TimeOperation(genericThread, (op_func)ECDH_DeriveWrap, "ECDH_Derive",
ecPriv, &ecPub, NULL, iterations, numThreads, 0, 0, 0, &deriveRate);
if (rv != SECSuccess) {
......@@ -496,7 +600,7 @@ ectest_curve_freebl(ECCurveName curve, int iterations, int numThreads,
}
}
if (ecCurve_mapB[curve]->usage & KU_DIGITAL_SIGNATURE) {
if (ecCurve_map[curve]->usage & KU_DIGITAL_SIGNATURE) {
rv = M_TimeOperation(genericThread, (op_func)ECDSA_SignDigest, "ECDSA_Sign",
ecPriv, &sig, &digest, iterations, numThreads, 0, 0, 1, &signRate);
if (rv != SECSuccess)
......
......@@ -10,7 +10,6 @@
#include "secder.h"
#include "secitem.h"
#include "nspr.h"
#include "secutil.h"
#include <stdio.h>
typedef struct {
......@@ -69,9 +68,9 @@ init_params(ECParams *ecParams, ECCurveName curve, PLArenaPool **arena,
ecParams->DEREncoding.data = NULL;
ecParams->DEREncoding.len = 0;
ecParams->arena = *arena;
ecParams->fieldID.size = ecCurve_mapB[curve]->size;
ecParams->fieldID.size = ecCurve_map[curve]->size;
ecParams->fieldID.type = type;
ecParams->cofactor = ecCurve_mapB[curve]->cofactor;
ecParams->cofactor = ecCurve_map[curve]->cofactor;
return SECSuccess;
}
......@@ -89,19 +88,26 @@ ectest_ecdh_kat(ECDH_KAT *kat)
SECItem answer = { siBuffer, NULL, 0 };
SECItem answer2 = { siBuffer, NULL, 0 };
SECItem derived = { siBuffer, NULL, 0 };
SECItem ecEncodedParams = { siBuffer, NULL, 0 };
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
int i;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
return SECFailure;
}
rv = SECU_ecName2params(curve, &ecEncodedParams);
rv = init_params(&ecParams, curve, &arena, kat->fieldType);
if (rv != SECSuccess) {
goto cleanup;
return rv;
}
EC_FillParams(arena, &ecEncodedParams, &ecParams);
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);
if (kat->our_pubhex) {
SECU_HexString2SECItem(arena, &answer, kat->our_pubhex);
......
......@@ -3960,93 +3960,3 @@ done:
*enabledGroups = groups;
return SECSuccess;
}
/* 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, 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;
}
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;
}
......@@ -18,7 +18,6 @@
#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"
......@@ -413,8 +412,6 @@ SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
unsigned int *enabledGroupsCount);
SSLNamedGroup groupNameToNamedGroup(char *name);
extern SECStatus SECU_ecName2params(ECCurveName curve, SECKEYECParams *params);
/*
*
* Error messaging
......
......@@ -22,6 +22,57 @@
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
......@@ -69,31 +120,40 @@ cleanup:
}
static SECStatus
gf_populate_params_bytes(ECCurveName name, ECFieldType field_type, ECParams *params)
gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
{
SECStatus rv = SECFailure;
const ECCurveBytes *curveParams;
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];
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve))
goto cleanup;
params->name = name;
curveParams = ecCurve_mapB[params->name];
curveParams = ecCurve_map[params->name];
CHECK_OK(curveParams);
params->fieldID.size = curveParams->size;
params->fieldID.type = field_type;
if (field_type != ec_field_GFp && field_type != ec_field_plain) {
return SECFailure;
if (field_type == ec_field_GFp ||
field_type == ec_field_plain) {
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
curveParams->irr));
} else {
CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
curveParams->irr));
}
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;
CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
curveParams->curvea));
CHECK_OK(hexString2SECItem(params->arena, &params->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, &params->base, genenc));
CHECK_OK(hexString2SECItem(params->arena, &params->order,
curveParams->order));
params->cofactor = curveParams->cofactor;
rv = SECSuccess;
......@@ -156,30 +216,29 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
/* Populate params for prime256v1 aka secp256r1
* (the NIST P-256 curve)
*/
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_X9_62_PRIME_256V1,
ec_field_GFp, params));
CHECK_SEC_OK(gf_populate_params(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_bytes(ECCurve_SECG_PRIME_384R1,
ec_field_GFp, params));
CHECK_SEC_OK(gf_populate_params(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_bytes(ECCurve_SECG_PRIME_521R1,
ec_field_GFp, params));
CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
params));
break;
case SEC_OID_CURVE25519:
/* Populate params for Curve25519 */
CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519, ec_field_plain,
params));
CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params));
break;
default:
......@@ -237,20 +296,16 @@ int
EC_GetPointSize(const ECParams *params)
{
ECCurveName name = params->name;
const ECCurveBytes *curveParams;
const ECCurveParams *curveParams;
if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) ||
((curveParams = ecCurve_mapB[name]) == NULL)) {
/* unknown curve, calculate point size from params. assume standard curves with 2 points
((curveParams = ecCurve_map[name]) == NULL)) {
/* 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;
}
if (name == ECCurve25519) {
/* Only X here */
return curveParams->scalarSize;
}
return curveParams->pointSize - 1;
return curveParams->pointSize;
}
#endif /* NSS_DISABLE_ECC */
This diff is collapsed.
......@@ -7,7 +7,6 @@
#include "ecl.h"
#include "ecl-priv.h"
#include "ecp.h"
#include "ecl-curve.h"
#include <stdlib.h>
#include <string.h>
......@@ -129,16 +128,37 @@ CLEANUP:
return group;
}
/* Construct an ECGroup. */
/* Construct ECGroup from hex parameters and name, if any. Called by
* ECGroup_fromHex and ECGroup_fromName. */
ECGroup *
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)
ecgroup_fromNameAndHex(const ECCurveName name,
const ECCurveParams *params)
{
mp_int irr, curvea, curveb, genx, geny, order;
int bits;
ECGroup *group = NULL;
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 */
bits = mpl_significant_bits(&irr) - 1;
if (bits < MP_OKAY) {
......@@ -147,12 +167,12 @@ construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
}
/* determine which optimizations (if any) to use */
if (field == ECField_GFp) {
if (params->field == ECField_GFp) {
switch (name) {
case ECCurve_SECG_PRIME_256R1:
group =
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
&order, cofactor);
&order, params->cofactor);
if (group == NULL) {
res = MP_UNDEF;
goto CLEANUP;
......@@ -163,7 +183,7 @@ construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
case ECCurve_SECG_PRIME_521R1:
group =
ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
&order, cofactor);
&order, params->cofactor);
if (group == NULL) {
res = MP_UNDEF;
goto CLEANUP;
......@@ -174,7 +194,7 @@ construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
/* use generic arithmetic */
group =
ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
&order, cofactor);
&order, params->cofactor);
if (group == NULL) {
res = MP_UNDEF;
goto CLEANUP;
......@@ -186,53 +206,13 @@ construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea,
}
/* set name, if any */
if ((group != NULL) && (text != NULL)) {
group->text = strdup(text);
if ((group != NULL) && (params->text != NULL)) {
group->text = strdup(params->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;
ECGroup *group = NULL;
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_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));
group = construct_ecgroup(name, irr, curvea, curveb, genx, geny, order,
params->cofactor, params->field, params->text);
CLEANUP:
mp_clear(&irr);
mp_clear(&curvea);
......@@ -240,23 +220,18 @@ CLEANUP:
mp_clear(&genx);
mp_clear(&geny);
mp_clear(&order);
if (group && res != MP_OKAY) {
if (res != MP_OKAY) {
ECGroup_free(group);
return NULL;
}
return group;
}
/* Construct ECCurveBytes from an ECCurveName */
const ECCurveBytes *
ec_GetNamedCurveParams(const ECCurveName name)
/* Construct ECGroup from hexadecimal representations of parameters. */
ECGroup *
ECGroup_fromHex(const ECCurveParams *params)
{
if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
(ecCurve_mapB[name] == NULL)) {
return NULL;
} else {
return ecCurve_mapB[name];
}
return ecgroup_fromNameAndHex(ECCurve_noName, params);
}
/* Construct ECGroup from named parameters. */
......@@ -264,26 +239,25 @@ ECGroup *
ECGroup_fromName(const ECCurveName name)
{
ECGroup *group = NULL;
const ECCurveBytes *params = NULL;
ECCurveParams *params = NULL;
mp_err res = MP_OKAY;
/* This doesn't work with Curve25519 but it's not necessary to. */
PORT_Assert(name != ECCurve25519);
params = ec_GetNamedCurveParams(name);
params = EC_GetNamedCurveParams(name);
if (params == NULL) {
res = MP_UNDEF