[openssl-dev] EC key generation in broken in all versions
Douglas E Engert
deengert at gmail.com
Sat Jan 3 18:34:40 UTC 2015
On 1/3/2015 6:41 AM, Annie Yousar wrote:
> Dear all,
> -----Facts-----
> The private EC key is always encoded as an OCTET STRING in ASN.1
It depends on its context, there are a number of ways to encode it:
PKCS#15 6.3.3 Private Elliptic Curve key objects
PrivateECKeyAttributes ::= SEQUENCE {
value ObjectValue {ECPrivateKey},
keyInfo KeyInfo {Parameters, PublicKeyOperations} OPTIONAL,
... -- For future extensions
}
ECPrivateKey ::= INTEGER
> cf. RFC 5915 http://tools.ietf.org/html/rfc5915#page-3:
> o privateKey is the private key. It is an octet string of length
> ceiling (log2(n)/8) (where n is the order of the curve) obtained
> from the unsigned integer via the Integer-to-Octet-String-
> Primitive (I2OSP) defined in [RFC3447].view
>
> Therefore the length of this OCTECT STRING is fixed by the curve parameters.
In the context of RFC5915, the OCTET STRING has a fixed length and the
I2OSP routine is provided with the length. RFC3447 is a more important reference,
as it says how to do a conversion.
https://tools.ietf.org/html/rfc344
This related to problem:
http://rt.openssl.org/Ticket/Display.html?id=3465&user=guest&pass=guest
It could have been addressed if the OCTET STRING was kept at the fixed length,
as the OCTET STRING should be xLen, which can be derived from the parameters
if they are present.
In the github master src/crypto/ec/ec_lcl.h defines struct ec_key_st
BIGNUM *priv_key;
OpenSSL is losing the xLen when converting internally to a BIGNUM.
Maybe it should be storing the xLen for use when group=NULL;
to convert the BIGNUM to OCTET STRING of the correct length.
>
> The EC private key encoding is wrong in OpenSSL from the very beginning:
> If the byte length of the private key is shorter than the byte length of
> the order then OpenSSL generates a shorter OCTET STRING than required.
> Keep in mind that the private key is not a DER encoded integer but an
> (unsigned) integer encoded in a fixed length byte string.
>
> Check that out with, e.g. the attached script and a log that shows up by
> the script.
> If you compare in the script the hexdata string length against 64 you will
> get more broken key encodings:
>
> openssl asn1parse gives:
> 0:d=0 hl=2 l= 117 cons: SEQUENCE
> 2:d=1 hl=2 l= 1 prim: INTEGER :01
> 5:d=1 hl=2 l= 30 prim: OCTET STRING [HEX DUMP]:0672D2....
> 37:d=1 hl=2 l= 10 cons: cont [ 0 ]
> 39:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
> 49:d=1 hl=2 l= 68 cons: cont [ 1 ]
> 51:d=2 hl=2 l= 66 prim: BIT STRING
>
> openssl ec -text shows:
> read EC key
> Private-Key: (256 bit)
> priv:
> 06:72:d2:f7:54:2a:1f:f8:35:06:12:81:94:9d:68:
> 84:bb:8f:f2:4d:f5:88:62:ad:a7:42:16:1f:15:30
> pub:
> 04:3f:ff:4b:5d:5b:4c:b5:ae:b2:1a:2e:8e:52:14:
> 7d:fc:1a:56:45:76:cd:ba:45:2e:ef:ea:d1:36:59:
> 9b:85:f3:c5:d5:09:bd:6c:d8:e3:f0:88:1a:37:2c:
> 20:1c:21:85:54:f3:53:6c:2e:51:66:67:c1:95:58:
> a0:64:f8:fa:97
> ASN1 OID: prime256v1
>
> -----Remark-----
> Note that is not required to output the encoded OCTET STRING by the text
> option, which displays an integer. Look instead at the output of the
> asn1parse command.
> As a side effect, if the upper bit of a shorter key is set, the text
> option shows an additional leading zero byte, which is in fact not in the
> encoding.
>
> -----How to proceed-----
> The encoding is broken and does not conform with the Specification.
> Full stop.
>
> Because OpenSSL gently handles leading zero bytes in a private key, I'm
> quite sure that a correction of the EC key encoding has no impact.
>
> Try out as examples the following conformaing private EC keys:
>
> -----BEGIN EC PRIVATE KEY-----
> MHcCAQEEIADurCM9Znleeiyft0Ll5fK9HLZiMsEa1prIsF/rj5ZmoAoGCCqGSM49
> AwEHoUQDQgAEbf8lX1VO8rfkHQao+D3PTIq9Mtg2Z54DNlTv2Fa4SnyKyjxbm/V9
> PmluypK/YofHS+Qsd4JkExbSZ0xC+G78dg==
> -----END EC PRIVATE KEY-----
> or
> -----BEGIN EC PRIVATE KEY-----
> MHcCAQEEIAAMVeMs6sJ6iKyn+3whuEo9KuAStgwyRo+KxaOCbnfKoAoGCCqGSM49
> AwEHoUQDQgAERYtBxIKY6Glq7sRHpYhrJ01KKAvH9LfD4L+B7GeMDht3Sw2IbK+e
> 82cUTBOXXBRHCL7xfk+DamHAcl9GtoO8XQ==
> -----END EC PRIVATE KEY-----
>
> OpenSSL converts this encoding into the internal structure, where the
> private key is stored as a BIGNUM, and leading zeros disappear.
>
> Any comments on the attached diff for 1.0.2.beta3 are welcome. It works,
> but I didn't check it carefully. It is applicable to the 1.0.1 branch as
> well.
>
> Regards,
> Ann.
>
>
>
> _______________________________________________
> openssl-dev mailing list
> openssl-dev at openssl.org
> https://mta.opensslfoundation.net/mailman/listinfo/openssl-dev
>
--
Douglas E. Engert <DEEngert at gmail.com>
More information about the openssl-dev
mailing list