diff options
author | Jack Lloyd <[email protected]> | 2018-07-24 12:44:08 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-07-24 12:44:08 -0400 |
commit | 68462e5824c83436d7340c4ca901efdd34632eb3 (patch) | |
tree | c84fb2d673b8dbe02b1d89ab621ec1bce0c4fc48 /src/lib/pubkey | |
parent | fb71b035bf663859847feed5ce436f1563b9aa39 (diff) |
Require SM2 ciphertexts be DER encoded
Previously SM2 test would fail about 1 in a thousand times because
we would corrupt the ciphertext such that the BER was still valid;
it would change the length field to an indefinite length marker,
which still decoded correctly.
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r-- | src/lib/pubkey/sm2/sm2_enc.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp index 587cad44f..4d27ec40b 100644 --- a/src/lib/pubkey/sm2/sm2_enc.cpp +++ b/src/lib/pubkey/sm2/sm2_enc.cpp @@ -165,9 +165,25 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption .end_cons() .verify_end(); + std::vector<uint8_t> recode_ctext; + DER_Encoder(recode_ctext) + .start_cons(SEQUENCE) + .encode(x1) + .encode(y1) + .encode(C3, OCTET_STRING) + .encode(masked_msg, OCTET_STRING) + .end_cons(); + + if(recode_ctext.size() != ciphertext_len) + return secure_vector<uint8_t>(); + + if(same_mem(recode_ctext.data(), ciphertext, ciphertext_len) == false) + return secure_vector<uint8_t>(); + PointGFp C1 = group.point(x1, y1); C1.randomize_repr(m_rng); + // Here C1 is publically invalid, so no problem with early return: if(!C1.on_the_curve()) return secure_vector<uint8_t>(); @@ -182,8 +198,8 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption const BigInt x2 = dbC1.get_affine_x(); const BigInt y2 = dbC1.get_affine_y(); - std::vector<uint8_t> x2_bytes(p_bytes); - std::vector<uint8_t> y2_bytes(p_bytes); + secure_vector<uint8_t> x2_bytes(p_bytes); + secure_vector<uint8_t> y2_bytes(p_bytes); BigInt::encode_1363(x2_bytes.data(), x2_bytes.size(), x2); BigInt::encode_1363(y2_bytes.data(), y2_bytes.size(), y2); |