bruteforce.c
1 // run with gcc -Wall -g -o bruteforce ../sbt.c bruteforce.c && ./bruteforce 2 3 #include "../sbt.h" 4 #include <stdint.h> 5 #include <string.h> 6 #include <stdio.h> 7 #include <stdarg.h> 8 9 void dump(const uint8_t *p, const size_t len, const char* msg, ...) { 10 va_list args; 11 va_start(args, msg); 12 vfprintf(stdout,msg, args); 13 va_end(args); 14 fprintf(stdout," "); 15 for(size_t i=0;i<len;i++) 16 fprintf(stdout,"%02x", p[i]); 17 fprintf(stdout,"\n"); 18 } 19 20 static int check(const uint8_t *ct, const size_t len, const int last, const uint8_t *cb) { 21 const uint8_t validchars[0x40] = { 22 0, 1, 1, 1, 1, 1, 1, 1, 23 1, 1, 1, 1, 1, 1, 1, 1, 24 1, 1, 1, 1, 1, 1, 1, 1, 25 1, 1, 1, 0, 0, 0, 0, 0, 26 1, 0, 0, 0, 0, 0, 0, 0, 27 0, 0, 0, 0, 1, 1, 1, 0, 28 1, 1, 1, 1, 1, 1, 1, 1, 29 1, 1, 0, 0, 0, 0, 0, 0}; 30 for(unsigned i=0;i<8 && i<len;i++) { 31 uint8_t pt=(ct[i]^cb[i]) & 0x3f; 32 if(!validchars[pt] && !(last && i>=len-2 && pt==0x1f)) return 0; 33 } 34 return 1; 35 } 36 37 void test_enc(void) { 38 const uint8_t __attribute__((nonstring)) key[15]="\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"; 39 uint8_t __attribute__((nonstring)) plaintext[11]="2PADDING..\xfe"; 40 uint8_t out[((sizeof(plaintext) / 3) + 1) * 6 + 6 + 1]={0}; 41 int i; 42 for(i=0;plaintext[i]!=0xfe;i++) { 43 plaintext[i]=(plaintext[i] & 0x3f); 44 } 45 //uint8_t prevcb0[5]={0xe6, 0x3c, 0x32, 0x65, 0x9a}; 46 uint8_t prevcb0[5]={0x24, 0x40, 0xe3, 0x5e, 0x2f}; 47 sbt_encrypt(plaintext, key, prevcb0, out); 48 printf("%s\n",out); 49 50 for(i=0;out[i]!=0xfe;i++) { 51 out[i]=(out[i] & 0x3f); 52 } 53 sbt_decrypt(out, key); 54 } 55 56 int main(void) { 57 // known test vector validation 58 const uint8_t __attribute__((nonstring)) key[15]="\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"; 59 const uint8_t __attribute__((nonstring)) tv[]="BAMLK GAFFJ EOBCP EEIMP CDAFP\xfe"; 60 uint8_t ctx[sizeof tv-1]={0}; 61 int i; 62 for(i=0;tv[i]!=0xfe;i++) { 63 ctx[i]=(tv[i] & 0x3f); 64 } 65 ctx[i]=tv[i]; 66 dump(ctx, sizeof ctx, "ct"); 67 sbt_decrypt(ctx, key); 68 69 test_enc(); 70 // testing ct length 1..16, how it decrypts, due to the scrambling, 71 // it gets always padded to multiples of 3 by appending 1 or 2 '_' 72 //for(int i=1;i<17;i++) { 73 // uint8_t plaintext[17]="\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"; 74 // for(int j=0;j<i;j++) plaintext[j]=(j+1); 75 // uint8_t out[((i / 3) + 1) * 6 + 6 + 2]; 76 // dump(plaintext, i+1, "pt"); 77 // encrypt(plaintext, key, out); 78 // out[sizeof out -1] = 0; 79 // fprintf(stderr,"ct: %s\n", out); 80 // for(int j=0;out[j]!=0xfe;j++) { 81 // out[j]=(out[j] & 0x3f); 82 // } 83 // decrypt(out, key); 84 //} 85 //return 0; 86 87 const uint8_t nonce[3]={2,1,0xd}; 88 const uint8_t ciphertext[] = {40, 49, 9, 4, 35, 58, 16, 49, 89 38, 36, 52, 33}; 90 unsigned long finds=0; 91 for(unsigned long long candidate=0;candidate < (1UL<<32);candidate++) { 92 if(candidate % (1UL<<24) == 0) { 93 fprintf(stderr, "candidate %llx found so far: %ld\n", candidate, finds); 94 } 95 uint8_t state[8] = { 0xf5, 0xc0, 0x7a, 0x10, 0x8a, 0xaf, 0x17, 0xcf }, 96 msgkey[7] = {0x19, 0xbe, 0xa3, 0x03, 0x59, 0x51, 0xf5}, 97 cipherblock[8]; 98 99 uint8_t pt[sizeof ciphertext + 1]={0}; 100 101 //msgkey[0] = candidate & 0xff; 102 msgkey[0] = candidate >> 24; 103 msgkey[1] = candidate >> 16; 104 msgkey[2] = candidate >> 8; 105 msgkey[3] = candidate & 0xff; 106 107 unsigned blockctr = 0; 108 int found=1; 109 do { 110 sbt_core(state,msgkey,cipherblock); 111 if(check(ciphertext + (blockctr*8), sizeof(ciphertext) - (8*blockctr), blockctr == sizeof(ciphertext)/8, cipherblock)==0) { 112 found=0; 113 break; 114 } 115 //dump(state, sizeof state, "state"); 116 //dump(msgkey, sizeof msgkey, "msgkey is valid"); 117 //state bfb7b6ef1a8c5090 118 //msgkey f5c07a108aaf17 119 for(unsigned i=0;i<8 && i < (sizeof(ciphertext) - (8*blockctr));i++) { 120 uint8_t tmp = ((ciphertext[i+blockctr*8]^cipherblock[i]) & 0x3f); 121 //fprintf(stderr, "%c", (tmp<32)?(0x40|tmp):tmp); 122 pt[blockctr*8 + i]=(tmp<32)?(0x40|tmp):tmp; 123 } 124 if(blockctr==0) { 125 memcpy(state + 5, nonce, 3); 126 } 127 } while(blockctr++ < sizeof(ciphertext)/8); 128 if(found) { 129 finds++; 130 printf("%s", pt); 131 dump(msgkey,7, " cv"); 132 } 133 } 134 fprintf(stderr, "total finds %ld\n", finds); 135 return 0; 136 }