Skip to content

Comments

feat: add sm2 encrypted test case from GM/T0003.5-2012.#16511

Closed
ymj-uos wants to merge 2 commits intoopenssl:masterfrom
ymj-uos:master
Closed

feat: add sm2 encrypted test case from GM/T0003.5-2012.#16511
ymj-uos wants to merge 2 commits intoopenssl:masterfrom
ymj-uos:master

Conversation

@ymj-uos
Copy link
Contributor

@ymj-uos ymj-uos commented Sep 6, 2021

Checklist
  • documentation is added or updated
  • tests are added or updated

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 6, 2021

#15869

this PR is the same to this one!

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 6, 2021

@mspncp

@mspncp mspncp added approval: otc review pending branch: 3.0 Applies to openssl-3.0 branch branch: master Applies to master branch labels Sep 6, 2021
@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 6, 2021

@paulidale @t8m @romen

@romen
Copy link
Member

romen commented Sep 6, 2021

@ymj-uos you have 2 commits in this PR and one of them is a Merge commit, which we do not allow.
You need to rebase on current master instead.

@romen
Copy link
Member

romen commented Sep 6, 2021

Also, as background, I did look previously into backporting this KAT to OpenSSL, but preferred not to, for 2 reasons:

  • there appears to be an error in the description of this KAT in GM/T0003.5-2012/GB/T 32918.5-2016 (at section C.2/page 13):

    • compute point 𝐶1 = [𝑘]𝐺 = (𝑥1, 𝑦1) of the elliptic curve:
      • coordinate 𝑥1: 04EBFC71 8E8D1798 62043226 8E77FEB6 415E2EDE 0E073C0F 4F640ECD 2E149A73
      • coordinate 𝑦1: E858F9D8 1E5430A5 7B36DAAB 8F950A3C 64E6EE6A 63094D99 283AFF76 7E124DF0
    • choose the uncompressed form of 𝐶1, convert the point to be byte string of form 𝑃𝐶 ∥ 𝑥1 ∥ 𝑦1 where 𝑃𝐶 is a single byte and 𝑃𝐶 = 04, and denoted still by 𝐶1.
    • … omitted steps …
    • compute 𝐶2 = 𝑀 ⊕ 𝑡: 21886C A989CA9C 7D580873 07CA9309 2D651EFA
    • … omitted steps …
    • compute 𝐶3 = 𝐻𝑎𝑠ℎ(𝑥2 ∥ 𝑀 ∥ 𝑦2): … :
      59983C18 F809E262 923C53AE C295D303 83B54E39 D609D160 AFCB1908 D0BD8766
    • output the cipher-text 𝐶 = 𝐶1 ∥ 𝐶2 ∥ 𝐶3:
      04EBFC71 8E8D1798 62043226 8E77FEB6 415E2EDE 0E073C0F 4F640ECD 2E149A73
      E858F9D8 1E5430A5 7B36DAAB 8F950A3C 64E6EE6A 63094D99 283AFF76 7E124DF0
      59983C18 F809E262 923C53AE C295D303 83B54E39 D609D160 AFCB1908 D0BD8766
      21886CA9 89CA9C7D 58087307 CA93092D 651EFA
    • the last step shows the order of 𝐶2 and 𝐶3 is swapped
    • the beginning of the cipher-text 𝐶 should start with 0404 as the first two bytes, as the KAT describes the encoding of 𝐶1 to be 𝑃𝐶 ∥ 𝑥1 ∥ 𝑦1, where 𝑃𝐶 is 04 and the encoding of 𝑥1 starts with another 04. The described point encoding (analogous to the SECG format) conforms to what is described in GM/T 0003.3-2012 (and GM/T 0003.1-2012), but the 𝐶1 part in the final cipher-text 𝐶 of this KAT does not match.
  • GM/T0003.5-2012/GB/T 32918.5-2016 seems to be incompatible with GM/T 0009-2012 (unofficial translation), which defines the ASN.1 structure we actually use to serialize/unserialize SM2 ciphertexts.
    From the latter, compare

    SM2Cipher ::= SEQENCE{
      XCoordinate     INTEGER,                -- x-coordinate
      YCoordinate     INTEGER,                -- y-coordinate
      HASH            OCTET STRING SIZE(32),  -- hash value
      CipherText      OCTET STRING            -- ciphertext
    }

    against the GM/T0003 family which mandates a SECG like encoding for the point described by the first two INTEGERS in the sequence above:

    • 6.1.A8 of GM/T 0003.4-2012 mandates the output ciphertext to be 𝐶1 || 𝐶2 || 𝐶3, where 𝐶1 is a elliptic curve point, defined in 6.1.A2
    • 6.1.A2, regarding its encoding, mandates: "convert the data type of 𝐶1 to bit string as specified in Clauses 4.2.8 and 4.2.4 of GM/T 0003.1‒2012"
    • 4.2.8 of GM/T 0003.1‒2012 (for uncompressed form & prime curve as the default SM2 curve) mandates to write 0x04 || X1 || Y1, where X1 and Y1 are 𝑙 = ⌈(log2 𝑞)/8⌉ bytes long as specified in 4.2.5
    • 4.2.5 refers to 4.2.1, which ultimately mandates to write 𝑙 bytes, from left to right, padding with zero bits as needed.

    This is incompatible with the ASN.1 structure, not only because the first byte signaling "uncompressed encoding" is missing, but also because the coordinates when defined as INTEGER cannot be padded but must take the shortest possible form.

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 14, 2021

