1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2021 NXP 3 */ 4 #include <stdio.h> 5 #include <inttypes.h> 6 #include <unistd.h> 7 #include <rte_pmd_dpaa2.h> 8 9 static unsigned int sbox(unsigned int x) 10 { 11 unsigned int a, b, c, d; 12 unsigned int oa, ob, oc, od; 13 14 a = x & 0x1; 15 b = (x >> 1) & 0x1; 16 c = (x >> 2) & 0x1; 17 d = (x >> 3) & 0x1; 18 19 oa = ((a & ~b & ~c & d) | (~a & b) | (~a & ~c & ~d) | (b & c)) & 0x1; 20 ob = ((a & ~b & d) | (~a & c & ~d) | (b & ~c)) & 0x1; 21 oc = ((a & ~b & c) | (a & ~b & ~d) | (~a & b & ~d) | (~a & c & ~d) | 22 (b & c & d)) & 0x1; 23 od = ((a & ~b & c) | (~a & b & ~c) | (a & b & ~d) | (~a & c & d)) & 0x1; 24 25 return ((od << 3) | (oc << 2) | (ob << 1) | oa); 26 } 27 28 static unsigned int sbox_tbl[16]; 29 30 static int pbox_tbl[16] = {5, 9, 0, 13, 31 7, 2, 11, 14, 32 1, 4, 12, 8, 33 3, 15, 6, 10 }; 34 35 static unsigned int mix_tbl[8][16]; 36 37 static unsigned int stage(unsigned int input) 38 { 39 int sbox_out = 0; 40 int pbox_out = 0; 41 int i; 42 43 /* mix */ 44 input ^= input >> 16; /* xor lower */ 45 input ^= input << 16; /* move original lower to upper */ 46 47 for (i = 0; i < 32; i += 4) /* sbox stage */ 48 sbox_out |= (sbox_tbl[(input >> i) & 0xf]) << i; 49 50 /* permutation */ 51 for (i = 0; i < 16; i++) 52 pbox_out |= ((sbox_out >> i) & 0x10001) << pbox_tbl[i]; 53 54 return pbox_out; 55 } 56 57 static unsigned int fast_stage(unsigned int input) 58 { 59 int pbox_out = 0; 60 int i; 61 62 /* mix */ 63 input ^= input >> 16; /* xor lower */ 64 input ^= input << 16; /* move original lower to upper */ 65 66 for (i = 0; i < 32; i += 4) /* sbox stage */ 67 pbox_out |= mix_tbl[i >> 2][(input >> i) & 0xf]; 68 69 return pbox_out; 70 } 71 72 static unsigned int fast_hash32(unsigned int x) 73 { 74 int i; 75 76 for (i = 0; i < 4; i++) 77 x = fast_stage(x); 78 return x; 79 } 80 81 static unsigned int 82 byte_crc32(unsigned char data /* new byte for the crc calculation */, 83 unsigned old_crc /* crc result of the last iteration */) 84 { 85 int i; 86 unsigned int crc, polynom = 0xedb88320; 87 /* the polynomial is built on the reversed version of 88 * the CRC polynomial with out the x64 element. 89 */ 90 91 crc = old_crc; 92 for (i = 0; i < 8; i++, data >>= 1) 93 crc = (crc >> 1) ^ (((crc ^ data) & 0x1) ? polynom : 0); 94 /* xor with polynomial is lsb of crc^data is 1 */ 95 96 return crc; 97 } 98 99 static unsigned int crc32_table[256]; 100 101 static void init_crc32_table(void) 102 { 103 int i; 104 105 for (i = 0; i < 256; i++) 106 crc32_table[i] = byte_crc32((unsigned char)i, 0LL); 107 } 108 109 static unsigned int 110 crc32_string(unsigned char *data, 111 int size, unsigned int old_crc) 112 { 113 unsigned int crc; 114 int i; 115 116 crc = old_crc; 117 for (i = 0; i < size; i++) 118 crc = (crc >> 8) ^ crc32_table[(crc ^ data[i]) & 0xff]; 119 120 return crc; 121 } 122 123 static void hash_init(void) 124 { 125 init_crc32_table(); 126 int i, j; 127 128 for (i = 0; i < 16; i++) 129 sbox_tbl[i] = sbox(i); 130 131 for (i = 0; i < 32; i += 4) 132 for (j = 0; j < 16; j++) { 133 /* (a,b) 134 * (b,a^b)=(X,Y) 135 * (X^Y,X) 136 */ 137 unsigned int input = (0x88888888 ^ (8 << i)) | (j << i); 138 139 input ^= input << 16; /* (X^Y,Y) */ 140 input ^= input >> 16; /* (X^Y,X) */ 141 mix_tbl[i >> 2][j] = stage(input); 142 } 143 } 144 145 uint32_t rte_pmd_dpaa2_get_tlu_hash(uint8_t *data, int size) 146 { 147 static int init; 148 149 if (~init) 150 hash_init(); 151 init = 1; 152 return fast_hash32(crc32_string(data, size, 0x0)); 153 } 154