| 53 | } |
| 54 | |
| 55 | td::SecureString MessageEncryption::encrypt_data_with_prefix(td::Slice data, td::Slice secret, td::Slice extra, |
| 56 | td::UInt256 *save_large_msg_id) { |
| 57 | CHECK(data.size() % 16 == 0); |
| 58 | auto large_secret = kdf_expand(secret, "tde2e_encrypt_data"); |
| 59 | auto encrypt_secret = large_secret.as_slice().substr(0, 32); |
| 60 | auto hmac_secret = large_secret.as_mutable_slice().substr(32, 32); |
| 61 | |
| 62 | td::SecureString tail_data(data.size() + extra.size() + 4, '\0'); |
| 63 | auto tail = tail_data.as_mutable_slice(); |
| 64 | tail.copy_from(data); |
| 65 | tail.remove_prefix(data.size()); |
| 66 | tail.copy_from(extra); |
| 67 | tail.remove_prefix(extra.size()); |
| 68 | CHECK(tail.size() == 4); |
| 69 | td::as<td::int32>(tail.data()) = td::narrow_cast<td::int32>(extra.size()); |
| 70 | auto large_msg_id = hmac_sha256(hmac_secret, tail_data); |
| 71 | if (save_large_msg_id) { |
| 72 | save_large_msg_id->as_mutable_slice().copy_from(large_msg_id); |
| 73 | } |
| 74 | |
| 75 | auto msg_id = large_msg_id.as_slice().substr(0, 16); |
| 76 | |
| 77 | td::SecureString res_buf(data.size() + 16, '\0'); |
| 78 | auto res = res_buf.as_mutable_slice(); |
| 79 | res.copy_from(msg_id); |
| 80 | |
| 81 | auto cbc_state = calc_aes_cbc_state_from_hash(hmac_sha512(encrypt_secret, msg_id)); |
| 82 | cbc_state.encrypt(data, res.substr(16)); |
| 83 | |
| 84 | return res_buf; |
| 85 | } |
| 86 | td::SecureString MessageEncryption::kdf_expand(td::Slice random_secret, td::Slice info) { |
| 87 | return hmac_sha512(random_secret, info); |
| 88 | } |