IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
AESCrypt_x86.cs
Go to the documentation of this file.
1#if NETCOREAPP3_0_OR_GREATER
2
3using System;
5using System.Runtime.InteropServices;
6using System.Runtime.Intrinsics;
7using System.Runtime.Intrinsics.X86;
8
10{
11
15 [SkipLocalsInit]
16 static class AESCrypt_x86
17 {
18
22 public static bool IsSupported => Aes.IsSupported && Ssse3.IsSupported;
23
24 public static ReadOnlySpan<int> KeyShuffleMask => [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f];
25
34 [MethodImpl(MethodImplOptions.AggressiveInlining)]
35 public static void DecryptBlock(ReadOnlySpan<byte> from, Span<byte> to, ReadOnlySpan<int> key)
36 {
37 // ext\openjdk\hotspot\src\cpu\x86\vm\stubGenerator_x86_32.cpp:3125-3210
38 Vector128<byte> xmm_temp1, xmm_temp2, xmm_temp3, xmm_temp4;
39 var xmm_key_shuf_mask = Vector128Util.LoadUnsafe(in MemoryMarshal.GetReference(KeyShuffleMask), 0).AsByte();
40 var xmm_result = Vector128Util.LoadUnsafe(in MemoryMarshal.GetReference(from));
41
42 xmm_temp1 = LoadKey(key, 0x10, xmm_key_shuf_mask);
43 xmm_temp2 = LoadKey(key, 0x20, xmm_key_shuf_mask);
44 xmm_temp3 = LoadKey(key, 0x30, xmm_key_shuf_mask);
45 xmm_temp4 = LoadKey(key, 0x40, xmm_key_shuf_mask);
46
47 xmm_result = Sse2.Xor(xmm_result, xmm_temp1);
48 xmm_result = Aes.Decrypt(xmm_result, xmm_temp2);
49 xmm_result = Aes.Decrypt(xmm_result, xmm_temp3);
50 xmm_result = Aes.Decrypt(xmm_result, xmm_temp4);
51
52 xmm_temp1 = LoadKey(key, 0x50, xmm_key_shuf_mask);
53 xmm_temp2 = LoadKey(key, 0x60, xmm_key_shuf_mask);
54 xmm_temp3 = LoadKey(key, 0x70, xmm_key_shuf_mask);
55 xmm_temp4 = LoadKey(key, 0x80, xmm_key_shuf_mask);
56
57 xmm_result = Aes.Decrypt(xmm_result, xmm_temp1);
58 xmm_result = Aes.Decrypt(xmm_result, xmm_temp2);
59 xmm_result = Aes.Decrypt(xmm_result, xmm_temp3);
60 xmm_result = Aes.Decrypt(xmm_result, xmm_temp4);
61
62 xmm_temp1 = LoadKey(key, 0x90, xmm_key_shuf_mask);
63 xmm_temp2 = LoadKey(key, 0xa0, xmm_key_shuf_mask);
64 xmm_temp3 = LoadKey(key, 0x00, xmm_key_shuf_mask);
65
66 if (key.Length == 44)
67 {
68 goto doLast;
69 }
70
71 xmm_result = Aes.Decrypt(xmm_result, xmm_temp1);
72 xmm_result = Aes.Decrypt(xmm_result, xmm_temp2);
73
74 xmm_temp1 = LoadKey(key, 0xb0, xmm_key_shuf_mask);
75 xmm_temp2 = LoadKey(key, 0xc0, xmm_key_shuf_mask);
76
77 if (key.Length == 52)
78 {
79 goto doLast;
80 }
81
82 xmm_result = Aes.Decrypt(xmm_result, xmm_temp1);
83 xmm_result = Aes.Decrypt(xmm_result, xmm_temp2);
84
85 xmm_temp1 = LoadKey(key, 0xd0, xmm_key_shuf_mask);
86 xmm_temp2 = LoadKey(key, 0xe0, xmm_key_shuf_mask);
87
88 doLast:;
89 xmm_result = Aes.Decrypt(xmm_result, xmm_temp1);
90 xmm_result = Aes.Decrypt(xmm_result, xmm_temp2);
91 xmm_result = Aes.DecryptLast(xmm_result, xmm_temp3);
92 xmm_result.CopyTo(to);
93 }
94
103 [MethodImpl(MethodImplOptions.AggressiveInlining)]
104 public static void EncryptBlock(ReadOnlySpan<byte> from, Span<byte> to, ReadOnlySpan<int> key)
105 {
106 // ext\openjdk\hotspot\src\cpu\x86\vm\stubGenerator_x86_32.cpp:2189-2277
107 Vector128<byte> xmm_temp1, xmm_temp2, xmm_temp3, xmm_temp4;
108 var xmm_key_shuf_mask = Vector128Util.LoadUnsafe(in MemoryMarshal.GetReference(KeyShuffleMask)).AsByte();
109 var xmm_result = Vector128Util.LoadUnsafe(in MemoryMarshal.GetReference(from));
110
111 xmm_temp1 = LoadKey(key, 0x00, xmm_key_shuf_mask);
112 xmm_result = Sse2.Xor(xmm_result, xmm_temp1);
113
114 xmm_temp1 = LoadKey(key, 0x10, xmm_key_shuf_mask);
115 xmm_temp2 = LoadKey(key, 0x20, xmm_key_shuf_mask);
116 xmm_temp3 = LoadKey(key, 0x30, xmm_key_shuf_mask);
117 xmm_temp4 = LoadKey(key, 0x40, xmm_key_shuf_mask);
118
119 xmm_result = Aes.Encrypt(xmm_result, xmm_temp1);
120 xmm_result = Aes.Encrypt(xmm_result, xmm_temp2);
121 xmm_result = Aes.Encrypt(xmm_result, xmm_temp3);
122 xmm_result = Aes.Encrypt(xmm_result, xmm_temp4);
123
124 xmm_temp1 = LoadKey(key, 0x50, xmm_key_shuf_mask);
125 xmm_temp2 = LoadKey(key, 0x60, xmm_key_shuf_mask);
126 xmm_temp3 = LoadKey(key, 0x70, xmm_key_shuf_mask);
127 xmm_temp4 = LoadKey(key, 0x80, xmm_key_shuf_mask);
128
129 xmm_result = Aes.Encrypt(xmm_result, xmm_temp1);
130 xmm_result = Aes.Encrypt(xmm_result, xmm_temp2);
131 xmm_result = Aes.Encrypt(xmm_result, xmm_temp3);
132 xmm_result = Aes.Encrypt(xmm_result, xmm_temp4);
133
134 xmm_temp1 = LoadKey(key, 0x90, xmm_key_shuf_mask);
135 xmm_temp2 = LoadKey(key, 0xa0, xmm_key_shuf_mask);
136
137 if (key.Length == 44)
138 {
139 goto doLast;
140 }
141
142 xmm_result = Aes.Encrypt(xmm_result, xmm_temp1);
143 xmm_result = Aes.Encrypt(xmm_result, xmm_temp2);
144
145 xmm_temp1 = LoadKey(key, 0xb0, xmm_key_shuf_mask);
146 xmm_temp2 = LoadKey(key, 0xc0, xmm_key_shuf_mask);
147
148 if (key.Length == 52)
149 {
150 goto doLast;
151 }
152
153 xmm_result = Aes.Encrypt(xmm_result, xmm_temp1);
154 xmm_result = Aes.Encrypt(xmm_result, xmm_temp2);
155
156 xmm_temp1 = LoadKey(key, 0xd0, xmm_key_shuf_mask);
157 xmm_temp2 = LoadKey(key, 0xe0, xmm_key_shuf_mask);
158
159 doLast:;
160 xmm_result = Aes.Encrypt(xmm_result, xmm_temp1);
161 xmm_result = Aes.EncryptLast(xmm_result, xmm_temp2);
162 xmm_result.CopyTo(to);
163 }
164
165 [MethodImpl(MethodImplOptions.AggressiveInlining)]
166 public static Vector128<byte> LoadKey(ReadOnlySpan<int> key, nuint offset, Vector128<byte>? shuffle_mask = null)
167 {
168 var xmm_temp = Vector128Util.LoadUnsafe(in Unsafe.As<int, byte>(ref MemoryMarshal.GetReference(key)), offset);
169 shuffle_mask ??= Vector128Util.LoadUnsafe(in MemoryMarshal.GetReference(KeyShuffleMask)).AsByte();
170
171 return Ssse3.Shuffle(xmm_temp, shuffle_mask.Value);
172 }
173
174 }
175
176}
177
178#endif