1*5697Smcpowers /*
2*5697Smcpowers * ***** BEGIN LICENSE BLOCK *****
3*5697Smcpowers * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4*5697Smcpowers *
5*5697Smcpowers * The contents of this file are subject to the Mozilla Public License Version
6*5697Smcpowers * 1.1 (the "License"); you may not use this file except in compliance with
7*5697Smcpowers * the License. You may obtain a copy of the License at
8*5697Smcpowers * http://www.mozilla.org/MPL/
9*5697Smcpowers *
10*5697Smcpowers * Software distributed under the License is distributed on an "AS IS" basis,
11*5697Smcpowers * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12*5697Smcpowers * for the specific language governing rights and limitations under the
13*5697Smcpowers * License.
14*5697Smcpowers *
15*5697Smcpowers * The Original Code is the Elliptic Curve Cryptography library.
16*5697Smcpowers *
17*5697Smcpowers * The Initial Developer of the Original Code is
18*5697Smcpowers * Sun Microsystems, Inc.
19*5697Smcpowers * Portions created by the Initial Developer are Copyright (C) 2003
20*5697Smcpowers * the Initial Developer. All Rights Reserved.
21*5697Smcpowers *
22*5697Smcpowers * Contributor(s):
23*5697Smcpowers * Dr Vipul Gupta <vipul.gupta@sun.com> and
24*5697Smcpowers * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
25*5697Smcpowers *
26*5697Smcpowers * Alternatively, the contents of this file may be used under the terms of
27*5697Smcpowers * either the GNU General Public License Version 2 or later (the "GPL"), or
28*5697Smcpowers * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29*5697Smcpowers * in which case the provisions of the GPL or the LGPL are applicable instead
30*5697Smcpowers * of those above. If you wish to allow use of your version of this file only
31*5697Smcpowers * under the terms of either the GPL or the LGPL, and not to allow others to
32*5697Smcpowers * use your version of this file under the terms of the MPL, indicate your
33*5697Smcpowers * decision by deleting the provisions above and replace them with the notice
34*5697Smcpowers * and other provisions required by the GPL or the LGPL. If you do not delete
35*5697Smcpowers * the provisions above, a recipient may use your version of this file under
36*5697Smcpowers * the terms of any one of the MPL, the GPL or the LGPL.
37*5697Smcpowers *
38*5697Smcpowers * ***** END LICENSE BLOCK ***** */
39*5697Smcpowers /*
40*5697Smcpowers * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
41*5697Smcpowers * Use is subject to license terms.
42*5697Smcpowers *
43*5697Smcpowers * Sun elects to use this software under the MPL license.
44*5697Smcpowers */
45*5697Smcpowers
46*5697Smcpowers #pragma ident "%Z%%M% %I% %E% SMI"
47*5697Smcpowers
48*5697Smcpowers #include <sys/types.h>
49*5697Smcpowers #include <sys/systm.h>
50*5697Smcpowers #include <sys/param.h>
51*5697Smcpowers #ifdef _KERNEL
52*5697Smcpowers #include <sys/kmem.h>
53*5697Smcpowers #else
54*5697Smcpowers #include <string.h>
55*5697Smcpowers #endif
56*5697Smcpowers #include "ec.h"
57*5697Smcpowers #include "ecl-curve.h"
58*5697Smcpowers #include "ecc_impl.h"
59*5697Smcpowers
60*5697Smcpowers #define MAX_ECKEY_LEN 72
61*5697Smcpowers #define SEC_ASN1_OBJECT_ID 0x06
62*5697Smcpowers
63*5697Smcpowers /*
64*5697Smcpowers * Initializes a SECItem from a hexadecimal string
65*5697Smcpowers *
66*5697Smcpowers * Warning: This function ignores leading 00's, so any leading 00's
67*5697Smcpowers * in the hexadecimal string must be optional.
68*5697Smcpowers */
69*5697Smcpowers static SECItem *
hexString2SECItem(PRArenaPool * arena,SECItem * item,const char * str,int kmflag)70*5697Smcpowers hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str,
71*5697Smcpowers int kmflag)
72*5697Smcpowers {
73*5697Smcpowers int i = 0;
74*5697Smcpowers int byteval = 0;
75*5697Smcpowers int tmp = strlen(str);
76*5697Smcpowers
77*5697Smcpowers if ((tmp % 2) != 0) return NULL;
78*5697Smcpowers
79*5697Smcpowers /* skip leading 00's unless the hex string is "00" */
80*5697Smcpowers while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
81*5697Smcpowers str += 2;
82*5697Smcpowers tmp -= 2;
83*5697Smcpowers }
84*5697Smcpowers
85*5697Smcpowers item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2, kmflag);
86*5697Smcpowers if (item->data == NULL) return NULL;
87*5697Smcpowers item->len = tmp/2;
88*5697Smcpowers
89*5697Smcpowers while (str[i]) {
90*5697Smcpowers if ((str[i] >= '0') && (str[i] <= '9'))
91*5697Smcpowers tmp = str[i] - '0';
92*5697Smcpowers else if ((str[i] >= 'a') && (str[i] <= 'f'))
93*5697Smcpowers tmp = str[i] - 'a' + 10;
94*5697Smcpowers else if ((str[i] >= 'A') && (str[i] <= 'F'))
95*5697Smcpowers tmp = str[i] - 'A' + 10;
96*5697Smcpowers else
97*5697Smcpowers return NULL;
98*5697Smcpowers
99*5697Smcpowers byteval = byteval * 16 + tmp;
100*5697Smcpowers if ((i % 2) != 0) {
101*5697Smcpowers item->data[i/2] = byteval;
102*5697Smcpowers byteval = 0;
103*5697Smcpowers }
104*5697Smcpowers i++;
105*5697Smcpowers }
106*5697Smcpowers
107*5697Smcpowers return item;
108*5697Smcpowers }
109*5697Smcpowers
110*5697Smcpowers static SECStatus
gf_populate_params(ECCurveName name,ECFieldType field_type,ECParams * params,int kmflag)111*5697Smcpowers gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params,
112*5697Smcpowers int kmflag)
113*5697Smcpowers {
114*5697Smcpowers SECStatus rv = SECFailure;
115*5697Smcpowers const ECCurveParams *curveParams;
116*5697Smcpowers /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
117*5697Smcpowers char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
118*5697Smcpowers
119*5697Smcpowers if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
120*5697Smcpowers params->name = name;
121*5697Smcpowers curveParams = ecCurve_map[params->name];
122*5697Smcpowers CHECK_OK(curveParams);
123*5697Smcpowers params->fieldID.size = curveParams->size;
124*5697Smcpowers params->fieldID.type = field_type;
125*5697Smcpowers if (field_type == ec_field_GFp) {
126*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.prime,
127*5697Smcpowers curveParams->irr, kmflag));
128*5697Smcpowers } else {
129*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->fieldID.u.poly,
130*5697Smcpowers curveParams->irr, kmflag));
131*5697Smcpowers }
132*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.a,
133*5697Smcpowers curveParams->curvea, kmflag));
134*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->curve.b,
135*5697Smcpowers curveParams->curveb, kmflag));
136*5697Smcpowers genenc[0] = '0';
137*5697Smcpowers genenc[1] = '4';
138*5697Smcpowers genenc[2] = '\0';
139*5697Smcpowers strcat(genenc, curveParams->genx);
140*5697Smcpowers strcat(genenc, curveParams->geny);
141*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->base, genenc, kmflag));
142*5697Smcpowers CHECK_OK(hexString2SECItem(NULL, ¶ms->order,
143*5697Smcpowers curveParams->order, kmflag));
144*5697Smcpowers params->cofactor = curveParams->cofactor;
145*5697Smcpowers
146*5697Smcpowers rv = SECSuccess;
147*5697Smcpowers
148*5697Smcpowers cleanup:
149*5697Smcpowers return rv;
150*5697Smcpowers }
151*5697Smcpowers
152*5697Smcpowers ECCurveName SECOID_FindOIDTag(const SECItem *);
153*5697Smcpowers
154*5697Smcpowers SECStatus
EC_FillParams(PRArenaPool * arena,const SECItem * encodedParams,ECParams * params,int kmflag)155*5697Smcpowers EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
156*5697Smcpowers ECParams *params, int kmflag)
157*5697Smcpowers {
158*5697Smcpowers SECStatus rv = SECFailure;
159*5697Smcpowers ECCurveName tag;
160*5697Smcpowers SECItem oid = { siBuffer, NULL, 0};
161*5697Smcpowers
162*5697Smcpowers #if EC_DEBUG
163*5697Smcpowers int i;
164*5697Smcpowers
165*5697Smcpowers printf("Encoded params in EC_DecodeParams: ");
166*5697Smcpowers for (i = 0; i < encodedParams->len; i++) {
167*5697Smcpowers printf("%02x:", encodedParams->data[i]);
168*5697Smcpowers }
169*5697Smcpowers printf("\n");
170*5697Smcpowers #endif
171*5697Smcpowers
172*5697Smcpowers if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
173*5697Smcpowers (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
174*5697Smcpowers PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
175*5697Smcpowers return SECFailure;
176*5697Smcpowers };
177*5697Smcpowers
178*5697Smcpowers oid.len = encodedParams->len - 2;
179*5697Smcpowers oid.data = encodedParams->data + 2;
180*5697Smcpowers if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
181*5697Smcpowers ((tag = SECOID_FindOIDTag(&oid)) == ECCurve_noName)) {
182*5697Smcpowers PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
183*5697Smcpowers return SECFailure;
184*5697Smcpowers }
185*5697Smcpowers
186*5697Smcpowers params->arena = arena;
187*5697Smcpowers params->cofactor = 0;
188*5697Smcpowers params->type = ec_params_named;
189*5697Smcpowers params->name = ECCurve_noName;
190*5697Smcpowers
191*5697Smcpowers /* For named curves, fill out curveOID */
192*5697Smcpowers params->curveOID.len = oid.len;
193*5697Smcpowers params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(NULL, oid.len,
194*5697Smcpowers kmflag);
195*5697Smcpowers if (params->curveOID.data == NULL) goto cleanup;
196*5697Smcpowers memcpy(params->curveOID.data, oid.data, oid.len);
197*5697Smcpowers
198*5697Smcpowers #if EC_DEBUG
199*5697Smcpowers printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
200*5697Smcpowers #endif
201*5697Smcpowers
202*5697Smcpowers switch (tag) {
203*5697Smcpowers
204*5697Smcpowers /* Binary curves */
205*5697Smcpowers
206*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB163V1:
207*5697Smcpowers /* Populate params for c2pnb163v1 */
208*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
209*5697Smcpowers params, kmflag) );
210*5697Smcpowers break;
211*5697Smcpowers
212*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB163V2:
213*5697Smcpowers /* Populate params for c2pnb163v2 */
214*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
215*5697Smcpowers params, kmflag) );
216*5697Smcpowers break;
217*5697Smcpowers
218*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB163V3:
219*5697Smcpowers /* Populate params for c2pnb163v3 */
220*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
221*5697Smcpowers params, kmflag) );
222*5697Smcpowers break;
223*5697Smcpowers
224*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB176V1:
225*5697Smcpowers /* Populate params for c2pnb176v1 */
226*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
227*5697Smcpowers params, kmflag) );
228*5697Smcpowers break;
229*5697Smcpowers
230*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB191V1:
231*5697Smcpowers /* Populate params for c2tnb191v1 */
232*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
233*5697Smcpowers params, kmflag) );
234*5697Smcpowers break;
235*5697Smcpowers
236*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB191V2:
237*5697Smcpowers /* Populate params for c2tnb191v2 */
238*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
239*5697Smcpowers params, kmflag) );
240*5697Smcpowers break;
241*5697Smcpowers
242*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB191V3:
243*5697Smcpowers /* Populate params for c2tnb191v3 */
244*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
245*5697Smcpowers params, kmflag) );
246*5697Smcpowers break;
247*5697Smcpowers
248*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB208W1:
249*5697Smcpowers /* Populate params for c2pnb208w1 */
250*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
251*5697Smcpowers params, kmflag) );
252*5697Smcpowers break;
253*5697Smcpowers
254*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB239V1:
255*5697Smcpowers /* Populate params for c2tnb239v1 */
256*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
257*5697Smcpowers params, kmflag) );
258*5697Smcpowers break;
259*5697Smcpowers
260*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB239V2:
261*5697Smcpowers /* Populate params for c2tnb239v2 */
262*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
263*5697Smcpowers params, kmflag) );
264*5697Smcpowers break;
265*5697Smcpowers
266*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB239V3:
267*5697Smcpowers /* Populate params for c2tnb239v3 */
268*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
269*5697Smcpowers params, kmflag) );
270*5697Smcpowers break;
271*5697Smcpowers
272*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB272W1:
273*5697Smcpowers /* Populate params for c2pnb272w1 */
274*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
275*5697Smcpowers params, kmflag) );
276*5697Smcpowers break;
277*5697Smcpowers
278*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB304W1:
279*5697Smcpowers /* Populate params for c2pnb304w1 */
280*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
281*5697Smcpowers params, kmflag) );
282*5697Smcpowers break;
283*5697Smcpowers
284*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB359V1:
285*5697Smcpowers /* Populate params for c2tnb359v1 */
286*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
287*5697Smcpowers params, kmflag) );
288*5697Smcpowers break;
289*5697Smcpowers
290*5697Smcpowers case ECCurve_X9_62_CHAR2_PNB368W1:
291*5697Smcpowers /* Populate params for c2pnb368w1 */
292*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
293*5697Smcpowers params, kmflag) );
294*5697Smcpowers break;
295*5697Smcpowers
296*5697Smcpowers case ECCurve_X9_62_CHAR2_TNB431R1:
297*5697Smcpowers /* Populate params for c2tnb431r1 */
298*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
299*5697Smcpowers params, kmflag) );
300*5697Smcpowers break;
301*5697Smcpowers
302*5697Smcpowers case ECCurve_SECG_CHAR2_113R1:
303*5697Smcpowers /* Populate params for sect113r1 */
304*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
305*5697Smcpowers params, kmflag) );
306*5697Smcpowers break;
307*5697Smcpowers
308*5697Smcpowers case ECCurve_SECG_CHAR2_113R2:
309*5697Smcpowers /* Populate params for sect113r2 */
310*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
311*5697Smcpowers params, kmflag) );
312*5697Smcpowers break;
313*5697Smcpowers
314*5697Smcpowers case ECCurve_SECG_CHAR2_131R1:
315*5697Smcpowers /* Populate params for sect131r1 */
316*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
317*5697Smcpowers params, kmflag) );
318*5697Smcpowers break;
319*5697Smcpowers
320*5697Smcpowers case ECCurve_SECG_CHAR2_131R2:
321*5697Smcpowers /* Populate params for sect131r2 */
322*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
323*5697Smcpowers params, kmflag) );
324*5697Smcpowers break;
325*5697Smcpowers
326*5697Smcpowers case ECCurve_SECG_CHAR2_163K1:
327*5697Smcpowers /* Populate params for sect163k1
328*5697Smcpowers * (the NIST K-163 curve)
329*5697Smcpowers */
330*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
331*5697Smcpowers params, kmflag) );
332*5697Smcpowers break;
333*5697Smcpowers
334*5697Smcpowers case ECCurve_SECG_CHAR2_163R1:
335*5697Smcpowers /* Populate params for sect163r1 */
336*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
337*5697Smcpowers params, kmflag) );
338*5697Smcpowers break;
339*5697Smcpowers
340*5697Smcpowers case ECCurve_SECG_CHAR2_163R2:
341*5697Smcpowers /* Populate params for sect163r2
342*5697Smcpowers * (the NIST B-163 curve)
343*5697Smcpowers */
344*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
345*5697Smcpowers params, kmflag) );
346*5697Smcpowers break;
347*5697Smcpowers
348*5697Smcpowers case ECCurve_SECG_CHAR2_193R1:
349*5697Smcpowers /* Populate params for sect193r1 */
350*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
351*5697Smcpowers params, kmflag) );
352*5697Smcpowers break;
353*5697Smcpowers
354*5697Smcpowers case ECCurve_SECG_CHAR2_193R2:
355*5697Smcpowers /* Populate params for sect193r2 */
356*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
357*5697Smcpowers params, kmflag) );
358*5697Smcpowers break;
359*5697Smcpowers
360*5697Smcpowers case ECCurve_SECG_CHAR2_233K1:
361*5697Smcpowers /* Populate params for sect233k1
362*5697Smcpowers * (the NIST K-233 curve)
363*5697Smcpowers */
364*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
365*5697Smcpowers params, kmflag) );
366*5697Smcpowers break;
367*5697Smcpowers
368*5697Smcpowers case ECCurve_SECG_CHAR2_233R1:
369*5697Smcpowers /* Populate params for sect233r1
370*5697Smcpowers * (the NIST B-233 curve)
371*5697Smcpowers */
372*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
373*5697Smcpowers params, kmflag) );
374*5697Smcpowers break;
375*5697Smcpowers
376*5697Smcpowers case ECCurve_SECG_CHAR2_239K1:
377*5697Smcpowers /* Populate params for sect239k1 */
378*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
379*5697Smcpowers params, kmflag) );
380*5697Smcpowers break;
381*5697Smcpowers
382*5697Smcpowers case ECCurve_SECG_CHAR2_283K1:
383*5697Smcpowers /* Populate params for sect283k1
384*5697Smcpowers * (the NIST K-283 curve)
385*5697Smcpowers */
386*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
387*5697Smcpowers params, kmflag) );
388*5697Smcpowers break;
389*5697Smcpowers
390*5697Smcpowers case ECCurve_SECG_CHAR2_283R1:
391*5697Smcpowers /* Populate params for sect283r1
392*5697Smcpowers * (the NIST B-283 curve)
393*5697Smcpowers */
394*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
395*5697Smcpowers params, kmflag) );
396*5697Smcpowers break;
397*5697Smcpowers
398*5697Smcpowers case ECCurve_SECG_CHAR2_409K1:
399*5697Smcpowers /* Populate params for sect409k1
400*5697Smcpowers * (the NIST K-409 curve)
401*5697Smcpowers */
402*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
403*5697Smcpowers params, kmflag) );
404*5697Smcpowers break;
405*5697Smcpowers
406*5697Smcpowers case ECCurve_SECG_CHAR2_409R1:
407*5697Smcpowers /* Populate params for sect409r1
408*5697Smcpowers * (the NIST B-409 curve)
409*5697Smcpowers */
410*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
411*5697Smcpowers params, kmflag) );
412*5697Smcpowers break;
413*5697Smcpowers
414*5697Smcpowers case ECCurve_SECG_CHAR2_571K1:
415*5697Smcpowers /* Populate params for sect571k1
416*5697Smcpowers * (the NIST K-571 curve)
417*5697Smcpowers */
418*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
419*5697Smcpowers params, kmflag) );
420*5697Smcpowers break;
421*5697Smcpowers
422*5697Smcpowers case ECCurve_SECG_CHAR2_571R1:
423*5697Smcpowers /* Populate params for sect571r1
424*5697Smcpowers * (the NIST B-571 curve)
425*5697Smcpowers */
426*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
427*5697Smcpowers params, kmflag) );
428*5697Smcpowers break;
429*5697Smcpowers
430*5697Smcpowers /* Prime curves */
431*5697Smcpowers
432*5697Smcpowers case ECCurve_X9_62_PRIME_192V1:
433*5697Smcpowers /* Populate params for prime192v1 aka secp192r1
434*5697Smcpowers * (the NIST P-192 curve)
435*5697Smcpowers */
436*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
437*5697Smcpowers params, kmflag) );
438*5697Smcpowers break;
439*5697Smcpowers
440*5697Smcpowers case ECCurve_X9_62_PRIME_192V2:
441*5697Smcpowers /* Populate params for prime192v2 */
442*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
443*5697Smcpowers params, kmflag) );
444*5697Smcpowers break;
445*5697Smcpowers
446*5697Smcpowers case ECCurve_X9_62_PRIME_192V3:
447*5697Smcpowers /* Populate params for prime192v3 */
448*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
449*5697Smcpowers params, kmflag) );
450*5697Smcpowers break;
451*5697Smcpowers
452*5697Smcpowers case ECCurve_X9_62_PRIME_239V1:
453*5697Smcpowers /* Populate params for prime239v1 */
454*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
455*5697Smcpowers params, kmflag) );
456*5697Smcpowers break;
457*5697Smcpowers
458*5697Smcpowers case ECCurve_X9_62_PRIME_239V2:
459*5697Smcpowers /* Populate params for prime239v2 */
460*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
461*5697Smcpowers params, kmflag) );
462*5697Smcpowers break;
463*5697Smcpowers
464*5697Smcpowers case ECCurve_X9_62_PRIME_239V3:
465*5697Smcpowers /* Populate params for prime239v3 */
466*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
467*5697Smcpowers params, kmflag) );
468*5697Smcpowers break;
469*5697Smcpowers
470*5697Smcpowers case ECCurve_X9_62_PRIME_256V1:
471*5697Smcpowers /* Populate params for prime256v1 aka secp256r1
472*5697Smcpowers * (the NIST P-256 curve)
473*5697Smcpowers */
474*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
475*5697Smcpowers params, kmflag) );
476*5697Smcpowers break;
477*5697Smcpowers
478*5697Smcpowers case ECCurve_SECG_PRIME_112R1:
479*5697Smcpowers /* Populate params for secp112r1 */
480*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
481*5697Smcpowers params, kmflag) );
482*5697Smcpowers break;
483*5697Smcpowers
484*5697Smcpowers case ECCurve_SECG_PRIME_112R2:
485*5697Smcpowers /* Populate params for secp112r2 */
486*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
487*5697Smcpowers params, kmflag) );
488*5697Smcpowers break;
489*5697Smcpowers
490*5697Smcpowers case ECCurve_SECG_PRIME_128R1:
491*5697Smcpowers /* Populate params for secp128r1 */
492*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
493*5697Smcpowers params, kmflag) );
494*5697Smcpowers break;
495*5697Smcpowers
496*5697Smcpowers case ECCurve_SECG_PRIME_128R2:
497*5697Smcpowers /* Populate params for secp128r2 */
498*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
499*5697Smcpowers params, kmflag) );
500*5697Smcpowers break;
501*5697Smcpowers
502*5697Smcpowers case ECCurve_SECG_PRIME_160K1:
503*5697Smcpowers /* Populate params for secp160k1 */
504*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
505*5697Smcpowers params, kmflag) );
506*5697Smcpowers break;
507*5697Smcpowers
508*5697Smcpowers case ECCurve_SECG_PRIME_160R1:
509*5697Smcpowers /* Populate params for secp160r1 */
510*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
511*5697Smcpowers params, kmflag) );
512*5697Smcpowers break;
513*5697Smcpowers
514*5697Smcpowers case ECCurve_SECG_PRIME_160R2:
515*5697Smcpowers /* Populate params for secp160r1 */
516*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
517*5697Smcpowers params, kmflag) );
518*5697Smcpowers break;
519*5697Smcpowers
520*5697Smcpowers case ECCurve_SECG_PRIME_192K1:
521*5697Smcpowers /* Populate params for secp192k1 */
522*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
523*5697Smcpowers params, kmflag) );
524*5697Smcpowers break;
525*5697Smcpowers
526*5697Smcpowers case ECCurve_SECG_PRIME_224K1:
527*5697Smcpowers /* Populate params for secp224k1 */
528*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
529*5697Smcpowers params, kmflag) );
530*5697Smcpowers break;
531*5697Smcpowers
532*5697Smcpowers case ECCurve_SECG_PRIME_224R1:
533*5697Smcpowers /* Populate params for secp224r1
534*5697Smcpowers * (the NIST P-224 curve)
535*5697Smcpowers */
536*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
537*5697Smcpowers params, kmflag) );
538*5697Smcpowers break;
539*5697Smcpowers
540*5697Smcpowers case ECCurve_SECG_PRIME_256K1:
541*5697Smcpowers /* Populate params for secp256k1 */
542*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
543*5697Smcpowers params, kmflag) );
544*5697Smcpowers break;
545*5697Smcpowers
546*5697Smcpowers case ECCurve_SECG_PRIME_384R1:
547*5697Smcpowers /* Populate params for secp384r1
548*5697Smcpowers * (the NIST P-384 curve)
549*5697Smcpowers */
550*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
551*5697Smcpowers params, kmflag) );
552*5697Smcpowers break;
553*5697Smcpowers
554*5697Smcpowers case ECCurve_SECG_PRIME_521R1:
555*5697Smcpowers /* Populate params for secp521r1
556*5697Smcpowers * (the NIST P-521 curve)
557*5697Smcpowers */
558*5697Smcpowers CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
559*5697Smcpowers params, kmflag) );
560*5697Smcpowers break;
561*5697Smcpowers
562*5697Smcpowers default:
563*5697Smcpowers break;
564*5697Smcpowers };
565*5697Smcpowers
566*5697Smcpowers cleanup:
567*5697Smcpowers if (!params->cofactor) {
568*5697Smcpowers PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
569*5697Smcpowers #if EC_DEBUG
570*5697Smcpowers printf("Unrecognized curve, returning NULL params\n");
571*5697Smcpowers #endif
572*5697Smcpowers }
573*5697Smcpowers
574*5697Smcpowers return rv;
575*5697Smcpowers }
576*5697Smcpowers
577*5697Smcpowers SECStatus
EC_DecodeParams(const SECItem * encodedParams,ECParams ** ecparams,int kmflag)578*5697Smcpowers EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams, int kmflag)
579*5697Smcpowers {
580*5697Smcpowers PRArenaPool *arena;
581*5697Smcpowers ECParams *params;
582*5697Smcpowers SECStatus rv = SECFailure;
583*5697Smcpowers
584*5697Smcpowers /* Initialize an arena for the ECParams structure */
585*5697Smcpowers if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
586*5697Smcpowers return SECFailure;
587*5697Smcpowers
588*5697Smcpowers params = (ECParams *)PORT_ArenaZAlloc(NULL, sizeof(ECParams), kmflag);
589*5697Smcpowers if (!params) {
590*5697Smcpowers PORT_FreeArena(NULL, B_TRUE);
591*5697Smcpowers return SECFailure;
592*5697Smcpowers }
593*5697Smcpowers
594*5697Smcpowers /* Copy the encoded params */
595*5697Smcpowers SECITEM_AllocItem(arena, &(params->DEREncoding), encodedParams->len,
596*5697Smcpowers kmflag);
597*5697Smcpowers memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
598*5697Smcpowers
599*5697Smcpowers /* Fill out the rest of the ECParams structure based on
600*5697Smcpowers * the encoded params
601*5697Smcpowers */
602*5697Smcpowers rv = EC_FillParams(NULL, encodedParams, params, kmflag);
603*5697Smcpowers if (rv == SECFailure) {
604*5697Smcpowers PORT_FreeArena(NULL, B_TRUE);
605*5697Smcpowers return SECFailure;
606*5697Smcpowers } else {
607*5697Smcpowers *ecparams = params;;
608*5697Smcpowers return SECSuccess;
609*5697Smcpowers }
610*5697Smcpowers }
611