diff options
author | Jack Lloyd <[email protected]> | 2017-09-10 12:12:47 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-09-10 12:12:47 -0400 |
commit | 903e92b8e7995d0fee605ce2e5d203f1cacae5d3 (patch) | |
tree | 10bf9889f805938c67a43d94bc1f9d6c18939692 /src | |
parent | 12e567da157057938505eb0cb0a0876644ae5380 (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/pubkey/sm2/sm2_enc.cpp | 10 | ||||
-rw-r--r-- | src/tests/data/pubkey/sm2_enc.vec | 3 |
2 files changed, 7 insertions, 6 deletions
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 |