7#if defined(USE_SIMULATOR)
13const Simulator::PACKey Simulator::kPACKeyIB = {0xeebb163b474e04c8,
14 0x5267ac6fc280fb7c, 1};
18uint64_t GetNibble(uint64_t in_data,
int position) {
22uint64_t PACCellShuffle(uint64_t in_data) {
23 static int in_positions[16] = {52, 24, 44, 0, 28, 48, 4, 40,
24 32, 12, 56, 20, 8, 36, 16, 60};
25 uint64_t out_data = 0;
26 for (
int i = 0;
i < 16; ++
i) {
27 out_data |= GetNibble(in_data, in_positions[
i]) << (4 *
i);
32uint64_t PACCellInvShuffle(uint64_t in_data) {
33 static int in_positions[16] = {12, 24, 48, 36, 56, 44, 4, 16,
34 32, 52, 28, 8, 20, 0, 40, 60};
35 uint64_t out_data = 0;
36 for (
int i = 0;
i < 16; ++
i) {
37 out_data |= GetNibble(in_data, in_positions[
i]) << (4 *
i);
42uint64_t RotCell(uint64_t in_cell,
int amount) {
43 DCHECK((amount >= 1) && (amount <= 3));
46 uint8_t temp = in_cell << 4 | in_cell;
47 return static_cast<uint64_t
>((temp >> (4 - amount)) & 0xf);
50uint64_t PACMult(uint64_t s_input) {
55 uint64_t s_output = 0;
57 for (
int i = 0;
i < 4; ++
i) {
58 uint8_t s12 = (s_input >> (4 * (
i + 12))) & 0xf;
59 uint8_t s8 = (s_input >> (4 * (
i + 8))) & 0xf;
60 uint8_t s4 = (s_input >> (4 * (
i + 4))) & 0xf;
61 uint8_t s0 = (s_input >> (4 * (
i + 0))) & 0xf;
63 t0 = RotCell(s8, 1) ^ RotCell(s4, 2) ^ RotCell(s0, 1);
64 t1 = RotCell(s12, 1) ^ RotCell(s4, 1) ^ RotCell(s0, 2);
65 t2 = RotCell(s12, 2) ^ RotCell(s8, 1) ^ RotCell(s0, 1);
66 t3 = RotCell(s12, 1) ^ RotCell(s8, 2) ^ RotCell(s4, 1);
68 s_output |=
static_cast<uint64_t
>(t3) << (4 * (
i + 0));
69 s_output |=
static_cast<uint64_t
>(t2) << (4 * (
i + 4));
70 s_output |=
static_cast<uint64_t
>(t1) << (4 * (
i + 8));
71 s_output |=
static_cast<uint64_t
>(t0) << (4 * (
i + 12));
76uint64_t PACSub(uint64_t t_input) {
77 uint64_t t_output = 0;
78 uint8_t substitutions[16] = {0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
79 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa};
80 for (
int i = 0;
i < 16; ++
i) {
81 unsigned index = ((t_input >> (4 *
i)) & 0xf);
82 t_output |=
static_cast<uint64_t
>(substitutions[
index]) << (4 *
i);
87uint64_t PACInvSub(uint64_t t_input) {
88 uint64_t t_output = 0;
89 uint8_t substitutions[16] = {0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
90 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3};
91 for (
int i = 0;
i < 16; ++
i) {
92 unsigned index = ((t_input >> (4 *
i)) & 0xf);
93 t_output |=
static_cast<uint64_t
>(substitutions[
index]) << (4 *
i);
98uint64_t TweakCellInvRot(uint64_t in_cell) {
99 uint64_t out_cell = 0;
100 out_cell |= (in_cell & 0x7) << 1;
101 out_cell |= (in_cell & 0x1) ^ ((in_cell >> 3) & 0x1);
105uint64_t TweakInvShuffle(uint64_t in_data) {
106 uint64_t out_data = 0;
107 out_data |= TweakCellInvRot(in_data >> 48) << 0;
108 out_data |= ((in_data >> 52) & 0xf) << 4;
109 out_data |= ((in_data >> 20) & 0xff) << 8;
110 out_data |= ((in_data >> 0) & 0xff) << 16;
111 out_data |= TweakCellInvRot(in_data >> 8) << 24;
112 out_data |= ((in_data >> 12) & 0xf) << 28;
113 out_data |= TweakCellInvRot(in_data >> 28) << 32;
114 out_data |= TweakCellInvRot(in_data >> 60) << 36;
115 out_data |= TweakCellInvRot(in_data >> 56) << 40;
116 out_data |= TweakCellInvRot(in_data >> 16) << 44;
117 out_data |= ((in_data >> 32) & 0xfff) << 48;
118 out_data |= TweakCellInvRot(in_data >> 44) << 60;
122uint64_t TweakCellRot(uint64_t in_cell) {
123 uint64_t out_cell = 0;
124 out_cell |= ((in_cell & 0x1) ^ ((in_cell >> 1) & 0x1)) << 3;
125 out_cell |= (in_cell >> 0x1) & 0x7;
129uint64_t TweakShuffle(uint64_t in_data) {
130 uint64_t out_data = 0;
131 out_data |= ((in_data >> 16) & 0xff) << 0;
132 out_data |= TweakCellRot(in_data >> 24) << 8;
133 out_data |= ((in_data >> 28) & 0xf) << 12;
134 out_data |= TweakCellRot(in_data >> 44) << 16;
135 out_data |= ((in_data >> 8) & 0xff) << 20;
136 out_data |= TweakCellRot(in_data >> 32) << 28;
137 out_data |= ((in_data >> 48) & 0xfff) << 32;
138 out_data |= TweakCellRot(in_data >> 60) << 44;
139 out_data |= TweakCellRot(in_data >> 0) << 48;
140 out_data |= ((in_data >> 4) & 0xf) << 52;
141 out_data |= TweakCellRot(in_data >> 40) << 56;
142 out_data |= TweakCellRot(in_data >> 36) << 60;
152uint64_t Simulator::ComputePAC(uint64_t data, uint64_t context, PACKey
key) {
153 uint64_t key0 =
key.high;
154 uint64_t key1 =
key.low;
155 const uint64_t RC[5] = {0x0000000000000000, 0x13198a2e03707344,
156 0xa4093822299f31d0, 0x082efa98ec4e6c89,
158 const uint64_t Alpha = 0xc0ac29B7c97c50dd;
160 uint64_t modk0 = ((key0 & 0x1) << 63) | ((key0 >> 2) << 1) |
161 ((key0 >> 63) ^ ((key0 >> 1) & 0x1));
162 uint64_t running_mod =
context;
163 uint64_t working_val = data ^ key0;
165 for (
int i = 0;
i < 5; ++
i) {
166 round_key = key1 ^ running_mod;
167 working_val ^= round_key;
168 working_val ^= RC[
i];
170 working_val = PACCellShuffle(working_val);
171 working_val = PACMult(working_val);
173 working_val = PACSub(working_val);
174 running_mod = TweakShuffle(running_mod);
177 round_key = modk0 ^ running_mod;
178 working_val ^= round_key;
179 working_val = PACCellShuffle(working_val);
180 working_val = PACMult(working_val);
181 working_val = PACSub(working_val);
182 working_val = PACCellShuffle(working_val);
183 working_val = PACMult(working_val);
185 working_val = PACCellInvShuffle(working_val);
186 working_val = PACInvSub(working_val);
187 working_val = PACMult(working_val);
188 working_val = PACCellInvShuffle(working_val);
190 working_val ^= running_mod;
192 for (
int i = 0;
i < 5; ++
i) {
193 working_val = PACInvSub(working_val);
195 working_val = PACMult(working_val);
196 working_val = PACCellInvShuffle(working_val);
198 running_mod = TweakInvShuffle(running_mod);
199 round_key = key1 ^ running_mod;
200 working_val ^= RC[4 -
i];
201 working_val ^= round_key;
202 working_val ^= Alpha;
205 return working_val ^ modk0;
211uint64_t Simulator::CalculatePACMask(uint64_t ptr, PointerType type,
int ttbr) {
212 int bottom_pac_bit = GetBottomPACBit(ptr, ttbr);
213 int top_pac_bit = GetTopPACBit(ptr, type);
219uint64_t Simulator::AuthPAC(uint64_t ptr, uint64_t context, PACKey
key,
223 uint64_t pac_mask = CalculatePACMask(ptr, type, (ptr >> 55) & 1);
224 uint64_t original_ptr =
225 ((ptr &
kTTBRMask) == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
227 uint64_t pac = ComputePAC(original_ptr, context,
key);
229 uint64_t error_code = UINT64_C(1) <<
key.number;
230 if ((pac & pac_mask) == (ptr & pac_mask)) {
233 int error_lsb = GetTopPACBit(ptr, type) - 2;
234 uint64_t error_mask = UINT64_C(0x3) << error_lsb;
235 if (
v8_flags.sim_abort_on_bad_auth) {
236 FATAL(
"Pointer authentication failure.");
238 return (original_ptr & ~error_mask) | (error_code << error_lsb);
242uint64_t Simulator::AddPAC(uint64_t ptr, uint64_t context, PACKey
key,
244 int top_pac_bit = GetTopPACBit(ptr, type);
246 DCHECK(HasTBI(ptr, type));
247 int ttbr = (ptr >> 55) & 1;
248 uint64_t pac_mask = CalculatePACMask(ptr, type, ttbr);
249 uint64_t ext_ptr = (ttbr == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
251 uint64_t pac = ComputePAC(ext_ptr, context,
key);
255 if (((ptr & (pac_mask |
kTTBRMask)) != 0x0) &&
256 ((~ptr & (pac_mask |
kTTBRMask)) != 0x0)) {
257 pac ^= UINT64_C(1) << (top_pac_bit - 1);
260 uint64_t ttbr_shifted =
static_cast<uint64_t
>(ttbr) << 55;
261 return (pac & pac_mask) | ttbr_shifted | (ptr & ~pac_mask);
264uint64_t Simulator::StripPAC(uint64_t ptr, PointerType type) {
265 uint64_t pac_mask = CalculatePACMask(ptr, type, (ptr >> 55) & 1);
266 return ((ptr &
kTTBRMask) == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
constexpr uint64_t kTTBRMask
V8_EXPORT_PRIVATE FlagValues v8_flags
uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x)
#define DCHECK(condition)