Skip to content

genpkey -genparam fails for some EC curves #12306

@romen

Description

@romen

In latest 1.1.1-stable (but also in the first 1.1.1 release, and persists in current master):

; openssl version
OpenSSL 1.1.1  11 Sep 2018
; # with a common binary curve
; openssl genpkey -genparam -algorithm EC -pkeyopt 'ec_paramgen_curve:sect233r1' -text
-----BEGIN EC PARAMETERS-----
BgUrgQQAGw==
-----END EC PARAMETERS-----
ECDSA-Parameters: (233 bit)
ASN1 OID: sect233r1
NIST CURVE: B-233
; # using some "special" curves instead, next command fails unexpectedly
; openssl genpkey -genparam -algorithm EC -pkeyopt 'ec_paramgen_curve:Oakley-EC2N-3' -pkeyopt 'ec_param_enc:named_curve' -text
-----BEGIN EC PARAMETERS-----
-----END EC PARAMETERS-----
Error writing key
140234914886080:error:100BF079:elliptic curve routines:i2d_ECPKParameters:i2d ecpkparameters failure:../crypto/ec/ec_asn1.c:882:
140234914886080:error:100BF079:elliptic curve routines:i2d_ECPKParameters:i2d ecpkparameters failure:../crypto/ec/ec_asn1.c:882:
140234914886080:error:09072007:PEM routines:PEM_write_bio:BUF lib:../crypto/pem/pem_lib.c:658:
ECDSA-Parameters: (154 bit)
ASN1 OID: Oakley-EC2N-3
; # but the same command works if encoding to explicit parameters
; openssl genpkey -genparam -algorithm EC -pkeyopt 'ec_paramgen_curve:Oakley-EC2N-3' -pkeyopt 'ec_param_enc:explicit' -text
-----BEGIN EC PARAMETERS-----
MIGUAgEBMB0GByqGSM49AQIwEgICAJsGCSqGSM49AQIDAgIBPjAsBBQAAAAAAAAA
AAAAAAAAAAAAAAAAAAQUAAAAAAAAAAAAAAAAAAAAAAAHM48EKQQAAAAAAAAAAAAA
AAAAAAAAAAAAewAAAAAAAAAAAAAAAAAAAAAAAAHIAhQCqqqqqqqqqqqqx/PHiBvQ
ho+obAIBAw==
-----END EC PARAMETERS-----
ECDSA-Parameters: (154 bit)
Field Type: characteristic-two-field
Basis Type: tpBasis
Polynomial:
    08:00:00:00:00:00:00:00:00:00:00:00:40:00:00:
    00:00:00:00:01
A:    0
B:    471951 (0x7338f)
Generator (uncompressed):
    04:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:7b:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:01:c8
Order:
    02:aa:aa:aa:aa:aa:aa:aa:aa:aa:c7:f3:c7:88:1b:
    d0:86:8f:a8:6c
Cofactor:  3 (0x3)
; # yet generating a key without explicit parameters does not yield a failure!!
; openssl genpkey -algorithm EC -pkeyopt 'ec_paramgen_curve:Oakley-EC2N-3' -text
-----BEGIN PRIVATE KEY-----
MFkCAQAwCQYHKoZIzj0CAQRJMEcCAQEEFAHhSAciTgkK8EsygXni/NBIhdG+oSwD
KgAEBTq+bixE479sUE4xJJJm+x6y78MBFPDo9h+E1znuqY5z+Yxo/D9zaw==
-----END PRIVATE KEY-----
Private-Key: (154 bit)
priv:
    01:e1:48:07:22:4e:09:0a:f0:4b:32:81:79:e2:fc:
    d0:48:85:d1:be
pub:
    04:05:3a:be:6e:2c:44:e3:bf:6c:50:4e:31:24:92:
    66:fb:1e:b2:ef:c3:01:14:f0:e8:f6:1f:84:d7:39:
    ee:a9:8e:73:f9:8c:68:fc:3f:73:6b
