OTC VOTE: Disallow SM2 with a non-SM2 curve

Nicola Tuveri nic.tuv at gmail.com
Wed Mar 10 03:44:22 UTC 2021


Yes, in 1.1.1j the following is possible:

- SM2 cryptosystem operations over the "SM2 curve"
- SM2 cryptosystem operations over arbitrary curve (including NIST ones)
- ECDSA/ECDH cryptosystem operations over the "SM2 curve"

(See attached patches to verify this is the case in the tests)

They require an explicit call to `EVP_PKEY_set_alias_type(pkey,
EVP_PKEY_SM2);` or `EVP_PKEY_set_alias_type(pkey, EVP_PKEY_EC);`, to pick
respectively SM2 cryptosystem operations or ECDSA/ECDH cryptosystem
operations.

In 3.0, we want to get rid of `EVP_PKEY_set_alias_type()` and make the
"type" of a key object immutable: this will be a breaking change for
applications that were using SM2 in 1.1.1.

This vote is, in addition, about removing existing functionality: doing SM2
stuff over non-SM2 curves (and, somewhat implicitly, also about doing
ECDSA/DH-stuff over the "SM2 curve").

I'd prefer to retain the functionality, accessible programmatically, to
create an EC keymgmt object over the "SM2 curve" as well as an SM2 keymgmt
object over any arbitrary curve. (Hence my -1 in this vote).

I'd also like to have a separate vote, when we will formalize that key
types are immutable, to require a `EVP_PKEY_todata()` mechanism to mirror
the `EVP_PKEY_fromdata()` mechanism, so that while key types remain
immutable, there will be a convenient way for us and our users to export a
key object from a keymgmt and import it into another keymgmt, letting
provider implementations define what is exported and if the exported data
is compatible with what is expected on import.


## Serialized SM2-related keys