I thought a long time, the two reason which you mentioned seem to be misunderstood.
about your 1st reason:
according to the GM/T0003.5-2012 and GB/T 32918.5-2016, "output the cipher-text" should be 𝐶 = 𝐶1 ∥ 𝐶3 ∥ 𝐶2, this is correct!
because of historial version, 𝐶 = 𝐶1 ∥ 𝐶2 ∥ 𝐶3 would be used for some time, which would be changed to 𝐶 = 𝐶1 ∥ 𝐶3 ∥ 𝐶2 later.

about C1 (PC ∥ x1 ∥ y1), this is a data-format problem. In the GM/T0003.1-2012 (at section 4.1 and 4.2/page 6),
there are 5 data formats (bit_string, byte_string, integer, Elliptic curve point, field_element),
all of them could be used to express C1. only byte_string format should add PC flag.

image

image

image

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 14, 2021

about your 2nd reason:

SM2Cipher ::= SEQENCE{
XCoordinate INTEGER, -- x-coordinate
YCoordinate INTEGER, -- y-coordinate
HASH OCTET STRING SIZE(32), -- hash value
CipherText OCTET STRING -- ciphertext
}

at the serialize/unserialize SM2 ciphertexts,
C1 does not use byte_string format, so we do not care about "PC". If C1 use byte_string format, we should think about the first byte signaling "uncompressed encoding"
about padding with zero bits, it is used during computing or transferring. If only communicating or saving SM2Cipher data, we should not care about padding.

section 6.1 (page 4-5) Encryption algorithm its process
Suppose the message to be sent is the bit string 𝑀 and 𝑘𝑙𝑒𝑛 represents the bit-length
of 𝑀.
To encrypt the plaintext 𝑀, encryption user A should perform the following procedures:
A1: generate a random number 𝑘 ∈ [1, 𝑛 − 1] with the random number generator.
A2: compute point 𝐶1 = [𝑘]𝐺 = (𝑥1, 𝑦1) of the elliptic curve, and convert the data type
of 𝐶1 to bit string as specified in Clauses 4.2.9 and 4.2.5 of GM/T 0003.1‒2012.
A3: compute point 𝑆 = [ℎ]𝑃𝐵 of the elliptic curve; if 𝑆 is the infinity point, report
error and exit.
A4: compute point [𝑘]𝑃𝐵 = (𝑥2, 𝑦2) of the elliptic curve, convert the data type of 𝑥2, 𝑦2
to bit string as specified in Clauses 4.2.6 and 4.2.5 of GM/T 0003.1‒2012.
A5: compute 𝑡 = 𝐾𝐷𝐹(𝑥2||𝑦2, 𝑘𝑙𝑒𝑛). If 𝑡 is an all-zero bit string, go to A1.
A6: compute 𝐶2 = 𝑀 ⊕ 𝑡.
A7: compute 𝐶3 = 𝐻𝑎𝑠ℎ(𝑥2||𝑀||𝑦2).
A8: output the ciphertext 𝐶 = 𝐶1||𝐶3||𝐶2.
Note: Examples of the process of encryption are described in Annex A (Appendix A, is the same to Annex C in GB/T32918.5-2016).

compared to the original version as below:

image

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 14, 2021

finally, In the GM/T 0009-2012 only asn.1 data format (C1,C2,C3) is defined. not say that the SM2 cipher must use asn.1 data format.
If someone need use asn.1 data structure (format), he could adopt the data format in the GM/T 0009-2012. if not, he could use one of 5 data formats in the GM/T0003.1-2012.
So, the code that I upload match all the sm2's standards.

