RFC 4492 のセクション 5.1.1 によると、任意のパラメーターを持つ曲線もサポートされています (以下の任意の_明示_プライム_曲線を参照してください)。これは、テストする各曲線の定義とすべての EC パラメーターが見つかった場合、EC_GROUP_new_curve、EC_KEY_set_group、EC_KEY_get0_private_key などの openssl 呼び出しを介してキーを生成し、TLS ハンドシェイクで使用できることを意味します。
したがって、結論は、名前付き曲線を使用する代わりにカスタム曲線を使用する場合、生成しているすべてのキーをサポート できるということです。
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」には、名前付き曲線の C コードを生成できる -C オプションもあります。
openssl ecparam -name prime256v1 -C
名前付き曲線のパラメーターと一致するパラメーターを持つカスタム曲線のキーを生成するために使用できる EC_GROUP オブジェクトを作成するためのコードを生成します。
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);
}