annotate src/share/native/sun/security/ec/impl/ecl.c @ 3909:272483f6650b

7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
author ohair
date Wed, 06 Apr 2011 22:06:11 -0700
parents 1b5c838b8db8
children b49a0af85821
rev   line source
vinnie@1674 1 /* *********************************************************************
vinnie@1674 2 *
vinnie@1674 3 * Sun elects to have this file available under and governed by the
vinnie@1674 4 * Mozilla Public License Version 1.1 ("MPL") (see
vinnie@1674 5 * http://www.mozilla.org/MPL/ for full license text). For the avoidance
vinnie@1674 6 * of doubt and subject to the following, Sun also elects to allow
vinnie@1674 7 * licensees to use this file under the MPL, the GNU General Public
vinnie@1674 8 * License version 2 only or the Lesser General Public License version
vinnie@1674 9 * 2.1 only. Any references to the "GNU General Public License version 2
vinnie@1674 10 * or later" or "GPL" in the following shall be construed to mean the
vinnie@1674 11 * GNU General Public License version 2 only. Any references to the "GNU
vinnie@1674 12 * Lesser General Public License version 2.1 or later" or "LGPL" in the
vinnie@1674 13 * following shall be construed to mean the GNU Lesser General Public
vinnie@1674 14 * License version 2.1 only. However, the following notice accompanied
vinnie@1674 15 * the original version of this file:
vinnie@1674 16 *
vinnie@1674 17 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
vinnie@1674 18 *
vinnie@1674 19 * The contents of this file are subject to the Mozilla Public License Version
vinnie@1674 20 * 1.1 (the "License"); you may not use this file except in compliance with
vinnie@1674 21 * the License. You may obtain a copy of the License at
vinnie@1674 22 * http://www.mozilla.org/MPL/
vinnie@1674 23 *
vinnie@1674 24 * Software distributed under the License is distributed on an "AS IS" basis,
vinnie@1674 25 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
vinnie@1674 26 * for the specific language governing rights and limitations under the
vinnie@1674 27 * License.
vinnie@1674 28 *
vinnie@1674 29 * The Original Code is the elliptic curve math library.
vinnie@1674 30 *
vinnie@1674 31 * The Initial Developer of the Original Code is
vinnie@1674 32 * Sun Microsystems, Inc.
vinnie@1674 33 * Portions created by the Initial Developer are Copyright (C) 2003
vinnie@1674 34 * the Initial Developer. All Rights Reserved.
vinnie@1674 35 *
vinnie@1674 36 * Contributor(s):
vinnie@1674 37 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
vinnie@1674 38 *
vinnie@1674 39 * Alternatively, the contents of this file may be used under the terms of
vinnie@1674 40 * either the GNU General Public License Version 2 or later (the "GPL"), or
vinnie@1674 41 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
vinnie@1674 42 * in which case the provisions of the GPL or the LGPL are applicable instead
vinnie@1674 43 * of those above. If you wish to allow use of your version of this file only
vinnie@1674 44 * under the terms of either the GPL or the LGPL, and not to allow others to
vinnie@1674 45 * use your version of this file under the terms of the MPL, indicate your
vinnie@1674 46 * decision by deleting the provisions above and replace them with the notice
vinnie@1674 47 * and other provisions required by the GPL or the LGPL. If you do not delete
vinnie@1674 48 * the provisions above, a recipient may use your version of this file under
vinnie@1674 49 * the terms of any one of the MPL, the GPL or the LGPL.
vinnie@1674 50 *
vinnie@1674 51 *********************************************************************** */
vinnie@1674 52 /*
ohair@3909 53 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
vinnie@1674 54 * Use is subject to license terms.
vinnie@1674 55 */
vinnie@1674 56
vinnie@1674 57 #include "mpi.h"
vinnie@1674 58 #include "mplogic.h"
vinnie@1674 59 #include "ecl.h"
vinnie@1674 60 #include "ecl-priv.h"
vinnie@1674 61 #include "ec2.h"
vinnie@1674 62 #include "ecp.h"
vinnie@1674 63 #ifndef _KERNEL
vinnie@1674 64 #include <stdlib.h>
vinnie@1674 65 #include <string.h>
vinnie@1674 66 #endif
vinnie@1674 67
vinnie@1674 68 /* Allocate memory for a new ECGroup object. */
vinnie@1674 69 ECGroup *
vinnie@1674 70 ECGroup_new(int kmflag)
vinnie@1674 71 {
vinnie@1674 72 mp_err res = MP_OKAY;
vinnie@1674 73 ECGroup *group;
vinnie@1674 74 #ifdef _KERNEL
vinnie@1674 75 group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
vinnie@1674 76 #else
vinnie@1674 77 group = (ECGroup *) malloc(sizeof(ECGroup));
vinnie@1674 78 #endif
vinnie@1674 79 if (group == NULL)
vinnie@1674 80 return NULL;
vinnie@1674 81 group->constructed = MP_YES;
vinnie@1674 82 group->meth = NULL;
vinnie@1674 83 group->text = NULL;
vinnie@1674 84 MP_DIGITS(&group->curvea) = 0;
vinnie@1674 85 MP_DIGITS(&group->curveb) = 0;
vinnie@1674 86 MP_DIGITS(&group->genx) = 0;
vinnie@1674 87 MP_DIGITS(&group->geny) = 0;
vinnie@1674 88 MP_DIGITS(&group->order) = 0;
vinnie@1674 89 group->base_point_mul = NULL;
vinnie@1674 90 group->points_mul = NULL;
vinnie@1674 91 group->validate_point = NULL;
vinnie@1674 92 group->extra1 = NULL;
vinnie@1674 93 group->extra2 = NULL;
vinnie@1674 94 group->extra_free = NULL;
vinnie@1674 95 MP_CHECKOK(mp_init(&group->curvea, kmflag));
vinnie@1674 96 MP_CHECKOK(mp_init(&group->curveb, kmflag));
vinnie@1674 97 MP_CHECKOK(mp_init(&group->genx, kmflag));
vinnie@1674 98 MP_CHECKOK(mp_init(&group->geny, kmflag));
vinnie@1674 99 MP_CHECKOK(mp_init(&group->order, kmflag));
vinnie@1674 100
vinnie@1674 101 CLEANUP:
vinnie@1674 102 if (res != MP_OKAY) {
vinnie@1674 103 ECGroup_free(group);
vinnie@1674 104 return NULL;
vinnie@1674 105 }
vinnie@1674 106 return group;
vinnie@1674 107 }
vinnie@1674 108
vinnie@1674 109 /* Construct a generic ECGroup for elliptic curves over prime fields. */
vinnie@1674 110 ECGroup *
vinnie@1674 111 ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
vinnie@1674 112 const mp_int *curveb, const mp_int *genx,
vinnie@1674 113 const mp_int *geny, const mp_int *order, int cofactor)
vinnie@1674 114 {
vinnie@1674 115 mp_err res = MP_OKAY;
vinnie@1674 116 ECGroup *group = NULL;
vinnie@1674 117
vinnie@1674 118 group = ECGroup_new(FLAG(irr));
vinnie@1674 119 if (group == NULL)
vinnie@1674 120 return NULL;
vinnie@1674 121
vinnie@1674 122 group->meth = GFMethod_consGFp(irr);
vinnie@1674 123 if (group->meth == NULL) {
vinnie@1674 124 res = MP_MEM;
vinnie@1674 125 goto CLEANUP;
vinnie@1674 126 }
vinnie@1674 127 MP_CHECKOK(mp_copy(curvea, &group->curvea));
vinnie@1674 128 MP_CHECKOK(mp_copy(curveb, &group->curveb));
vinnie@1674 129 MP_CHECKOK(mp_copy(genx, &group->genx));
vinnie@1674 130 MP_CHECKOK(mp_copy(geny, &group->geny));
vinnie@1674 131 MP_CHECKOK(mp_copy(order, &group->order));
vinnie@1674 132 group->cofactor = cofactor;
vinnie@1674 133 group->point_add = &ec_GFp_pt_add_aff;
vinnie@1674 134 group->point_sub = &ec_GFp_pt_sub_aff;
vinnie@1674 135 group->point_dbl = &ec_GFp_pt_dbl_aff;
vinnie@1674 136 group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
vinnie@1674 137 group->base_point_mul = NULL;
vinnie@1674 138 group->points_mul = &ec_GFp_pts_mul_jac;
vinnie@1674 139 group->validate_point = &ec_GFp_validate_point;
vinnie@1674 140
vinnie@1674 141 CLEANUP:
vinnie@1674 142 if (res != MP_OKAY) {
vinnie@1674 143 ECGroup_free(group);
vinnie@1674 144 return NULL;
vinnie@1674 145 }
vinnie@1674 146 return group;
vinnie@1674 147 }
vinnie@1674 148
vinnie@1674 149 /* Construct a generic ECGroup for elliptic curves over prime fields with
vinnie@1674 150 * field arithmetic implemented in Montgomery coordinates. */
vinnie@1674 151 ECGroup *
vinnie@1674 152 ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
vinnie@1674 153 const mp_int *curveb, const mp_int *genx,
vinnie@1674 154 const mp_int *geny, const mp_int *order, int cofactor)
vinnie@1674 155 {
vinnie@1674 156 mp_err res = MP_OKAY;
vinnie@1674 157 ECGroup *group = NULL;
vinnie@1674 158
vinnie@1674 159 group = ECGroup_new(FLAG(irr));
vinnie@1674 160 if (group == NULL)
vinnie@1674 161 return NULL;
vinnie@1674 162
vinnie@1674 163 group->meth = GFMethod_consGFp_mont(irr);
vinnie@1674 164 if (group->meth == NULL) {
vinnie@1674 165 res = MP_MEM;
vinnie@1674 166 goto CLEANUP;
vinnie@1674 167 }
vinnie@1674 168 MP_CHECKOK(group->meth->
vinnie@1674 169 field_enc(curvea, &group->curvea, group->meth));
vinnie@1674 170 MP_CHECKOK(group->meth->
vinnie@1674 171 field_enc(curveb, &group->curveb, group->meth));
vinnie@1674 172 MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
vinnie@1674 173 MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
vinnie@1674 174 MP_CHECKOK(mp_copy(order, &group->order));
vinnie@1674 175 group->cofactor = cofactor;
vinnie@1674 176 group->point_add = &ec_GFp_pt_add_aff;
vinnie@1674 177 group->point_sub = &ec_GFp_pt_sub_aff;
vinnie@1674 178 group->point_dbl = &ec_GFp_pt_dbl_aff;
vinnie@1674 179 group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
vinnie@1674 180 group->base_point_mul = NULL;
vinnie@1674 181 group->points_mul = &ec_GFp_pts_mul_jac;
vinnie@1674 182 group->validate_point = &ec_GFp_validate_point;
vinnie@1674 183
vinnie@1674 184 CLEANUP:
vinnie@1674 185 if (res != MP_OKAY) {
vinnie@1674 186 ECGroup_free(group);
vinnie@1674 187 return NULL;
vinnie@1674 188 }
vinnie@1674 189 return group;
vinnie@1674 190 }
vinnie@1674 191
vinnie@1674 192 #ifdef NSS_ECC_MORE_THAN_SUITE_B
vinnie@1674 193 /* Construct a generic ECGroup for elliptic curves over binary polynomial
vinnie@1674 194 * fields. */
vinnie@1674 195 ECGroup *
vinnie@1674 196 ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
vinnie@1674 197 const mp_int *curvea, const mp_int *curveb,
vinnie@1674 198 const mp_int *genx, const mp_int *geny,
vinnie@1674 199 const mp_int *order, int cofactor)
vinnie@1674 200 {
vinnie@1674 201 mp_err res = MP_OKAY;
vinnie@1674 202 ECGroup *group = NULL;
vinnie@1674 203
vinnie@1674 204 group = ECGroup_new(FLAG(irr));
vinnie@1674 205 if (group == NULL)
vinnie@1674 206 return NULL;
vinnie@1674 207
vinnie@1674 208 group->meth = GFMethod_consGF2m(irr, irr_arr);
vinnie@1674 209 if (group->meth == NULL) {
vinnie@1674 210 res = MP_MEM;
vinnie@1674 211 goto CLEANUP;
vinnie@1674 212 }
vinnie@1674 213 MP_CHECKOK(mp_copy(curvea, &group->curvea));
vinnie@1674 214 MP_CHECKOK(mp_copy(curveb, &group->curveb));
vinnie@1674 215 MP_CHECKOK(mp_copy(genx, &group->genx));
vinnie@1674 216 MP_CHECKOK(mp_copy(geny, &group->geny));
vinnie@1674 217 MP_CHECKOK(mp_copy(order, &group->order));
vinnie@1674 218 group->cofactor = cofactor;
vinnie@1674 219 group->point_add = &ec_GF2m_pt_add_aff;
vinnie@1674 220 group->point_sub = &ec_GF2m_pt_sub_aff;
vinnie@1674 221 group->point_dbl = &ec_GF2m_pt_dbl_aff;
vinnie@1674 222 group->point_mul = &ec_GF2m_pt_mul_mont;
vinnie@1674 223 group->base_point_mul = NULL;
vinnie@1674 224 group->points_mul = &ec_pts_mul_basic;
vinnie@1674 225 group->validate_point = &ec_GF2m_validate_point;
vinnie@1674 226
vinnie@1674 227 CLEANUP:
vinnie@1674 228 if (res != MP_OKAY) {
vinnie@1674 229 ECGroup_free(group);
vinnie@1674 230 return NULL;
vinnie@1674 231 }
vinnie@1674 232 return group;
vinnie@1674 233 }
vinnie@1674 234 #endif
vinnie@1674 235
vinnie@1674 236 /* Construct ECGroup from hex parameters and name, if any. Called by
vinnie@1674 237 * ECGroup_fromHex and ECGroup_fromName. */
vinnie@1674 238 ECGroup *
vinnie@1674 239 ecgroup_fromNameAndHex(const ECCurveName name,
vinnie@1674 240 const ECCurveParams * params, int kmflag)
vinnie@1674 241 {
vinnie@1674 242 mp_int irr, curvea, curveb, genx, geny, order;
vinnie@1674 243 int bits;
vinnie@1674 244 ECGroup *group = NULL;
vinnie@1674 245 mp_err res = MP_OKAY;
vinnie@1674 246
vinnie@1674 247 /* initialize values */
vinnie@1674 248 MP_DIGITS(&irr) = 0;
vinnie@1674 249 MP_DIGITS(&curvea) = 0;
vinnie@1674 250 MP_DIGITS(&curveb) = 0;
vinnie@1674 251 MP_DIGITS(&genx) = 0;
vinnie@1674 252 MP_DIGITS(&geny) = 0;
vinnie@1674 253 MP_DIGITS(&order) = 0;
vinnie@1674 254 MP_CHECKOK(mp_init(&irr, kmflag));
vinnie@1674 255 MP_CHECKOK(mp_init(&curvea, kmflag));
vinnie@1674 256 MP_CHECKOK(mp_init(&curveb, kmflag));
vinnie@1674 257 MP_CHECKOK(mp_init(&genx, kmflag));
vinnie@1674 258 MP_CHECKOK(mp_init(&geny, kmflag));
vinnie@1674 259 MP_CHECKOK(mp_init(&order, kmflag));
vinnie@1674 260 MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
vinnie@1674 261 MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
vinnie@1674 262 MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
vinnie@1674 263 MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
vinnie@1674 264 MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
vinnie@1674 265 MP_CHECKOK(mp_read_radix(&order, params->order, 16));
vinnie@1674 266
vinnie@1674 267 /* determine number of bits */
vinnie@1674 268 bits = mpl_significant_bits(&irr) - 1;
vinnie@1674 269 if (bits < MP_OKAY) {
vinnie@1674 270 res = bits;
vinnie@1674 271 goto CLEANUP;
vinnie@1674 272 }
vinnie@1674 273
vinnie@1674 274 /* determine which optimizations (if any) to use */
vinnie@1674 275 if (params->field == ECField_GFp) {
vinnie@1674 276 #ifdef NSS_ECC_MORE_THAN_SUITE_B
vinnie@1674 277 switch (name) {
vinnie@1674 278 #ifdef ECL_USE_FP
vinnie@1674 279 case ECCurve_SECG_PRIME_160R1:
vinnie@1674 280 group =
vinnie@1674 281 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 282 &order, params->cofactor);
vinnie@1674 283 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 284 MP_CHECKOK(ec_group_set_secp160r1_fp(group));
vinnie@1674 285 break;
vinnie@1674 286 #endif
vinnie@1674 287 case ECCurve_SECG_PRIME_192R1:
vinnie@1674 288 #ifdef ECL_USE_FP
vinnie@1674 289 group =
vinnie@1674 290 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 291 &order, params->cofactor);
vinnie@1674 292 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 293 MP_CHECKOK(ec_group_set_nistp192_fp(group));
vinnie@1674 294 #else
vinnie@1674 295 group =
vinnie@1674 296 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 297 &order, params->cofactor);
vinnie@1674 298 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 299 MP_CHECKOK(ec_group_set_gfp192(group, name));
vinnie@1674 300 #endif
vinnie@1674 301 break;
vinnie@1674 302 case ECCurve_SECG_PRIME_224R1:
vinnie@1674 303 #ifdef ECL_USE_FP
vinnie@1674 304 group =
vinnie@1674 305 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 306 &order, params->cofactor);
vinnie@1674 307 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 308 MP_CHECKOK(ec_group_set_nistp224_fp(group));
vinnie@1674 309 #else
vinnie@1674 310 group =
vinnie@1674 311 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 312 &order, params->cofactor);
vinnie@1674 313 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 314 MP_CHECKOK(ec_group_set_gfp224(group, name));
vinnie@1674 315 #endif
vinnie@1674 316 break;
vinnie@1674 317 case ECCurve_SECG_PRIME_256R1:
vinnie@1674 318 group =
vinnie@1674 319 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 320 &order, params->cofactor);
vinnie@1674 321 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 322 MP_CHECKOK(ec_group_set_gfp256(group, name));
vinnie@1674 323 break;
vinnie@1674 324 case ECCurve_SECG_PRIME_521R1:
vinnie@1674 325 group =
vinnie@1674 326 ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 327 &order, params->cofactor);
vinnie@1674 328 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 329 MP_CHECKOK(ec_group_set_gfp521(group, name));
vinnie@1674 330 break;
vinnie@1674 331 default:
vinnie@1674 332 /* use generic arithmetic */
vinnie@1674 333 #endif
vinnie@1674 334 group =
vinnie@1674 335 ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
vinnie@1674 336 &order, params->cofactor);
vinnie@1674 337 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 338 #ifdef NSS_ECC_MORE_THAN_SUITE_B
vinnie@1674 339 }
vinnie@1674 340 } else if (params->field == ECField_GF2m) {
vinnie@1674 341 group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
vinnie@1674 342 if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
vinnie@1674 343 if ((name == ECCurve_NIST_K163) ||
vinnie@1674 344 (name == ECCurve_NIST_B163) ||
vinnie@1674 345 (name == ECCurve_SECG_CHAR2_163R1)) {
vinnie@1674 346 MP_CHECKOK(ec_group_set_gf2m163(group, name));
vinnie@1674 347 } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
vinnie@1674 348 (name == ECCurve_SECG_CHAR2_193R2)) {
vinnie@1674 349 MP_CHECKOK(ec_group_set_gf2m193(group, name));
vinnie@1674 350 } else if ((name == ECCurve_NIST_K233) ||
vinnie@1674 351 (name == ECCurve_NIST_B233)) {
vinnie@1674 352 MP_CHECKOK(ec_group_set_gf2m233(group, name));
vinnie@1674 353 }
vinnie@1674 354 #endif
vinnie@1674 355 } else {
vinnie@1674 356 res = MP_UNDEF;
vinnie@1674 357 goto CLEANUP;
vinnie@1674 358 }
vinnie@1674 359
vinnie@1674 360 /* set name, if any */
vinnie@1674 361 if ((group != NULL) && (params->text != NULL)) {
vinnie@1674 362 #ifdef _KERNEL
vinnie@1674 363 int n = strlen(params->text) + 1;
vinnie@1674 364
vinnie@1674 365 group->text = kmem_alloc(n, kmflag);
vinnie@1674 366 if (group->text == NULL) {
vinnie@1674 367 res = MP_MEM;
vinnie@1674 368 goto CLEANUP;
vinnie@1674 369 }
vinnie@1674 370 bcopy(params->text, group->text, n);
vinnie@1674 371 group->text_len = n;
vinnie@1674 372 #else
vinnie@1674 373 group->text = strdup(params->text);
vinnie@1674 374 if (group->text == NULL) {
vinnie@1674 375 res = MP_MEM;
vinnie@1674 376 }
vinnie@1674 377 #endif
vinnie@1674 378 }
vinnie@1674 379
vinnie@1674 380 CLEANUP:
vinnie@1674 381 mp_clear(&irr);
vinnie@1674 382 mp_clear(&curvea);
vinnie@1674 383 mp_clear(&curveb);
vinnie@1674 384 mp_clear(&genx);
vinnie@1674 385 mp_clear(&geny);
vinnie@1674 386 mp_clear(&order);
vinnie@1674 387 if (res != MP_OKAY) {
vinnie@1674 388 ECGroup_free(group);
vinnie@1674 389 return NULL;
vinnie@1674 390 }
vinnie@1674 391 return group;
vinnie@1674 392 }
vinnie@1674 393
vinnie@1674 394 /* Construct ECGroup from hexadecimal representations of parameters. */
vinnie@1674 395 ECGroup *
vinnie@1674 396 ECGroup_fromHex(const ECCurveParams * params, int kmflag)
vinnie@1674 397 {
vinnie@1674 398 return ecgroup_fromNameAndHex(ECCurve_noName, params, kmflag);
vinnie@1674 399 }
vinnie@1674 400
vinnie@1674 401 /* Construct ECGroup from named parameters. */
vinnie@1674 402 ECGroup *
vinnie@1674 403 ECGroup_fromName(const ECCurveName name, int kmflag)
vinnie@1674 404 {
vinnie@1674 405 ECGroup *group = NULL;
vinnie@1674 406 ECCurveParams *params = NULL;
vinnie@1674 407 mp_err res = MP_OKAY;
vinnie@1674 408
vinnie@1674 409 params = EC_GetNamedCurveParams(name, kmflag);
vinnie@1674 410 if (params == NULL) {
vinnie@1674 411 res = MP_UNDEF;
vinnie@1674 412 goto CLEANUP;
vinnie@1674 413 }
vinnie@1674 414
vinnie@1674 415 /* construct actual group */
vinnie@1674 416 group = ecgroup_fromNameAndHex(name, params, kmflag);
vinnie@1674 417 if (group == NULL) {
vinnie@1674 418 res = MP_UNDEF;
vinnie@1674 419 goto CLEANUP;
vinnie@1674 420 }
vinnie@1674 421
vinnie@1674 422 CLEANUP:
vinnie@1674 423 EC_FreeCurveParams(params);
vinnie@1674 424 if (res != MP_OKAY) {
vinnie@1674 425 ECGroup_free(group);
vinnie@1674 426 return NULL;
vinnie@1674 427 }
vinnie@1674 428 return group;
vinnie@1674 429 }
vinnie@1674 430
vinnie@1674 431 /* Validates an EC public key as described in Section 5.2.2 of X9.62. */
vinnie@1674 432 mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
vinnie@1674 433 mp_int *py)
vinnie@1674 434 {
vinnie@1674 435 /* 1: Verify that publicValue is not the point at infinity */
vinnie@1674 436 /* 2: Verify that the coordinates of publicValue are elements
vinnie@1674 437 * of the field.
vinnie@1674 438 */
vinnie@1674 439 /* 3: Verify that publicValue is on the curve. */
vinnie@1674 440 /* 4: Verify that the order of the curve times the publicValue
vinnie@1674 441 * is the point at infinity.
vinnie@1674 442 */
vinnie@1674 443 return group->validate_point(px, py, group);
vinnie@1674 444 }
vinnie@1674 445
vinnie@1674 446 /* Free the memory allocated (if any) to an ECGroup object. */
vinnie@1674 447 void
vinnie@1674 448 ECGroup_free(ECGroup *group)
vinnie@1674 449 {
vinnie@1674 450 if (group == NULL)
vinnie@1674 451 return;
vinnie@1674 452 GFMethod_free(group->meth);
vinnie@1674 453 if (group->constructed == MP_NO)
vinnie@1674 454 return;
vinnie@1674 455 mp_clear(&group->curvea);
vinnie@1674 456 mp_clear(&group->curveb);
vinnie@1674 457 mp_clear(&group->genx);
vinnie@1674 458 mp_clear(&group->geny);
vinnie@1674 459 mp_clear(&group->order);
vinnie@1674 460 if (group->text != NULL)
vinnie@1674 461 #ifdef _KERNEL
vinnie@1674 462 kmem_free(group->text, group->text_len);
vinnie@1674 463 #else
vinnie@1674 464 free(group->text);
vinnie@1674 465 #endif
vinnie@1674 466 if (group->extra_free != NULL)
vinnie@1674 467 group->extra_free(group);
vinnie@1674 468 #ifdef _KERNEL
vinnie@1674 469 kmem_free(group, sizeof (ECGroup));
vinnie@1674 470 #else
vinnie@1674 471 free(group);
vinnie@1674 472 #endif
vinnie@1674 473 }