ASN1 OID: Oakley-EC2N-3
; # nor does generating a key encoding with explicit parameters
; openssl genpkey -algorithm EC -pkeyopt 'ec_paramgen_curve:Oakley-EC2N-3' -pkeyopt 'ec_param_enc:explicit' -text
-----BEGIN PRIVATE KEY-----
MIHxAgEAMIGgBgcqhkjOPQIBMIGUAgEBMB0GByqGSM49AQIwEgICAJsGCSqGSM49
AQIDAgIBPjAsBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAQUAAAAAAAAAAAAAAAAAAAA
AAAHM48EKQQAAAAAAAAAAAAAAAAAAAAAAAAAewAAAAAAAAAAAAAAAAAAAAAAAAHI
AhQCqqqqqqqqqqqqx/PHiBvQho+obAIBAwRJMEcCAQEEFABPnwFTo0d1svnE81dE
Pc/HMgl1oSwDKgAEAN+YcZmOVXfgdgEiT2E9tEmIM4oARhuzPbbxDbc0e+1kuxBT
oY4/IA==
-----END PRIVATE KEY-----
Private-Key: (154 bit)
priv:
    00:4f:9f:01:53:a3:47:75:b2:f9:c4:f3:57:44:3d:
    cf:c7:32:09:75
pub:
    04:00:df:98:71:99:8e:55:77:e0:76:01:22:4f:61:
    3d:b4:49:88:33:8a:00:46:1b:b3:3d:b6:f1:0d:b7:
    34:7b:ed:64:bb:10:53:a1:8e:3f:20
Field Type: characteristic-two-field
Basis Type: tpBasis
Polynomial:
    08:00:00:00:00:00:00:00:00:00:00:00:40:00:00:
    00:00:00:00:01
A:    0
B:    471951 (0x7338f)
Generator (uncompressed):
    04:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:7b:00:00:00:00:00:00:00:00:00:
    00:00:00:00:00:00:00:00:00:01:c8
Order:
    02:aa:aa:aa:aa:aa:aa:aa:aa:aa:c7:f3:c7:88:1b:
    d0:86:8f:a8:6c
Cofactor:  3 (0x3)

this will cause test failures in test_genec once #12305 is merged to master/backported to 1.1.1 as the error will be reflected also in the exit status.

Curves showing the problem:

  • Oakley-EC2N-3
  • Oakley-EC2N-4

These curves are "special" — as in "stay away from them, HERE BE DRAGONS is an understatement, dragons ran away in fear!" —:

openssl/crypto/ec/ec_curve.c

Lines 3073 to 3081 in 92db29e

# ifndef OPENSSL_NO_EC2M
/* IPSec curves */
{"Oakley-EC2N-3", NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
{"Oakley-EC2N-4", NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
# endif

openssl/crypto/ec/ec_curve.c

Lines 2157 to 2226 in 92db29e

/* IPSec curves */
/*
* NOTE: The of curves over a extension field of non prime degree is not
* recommended (Weil-descent). As the group order is not a prime this curve
* is not suitable for ECDSA.
*/
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 20 * 6];
} _EC_IPSEC_155_ID3 = {
{
NID_X9_62_characteristic_two_field, 0, 20, 3
},
{
/* no seed */
/* p */
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
/* a */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* b */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
/* x */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
/* y */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
/* order */
0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3,
0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
}
};
/*
* NOTE: The of curves over a extension field of non prime degree is not
* recommended (Weil-descent). As the group order is not a prime this curve
* is not suitable for ECDSA.
*/
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 24 * 6];
} _EC_IPSEC_185_ID4 = {
{
NID_X9_62_characteristic_two_field, 0, 24, 2
},
{
/* no seed */
/* p */
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
/* a */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* b */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9,
/* x */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
/* y */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
/* order */
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E
}
};

Yet I fail to see the difference that could trigger the failure in i2d_ECPKParameters() when compared to a "normal" binary curve:

openssl/crypto/ec/ec_curve.c

Lines 2881 to 2882 in 92db29e

{"sect233r1", NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},

openssl/crypto/ec/ec_curve.c

Lines 1184 to 1220 in 92db29e

static const struct {
EC_CURVE_DATA h;
unsigned char data[20 + 30 * 6];
} _EC_NIST_CHAR2_233B = {
{
NID_X9_62_characteristic_two_field, 20, 30, 2
},
{
/* seed */
0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34,
0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
/* p */
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
/* a */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
/* b */
0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23,
0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE,
0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
/* x */
0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1,
0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8,
0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
/* y */
0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85,
0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71,
0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
/* order */
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03,
0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
}
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    branch: 1.1.1Applies to OpenSSL_1_1_1-stable branch (EOL)branch: masterApplies to master branchtriaged: bugThe issue/pr is/fixes a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions