1 #include <assert.h> 2 #include "pauth.h" 3 4 static int x; 5 6 int main() 7 { 8 int *p0 = &x, *p1, *p2, *p3; 9 unsigned long salt = 0; 10 int pac_feature = get_pac_feature(); 11 12 /* 13 * Exit if no PAuth or FEAT_FPAC, which will SIGILL on AUTDA failure 14 * rather than return an error for us to check below. 15 */ 16 if (pac_feature == 0 || pac_feature >= 4) { 17 return 0; 18 } 19 20 /* 21 * With TBI enabled and a 48-bit VA, there are 7 bits of auth, and so 22 * a 1/128 chance of auth = pac(ptr,key,salt) producing zero. 23 * Find a salt that creates auth != 0. 24 */ 25 do { 26 salt++; 27 asm("pacda %0, %1" : "=r"(p1) : "r"(salt), "0"(p0)); 28 } while (p0 == p1); 29 30 /* 31 * This pac must fail, because the input pointer bears an encryption, 32 * and so is not properly extended within bits [55:47]. This will 33 * toggle bit 54 in the output... 34 */ 35 asm("pacda %0, %1" : "=r"(p2) : "r"(salt), "0"(p1)); 36 37 /* ... so that the aut must fail, setting bit 53 in the output ... */ 38 asm("autda %0, %1" : "=r"(p3) : "r"(salt), "0"(p2)); 39 40 /* ... which means this equality must not hold. */ 41 assert(p3 != p0); 42 return 0; 43 } 44