* -out arg - output file - default stdout
* -noout
* -text
+ * -check - validate the ec parameters
* -C
* -noout
* -genkey - generate a private public keypair based on the supplied curve
* -named_curve - use the curve oid instead of the parameters
- * -NIST_192 - use the NIST recommeded curve parameters over a 192 bit prime field
- * -NIST_224 - use the NIST recommeded curve parameters over a 224 bit prime field
- * -NIST_256 - use the NIST recommeded curve parameters over a 256 bit prime field
- * -NIST_384 - use the NIST recommeded curve parameters over a 384 bit prime field
- * -NIST_521 - use the NIST recommeded curve parameters over a 521 bit prime field
+ * -NIST_192 - use the NIST recommended curve parameters over a 192 bit prime field
+ * -NIST_224 - use the NIST recommended curve parameters over a 224 bit prime field
+ * -NIST_256 - use the NIST recommended curve parameters over a 256 bit prime field
+ * -NIST_384 - use the NIST recommended curve parameters over a 384 bit prime field
+ * -NIST_521 - use the NIST recommended curve parameters over a 521 bit prime field
* -X9_62_192v1 - use the X9_62 192v1 example curve over a 192 bit prime field
* -X9_62_192v2 - use the X9_62 192v2 example curve over a 192 bit prime field
* -X9_62_192v3 - use the X9_62 192v3 example curve over a 192 bit prime field
* -X9_62_239v2 - use the X9_62 239v2 example curve over a 239 bit prime field
* -X9_62_239v3 - use the X9_62 239v3 example curve over a 239 bit prime field
* -X9_62_256v1 - use the X9_62 239v1 example curve over a 256 bit prime field
+ * -SECG_PRIME_112R1 - use the SECG 112r1 recommended curve over a 112 bit prime field
+ * -SECG_PRIME_112R2 - use the SECG 112r2 recommended curve over a 112 bit prime field
+ * -SECG_PRIME_128R1 - use the SECG 128r1 recommended curve over a 128 bit prime field
+ * -SECG_PRIME_128R2 - use the SECG 128r2 recommended curve over a 128 bit prime field
+ * -SECG_PRIME_160K1 - use the SECG 160k1 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_160R1 - use the SECG 160r1 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_160R2 - use the SECG 160r2 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_192K1 - use the SECG 192k1 recommended curve over a 192 bit prime field
+ * -SECG_PRIME_192R1 - use the SECG 192r1 recommended curve over a 192 bit prime field
+ * -SECG_PRIME_224K1 - use the SECG 224k1 recommended curve over a 224 bit prime field
+ * -SECG_PRIME_224R1 - use the SECG 224r1 recommended curve over a 224 bit prime field
+ * -SECG_PRIME_256K1 - use the SECG 256k1 recommended curve over a 256 bit prime field
+ * -SECG_PRIME_256R1 - use the SECG 256r1 recommended curve over a 256 bit prime field
+ * -SECG_PRIME_384R1 - use the SECG 384r1 recommended curve over a 384 bit prime field
+ * -SECG_PRIME_521R1 - use the SECG 521r1 recommended curve over a 521 bit prime field
+ * -WTLS_6 - use the WAP/WTLS recommended curve number 6 over a 112 bit field
+ * -WTLS_8 - use the WAP/WTLS recommended curve number 8 over a 112 bit field
+ * -WTLS_9 - use the WAP/WTLS recommended curve number 9 over a 160 bit field
*/
int MAIN(int, char **);
int informat, outformat, noout = 0, C = 0, ret = 1;
char *infile, *outfile, *prog, *inrand = NULL;
int genkey = 0;
+ int check = 0;
int need_rand = 0;
char *engine=NULL;
int curve_type = EC_GROUP_NO_CURVE;
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+ if (!load_config(bio_err, NULL))
+ goto end;
+
infile=NULL;
outfile=NULL;
informat=FORMAT_PEM;
text = 1;
else if (strcmp(*argv,"-C") == 0)
C = 1;
+ else if (strcmp(*argv,"-check") == 0)
+ check = 1;
else if (strcmp(*argv,"-genkey") == 0)
{
genkey = 1;
curve_type = EC_GROUP_X9_62_PRIME_239V3;
else if (strcmp(*argv, "-X9_62_256v1") == 0)
curve_type = EC_GROUP_X9_62_PRIME_256V1;
+ else if (strcmp(*argv, "-SECG_PRIME_112R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_112R1;
+ else if (strcmp(*argv, "-SECG_PRIME_112R2") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_112R2;
+ else if (strcmp(*argv, "-SECG_PRIME_128R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_128R1;
+ else if (strcmp(*argv, "-SECG_PRIME_128R2") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_128R2;
+ else if (strcmp(*argv, "-SECG_PRIME_160K1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_160K1;
+ else if (strcmp(*argv, "-SECG_PRIME_160R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_160R1;
+ else if (strcmp(*argv, "-SECG_PRIME_160R2") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_160R2;
+ else if (strcmp(*argv, "-SECG_PRIME_192K1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_192K1;
+ else if (strcmp(*argv, "-SECG_PRIME_192R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_192R1;
+ else if (strcmp(*argv, "-SECG_PRIME_224K1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_224K1;
+ else if (strcmp(*argv, "-SECG_PRIME_224R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_224R1;
+ else if (strcmp(*argv, "-SECG_PRIME_256K1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_256K1;
+ else if (strcmp(*argv, "-SECG_PRIME_256R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_256R1;
+ else if (strcmp(*argv, "-SECG_PRIME_384R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_384R1;
+ else if (strcmp(*argv, "-SECG_PRIME_521R1") == 0)
+ curve_type = EC_GROUP_SECG_PRIME_521R1;
+ else if (strcmp(*argv, "-WTLS_6") == 0)
+ curve_type = EC_GROUP_WTLS_6;
+ else if (strcmp(*argv, "-WTLS_8") == 0)
+ curve_type = EC_GROUP_WTLS_8;
+ else if (strcmp(*argv, "-WTLS_9") == 0)
+ curve_type = EC_GROUP_WTLS_9;
else if (strcmp(*argv, "-noout") == 0)
noout=1;
else
bad:
BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
BIO_printf(bio_err,"where options are\n");
- BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
- BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
- BIO_printf(bio_err," -in arg input file\n");
- BIO_printf(bio_err," -out arg output file\n");
- BIO_printf(bio_err," -text print the key in text\n");
- BIO_printf(bio_err," -C Output C code\n");
- BIO_printf(bio_err," -noout no output\n");
- BIO_printf(bio_err," -rand files to use for random number input\n");
- BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
- BIO_printf(bio_err," -named_curve use the curve oid instead of the parameters\n");
- BIO_printf(bio_err," -NIST_192 use the NIST recommeded curve parameters over a 192 bit prime field\n");
- BIO_printf(bio_err," -NIST_224 use the NIST recommeded curve parameters over a 224 bit prime field\n");
- BIO_printf(bio_err," -NIST_256 use the NIST recommeded curve parameters over a 256 bit prime field\n");
- BIO_printf(bio_err," -NIST_384 use the NIST recommeded curve parameters over a 384 bit prime field\n");
- BIO_printf(bio_err," -NIST_521 use the NIST recommeded curve parameters over a 521 bit prime field\n");
- BIO_printf(bio_err," -X9_62_192v1 use the X9_62 192v1 example curve over a 192 bit prime field\n");
- BIO_printf(bio_err," -X9_62_192v2 use the X9_62 192v2 example curve over a 192 bit prime field\n");
- BIO_printf(bio_err," -X9_62_192v3 use the X9_62 192v3 example curve over a 192 bit prime field\n");
- BIO_printf(bio_err," -X9_62_239v1 use the X9_62 239v1 example curve over a 239 bit prime field\n");
- BIO_printf(bio_err," -X9_62_239v2 use the X9_62 239v2 example curve over a 239 bit prime field\n");
- BIO_printf(bio_err," -X9_62_239v3 use the X9_62 239v3 example curve over a 239 bit prime field\n");
- BIO_printf(bio_err," -X9_62_256v1 use the X9_62 239v1 example curve over a 256 bit prime field\n");
+ BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
+ BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
+ BIO_printf(bio_err," -in arg input file\n");
+ BIO_printf(bio_err," -out arg output file\n");
+ BIO_printf(bio_err," -text print as text\n");
+ BIO_printf(bio_err," -C Output C code\n");
+ BIO_printf(bio_err," -check validate the ec parameters\n");
+ BIO_printf(bio_err," -noout no output\n");
+ BIO_printf(bio_err," -rand files to use for random number input\n");
+ BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
+ BIO_printf(bio_err," -named_curve use the curve oid instead of the parameters\n");
+ BIO_printf(bio_err," -NIST_192 use the NIST recommended curve parameters over a 192 bit prime field\n");
+ BIO_printf(bio_err," -NIST_224 use the NIST recommended curve parameters over a 224 bit prime field\n");
+ BIO_printf(bio_err," -NIST_256 use the NIST recommended curve parameters over a 256 bit prime field\n");
+ BIO_printf(bio_err," -NIST_384 use the NIST recommended curve parameters over a 384 bit prime field\n");
+ BIO_printf(bio_err," -NIST_521 use the NIST recommended curve parameters over a 521 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_192v1 use the X9_62 192v1 example curve over a 192 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_192v2 use the X9_62 192v2 example curve over a 192 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_192v3 use the X9_62 192v3 example curve over a 192 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_239v1 use the X9_62 239v1 example curve over a 239 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_239v2 use the X9_62 239v2 example curve over a 239 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_239v3 use the X9_62 239v3 example curve over a 239 bit prime field\n");
+ BIO_printf(bio_err," -X9_62_256v1 use the X9_62 239v1 example curve over a 256 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_112R1 use the SECG 112r1 recommended curve over a 112 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_112R2 use the SECG 112r2 recommended curve over a 112 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_128R1 use the SECG 128r1 recommended curve over a 128 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_128R2 use the SECG 128r2 recommended curve over a 128 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_160K1 use the SECG 160k1 recommended curve over a 160 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_160R1 use the SECG 160r1 recommended curve over a 160 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_160R2 use the SECG 160r2 recommended curve over a 160 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_192K1 use the SECG 192k1 recommended curve over a 192 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_192R1 use the SECG 192r1 recommended curve over a 192 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_224K1 use the SECG 224k1 recommended curve over a 224 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_224R1 use the SECG 224r1 recommended curve over a 224 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_256K1 use the SECG 256k1 recommended curve over a 256 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_256R1 use the SECG 256r1 recommended curve over a 256 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_384R1 use the SECG 384r1 recommended curve over a 384 bit prime field\n");
+ BIO_printf(bio_err," -SECG_PRIME_521R1 use the SECG 521r1 recommended curve over a 521 bit prime field\n");
+ BIO_printf(bio_err," -WTLS_6 use the WAP/WTLS recommended curve number 6 over a 112 bit field\n");
+ BIO_printf(bio_err," -WTLS_8 use the WAP/WTLS recommended curve number 8 over a 112 bit field\n");
+ BIO_printf(bio_err," -WTLS_9 use the WAP/WTLS recommended curve number 9 over a 112 bit field\n");
goto end;
}
goto end;
ecdsa->group = EC_GROUP_new_by_name(curve_type);
if (named_curve)
- ECDSA_set_parameter_flags(ecdsa, ECDSA_FLAG_NAMED_CURVE);
+ EC_GROUP_set_asn1_flag(ecdsa->group,
+ OPENSSL_EC_NAMED_CURVE);
}
else if (informat == FORMAT_ASN1)
ecdsa = d2i_ECDSAParameters_bio(in,NULL);
{
ECDSAParameters_print(out, ecdsa);
}
+
+ if (check)
+ {
+ if (ecdsa == NULL)
+ BIO_printf(bio_err, "no elliptic curve parameters\n");
+ BIO_printf(bio_err, "checking elliptic curve parameters: ");
+ if (!EC_GROUP_check(ecdsa->group, NULL))
+ {
+ BIO_printf(bio_err, "failed\n");
+ ERR_print_errors(bio_err);
+ }
+ else
+ BIO_printf(bio_err, "ok\n");
+
+ }
if (C)
- { // TODO : characteristic two
- int l, len, bits_p, bits_a, bits_b, bits_x, bits_y, bits_o, bits_c;
+ { /* TODO: characteristic two */
+ int l, len, bits_p;
if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL ||
(tmp_3 = BN_new()) == NULL || (tmp_4 = BN_new()) == NULL ||
(tmp_5 = BN_new()) == NULL || (tmp_6 = BN_new()) == NULL ||
len = BN_num_bytes(tmp_1);
bits_p = BN_num_bits(tmp_1);
- bits_a = BN_num_bits(tmp_2);
- bits_b = BN_num_bits(tmp_3);
- bits_x = BN_num_bits(tmp_4);
- bits_y = BN_num_bits(tmp_5);
- bits_o = BN_num_bits(tmp_6);
- bits_c = BN_num_bits(tmp_7);
data=(unsigned char *)OPENSSL_malloc(len+20);
if (data == NULL)
{
if ((i%12) == 0) printf("\n\t");
printf("0x%02X,",data[i]);
}
- printf("\n\t};\n");
+ printf("\n\t};\n\n");
l = BN_bn2bin(tmp_2, data);
printf("static unsigned char ecdsa%d_a[]={",bits_p);
}
printf("\n\t};\n\n");
- l = BN_bn2bin(tmp_3, data);
- printf("static unsigned char ecdsa%d_x[]={", bits_x);
+ l = BN_bn2bin(tmp_4, data);
+ printf("static unsigned char ecdsa%d_x[]={", bits_p);
for (i=0; i<l; i++)
{
if ((i%12) == 0) printf("\n\t");
printf("0x%02X,",data[i]);
}
- printf("\n\t};\n\n");
+ printf("\n\t};\n");
- l = BN_bn2bin(tmp_3, data);
- printf("static unsigned char ecdsa%d_y[]={", bits_y);
+ l = BN_bn2bin(tmp_5, data);
+ printf("static unsigned char ecdsa%d_y[]={", bits_p);
for (i=0; i<l; i++)
{
if ((i%12) == 0) printf("\n\t");
printf("0x%02X,",data[i]);
}
- printf("\n\t};\n\n");
+ printf("\n\t};\n");
- l = BN_bn2bin(tmp_3, data);
- printf("static unsigned char ecdsa%d_o[]={", bits_o);
+ l = BN_bn2bin(tmp_6, data);
+ printf("static unsigned char ecdsa%d_o[]={", bits_p);
for (i=0; i<l; i++)
{
if ((i%12) == 0) printf("\n\t");
printf("0x%02X,",data[i]);
}
- printf("\n\t};\n\n");
+ printf("\n\t};\n");
- l = BN_bn2bin(tmp_3, data);
- printf("static unsigned char ecdsa%d_c[]={", bits_c);
+ l = BN_bn2bin(tmp_7, data);
+ printf("static unsigned char ecdsa%d_c[]={", bits_p);
for (i=0; i<l; i++)
{
if ((i%12) == 0) printf("\n\t");
}
printf("\n\t};\n\n");
- printf("ECDSA *get_ecdsa%d()\n\t{\n",bits_p);
- printf("\tint ok=1;\n");
+ /* FIXME:
+ * generated code should check for errors
+ */
+
+ printf("ECDSA *get_ecdsa%d(void)\n\t{\n",bits_p);
+ printf("\tint ok=0;\n");
printf("\tECDSA *ecdsa=NULL;\n");
printf("\tEC_POINT *point=NULL;\n");
- printf("\tBIGNUM *tmp_1=NULL,*tmp_2=NULL,*tmp_3=NULL;\n");
- printf("\tBN_CTX *ctx=NULL;\n\n");
- printf("\tecdsa=ECDSA_new();\n");
- printf("\ttmp_1=BN_new();\n");
- printf("\ttmp_2=BN_new();\n");
- printf("\ttmp_3=BN_new();\n");
- printf("\tctx=BN_CTX_new();\n");
- printf("\tif (!ecdsa || !tmp_1 || !tmp_2 || !tmp_3 || !ctx) ok=0;\n");
- printf("\tif (ok && !ecdsa->group=EC_GROUP_new(EC_GFp_mont_method())) == NULL) ok=0;");
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_p,sizeof(ecdsa%d_p),tmp_1)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_a,sizeof(ecdsa%d_a),tmp_2)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_b,sizeof(ecdsa%d_b),tmp_3)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !EC_GROUP_set_curve_GFp(ecdsa->group,tmp_1,tmp_2,tmp_3,ctx)) ok=0;\n");
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_x,sizeof(ecdsa%d_p),tmp_1)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_y,sizeof(ecdsa%d_a),tmp_2)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && (point = EC_POINT_new(ecdsa->group)) == NULL) ok=0;\n");
- printf("\tif (ok && !EC_POINT_set_affine_coordinates_GFp(ecdsa->group,point,tmp_1,tmp_2,ctx)) ok=0:\n");
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_o,sizeof(ecdsa%d_b),tmp_1)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !BN_bin2bn(ecdsa%d_c,sizeof(ecdsa%d_b),tmp_2)) ok=0;\n", bits_p, bits_p);
- printf("\tif (ok && !EC_GROUP_set_generator(ecdsa->group,point,tmp_1,tmp_2)) ok=0;\n");
- printf("\tif ((ecdsa->group == NULL) || (ecdsa->pub_key == NULL) || (ecdsa->priv_key == NULL))\n");
- printf("\t\t{ ECDSA_free(ecdsa); return(NULL); }\n");
+ printf("\tBIGNUM *tmp_1=NULL,*tmp_2=NULL,*tmp_3=NULL;\n\n");
+ printf("\tif ((ecdsa=ECDSA_new()) == NULL)\n");
+ printf("\t\treturn(NULL);\n\n");
+ printf("\t/* generate EC_GROUP structure */\n");
+ printf("\tif ((tmp_1 = BN_bin2bn(ecdsa%d_p, sizeof(ecdsa%d_p), NULL)) == NULL) goto err;\n", bits_p, bits_p);
+ printf("\tif ((tmp_2 = BN_bin2bn(ecdsa%d_a, sizeof(ecdsa%d_a), NULL)) == NULL) goto err;\n", bits_p, bits_p);
+ printf("\tif ((tmp_3 = BN_bin2bn(ecdsa%d_b, sizeof(ecdsa%d_b), NULL)) == NULL) goto err;\n", bits_p, bits_p);
+ printf("\tif ((ecdsa->group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL) goto err;\n\n");
+ printf("\t/* build generator */\n");
+ printf("\tif (!BN_bin2bn(ecdsa%d_x, sizeof(ecdsa%d_x), tmp_1)) goto err;\n", bits_p, bits_p);
+ printf("\tif (!BN_bin2bn(ecdsa%d_y, sizeof(ecdsa%d_y), tmp_2)) goto err;\n", bits_p, bits_p);
+ printf("\tif ((point = EC_POINT_new(ecdsa->group)) == NULL) goto err;\n");
+ printf("\tif (!EC_POINT_set_affine_coordinates_GFp(ecdsa->group, point, tmp_1, tmp_2, NULL)) goto err;\n");
+ printf("\t/* set generator, order and cofactor */\n");
+ printf("\tif (!BN_bin2bn(ecdsa%d_o, sizeof(ecdsa%d_o), tmp_1)) goto err;\n", bits_p, bits_p);
+ printf("\tif (!BN_bin2bn(ecdsa%d_c, sizeof(ecdsa%d_c), tmp_2)) goto err;\n", bits_p, bits_p);
+ printf("\tif (!EC_GROUP_set_generator(ecdsa->group, point, tmp_1, tmp_2)) goto err;\n");
+ printf("\n\tok=1;\n");
+ printf("err:\n");
+ printf("\tif (tmp_1) BN_free(tmp_1);\n");
+ printf("\tif (tmp_2) BN_free(tmp_2);\n");
+ printf("\tif (tmp_3) BN_free(tmp_3);\n");
+ printf("\tif (point) EC_POINT_free(point);\n");
+ printf("\tif (!ok)\n");
+ printf("\t\t{\n");
+ printf("\t\tECDSA_free(ecdsa);\n");
+ printf("\t\tecdsa = NULL;\n");
+ printf("\t\t}\n");
printf("\treturn(ecdsa);\n\t}\n");
}