aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-09-10 12:12:47 -0400
committerJack Lloyd <[email protected]>2017-09-10 12:12:47 -0400
commit903e92b8e7995d0fee605ce2e5d203f1cacae5d3 (patch)
tree10bf9889f805938c67a43d94bc1f9d6c18939692
parent12e567da157057938505eb0cb0a0876644ae5380 (diff)
Change SM2 encryption to match updated standard.
Unfortunately it seems the SM2 format changed between 2010 and 2012, now the ciphertext is C1 || C3 || C2. Unfortunate no matter how you slice it, but at least it's easy to convert from one form to another.
-rw-r--r--news.rst4
-rw-r--r--src/lib/pubkey/sm2/sm2_enc.cpp10
-rw-r--r--src/tests/data/pubkey/sm2_enc.vec3
3 files changed, 11 insertions, 6 deletions
diff --git a/news.rst b/news.rst
index 8cafaaeaf..5bc4c13f4 100644
--- a/news.rst
+++ b/news.rst
@@ -22,6 +22,10 @@ Version 2.3.0, Not Yet Released
* SM2 encryption and signature schemes were previously hardcoded to use SM3
hash, now any hash is allowed. (GH #1188)
+* SM2 encryption in 2.2 followed an obsolete version of the standard. The
+ format of the ciphertext changed with GM/T 0003:2012. The only difference is
+ in the ordering of the embedded MAC vs the masked input.
+
* XTS mode now supports 256-bit and 512-bit block ciphers.
* Add ids to allow SHA-3 signatures with PKCSv1.5 (GH #1184)
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp
index 9bd4bf11c..b05ce12da 100644
--- a/src/lib/pubkey/sm2/sm2_enc.cpp
+++ b/src/lib/pubkey/sm2/sm2_enc.cpp
@@ -105,8 +105,8 @@ class SM2_Encryption_Operation : public PK_Ops::Encryption
ciphertext.push_back(0x04);
ciphertext += x1_bytes;
ciphertext += y1_bytes;
- ciphertext += masked_msg;
ciphertext += C3;
+ ciphertext += masked_msg;
return ciphertext;
}
@@ -153,6 +153,8 @@ class SM2_Decryption_Operation : public PK_Ops::Decryption
return secure_vector<uint8_t>();
}
+ const size_t msg_len = ciphertext_len - (1 + p_bytes*2 + hash->output_length());
+
const PointGFp C1 = OS2ECP(ciphertext, 1 + p_bytes*2, m_key.domain().get_curve());
// OS2ECP verifies C1 is on the curve
@@ -177,20 +179,18 @@ class SM2_Decryption_Operation : public PK_Ops::Decryption
kdf_input += x2_bytes;
kdf_input += y2_bytes;
- const size_t msg_len = ciphertext_len - (1 + p_bytes*2 + hash->output_length());
-
const secure_vector<uint8_t> kdf_output =
kdf->derive_key(msg_len, kdf_input.data(), kdf_input.size());
secure_vector<uint8_t> msg(msg_len);
- xor_buf(msg.data(), ciphertext + (1+p_bytes*2), kdf_output.data(), msg_len);
+ xor_buf(msg.data(), ciphertext + (1+p_bytes*2+hash->output_length()), kdf_output.data(), msg_len);
hash->update(x2_bytes);
hash->update(msg);
hash->update(y2_bytes);
secure_vector<uint8_t> u = hash->final();
- if(same_mem(u.data(), ciphertext + (1+p_bytes*2+msg_len), hash->output_length()) == false)
+ if(same_mem(u.data(), ciphertext + (1+p_bytes*2), hash->output_length()) == false)
return secure_vector<uint8_t>();
valid_mask = 0xFF;
diff --git a/src/tests/data/pubkey/sm2_enc.vec b/src/tests/data/pubkey/sm2_enc.vec
index f878a11a2..120eab583 100644
--- a/src/tests/data/pubkey/sm2_enc.vec
+++ b/src/tests/data/pubkey/sm2_enc.vec
@@ -1,4 +1,5 @@
# Example from draft-shen-sm2-ecdsa-02
+# Corrected to use (C1||C3||C2) - the draft is wrong!
P = 0x8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3
A = 0x787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498
@@ -11,4 +12,4 @@ Cofactor = 1
Msg = 656E6372797074696F6E207374616E64617264
x = 0x1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
Nonce = 4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F
-Ciphertext = 04245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252E776CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01B8650053A89B41C418B0C3AAD00D886C002864679C3D7360C30156FAB7C80A0276712DA9D8094A634B766D3A285E07480653426D
+Ciphertext = 04245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252E776CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01B89C3D7360C30156FAB7C80A0276712DA9D8094A634B766D3A285E07480653426D650053A89B41C418B0C3AAD00D886C00286467