/
GHSA-jp3w-3q88-34cf.json
58 lines (55 loc) · 4.84 KB
/
GHSA-jp3w-3q88-34cf.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
"schema_version": "1.4.0",
"id": "GHSA-jp3w-3q88-34cf",
"modified": "2022-06-17T00:17:08Z",
"published": "2022-06-17T00:17:08Z",
"aliases": [
],
"summary": "Miscomputation when performing AES encryption in rust-crypto",
"details": "The following Rust program demonstrates some strangeness in AES encryption - if you have an immutable key slice and then operate on that slice, you get different encryption output than if you operate on a copy of that key.\n\nFor these functions, we expect that extending a 16 byte key to a 32 byte key by repeating it gives the same encrypted data, because the underlying rust-crypto functions repeat key data up to the necessary key size for the cipher.\n\n```rust\nuse crypto::{\n aes, blockmodes, buffer,\n buffer::{BufferResult, ReadBuffer, WriteBuffer},\n symmetriccipher,\n};\n\nfn encrypt(\n key: &[u8],\n iv: &[u8],\n data: &str,\n) -> Result<String, symmetriccipher::SymmetricCipherError> {\n let mut encryptor =\n aes::cbc_encryptor(aes::KeySize::KeySize256, key, iv, blockmodes::PkcsPadding);\n\n let mut encrypted_data = Vec::<u8>::new();\n let mut read_buffer = buffer::RefReadBuffer::new(data.as_bytes());\n let mut buffer = [0; 4096];\n let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);\n\n loop {\n let result = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true)?;\n\n encrypted_data.extend(\n write_buffer\n .take_read_buffer()\n .take_remaining()\n .iter()\n .copied(),\n );\n\n match result {\n BufferResult::BufferUnderflow => break,\n BufferResult::BufferOverflow => {}\n }\n }\n\n Ok(hex::encode(encrypted_data))\n}\n\nfn working() {\n let data = \"data\";\n let iv = [\n 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE,\n 0xFF,\n ];\n let key = [\n 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,\n 0x0F,\n ];\n // The copy here makes the code work.\n let key_copy = key;\n let key2: Vec<u8> = key_copy.iter().cycle().take(32).copied().collect();\n println!(\"key1:{} key2: {}\", hex::encode(&key), hex::encode(&key2));\n\n let x1 = encrypt(&key, &iv, data).unwrap();\n println!(\"X1: {}\", x1);\n\n let x2 = encrypt(&key2, &iv, data).unwrap();\n println!(\"X2: {}\", x2);\n\n assert_eq!(x1, x2);\n}\n\nfn broken() {\n let data = \"data\";\n let iv = [\n 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE,\n 0xFF,\n ];\n let key = [\n 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,\n 0x0F,\n ];\n // This operation shouldn't affect the contents of key at all.\n let key2: Vec<u8> = key.iter().cycle().take(32).copied().collect();\n println!(\"key1:{} key2: {}\", hex::encode(&key), hex::encode(&key2));\n\n let x1 = encrypt(&key, &iv, data).unwrap();\n println!(\"X1: {}\", x1);\n\n let x2 = encrypt(&key2, &iv, data).unwrap();\n println!(\"X2: {}\", x2);\n\n assert_eq!(x1, x2);\n}\n\nfn main() {\n working();\n broken();\n}\n```\n\nThe output from this program:\n\n```shell\n Running `target/host/debug/rust-crypto-test`\nkey1:000102030405060708090a0b0c0d0e0f key2: 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\nX1: 90462bbe32965c8e7ea0addbbed4cddb\nX2: 90462bbe32965c8e7ea0addbbed4cddb\nkey1:000102030405060708090a0b0c0d0e0f key2: 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f\nX1: 26e847e5e7df1947bf82a650548a7d5b\nX2: 90462bbe32965c8e7ea0addbbed4cddb\nthread 'main' panicked at 'assertion failed: `(left == right)`\n left: `\"26e847e5e7df1947bf82a650548a7d5b\"`,\n right: `\"90462bbe32965c8e7ea0addbbed4cddb\"`', src/main.rs:83:5\n```\n\nNotably, the X1 key in the `broken()` test changes every time after rerunning the program.\n\n",
"severity": [
],
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "rust-crypto"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
},
{
"last_affected": "0.2.36"
}
]
}
]
}
],
"references": [
{
"type": "WEB",
"url": "https://github.com/DaGenix/rust-crypto/issues/476"
},
{
"type": "WEB",
"url": "https://github.com/DaGenix/rust-crypto"
},
{
"type": "WEB",
"url": "https://rustsec.org/advisories/RUSTSEC-2022-0011.html"
}
],
"database_specific": {
"cwe_ids": [
],
"severity": "CRITICAL",
"github_reviewed": true,
"github_reviewed_at": "2022-06-17T00:17:08Z",
"nvd_published_at": null
}
}