| 1 | #ifndef _CRYPTO1_BS_H |
| 2 | #define _CRYPTO1_BS_H |
| 3 | #include <stdbool.h> |
| 4 | #include <stdint.h> |
| 5 | #include <stdio.h> |
| 6 | #include <string.h> |
| 7 | #include <stdlib.h> |
| 8 | #include <unistd.h> |
| 9 | |
| 10 | // bitslice type |
| 11 | // while AVX supports 256 bit vector floating point operations, we need integer operations for boolean logic |
| 12 | // same for AVX2 and 512 bit vectors |
| 13 | // using larger vectors works but seems to generate more register pressure |
| 14 | #if defined(__AVX2__) |
| 15 | #define MAX_BITSLICES 256 |
| 16 | #elif defined(__AVX__) |
| 17 | #define MAX_BITSLICES 128 |
| 18 | #elif defined(__SSE2__) |
| 19 | #define MAX_BITSLICES 128 |
| 20 | #else |
| 21 | #define MAX_BITSLICES 64 |
| 22 | #endif |
| 23 | |
| 24 | #define VECTOR_SIZE (MAX_BITSLICES/8) |
| 25 | typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t; |
| 26 | typedef union { |
| 27 | bitslice_value_t value; |
| 28 | uint64_t bytes64[MAX_BITSLICES/64]; |
| 29 | uint8_t bytes[MAX_BITSLICES/8]; |
| 30 | } bitslice_t; |
| 31 | |
| 32 | // filter function (f20) |
| 33 | // sourced from ``Wirelessly Pickpocketing a Mifare Classic Card'' by Flavio Garcia, Peter van Rossum, Roel Verdult and Ronny Wichers Schreur |
| 34 | #define f20a(a,b,c,d) (((a|b)^(a&d))^(c&((a^b)|d))) |
| 35 | #define f20b(a,b,c,d) (((a&b)|c)^((a^b)&(c|d))) |
| 36 | #define f20c(a,b,c,d,e) ((a|((b|e)&(d^e)))^((a^(b&d))&((c^d)|(b&e)))) |
| 37 | |
| 38 | #define crypto1_bs_f20(s) \ |
| 39 | f20c(f20a((s[47- 9].value), (s[47-11].value), (s[47-13].value), (s[47-15].value)), \ |
| 40 | f20b((s[47-17].value), (s[47-19].value), (s[47-21].value), (s[47-23].value)), \ |
| 41 | f20b((s[47-25].value), (s[47-27].value), (s[47-29].value), (s[47-31].value)), \ |
| 42 | f20a((s[47-33].value), (s[47-35].value), (s[47-37].value), (s[47-39].value)), \ |
| 43 | f20b((s[47-41].value), (s[47-43].value), (s[47-45].value), (s[47-47].value))) |
| 44 | |
| 45 | // bit indexing |
| 46 | #define get_bit(n, word) ((word >> (n)) & 1) |
| 47 | #define get_vector_bit(slice, value) get_bit(slice&0x3f, value.bytes64[slice>>6]) |
| 48 | |
| 49 | // constant ones/zeroes |
| 50 | bitslice_t bs_ones; |
| 51 | bitslice_t bs_zeroes; |
| 52 | |
| 53 | // size of crypto-1 state |
| 54 | #define STATE_SIZE 48 |
| 55 | // size of nonce to be decrypted |
| 56 | #define KEYSTREAM_SIZE 32 |
| 57 | // size of first uid^nonce byte to be rolled back to the initial key |
| 58 | #define ROLLBACK_SIZE 8 |
| 59 | // number of nonces required to test to cover entire 48-bit state |
| 60 | // I would have said it's 12... but bla goes with 100, so I do too |
| 61 | #define NONCE_TESTS 100 |
| 62 | |
| 63 | // state pointer management |
| 64 | extern __thread bitslice_t states[KEYSTREAM_SIZE+STATE_SIZE]; |
| 65 | extern __thread bitslice_t * restrict state_p; |
| 66 | |
| 67 | // rewind to the point a0, at which KEYSTREAM_SIZE more bits can be generated |
| 68 | #define crypto1_bs_rewind_a0() (state_p = &states[KEYSTREAM_SIZE]) |
| 69 | |
| 70 | // bitsliced bytewise parity |
| 71 | #define bitsliced_byte_parity(n) (n[0].value ^ n[1].value ^ n[2].value ^ n[3].value ^ n[4].value ^ n[5].value ^ n[6].value ^ n[7].value) |
| 72 | |
| 73 | // 48-bit crypto-1 states are normally represented using 64-bit values |
| 74 | typedef union { |
| 75 | uint64_t value; |
| 76 | uint8_t bytes[8]; |
| 77 | } state_t; |
| 78 | |
| 79 | // endianness conversion |
| 80 | #define rev32(word) (((word & 0xff) << 24) | (((word >> 8) & 0xff) << 16) | (((word >> 16) & 0xff) << 8) | (((word >> 24) & 0xff))) |
| 81 | #define rev64(x) (rev32(x)<<32|(rev32((x>>32)))) |
| 82 | #define rev_state_t rev64 |
| 83 | |
| 84 | // crypto-1 functions |
| 85 | const bitslice_value_t crypto1_bs_bit(const bitslice_value_t input, const bool is_encrypted); |
| 86 | const bitslice_value_t crypto1_bs_lfsr_rollback(const bitslice_value_t input, const bool is_encrypted); |
| 87 | |
| 88 | // initialization functions |
| 89 | void crypto1_bs_init(); |
| 90 | |
| 91 | // conversion functions |
| 92 | void crypto1_bs_bitslice_value32(uint32_t value, bitslice_t bitsliced_value[], size_t bit_len); |
| 93 | void crypto1_bs_convert_states(bitslice_t bitsliced_states[], state_t regular_states[]); |
| 94 | |
| 95 | // debug print |
| 96 | void crypto1_bs_print_states(bitslice_t *bitsliced_states); |
| 97 | |
| 98 | #endif // _CRYPTO1_BS_H |
| 99 | |