2
* ***** BEGIN LICENSE BLOCK *****
3
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Mozilla Public License Version
6
* 1.1 (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/MPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is the Elliptic Curve Cryptography library.
17
* The Initial Developer of the Original Code is
18
* Sun Microsystems, Inc.
19
* Portions created by the Initial Developer are Copyright (C) 2003
20
* the Initial Developer. All Rights Reserved.
23
* Dr Vipul Gupta <vipul.gupta@sun.com> and
24
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the MPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the MPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
47
#include "ecl-curve.h"
49
#define CHECK_OK(func) if (func == NULL) goto cleanup
50
#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
53
* Initializes a SECItem from a hexadecimal string
55
* Warning: This function ignores leading 00's, so any leading 00's
56
* in the hexadecimal string must be optional.
59
hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
63
int tmp = PORT_Strlen(str);
65
if ((tmp % 2) != 0) return NULL;
67
/* skip leading 00's unless the hex string is "00" */
68
while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
73
item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2);
74
if (item->data == NULL) return NULL;
78
if ((str[i] >= '0') && (str[i] <= '9'))
80
else if ((str[i] >= 'a') && (str[i] <= 'f'))
81
tmp = str[i] - 'a' + 10;
82
else if ((str[i] >= 'A') && (str[i] <= 'F'))
83
tmp = str[i] - 'A' + 10;
87
byteval = byteval * 16 + tmp;
89
item->data[i/2] = byteval;
98
/* Copy all of the fields from srcParams into dstParams
101
EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
102
const ECParams *srcParams)
104
SECStatus rv = SECFailure;
106
dstParams->arena = arena;
107
dstParams->type = srcParams->type;
108
dstParams->fieldID.size = srcParams->fieldID.size;
109
dstParams->fieldID.type = srcParams->fieldID.type;
110
if (srcParams->fieldID.type == ec_field_GFp) {
111
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime,
112
&srcParams->fieldID.u.prime));
114
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly,
115
&srcParams->fieldID.u.poly));
117
dstParams->fieldID.k1 = srcParams->fieldID.k1;
118
dstParams->fieldID.k2 = srcParams->fieldID.k2;
119
dstParams->fieldID.k3 = srcParams->fieldID.k3;
120
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a,
121
&srcParams->curve.a));
122
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b,
123
&srcParams->curve.b));
124
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed,
125
&srcParams->curve.seed));
126
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base,
128
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order,
130
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding,
131
&srcParams->DEREncoding));
132
dstParams->name = srcParams->name;
133
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID,
134
&srcParams->curveOID));
135
dstParams->cofactor = srcParams->cofactor;
144
EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
148
SECItem oid = { siBuffer, NULL, 0};
149
const ECCurveParams *curveParams;
150
/* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
151
char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
156
printf("Encoded params in EC_DecodeParams: ");
157
for (i = 0; i < encodedParams->len; i++) {
158
printf("%02x:", encodedParams->data[i]);
163
if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
164
(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
165
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
169
oid.len = encodedParams->len - 2;
170
oid.data = encodedParams->data + 2;
171
if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
172
((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
173
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
177
params->arena = arena;
178
params->cofactor = 0;
179
params->type = ec_params_named;
180
params->name = ECCurve_noName;
182
/* For named curves, fill out curveOID */
183
params->curveOID.len = oid.len;
184
params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
185
if (params->curveOID.data == NULL) goto cleanup;
186
memcpy(params->curveOID.data, oid.data, oid.len);
189
printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
194
#define GF2M_POPULATE \
195
if ((params->name < ECCurve_noName) || \
196
(params->name > ECCurve_pastLastCurve)) goto cleanup; \
197
CHECK_OK(curveParams); \
198
params->fieldID.size = curveParams->size; \
199
params->fieldID.type = ec_field_GF2m; \
200
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, \
201
curveParams->irr)); \
202
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, \
203
curveParams->curvea)); \
204
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, \
205
curveParams->curveb)); \
209
CHECK_OK(strcat(genenc, curveParams->genx)); \
210
CHECK_OK(strcat(genenc, curveParams->geny)); \
211
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, \
213
CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, \
214
curveParams->order)); \
215
params->cofactor = curveParams->cofactor;
217
case SEC_OID_ANSIX962_EC_C2PNB163V1:
218
/* Populate params for c2pnb163v1 */
219
params->name = ECCurve_X9_62_CHAR2_PNB163V1;
220
curveParams = ecCurve_map[params->name];
224
case SEC_OID_ANSIX962_EC_C2PNB163V2:
225
/* Populate params for c2pnb163v2 */
226
params->name = ECCurve_X9_62_CHAR2_PNB163V2;
227
curveParams = ecCurve_map[params->name];
231
case SEC_OID_ANSIX962_EC_C2PNB163V3:
232
/* Populate params for c2pnb163v3 */
233
params->name = ECCurve_X9_62_CHAR2_PNB163V3;
234
curveParams = ecCurve_map[params->name];
238
case SEC_OID_ANSIX962_EC_C2PNB176V1:
239
/* Populate params for c2pnb176v1 */
240
params->name = ECCurve_X9_62_CHAR2_PNB176V1;
241
curveParams = ecCurve_map[params->name];
245
case SEC_OID_ANSIX962_EC_C2TNB191V1:
246
/* Populate params for c2tnb191v1 */
247
params->name = ECCurve_X9_62_CHAR2_TNB191V1;
248
curveParams = ecCurve_map[params->name];
252
case SEC_OID_ANSIX962_EC_C2TNB191V2:
253
/* Populate params for c2tnb191v2 */
254
params->name = ECCurve_X9_62_CHAR2_TNB191V2;
255
curveParams = ecCurve_map[params->name];
259
case SEC_OID_ANSIX962_EC_C2TNB191V3:
260
/* Populate params for c2tnb191v3 */
261
params->name = ECCurve_X9_62_CHAR2_TNB191V3;
262
curveParams = ecCurve_map[params->name];
266
case SEC_OID_ANSIX962_EC_C2PNB208W1:
267
/* Populate params for c2pnb208w1 */
268
params->name = ECCurve_X9_62_CHAR2_PNB208W1;
269
curveParams = ecCurve_map[params->name];
273
case SEC_OID_ANSIX962_EC_C2TNB239V1:
274
/* Populate params for c2tnb239v1 */
275
params->name = ECCurve_X9_62_CHAR2_TNB239V1;
276
curveParams = ecCurve_map[params->name];
280
case SEC_OID_ANSIX962_EC_C2TNB239V2:
281
/* Populate params for c2tnb239v2 */
282
params->name = ECCurve_X9_62_CHAR2_TNB239V2;
283
curveParams = ecCurve_map[params->name];
287
case SEC_OID_ANSIX962_EC_C2TNB239V3:
288
/* Populate params for c2tnb239v3 */
289
params->name = ECCurve_X9_62_CHAR2_TNB239V3;
290
curveParams = ecCurve_map[params->name];
294
case SEC_OID_ANSIX962_EC_C2PNB272W1:
295
/* Populate params for c2pnb272w1 */
296
params->name = ECCurve_X9_62_CHAR2_PNB272W1;
297
curveParams = ecCurve_map[params->name];
301
case SEC_OID_ANSIX962_EC_C2PNB304W1:
302
/* Populate params for c2pnb304w1 */
303
params->name = ECCurve_X9_62_CHAR2_PNB304W1;
304
curveParams = ecCurve_map[params->name];
308
case SEC_OID_ANSIX962_EC_C2TNB359V1:
309
/* Populate params for c2tnb359v1 */
310
params->name = ECCurve_X9_62_CHAR2_TNB359V1;
311
curveParams = ecCurve_map[params->name];
315
case SEC_OID_ANSIX962_EC_C2PNB368W1:
316
/* Populate params for c2pnb368w1 */
317
params->name = ECCurve_X9_62_CHAR2_PNB368W1;
318
curveParams = ecCurve_map[params->name];
322
case SEC_OID_ANSIX962_EC_C2TNB431R1:
323
/* Populate params for c2tnb431r1 */
324
params->name = ECCurve_X9_62_CHAR2_TNB431R1;
325
curveParams = ecCurve_map[params->name];
329
case SEC_OID_SECG_EC_SECT113R1:
330
/* Populate params for sect113r1 */
331
params->name = ECCurve_SECG_CHAR2_113R1;
332
curveParams = ecCurve_map[params->name];
336
case SEC_OID_SECG_EC_SECT113R2:
337
/* Populate params for sect113r2 */
338
params->name = ECCurve_SECG_CHAR2_113R2;
339
curveParams = ecCurve_map[params->name];
343
case SEC_OID_SECG_EC_SECT131R1:
344
/* Populate params for sect131r1 */
345
params->name = ECCurve_SECG_CHAR2_131R1;
346
curveParams = ecCurve_map[params->name];
350
case SEC_OID_SECG_EC_SECT131R2:
351
/* Populate params for sect131r2 */
352
params->name = ECCurve_SECG_CHAR2_131R2;
353
curveParams = ecCurve_map[params->name];
357
case SEC_OID_SECG_EC_SECT163K1:
358
/* Populate params for sect163k1
359
* (the NIST K-163 curve)
361
params->name = ECCurve_SECG_CHAR2_163K1;
362
curveParams = ecCurve_map[params->name];
366
case SEC_OID_SECG_EC_SECT163R1:
367
/* Populate params for sect163r1 */
368
params->name = ECCurve_SECG_CHAR2_163R1;
369
curveParams = ecCurve_map[params->name];
373
case SEC_OID_SECG_EC_SECT163R2:
374
/* Populate params for sect163r2
375
* (the NIST B-163 curve)
377
params->name = ECCurve_SECG_CHAR2_163R2;
378
curveParams = ecCurve_map[params->name];
382
case SEC_OID_SECG_EC_SECT193R1:
383
/* Populate params for sect193r1 */
384
params->name = ECCurve_SECG_CHAR2_193R1;
385
curveParams = ecCurve_map[params->name];
389
case SEC_OID_SECG_EC_SECT193R2:
390
/* Populate params for sect193r2 */
391
params->name = ECCurve_SECG_CHAR2_193R2;
392
curveParams = ecCurve_map[params->name];
396
case SEC_OID_SECG_EC_SECT233K1:
397
/* Populate params for sect233k1
398
* (the NIST K-233 curve)
400
params->name = ECCurve_SECG_CHAR2_233K1;
401
curveParams = ecCurve_map[params->name];
405
case SEC_OID_SECG_EC_SECT233R1:
406
/* Populate params for sect233r1
407
* (the NIST B-233 curve)
409
params->name = ECCurve_SECG_CHAR2_233R1;
410
curveParams = ecCurve_map[params->name];
414
case SEC_OID_SECG_EC_SECT239K1:
415
/* Populate params for sect239k1 */
416
params->name = ECCurve_SECG_CHAR2_239K1;
417
curveParams = ecCurve_map[params->name];
421
case SEC_OID_SECG_EC_SECT283K1:
422
/* Populate params for sect283k1
423
* (the NIST K-283 curve)
425
params->name = ECCurve_SECG_CHAR2_283K1;
426
curveParams = ecCurve_map[params->name];
430
case SEC_OID_SECG_EC_SECT283R1:
431
/* Populate params for sect283r1
432
* (the NIST B-283 curve)
434
params->name = ECCurve_SECG_CHAR2_283R1;
435
curveParams = ecCurve_map[params->name];
439
case SEC_OID_SECG_EC_SECT409K1:
440
/* Populate params for sect409k1
441
* (the NIST K-409 curve)
443
params->name = ECCurve_SECG_CHAR2_409K1;
444
curveParams = ecCurve_map[params->name];
448
case SEC_OID_SECG_EC_SECT409R1:
449
/* Populate params for sect409r1
450
* (the NIST B-409 curve)
452
params->name = ECCurve_SECG_CHAR2_409R1;
453
curveParams = ecCurve_map[params->name];
457
case SEC_OID_SECG_EC_SECT571K1:
458
/* Populate params for sect571k1
459
* (the NIST K-571 curve)
461
params->name = ECCurve_SECG_CHAR2_571K1;
462
curveParams = ecCurve_map[params->name];
466
case SEC_OID_SECG_EC_SECT571R1:
467
/* Populate params for sect571r1
468
* (the NIST B-571 curve)
470
params->name = ECCurve_SECG_CHAR2_571R1;
471
curveParams = ecCurve_map[params->name];
475
#define GFP_POPULATE \
476
if ((params->name < ECCurve_noName) || \
477
(params->name > ECCurve_pastLastCurve)) goto cleanup; \
478
CHECK_OK(curveParams); \
479
params->fieldID.size = curveParams->size; \
480
params->fieldID.type = ec_field_GFp; \
481
CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, \
482
curveParams->irr)); \
483
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, \
484
curveParams->curvea)); \
485
CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, \
486
curveParams->curveb)); \
490
CHECK_OK(strcat(genenc, curveParams->genx)); \
491
CHECK_OK(strcat(genenc, curveParams->geny)); \
492
CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, \
494
CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, \
495
curveParams->order)); \
496
params->cofactor = curveParams->cofactor;
498
case SEC_OID_ANSIX962_EC_PRIME192V1:
499
/* Populate params for prime192v1 aka secp192r1
500
* (the NIST P-192 curve)
502
params->name = ECCurve_X9_62_PRIME_192V1;
503
curveParams = ecCurve_map[params->name];
507
case SEC_OID_ANSIX962_EC_PRIME192V2:
508
/* Populate params for prime192v2 */
509
params->name = ECCurve_X9_62_PRIME_192V2;
510
curveParams = ecCurve_map[params->name];
514
case SEC_OID_ANSIX962_EC_PRIME192V3:
515
/* Populate params for prime192v3 */
516
params->name = ECCurve_X9_62_PRIME_192V3;
517
curveParams = ecCurve_map[params->name];
521
case SEC_OID_ANSIX962_EC_PRIME239V1:
522
/* Populate params for prime239v1 */
523
params->name = ECCurve_X9_62_PRIME_239V1;
524
curveParams = ecCurve_map[params->name];
528
case SEC_OID_ANSIX962_EC_PRIME239V2:
529
/* Populate params for prime239v2 */
530
params->name = ECCurve_X9_62_PRIME_239V2;
531
curveParams = ecCurve_map[params->name];
535
case SEC_OID_ANSIX962_EC_PRIME239V3:
536
/* Populate params for prime239v3 */
537
params->name = ECCurve_X9_62_PRIME_239V3;
538
curveParams = ecCurve_map[params->name];
542
case SEC_OID_ANSIX962_EC_PRIME256V1:
543
/* Populate params for prime256v1 aka secp256r1
544
* (the NIST P-256 curve)
546
params->name = ECCurve_X9_62_PRIME_256V1;
547
curveParams = ecCurve_map[params->name];
551
case SEC_OID_SECG_EC_SECP112R1:
552
/* Populate params for secp112r1 */
553
params->name = ECCurve_SECG_PRIME_112R1;
554
curveParams = ecCurve_map[params->name];
558
case SEC_OID_SECG_EC_SECP112R2:
559
/* Populate params for secp112r2 */
560
params->name = ECCurve_SECG_PRIME_112R2;
561
curveParams = ecCurve_map[params->name];
565
case SEC_OID_SECG_EC_SECP128R1:
566
/* Populate params for secp128r1 */
567
params->name = ECCurve_SECG_PRIME_128R1;
568
curveParams = ecCurve_map[params->name];
572
case SEC_OID_SECG_EC_SECP128R2:
573
/* Populate params for secp128r2 */
574
params->name = ECCurve_SECG_PRIME_128R2;
575
curveParams = ecCurve_map[params->name];
579
case SEC_OID_SECG_EC_SECP160K1:
580
/* Populate params for secp160k1 */
581
params->name = ECCurve_SECG_PRIME_160K1;
582
curveParams = ecCurve_map[params->name];
586
case SEC_OID_SECG_EC_SECP160R1:
587
/* Populate params for secp160r1 */
588
params->name = ECCurve_SECG_PRIME_160R1;
589
curveParams = ecCurve_map[params->name];
593
case SEC_OID_SECG_EC_SECP160R2:
594
/* Populate params for secp160r1 */
595
params->name = ECCurve_SECG_PRIME_160R2;
596
curveParams = ecCurve_map[params->name];
600
case SEC_OID_SECG_EC_SECP192K1:
601
/* Populate params for secp192k1 */
602
params->name = ECCurve_SECG_PRIME_192K1;
603
curveParams = ecCurve_map[params->name];
607
case SEC_OID_SECG_EC_SECP224K1:
608
/* Populate params for secp224k1 */
609
params->name = ECCurve_SECG_PRIME_224K1;
610
curveParams = ecCurve_map[params->name];
614
case SEC_OID_SECG_EC_SECP224R1:
615
/* Populate params for secp224r1
616
* (the NIST P-224 curve)
618
params->name = ECCurve_SECG_PRIME_224R1;
619
curveParams = ecCurve_map[params->name];
623
case SEC_OID_SECG_EC_SECP256K1:
624
/* Populate params for secp256k1 */
625
params->name = ECCurve_SECG_PRIME_256K1;
626
curveParams = ecCurve_map[params->name];
630
case SEC_OID_SECG_EC_SECP384R1:
631
/* Populate params for secp384r1
632
* (the NIST P-384 curve)
634
params->name = ECCurve_SECG_PRIME_384R1;
635
curveParams = ecCurve_map[params->name];
639
case SEC_OID_SECG_EC_SECP521R1:
640
/* Populate params for secp521r1
641
* (the NIST P-521 curve)
643
params->name = ECCurve_SECG_PRIME_521R1;
644
curveParams = ecCurve_map[params->name];
653
if (!params->cofactor) {
654
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
656
printf("Unrecognized curve, returning NULL params\n");
665
EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
669
SECStatus rv = SECFailure;
671
/* Initialize an arena for the ECParams structure */
672
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
675
params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
677
PORT_FreeArena(arena, PR_TRUE);
681
/* Copy the encoded params */
682
SECITEM_AllocItem(arena, &(params->DEREncoding),
684
memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
686
/* Fill out the rest of the ECParams structure based on
689
rv = EC_FillParams(arena, encodedParams, params);
690
if (rv == SECFailure) {
691
PORT_FreeArena(arena, PR_TRUE);
699
#endif /* NSS_ENABLE_ECC */