Some elliptic curves in openssl give "no general encryption" errors

Some curves do not work when generating keys when using the openssl s_server / s_client combination. I checked this using the following methodology:

  • create a pair of balls with an elliptic curve with openssl ecparam -out ec_$curve.key -name $curve -genkey , foreach $curve in openssl ecparam -list_curves

  • create self-signed certificates for each ec_$curve.key using openssl req -x509 -new -days 365 -key ec_$curve.key -out ec_$curve.crt -subj $SOME_SUBJ

  • for each ec_$curve.key , do: in one window openssl s_server -cert ec_$curve.crt -key ec_$curve.key -accept 10000 , another openssl s_client -host localhost -port 10000

I get a handshake:

Using default temp DH parameters Using default temp ECDH parameters ACCEPT ERROR 8606155664:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1355: shutting down SSL CONNECTION CLOSED

for only keys created with the following curves: c2.* curves (for example, c2pnb163v1 ), prime192v[23] , prime239.* and sec.1[123].* curves sec.1[123].* . All other curves work fine.

That makes no sense to me. s_client should be able to talk to s_server, so either this is an OpenSSL error, or I configured the client or server, or by mistake. I tried adding the server-server parameters -named_curve, but this does not improve the situation. OpenSSL version 1.0.1e.

So, someone with a more crypto / EC key, what the hell is going on here?

+4
source share
2 answers

According to Section 5.1.1 of RFC 4492, curves with arbitrary parameters are also supported (see arbitrary_explicit_prime_curves below). This means that if you find the definitions and all EC parameters for each curve that you want to test, you can generate keys through openssl calls, such as EC_GROUP_new_curve, EC_KEY_set_group, EC_KEY_get0_private_key, and then use them in TLS handshakes.

So, the conclusion is that all the keys that you generate can be supported if instead of using the named curves you are sending with custom ones.

  enum { sect163k1 (1), sect163r1 (2), sect163r2 (3), sect193r1 (4), sect193r2 (5), sect233k1 (6), sect233r1 (7), sect239k1 (8), sect283k1 (9), sect283r1 (10), sect409k1 (11), sect409r1 (12), sect571k1 (13), sect571r1 (14), secp160k1 (15), secp160r1 (16), secp160r2 (17), secp192k1 (18), secp192r1 (19), secp224k1 (20), secp224r1 (21), secp256k1 (22), secp256r1 (23), secp384r1 (24), secp521r1 (25), reserved (0xFE00..0xFEFF), arbitrary_explicit_prime_curves(0xFF01), arbitrary_explicit_char2_curves(0xFF02), (0xFFFF) } NamedCurve; 

'Openssl ecparam' also has the -C option, which allows you to generate C code for a named curve, for example

 openssl ecparam -name prime256v1 -C 

will create code to create an EC_GROUP object, which can be used to generate a custom curve key with parameters corresponding to the parameters of the named curve:

 static unsigned char ec_p_256[] = { 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF }; static unsigned char ec_a_256[] = { 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC }; static unsigned char ec_b_256[] = { 0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB,0xBD,0x55, 0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,0xCC,0x53,0xB0,0xF6, 0x3B,0xCE,0x3C,0x3E,0x27,0xD2,0x60,0x4B }; static unsigned char ec_gen_256[] = { 0x04,0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC,0xE6, 0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,0x2D,0xEB,0x33, 0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,0xC2,0x96,0x4F,0xE3,0x42, 0xE2,0xFE,0x1A,0x7F,0x9B,0x8E,0xE7,0xEB,0x4A,0x7C,0x0F,0x9E, 0x16,0x2B,0xCE,0x33,0x57,0x6B,0x31,0x5E,0xCE,0xCB,0xB6,0x40, 0x68,0x37,0xBF,0x51,0xF5 }; static unsigned char ec_order_256[] = { 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,0xA7,0x17,0x9E,0x84, 0xF3,0xB9,0xCA,0xC2,0xFC,0x63,0x25,0x51 }; static unsigned char ec_cofactor_256[] = { 0x01 }; EC_GROUP *get_ec_group_256(void) { int ok=0; EC_GROUP *group = NULL; EC_POINT *point = NULL; BIGNUM *tmp_1 = NULL, *tmp_2 = NULL, *tmp_3 = NULL; if ((tmp_1 = BN_bin2bn(ec_p_256, sizeof(ec_p_256), NULL)) == NULL) goto err; if ((tmp_2 = BN_bin2bn(ec_a_256, sizeof(ec_a_256), NULL)) == NULL) goto err; if ((tmp_3 = BN_bin2bn(ec_b_256, sizeof(ec_b_256), NULL)) == NULL) goto err; if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL) goto err; /* build generator */ if ((tmp_1 = BN_bin2bn(ec_gen_256, sizeof(ec_gen_256), tmp_1)) == NULL) goto err; point = EC_POINT_bn2point(group, tmp_1, NULL, NULL); if (point == NULL) goto err; if ((tmp_2 = BN_bin2bn(ec_order_256, sizeof(ec_order_256), tmp_2)) == NULL) goto err; if ((tmp_3 = BN_bin2bn(ec_cofactor_256, sizeof(ec_cofactor_256), tmp_3)) == NULL) goto err; if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3)) goto err; ok=1; err: if (tmp_1) BN_free(tmp_1); if (tmp_2) BN_free(tmp_2); if (tmp_3) BN_free(tmp_3); if (point) EC_POINT_free(point); if (!ok) { EC_GROUP_free(group); group = NULL; } return(group); } 
+2
source

The TLS standard defines support only for these curves:

  sect163k1 (1), sect163r1 (2), sect163r2 (3), sect193r1 (4), sect193r2 (5), sect233k1 (6), sect233r1 (7), sect239k1 (8), sect283k1 (9), sect283r1 (10), sect409k1 (11), sect409r1 (12), sect571k1 (13), sect571r1 (14), secp160k1 (15), secp160r1 (16), secp160r2 (17), secp192k1 (18), secp192r1 (19), secp224k1 (20), secp224r1 (21), secp256k1 (22), secp256r1 (23), secp384r1 (24), secp521r1 (25) 

Although OpenSSL can generate certificates with other curves, they cannot be used for SSL / TLS. Most likely, this is the reason.

+4
source

All Articles