-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathKnownPlainTextVulnerability.ino
88 lines (68 loc) · 2.27 KB
/
KnownPlainTextVulnerability.ino
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* This sketch implements the known plaintext vulnerability exposed by
silkeh that is able to obtain the key for a certain set of plaintexts,
keys and salt values. All other salt values scrambles the key but expose
good hints about it. See https://github.com/gioblu/Cape/issues/17 */
#include <Cape.h>
// Encryption key unkown to the attacker
unsigned char key[] = "2345678901";
// Source content to be crypted that is known to the attacker
unsigned char source[] = "0000000000";
unsigned char destination[10];
unsigned char calculated_key[10];
unsigned char reduced_key;
// Insert secret key and its length
Cape cape(key, 10);
void compute_reduced_key() {
reduced_key = 0;
for(uint16_t i = 0; i < 10; i++)
reduced_key ^= (key[i] << (i % 8));
}
void setup() {
Serial.begin(115200);
cape.set_key(key, 10);
// Set a fixed known salt
cape.salt = 0;
compute_reduced_key();
};
void loop() {
Serial.print("Salt: ");
// Set a new salt
cape.salt++;
Serial.print(cape.salt, DEC);
Serial.print(" Encryption key: ");
for(int i = 0; i < 10; i++) {
Serial.print((char)key[i]);
}
cape.hash(source, destination, 10);
Serial.print(" Cipher text: ");
for(int i = 0; i < 10; i++)
Serial.print((char)destination[i]);
/* Simulating known plain text attack with the following assumptions:
- Known plaintext
- Known ciphertext
- Known key length (can be obtained using brute force quickly)
- Known function used (hash/encrypt)
- Known reduced key (can be obtained using brute force quickly)
- Salt is obtained using brute force: */
Serial.print(" Calculate key: ");
for(uint8_t i = 0; i < 10; i++)
calculated_key[(i ^ cape.salt ^ reduced_key) % 10] =
(destination[i] ^ source[i] ^ cape.salt ^ reduced_key ^ i);
for(uint8_t i = 0; i < 10; i++)
Serial.print((char)calculated_key[i]);
Serial.println();
// More than one salt value generates the key originally used (bad)
for(uint8_t i = 0; i < 10; i++) {
if(calculated_key[i] != key[i]) break;
if(i == 9) {
Serial.print(" ------------------------------------ BROKEN USING SALT: ");
Serial.println(cape.salt, DEC);
}
}
// Erase buffer
for(int i = 0; i < 10; i++) {
source[i] = '0';
destination[i] = 0;
calculated_key[i] = 0;
}
};