Regarding serialization/deserialization of SM2-related keys: at the
standard level SM2 reuses the format for standard EC keys, including the
"outer" OID for the key type which is "id-ecPublicKey"; it also defines an
OID to be used for the (currently) only curve that is recommended for use
by the SM2 standard.
This OID (`1.2.156.10197.1.301`
<http://oid-info.com/get/1.2.156.10197.1.301>) is also a bit weird: it's
labeled as `"SM2" elliptic curve cryptography` and it's not a leaf node in
the OID tree, among the children there are `.1` for `SM2-1 Digital
Signature Algorithm`, `.3` for `"SM2-3" public key encryption` and `.101`
for `"wapip192v1"` (which seems to be another SM2 curve, but I never found
where it is actually used); but because most implementations (including
OpenSSL) use `1.2.156.10197.1.301` to indicate the SM2-recommended 256-bit
prime curve some projects (notably gmSSL) refer to at as `sm2p256v1`.

At the same time, from the available SM2 standards
<https://gist.github.com/romen/d752b8d1897bc1a0009017511770de06>, while
`sm2p256v1` is currently the only recommended curve, nothing prevents using
other elliptic curves: in theory both prime and binary curves are allowed,
and IIRC also explicit parameter ones.

Overall the current scenario of how SM2 OIDs are assigned/used, combined
with the fact that the SM2 standard reuses the same serialization format
defined by SECG for regular ECDSA/ECDH keys, makes it impossible to
distinguish between a key for the SM2 cryptosystems or for the ECDSA/DH
cryptosystems.

In 1.1.1j, when deserializing with `PEM_read_PrivateKey()` this key:

~~~
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgOYffNMmrl1T1HVVC
wijmHL5xn9vm/IeLWfLnA/NJwgehRANCAAQsIGyWbZl+m04MHFOf47z/Z06Yyr69
ZjZZoyJviFyj/9mx4B8Mjs2ranuRjykBF6SdIcLD+c6AqZ9cvs2V4m2R
-----END PRIVATE KEY-----

    0:d=0  hl=3 l= 135 cons: SEQUENCE
    3:d=1  hl=2 l=   1 prim:  INTEGER           :00
    6:d=1  hl=2 l=  19 cons:  SEQUENCE
    8:d=2  hl=2 l=   7 prim:   OBJECT            :id-ecPublicKey
   17:d=2  hl=2 l=   8 prim:   OBJECT            :sm2
   27:d=1  hl=2 l= 109 prim:  OCTET STRING
      0000 - 30 6b 02 01 01 04 20 39-87 df 34 c9 ab 97 54 f5   0k....
9..4...T.
      0010 - 1d 55 42 c2 28 e6 1c be-71 9f db e6 fc 87 8b 59
.UB.(...q......Y
      0020 - f2 e7 03 f3 49 c2 07 a1-44 03 42 00 04 2c 20 6c
....I...D.B.., l
      0030 - 96 6d 99 7e 9b 4e 0c 1c-53 9f e3 bc ff 67 4e 98
.m.~.N..S....gN.
      0040 - ca be bd 66 36 59 a3 22-6f 88 5c a3 ff d9 b1 e0
...f6Y."o.\.....
      0050 - 1f 0c 8e cd ab 6a 7b 91-8f 29 01 17 a4 9d 21 c2
.....j{..)....!.
      0060 - c3 f9 ce 80 a9 9f 5c be-cd 95 e2 6d 91            ......\....m.

~~~

we create an EVP_PKEY object with `{ .type = 408 (= EVP_PKEY_EC,
"id-ecPublicKey"), .save_type = 408 }`. If used via EVP functions in this
form, this will be used as a regular EC key, computing ECDSA/ECDH.

After an explicit call to `EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))`,
the EVP_PKEY object reads `{ .type = 1172 (= EVP_PKEY_SM2, "SM2"),
.save_type = 408 }`, and using EVP functions will result in using this as a
key for the SM2 cryptosystems (e.g. SM2DSA).


In 3.0, as of 3e6a0d5738, our DECODER implementation is able to distinguish
on the inner curve OID, so parsing the PEM above results in a key object
belonging to the SM2 keymgmt.
Because `EVP_PKEY_set_alias_type()` is not supported, in current 3.0 it is
hard (if not impossible) to flexibly use EC/SM2 keys as in 1.1.1, but it is
still possible to do something with ephemeral keys (e.g. one can initialize
an SM2 keygen EVP_PKEY_CTX and set P-521 as the curve, which ultimately
delivers an SM2 key object over an arbitrary curve that can be used, for
example, for SM2DSA operations as demonstrated by
0001-drop-3.0.0-test-SM2DSA-and-SM2ENC-DEC-over-NIST-P-52.patch).


Nicola


On Tue, Mar 9, 2021 at 8:50 PM Kurt Roeckx <kurt at roeckx.be> wrote:

> On Tue, Mar 09, 2021 at 03:57:32PM +0200, Nicola Tuveri wrote:
> > It is tangent to the vote in itself, but I'd like to highlight that in
> part
> > this vote is motivated by getting rid of cases where there is a need to
> > convert between compatible key types (e.g. SM2 & EC, DH & DHX).
> >
> > The vote of this text does not cover it, but another use case that we
> will
> > likely lose in 3.0 when this vote passes is using ECDH/ECDSA over the
> curve
> > identified by the SM2 OID.
> >
> > It's likely another niche use, not relevant for any production system,
> but
> > it is creating a precedent where OpenSSL accepts that the SM2 standard
> > overrides the SECG standard.
> >
> > In 1.1.1 we do _default_ to decode a key serialized as "SECG EC over the
> > SM2 OID curve" as a SM2 key, but we are not preventing developers from
> > creating an EC key object over that curve, nor an SM2 key object over any
> > other curve (serialization of such "weird" key objects would be
> identical,
> > deserialization would require an explicit set_alias call to mutate from
> the
> > default type).
> >
> > With the changes proposed as a corollary to this vote that were discussed
> > on the last OTC meeting, we would remove this ability: we could maybe
> still
> > create an ephemeral "EC over SM2 OID" key object but there would be no
> way
> > to deserialize one.
> >
> >
> > I would instead prefer to vote on requiring for 3.0 a mechanism to
> > "convert" key types: an EVP_PKEY_todata function to mirror
> > EVP_PKEY_fromdata.
> > It will be then up to the individual keymgmt of the source key object to
> > decide if it can be exported to OSSL_PARAMs, and to the receiving keymgmt
> > on which fromdata is called to determine if the input OSSL_PARAMs are
> valid
> > to create a proper key object.
> > Yes, we would still have a breaking change (set_alias needs to be
> replaced
> > by the todata/fromdata dance) but we wouldn't lose functionality.
> >
> > Such a mechanism could be useful also beyond the current problem of key
> > conversions within the builtin providers, and allow future proofing and
> > interoperability between different providers that might end up using
> > different names for compatible key types (for whatever reason it might
> > happen).
>
> This text does not seem to help me to make a vote, it seems I just
> get more questions.
>
> The EVP_PKEY_set_alias_type() manpage says that SM2 use the same
> encoding an ECDSA. I assume that during deserialization we don't
> know if we should create an ECDSA key or an SM2 key, because we
> don't look at the OID when deserializing and always create an
> ECDSA key. My understanding is that there is code that needs to
> know an SM2 key is stored in that object, and is not looking at
> the OID, but instead looks at what the pkey type is. My suggested
> fix for that would be to make the deserialization smarter so it
> sets the correct pkey type base on the OID.
>
> Assuming that we can get an SM2 key, I currently fail to see why
> ECDSA or ECDH wouldn't work with them, but I know very little
> about SM2.
>
> I also don't understand what the vote is really about. Can 1.1.1
> do SM2 on one of the nist curves?
>
>
> Kurt
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-project/attachments/20210310/1b1f70ca/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-drop-test-SM2DSA-and-SM2ENC-DEC-over-NIST-P-521-curv.patch
Type: text/x-patch
Size: 2284 bytes
Desc: not available
URL: <https://mta.openssl.org/pipermail/openssl-project/attachments/20210310/1b1f70ca/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-drop-test-ECDSA-over-SM2-curve.patch
Type: text/x-patch
Size: 2155 bytes
Desc: not available
URL: <https://mta.openssl.org/pipermail/openssl-project/attachments/20210310/1b1f70ca/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-drop-3.0.0-test-SM2DSA-and-SM2ENC-DEC-over-NIST-P-52.patch
Type: text/x-patch
Size: 2903 bytes
Desc: not available
URL: <https://mta.openssl.org/pipermail/openssl-project/attachments/20210310/1b1f70ca/attachment-0005.bin>


More information about the openssl-project mailing list