diff options
Diffstat (limited to 'security/nss/lib/freebl/ecl/ecl.c')
-rw-r--r-- | security/nss/lib/freebl/ecl/ecl.c | 127 |
1 files changed, 72 insertions, 55 deletions
diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c index 3540af7812..ca87b490cd 100644 --- a/security/nss/lib/freebl/ecl/ecl.c +++ b/security/nss/lib/freebl/ecl/ecl.c @@ -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,37 +133,16 @@ 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) { - 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) { @@ -167,12 +151,12 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* determine which optimizations (if any) to use */ - if (params->field == ECField_GFp) { + if (field == ECField_GFp) { switch (name) { case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -183,7 +167,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -194,7 +178,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, /* use generic arithmetic */ group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -206,62 +190,95 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* set name, if any */ - if ((group != NULL) && (params->text != NULL)) { - group->text = strdup(params->text); + 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; + 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); mp_clear(&curveb); 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. */ ECGroup * ECGroup_fromName(const ECCurveName name) { - ECGroup *group = NULL; - ECCurveParams *params = NULL; - mp_err res = MP_OKAY; + const ECCurveBytes *params = NULL; - 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; + return NULL; } /* construct actual group */ - group = ecgroup_fromNameAndHex(name, params); - if (group == NULL) { - res = MP_UNDEF; - goto CLEANUP; - } - -CLEANUP: - EC_FreeCurveParams(params); - if (res != MP_OKAY) { - ECGroup_free(group); - return NULL; - } - return group; + return ecgroup_fromName(name, params); } /* Validates an EC public key as described in Section 5.2.2 of X9.62. */ |