1*0957b409SSimon J. Gerraty /* 2*0957b409SSimon J. Gerraty * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3*0957b409SSimon J. Gerraty * 4*0957b409SSimon J. Gerraty * Permission is hereby granted, free of charge, to any person obtaining 5*0957b409SSimon J. Gerraty * a copy of this software and associated documentation files (the 6*0957b409SSimon J. Gerraty * "Software"), to deal in the Software without restriction, including 7*0957b409SSimon J. Gerraty * without limitation the rights to use, copy, modify, merge, publish, 8*0957b409SSimon J. Gerraty * distribute, sublicense, and/or sell copies of the Software, and to 9*0957b409SSimon J. Gerraty * permit persons to whom the Software is furnished to do so, subject to 10*0957b409SSimon J. Gerraty * the following conditions: 11*0957b409SSimon J. Gerraty * 12*0957b409SSimon J. Gerraty * The above copyright notice and this permission notice shall be 13*0957b409SSimon J. Gerraty * included in all copies or substantial portions of the Software. 14*0957b409SSimon J. Gerraty * 15*0957b409SSimon J. Gerraty * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16*0957b409SSimon J. Gerraty * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17*0957b409SSimon J. Gerraty * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18*0957b409SSimon J. Gerraty * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19*0957b409SSimon J. Gerraty * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20*0957b409SSimon J. Gerraty * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21*0957b409SSimon J. Gerraty * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22*0957b409SSimon J. Gerraty * SOFTWARE. 23*0957b409SSimon J. Gerraty */ 24*0957b409SSimon J. Gerraty 25*0957b409SSimon J. Gerraty #include "inner.h" 26*0957b409SSimon J. Gerraty 27*0957b409SSimon J. Gerraty /* see inner.h */ 28*0957b409SSimon J. Gerraty void 29*0957b409SSimon J. Gerraty br_aes_ct64_bitslice_invSbox(uint64_t *q) 30*0957b409SSimon J. Gerraty { 31*0957b409SSimon J. Gerraty /* 32*0957b409SSimon J. Gerraty * See br_aes_ct_bitslice_invSbox(). This is the natural extension 33*0957b409SSimon J. Gerraty * to 64-bit registers. 34*0957b409SSimon J. Gerraty */ 35*0957b409SSimon J. Gerraty uint64_t q0, q1, q2, q3, q4, q5, q6, q7; 36*0957b409SSimon J. Gerraty 37*0957b409SSimon J. Gerraty q0 = ~q[0]; 38*0957b409SSimon J. Gerraty q1 = ~q[1]; 39*0957b409SSimon J. Gerraty q2 = q[2]; 40*0957b409SSimon J. Gerraty q3 = q[3]; 41*0957b409SSimon J. Gerraty q4 = q[4]; 42*0957b409SSimon J. Gerraty q5 = ~q[5]; 43*0957b409SSimon J. Gerraty q6 = ~q[6]; 44*0957b409SSimon J. Gerraty q7 = q[7]; 45*0957b409SSimon J. Gerraty q[7] = q1 ^ q4 ^ q6; 46*0957b409SSimon J. Gerraty q[6] = q0 ^ q3 ^ q5; 47*0957b409SSimon J. Gerraty q[5] = q7 ^ q2 ^ q4; 48*0957b409SSimon J. Gerraty q[4] = q6 ^ q1 ^ q3; 49*0957b409SSimon J. Gerraty q[3] = q5 ^ q0 ^ q2; 50*0957b409SSimon J. Gerraty q[2] = q4 ^ q7 ^ q1; 51*0957b409SSimon J. Gerraty q[1] = q3 ^ q6 ^ q0; 52*0957b409SSimon J. Gerraty q[0] = q2 ^ q5 ^ q7; 53*0957b409SSimon J. Gerraty 54*0957b409SSimon J. Gerraty br_aes_ct64_bitslice_Sbox(q); 55*0957b409SSimon J. Gerraty 56*0957b409SSimon J. Gerraty q0 = ~q[0]; 57*0957b409SSimon J. Gerraty q1 = ~q[1]; 58*0957b409SSimon J. Gerraty q2 = q[2]; 59*0957b409SSimon J. Gerraty q3 = q[3]; 60*0957b409SSimon J. Gerraty q4 = q[4]; 61*0957b409SSimon J. Gerraty q5 = ~q[5]; 62*0957b409SSimon J. Gerraty q6 = ~q[6]; 63*0957b409SSimon J. Gerraty q7 = q[7]; 64*0957b409SSimon J. Gerraty q[7] = q1 ^ q4 ^ q6; 65*0957b409SSimon J. Gerraty q[6] = q0 ^ q3 ^ q5; 66*0957b409SSimon J. Gerraty q[5] = q7 ^ q2 ^ q4; 67*0957b409SSimon J. Gerraty q[4] = q6 ^ q1 ^ q3; 68*0957b409SSimon J. Gerraty q[3] = q5 ^ q0 ^ q2; 69*0957b409SSimon J. Gerraty q[2] = q4 ^ q7 ^ q1; 70*0957b409SSimon J. Gerraty q[1] = q3 ^ q6 ^ q0; 71*0957b409SSimon J. Gerraty q[0] = q2 ^ q5 ^ q7; 72*0957b409SSimon J. Gerraty } 73*0957b409SSimon J. Gerraty 74*0957b409SSimon J. Gerraty static void 75*0957b409SSimon J. Gerraty add_round_key(uint64_t *q, const uint64_t *sk) 76*0957b409SSimon J. Gerraty { 77*0957b409SSimon J. Gerraty int i; 78*0957b409SSimon J. Gerraty 79*0957b409SSimon J. Gerraty for (i = 0; i < 8; i ++) { 80*0957b409SSimon J. Gerraty q[i] ^= sk[i]; 81*0957b409SSimon J. Gerraty } 82*0957b409SSimon J. Gerraty } 83*0957b409SSimon J. Gerraty 84*0957b409SSimon J. Gerraty static void 85*0957b409SSimon J. Gerraty inv_shift_rows(uint64_t *q) 86*0957b409SSimon J. Gerraty { 87*0957b409SSimon J. Gerraty int i; 88*0957b409SSimon J. Gerraty 89*0957b409SSimon J. Gerraty for (i = 0; i < 8; i ++) { 90*0957b409SSimon J. Gerraty uint64_t x; 91*0957b409SSimon J. Gerraty 92*0957b409SSimon J. Gerraty x = q[i]; 93*0957b409SSimon J. Gerraty q[i] = (x & (uint64_t)0x000000000000FFFF) 94*0957b409SSimon J. Gerraty | ((x & (uint64_t)0x000000000FFF0000) << 4) 95*0957b409SSimon J. Gerraty | ((x & (uint64_t)0x00000000F0000000) >> 12) 96*0957b409SSimon J. Gerraty | ((x & (uint64_t)0x000000FF00000000) << 8) 97*0957b409SSimon J. Gerraty | ((x & (uint64_t)0x0000FF0000000000) >> 8) 98*0957b409SSimon J. Gerraty | ((x & (uint64_t)0x000F000000000000) << 12) 99*0957b409SSimon J. Gerraty | ((x & (uint64_t)0xFFF0000000000000) >> 4); 100*0957b409SSimon J. Gerraty } 101*0957b409SSimon J. Gerraty } 102*0957b409SSimon J. Gerraty 103*0957b409SSimon J. Gerraty static inline uint64_t 104*0957b409SSimon J. Gerraty rotr32(uint64_t x) 105*0957b409SSimon J. Gerraty { 106*0957b409SSimon J. Gerraty return (x << 32) | (x >> 32); 107*0957b409SSimon J. Gerraty } 108*0957b409SSimon J. Gerraty 109*0957b409SSimon J. Gerraty static void 110*0957b409SSimon J. Gerraty inv_mix_columns(uint64_t *q) 111*0957b409SSimon J. Gerraty { 112*0957b409SSimon J. Gerraty uint64_t q0, q1, q2, q3, q4, q5, q6, q7; 113*0957b409SSimon J. Gerraty uint64_t r0, r1, r2, r3, r4, r5, r6, r7; 114*0957b409SSimon J. Gerraty 115*0957b409SSimon J. Gerraty q0 = q[0]; 116*0957b409SSimon J. Gerraty q1 = q[1]; 117*0957b409SSimon J. Gerraty q2 = q[2]; 118*0957b409SSimon J. Gerraty q3 = q[3]; 119*0957b409SSimon J. Gerraty q4 = q[4]; 120*0957b409SSimon J. Gerraty q5 = q[5]; 121*0957b409SSimon J. Gerraty q6 = q[6]; 122*0957b409SSimon J. Gerraty q7 = q[7]; 123*0957b409SSimon J. Gerraty r0 = (q0 >> 16) | (q0 << 48); 124*0957b409SSimon J. Gerraty r1 = (q1 >> 16) | (q1 << 48); 125*0957b409SSimon J. Gerraty r2 = (q2 >> 16) | (q2 << 48); 126*0957b409SSimon J. Gerraty r3 = (q3 >> 16) | (q3 << 48); 127*0957b409SSimon J. Gerraty r4 = (q4 >> 16) | (q4 << 48); 128*0957b409SSimon J. Gerraty r5 = (q5 >> 16) | (q5 << 48); 129*0957b409SSimon J. Gerraty r6 = (q6 >> 16) | (q6 << 48); 130*0957b409SSimon J. Gerraty r7 = (q7 >> 16) | (q7 << 48); 131*0957b409SSimon J. Gerraty 132*0957b409SSimon J. Gerraty q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr32(q0 ^ q5 ^ q6 ^ r0 ^ r5); 133*0957b409SSimon J. Gerraty q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); 134*0957b409SSimon J. Gerraty q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr32(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); 135*0957b409SSimon J. Gerraty q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr32(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); 136*0957b409SSimon J. Gerraty q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); 137*0957b409SSimon J. Gerraty q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); 138*0957b409SSimon J. Gerraty q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr32(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); 139*0957b409SSimon J. Gerraty q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr32(q4 ^ q5 ^ q7 ^ r4 ^ r7); 140*0957b409SSimon J. Gerraty } 141*0957b409SSimon J. Gerraty 142*0957b409SSimon J. Gerraty /* see inner.h */ 143*0957b409SSimon J. Gerraty void 144*0957b409SSimon J. Gerraty br_aes_ct64_bitslice_decrypt(unsigned num_rounds, 145*0957b409SSimon J. Gerraty const uint64_t *skey, uint64_t *q) 146*0957b409SSimon J. Gerraty { 147*0957b409SSimon J. Gerraty unsigned u; 148*0957b409SSimon J. Gerraty 149*0957b409SSimon J. Gerraty add_round_key(q, skey + (num_rounds << 3)); 150*0957b409SSimon J. Gerraty for (u = num_rounds - 1; u > 0; u --) { 151*0957b409SSimon J. Gerraty inv_shift_rows(q); 152*0957b409SSimon J. Gerraty br_aes_ct64_bitslice_invSbox(q); 153*0957b409SSimon J. Gerraty add_round_key(q, skey + (u << 3)); 154*0957b409SSimon J. Gerraty inv_mix_columns(q); 155*0957b409SSimon J. Gerraty } 156*0957b409SSimon J. Gerraty inv_shift_rows(q); 157*0957b409SSimon J. Gerraty br_aes_ct64_bitslice_invSbox(q); 158*0957b409SSimon J. Gerraty add_round_key(q, skey); 159*0957b409SSimon J. Gerraty } 160