rework cryptorf

This commit is contained in:
Philippe Teuwen 2020-08-19 21:38:21 +02:00
commit 9ade745f07
16 changed files with 693 additions and 985 deletions

View file

@ -20,12 +20,10 @@
*
* Modifed Iceman, 2020
*/
#include "defines.h"
#include "cryptolib.h"
#include "util.h"
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <inttypes.h>
#include <iostream>
#include <vector>
#include <map>
@ -34,9 +32,15 @@
#include <thread> // std::thread
#include <atomic>
#include <mutex>
#include "cryptolib.h"
#include "util.h"
using namespace std;
#ifdef _MSC_VER
// avoid scanf warnings in Visual Studio
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define inline __inline
#endif
@ -127,13 +131,13 @@ typedef struct {
nibble b1r;
nibble b1s;
bool invalid;
byte_t Gc[8];
uint8_t Gc[8];
}cs_t;
typedef cs_t* pcs;
typedef struct {
byte_t addition;
byte_t out;
uint8_t addition;
uint8_t out;
} lookup_entry;
enum cipher_state_side {
@ -147,21 +151,21 @@ void print_cs(const char* text,pcs s) {
printf("%s",text);
for(pos=6;pos>=0;pos--)
printf(" %02x",(byte_t)(s->l>>(pos*5))&0x1f);
printf(" %02x",(uint8_t)(s->l>>(pos*5))&0x1f);
printf(" |");
for(pos=6;pos>=0;pos--)
printf(" %02x",(byte_t)(s->m>>(pos*7))&0x7f);
printf(" %02x",(uint8_t)(s->m>>(pos*7))&0x7f);
printf(" |");
for(pos=4;pos>=0;pos--)
printf(" %02x",(byte_t)(s->r>>(pos*5))&0x1f);
printf(" %02x",(uint8_t)(s->r>>(pos*5))&0x1f);
printf("\n");
}
static inline byte_t mod(byte_t a, byte_t m) {
static inline uint8_t mod(uint8_t a, uint8_t m) {
// Just return the input when this is less or equal than the modular value
if (a<m) return a;
@ -173,13 +177,13 @@ static inline byte_t mod(byte_t a, byte_t m) {
}
/*
static inline byte_t bit_rotate_l(byte_t a, byte_t n_bits) {
static inline uint8_t bit_rotate_l(uint8_t a, uint8_t n_bits) {
// Rotate value a with the length of n_bits only 1 time
byte_t mask = (1 << n_bits) - 1;
uint8_t mask = (1 << n_bits) - 1;
return ((a << 1) | (a >> (n_bits - 1))) & mask;
}
static inline byte_t bit_rotate_r(byte_t a, byte_t n_bits) {
static inline uint8_t bit_rotate_r(uint8_t a, uint8_t n_bits) {
return ((a >> 1) | ((a&1) << (n_bits - 1)));
}
*/
@ -189,14 +193,14 @@ static inline byte_t bit_rotate_r(byte_t a, byte_t n_bits) {
#define BIT_ROR(a) (((a) >> 1) | (((a) & 1) << 4))
static byte_t lookup_left_substraction[0x400];
static byte_t lookup_right_subtraction[0x400];
static uint8_t lookup_left_substraction[0x400];
static uint8_t lookup_right_subtraction[0x400];
static lookup_entry lookup_left[0x100000];
static lookup_entry lookup_right[0x8000];
static byte_t left_addition[0x100000];
static uint8_t left_addition[0x100000];
static inline void init_lookup_left() {
byte_t b3, b6, temp;
uint8_t b3, b6, temp;
int i, index;
for (i = 0; i <0x400; i++){
@ -215,7 +219,7 @@ static inline void init_lookup_left() {
}
static inline void init_lookup_right() {
byte_t b16, b18, temp;
uint8_t b16, b18, temp;
int i, index;
for(i = 0; i <0x400; i++) {
@ -231,8 +235,8 @@ static inline void init_lookup_right() {
static void init_lookup_left_substraction() {
for(int index = 0; index < 0x400 ; index++) {
byte_t b3 = (index >> 5 & 0x1f);
byte_t bx = (index & 0x1f);
uint8_t b3 = (index >> 5 & 0x1f);
uint8_t bx = (index & 0x1f);
//lookup_left_substraction[index] = bit_rotate_r(mod((bx+0x1f)-b3,0x1f),5);
lookup_left_substraction[index] = BIT_ROR( mod((bx + 0x1F) - b3, 0x1F));
@ -242,18 +246,18 @@ static void init_lookup_left_substraction() {
static void init_lookup_right_substraction() {
for(int index = 0; index < 0x400 ; index++) {
int b16 = (index >>5);
byte_t bx = (index & 0x1f);
uint8_t bx = (index & 0x1f);
lookup_right_subtraction[index] = mod((bx + 0x1F) - b16, 0x1F);
}
}
static inline void previous_left(byte_t in, vector<cs_t> *candidate_states) {
static inline void previous_left(uint8_t in, vector<cs_t> *candidate_states) {
pcs state;
size_t size = candidate_states->size();
for(size_t pos=0; pos<size; pos++) {
state = &((*candidate_states)[pos]);
byte_t bx = (byte_t)((state->l >> 30) & 0x1f);
uint8_t bx = (uint8_t)((state->l >> 30) & 0x1f);
unsigned b3 = (unsigned)(state->l >> 5) & 0x3e0;
state->l = (state->l << 5);
@ -268,7 +272,7 @@ static inline void previous_left(byte_t in, vector<cs_t> *candidate_states) {
state->l ^= (((uint64_t)in & 0x1f) << 20);
}
} else {
byte_t b6 = lookup_left_substraction[b3|bx];
uint8_t b6 = lookup_left_substraction[b3|bx];
state->l = (state->l & 0x7ffffffe0ull) | b6;
state->l ^= (((uint64_t)in & 0x1f) << 20);
@ -282,13 +286,13 @@ static inline void previous_left(byte_t in, vector<cs_t> *candidate_states) {
}
}
static inline void previous_right(byte_t in, vector<cs_t> *candidate_states) {
static inline void previous_right(uint8_t in, vector<cs_t> *candidate_states) {
pcs state;
size_t size = candidate_states->size();
for(size_t pos=0; pos<size; pos++) {
state = &((*candidate_states)[pos]);
byte_t bx = (byte_t)((state->r >> 20) & 0x1f);
uint8_t bx = (uint8_t)((state->r >> 20) & 0x1f);
unsigned b16 = (unsigned)(state->r & 0x3e0);//(state->buffer_r >> 10) & 0x1f;
state->r = (state->r << 5);
@ -303,7 +307,7 @@ static inline void previous_right(byte_t in, vector<cs_t> *candidate_states) {
state->r ^= (((uint64_t)in & 0xf8) << 12);
}
} else {
byte_t b18 = lookup_right_subtraction[b16|bx];
uint8_t b18 = lookup_right_subtraction[b16|bx];
state->r = (state->r & 0x1ffffe0ull) | b18;
state->r ^= (((uint64_t)in & 0xf8) << 12);
//state->b_right = ((b14^b17) & 0x0f);
@ -318,7 +322,7 @@ static inline void previous_right(byte_t in, vector<cs_t> *candidate_states) {
}
}
static inline byte_t next_left_fast(byte_t in, uint64_t* left) {
static inline uint8_t next_left_fast(uint8_t in, uint64_t* left) {
if (in)
*left ^= ((in & 0x1f) << 20);
@ -327,9 +331,9 @@ static inline byte_t next_left_fast(byte_t in, uint64_t* left) {
return lookup->out;
}
static inline byte_t next_left_ksbyte(uint64_t* left) {
static inline uint8_t next_left_ksbyte(uint64_t* left) {
lookup_entry* lookup;
byte_t bt;
uint8_t bt;
*left = (((*left) >> 5)| ((uint64_t)left_addition[((*left) & 0xf801f)] << 30));
lookup = &(lookup_left[((*left) & 0xf801f)]);
@ -342,17 +346,17 @@ static inline byte_t next_left_ksbyte(uint64_t* left) {
return bt;
}
static inline byte_t next_right_fast(byte_t in, uint64_t* right) {
static inline uint8_t next_right_fast(uint8_t in, uint64_t* right) {
if (in) *right ^= ((in&0xf8) << 12);
lookup_entry* lookup = &(lookup_right[((*right) & 0x7c1f)]);
*right = (((*right) >> 5) | (lookup->addition << 20));
return lookup->out;
}
static inline void sm_left_mask(const byte_t* ks, byte_t* mask, uint64_t rstate) {
static inline void sm_left_mask(const uint8_t* ks, uint8_t* mask, uint64_t rstate) {
for (uint8_t pos = 0; pos < 16; pos++) {
next_right_fast(0,&rstate);
byte_t bt = next_right_fast(0,&rstate) << 4;
uint8_t bt = next_right_fast(0,&rstate) << 4;
next_right_fast(0,&rstate);
bt |= next_right_fast(0,&rstate);
@ -375,13 +379,13 @@ uint32_t g_num_cpus = std::thread::hardware_concurrency();
static void ice_sm_right_thread(
uint8_t offset,
uint8_t skips,
const byte_t* ks,
const uint8_t* ks,
map<uint64_t,uint64_t>* bincstates,
byte_t* mask
uint8_t* mask
) {
byte_t tmp_mask[16];
byte_t bt;
uint8_t tmp_mask[16];
uint8_t bt;
for (uint64_t counter = offset; counter < 0x2000000; counter += skips) {
// Reset the current bitcount of correct bits
@ -444,7 +448,7 @@ static void ice_sm_right_thread(
}
}
}
static uint32_t ice_sm_right(const byte_t* ks, byte_t* mask, vector<uint64_t>* pcrstates) {
static uint32_t ice_sm_right(const uint8_t* ks, uint8_t* mask, vector<uint64_t>* pcrstates) {
uint32_t g_num_cpus = std::thread::hardware_concurrency();
map<uint64_t,uint64_t> bincstates;
@ -478,14 +482,14 @@ static uint32_t ice_sm_right(const byte_t* ks, byte_t* mask, vector<uint64_t>* p
static void ice_sm_left_thread(
uint8_t offset,
uint8_t skips,
const byte_t* ks,
const uint8_t* ks,
map<uint64_t, cs_t>* bincstates,
byte_t* mask
uint8_t* mask
) {
size_t pos, bits;
byte_t correct_bits[16];
byte_t bt;
uint8_t correct_bits[16];
uint8_t bt;
lookup_entry* lookup;
// Reset and initialize the cryptostate and vector
@ -561,7 +565,7 @@ static void ice_sm_left_thread(
}
}
static void ice_sm_left(const byte_t* ks, byte_t* mask, vector<cs_t>* pcstates) {
static void ice_sm_left(const uint8_t* ks, uint8_t* mask, vector<cs_t>* pcstates) {
uint32_t g_num_cpus = std::thread::hardware_concurrency();
@ -589,12 +593,12 @@ static void ice_sm_left(const byte_t* ks, byte_t* mask, vector<cs_t>* pcstates)
reverse(pcstates->begin(), pcstates->end());
}
static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector<uint64_t>* pcrstates) {
byte_t tmp_mask[16];
static inline uint32_t sm_right(const uint8_t* ks, uint8_t* mask, vector<uint64_t>* pcrstates) {
uint8_t tmp_mask[16];
size_t pos, bits, bit, topbits;
map<uint64_t,uint64_t> bincstates;
map<uint64_t,uint64_t>::iterator it;
byte_t bt;
uint8_t bt;
topbits = 0;
@ -658,7 +662,7 @@ static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector<uint64_t>
}
static inline void previous_all_input(vector<cs_t> *pcstates, uint32_t gc_byte_index, cipher_state_side css) {
byte_t btGc,in;
uint8_t btGc,in;
vector<cs_t> ncstates;
vector<cs_t> prev_ncstates;
vector<cs_t>::iterator it,itnew;
@ -691,7 +695,7 @@ static inline void previous_all_input(vector<cs_t> *pcstates, uint32_t gc_byte_i
*pcstates = prev_ncstates;
}
static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const byte_t* Q, vector<cs_t>* pcstates) {
static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const uint8_t* Q, vector<cs_t>* pcstates) {
vector<cs_t>::iterator it;
vector<cs_t> csl_cand;
map<uint64_t,uint64_t> matchbox;
@ -743,13 +747,13 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c
}
}
static inline void sm_left(const byte_t* ks, byte_t* mask, vector<cs_t>* pcstates) {
static inline void sm_left(const uint8_t* ks, uint8_t* mask, vector<cs_t>* pcstates) {
map<uint64_t, cs_t> bincstates;
map<uint64_t, cs_t>::iterator it;
uint64_t counter, lstate;
size_t pos, bits;
byte_t correct_bits[16];
byte_t bt;
uint8_t correct_bits[16];
uint8_t bt;
cs_t state;
lookup_entry* lookup;
@ -831,7 +835,7 @@ static inline void sm_left(const byte_t* ks, byte_t* mask, vector<cs_t>* pcstate
reverse(pcstates->begin(), pcstates->end());
}
static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const byte_t* Q, vector<cs_t>* pcstates) {
static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const uint8_t* Q, vector<cs_t>* pcstates) {
vector<cs_t> csl_cand,csl_search;
vector<cs_t>::iterator itsearch,itcand;
map<uint64_t,uint64_t> matchbox;
@ -937,14 +941,14 @@ static void ice_compare(
uint8_t skips,
vector<uint64_t>* candidates,
crypto_state_t* ostate,
byte_t *Ci,
byte_t *Q,
byte_t *Ch,
byte_t *Ci_1
uint8_t *Ci,
uint8_t *Q,
uint8_t *Ch,
uint8_t *Ci_1
) {
byte_t Gc_chk[8];
byte_t Ch_chk[ 8];
byte_t Ci_1_chk[ 8];
uint8_t Gc_chk[8];
uint8_t Ch_chk[ 8];
uint8_t Ci_1_chk[ 8];
for (std::size_t i = offset; i < candidates->size(); i += skips) {
if (key_found.load(std::memory_order_relaxed))
@ -976,27 +980,27 @@ int main(int argc, const char* argv[]) {
vector<cs_t>::iterator it;
uint32_t rbits;
// byte_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81};
// byte_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// byte_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
// byte_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78};
byte_t Gc[ 8];
byte_t Ci[ 8];
byte_t Q[ 8];
byte_t Ch[ 8];
byte_t Ci_1[ 8];
// uint8_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81};
// uint8_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// uint8_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
// uint8_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78};
uint8_t Gc[ 8];
uint8_t Ci[ 8];
uint8_t Q[ 8];
uint8_t Ch[ 8];
uint8_t Ci_1[ 8];
// byte_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87};
// byte_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// byte_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80};
// uint8_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87};
// uint8_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// uint8_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80};
byte_t ks[16];
byte_t mask[16];
uint8_t ks[16];
uint8_t mask[16];
ui64 nCi; // Card random
ui64 nQ; // Reader random
ui64 nCh; // Reader challange
ui64 nCi_1; // Card anwser
uint64_t nCi; // Card random
uint64_t nQ; // Reader random
uint64_t nCh; // Reader challange
uint64_t nCi_1; // Card anwser
if ((argc != 2) && (argc != 5)) {
printf("SecureMemory recovery - (c) Radboud University Nijmegen\n\n");
@ -1010,7 +1014,7 @@ int main(int argc, const char* argv[]) {
// Check if this is a simulation
if (argc == 2) {
// Generate random values for the key and randoms
srand((uint32_t)time(null));
srand((uint32_t)time(NULL));
for (pos = 0; pos<8; pos++) {
Gc[pos] = rand();
Ci[pos] = rand();
@ -1019,10 +1023,10 @@ int main(int argc, const char* argv[]) {
sm_auth(Gc,Ci,Q,Ch,Ci_1,&ostate);
printf(" Gc: "); print_bytes(Gc,8);
} else {
sscanf(argv[1],"%016llx",&nCi); num_to_bytes(nCi,8,Ci);
sscanf(argv[2],"%016llx",&nQ); num_to_bytes(nQ,8,Q);
sscanf(argv[3],"%016llx",&nCh); num_to_bytes(nCh,8,Ch);
sscanf(argv[4],"%016llx",&nCi_1); num_to_bytes(nCi_1,8,Ci_1);
sscanf(argv[1],"%016" SCNx64,&nCi); num_to_bytes(nCi,8,Ci);
sscanf(argv[2],"%016" SCNx64,&nQ); num_to_bytes(nQ,8,Q);
sscanf(argv[3],"%016" SCNx64,&nCh); num_to_bytes(nCh,8,Ch);
sscanf(argv[4],"%016" SCNx64,&nCi_1); num_to_bytes(nCi_1,8,Ci_1);
printf(" Gc: unknown\n");
}
@ -1080,7 +1084,7 @@ int main(int argc, const char* argv[]) {
for (itrstates = rstates.begin(); itrstates != rstates.end(); ++itrstates) {
rstate_after_gc = *itrstates;
sm_left_mask(ks, mask, rstate_after_gc);
printf("Using the state from the top-right bin: " _YELLOW_("0x%07llx")"\n", (unsigned long long)rstate_after_gc);
printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc);
search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates);
printf("Found " _YELLOW_("%lu")" right candidates using the meet-in-the-middle attack\n", crstates.size());