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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use u64x2::u64x2;
mod expand;
#[derive(Copy, Clone)]
pub struct Aes192 {
encrypt_keys: [u64x2; 13],
decrypt_keys: [u64x2; 13],
}
impl Aes192 {
#[inline]
pub(crate) fn init(key: &[u8; 24]) -> Self {
let (encrypt_keys, decrypt_keys) = expand::expand(key);
Aes192 { encrypt_keys: encrypt_keys, decrypt_keys: decrypt_keys }
}
#[inline]
pub(crate) fn encrypt(&self, block: &mut [u8; 16]) {
let mut data = u64x2::read(block);
self.encrypt_u64x2(&mut data);
data.write(block);
}
#[inline]
pub(crate) fn decrypt(&self, block: &mut [u8; 16]) {
let keys = self.decrypt_keys;
let mut data = u64x2::read(block);
unsafe {
asm!(include_str!("decrypt.asm")
: "+{xmm0}"(data)
:
"{xmm1}"(keys[12]), "{xmm2}"(keys[11]), "{xmm3}"(keys[10]),
"{xmm4}"(keys[9]), "{xmm5}"(keys[8]), "{xmm6}"(keys[7]),
"{xmm7}"(keys[6]), "{xmm8}"(keys[5]), "{xmm9}"(keys[4]),
"{xmm10}"(keys[3]), "{xmm11}"(keys[2]), "{xmm12}"(keys[1]),
"{xmm13}"(keys[0])
:
: "intel", "alignstack"
);
}
data.write(block);
}
#[inline]
pub(crate) fn encrypt8(&self, blocks: &mut [u8; 8*16]) {
let mut data = u64x2::read8(blocks);
self.encrypt_u64x2_8(&mut data);
u64x2::write8(data, blocks);
}
#[inline]
pub(crate) fn decrypt8(&self, blocks: &mut [u8; 8*16]) {
let keys = self.decrypt_keys;
let mut data = u64x2::read8(blocks);
unsafe {
asm!(include_str!("decrypt8_1.asm")
:
"+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]),
"+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]),
"+{xmm6}"(data[6]), "+{xmm7}"(data[7])
:
"{xmm8}"(keys[12]), "{xmm9}"(keys[11]), "{xmm10}"(keys[10]),
"{xmm11}"(keys[9]), "{xmm12}"(keys[8]), "{xmm13}"(keys[7]),
"{xmm14}"(keys[6]), "{xmm15}"(keys[5])
:
: "intel", "alignstack"
);
asm!(include_str!("decrypt8_2.asm")
:
"+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]),
"+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]),
"+{xmm6}"(data[6]), "+{xmm7}"(data[7])
:
"{xmm11}"(keys[4]), "{xmm12}"(keys[3]), "{xmm13}"(keys[2]),
"{xmm14}"(keys[1]), "{xmm15}"(keys[0])
:
: "intel", "alignstack"
);
}
u64x2::write8(data, blocks);
}
#[inline(always)]
pub(crate) fn encrypt_u64x2(&self, data: &mut u64x2) {
let keys = self.encrypt_keys;
unsafe {
asm!(include_str!("encrypt.asm")
: "+{xmm0}"(*data)
:
"{xmm1}"(keys[0]), "{xmm2}"(keys[1]), "{xmm3}"(keys[2]),
"{xmm4}"(keys[3]), "{xmm5}"(keys[4]), "{xmm6}"(keys[5]),
"{xmm7}"(keys[6]), "{xmm8}"(keys[7]), "{xmm9}"(keys[8]),
"{xmm10}"(keys[9]), "{xmm11}"(keys[10]), "{xmm12}"(keys[11]),
"{xmm13}"(keys[12])
:
: "intel", "alignstack"
);
}
}
#[inline(always)]
pub(crate) fn encrypt_u64x2_8(&self, data: &mut [u64x2; 8]) {
let keys = self.encrypt_keys;
unsafe {
asm!(include_str!("encrypt8_1.asm")
:
"+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]),
"+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]),
"+{xmm6}"(data[6]), "+{xmm7}"(data[7])
:
"{xmm8}"(keys[0]), "{xmm9}"(keys[1]), "{xmm10}"(keys[2]),
"{xmm11}"(keys[3]), "{xmm12}"(keys[4]), "{xmm13}"(keys[5]),
"{xmm14}"(keys[6]), "{xmm15}"(keys[7])
:
: "intel", "alignstack"
);
asm!(include_str!("encrypt8_2.asm")
:
"+{xmm0}"(data[0]), "+{xmm1}"(data[1]), "+{xmm2}"(data[2]),
"+{xmm3}"(data[3]), "+{xmm4}"(data[4]), "+{xmm5}"(data[5]),
"+{xmm6}"(data[6]), "+{xmm7}"(data[7])
:
"{xmm11}"(keys[8]), "{xmm12}"(keys[9]), "{xmm13}"(keys[10]),
"{xmm14}"(keys[11]), "{xmm15}"(keys[12])
:
: "intel", "alignstack"
);
}
}
}
#[cfg(test)]
mod test_expand;