@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 14, 2021

GMT 0003.4-2012 SM2椭圆曲线公钥密码算法第4部分:公钥加密算法.pdf

This is the original version standard. If you want to check some detail,you can use it.

@ymj-uos ymj-uos requested a review from romen September 16, 2021 01:31
@t8m t8m added the triaged: feature The issue/pr requests/adds a feature label Sep 17, 2021
@romen
Copy link
Member

romen commented Sep 20, 2021

Thanks for your comments @ymj-uos , but even considering that the problem might be related to the English version of the standard (which is a problem, because that is the one we can use for our reviews), I still have some doubts:

  • looking at the version in Chinese you linked, I can still clearly see in the KAT that C1 is supposed to be serialized as PC || x || y with PC = 04, and this is still evident looking for example at page 9 at the expected ciphertext C under A2
  • even looking at the Chinese original of GM/T 0003.5-2012 (Appendix C, at page 8-9 seems to be the one about the SM2 encryption standard) C1 (and also in the expected ciphertext) is serialized using the SECG standard and prefixed with PC = 04
  • In the GM/T 0003.5-2012 document above I am not finding a reference to the KAT being added in this PR.

@romen
Copy link
Member

romen commented Sep 23, 2021

@ymj-uos I apologize, I finally managed to understand why I was seeing discrepancies, I will update my review shortly

Copy link
Member

@romen romen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patience @ymj-uos .

Here is my updated review, I'd like to apply some changes to make this test readable for future readers, especially considering that the expected answer technically differs from the one published in the document from which this tests originates.

@t8m t8m added this to the Post 3.0.0 milestone Sep 24, 2021
Copy link
Member

@romen romen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks again @ymj-uos !

@romen romen added approval: review pending This pull request needs review by a committer and removed approval: otc review pending labels Sep 25, 2021
@romen
Copy link
Member

romen commented Sep 25, 2021

Note for whoever will merge this, remember to squash the commits!

@romen romen self-assigned this Sep 25, 2021
@ymj-uos
Copy link
Contributor Author

ymj-uos commented Sep 26, 2021

@paulidale

@paulidale paulidale removed the approval: review pending This pull request needs review by a committer label Sep 27, 2021
@paulidale paulidale added the approval: done This pull request has the required number of approvals label Sep 27, 2021
@romen
Copy link
Member

romen commented Sep 27, 2021

Note for whoever will merge this, remember to squash the commits!

@paulidale I plan to take care of merging this tomorrow morning (European timezones) once the 24h grace period is over.

@openssl-machine
Copy link
Collaborator

24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually.

@romen romen added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Sep 28, 2021
openssl-machine pushed a commit that referenced this pull request Sep 28, 2021
Reviewed-by: Nicola Tuveri <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from #16511)
openssl-machine pushed a commit that referenced this pull request Sep 28, 2021
Reviewed-by: Nicola Tuveri <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from #16511)

(cherry picked from commit 8ba65c3)
@romen
Copy link
Member

romen commented Sep 28, 2021

Merged

Thanks @ymj-uos for your contribution!

edit: added 1.1.1 commit for completion

@romen
Copy link
Member

romen commented Sep 28, 2021

@paulidale This could be cherry-picked cleanly to 1.1.1, and I would propose to do so.
If you agree, could you please add the 1.1.1 label and state that you agree for the record?

@romen romen removed the approval: ready to merge The 24 hour grace period has passed, ready to merge label Sep 28, 2021
@romen
Copy link
Member

romen commented Sep 28, 2021

(removed the ready to merge label, so we can restart the 24h grace period for 1.1.1 if @paulidale agrees)

Copy link
Contributor

@paulidale paulidale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good for 1.1.1 too.

@paulidale paulidale added approval: done This pull request has the required number of approvals branch: 1.1.1 Applies to OpenSSL_1_1_1-stable branch (EOL) labels Sep 28, 2021
@openssl-machine openssl-machine removed the approval: done This pull request has the required number of approvals label Sep 29, 2021
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@openssl-machine openssl-machine added the approval: ready to merge The 24 hour grace period has passed, ready to merge label Sep 29, 2021
openssl-machine pushed a commit that referenced this pull request Sep 29, 2021
Reviewed-by: Nicola Tuveri <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from #16511)

(cherry picked from commit 8ba65c3)
@romen