// bitslice a value void crypto1_bs_bitslice_value32(uint32_t value, bitslice_t bitsliced_value[], size_t bit_len){ // load nonce bytes with unswapped endianness size_t bit_idx; for(bit_idx = 0; bit_idx < bit_len; bit_idx++){ bool bit = get_bit(bit_len-1-bit_idx, rev32(value)); if(bit){ bitsliced_value[bit_idx].value = bs_ones.value; } else { bitsliced_value[bit_idx].value = bs_zeroes.value; } } }
/***** BMP read *****/ int bmread(char *fn, int *x, int *y, unsigned char *buf3[3]) { unsigned char bmHead[14]; unsigned char bmInfo[40]; unsigned char pbuf[1024]; int i,j,k; int xx,yy,x0,y0; FILE *fp; unsigned char *b0; int bits, ofbits; if(NULL==(fp=fopen(fn,"rb"))) { //printf("no file %s:",fn); return(1); } fread(&bmHead,1,14,fp); fread(&bmInfo,1,40,fp); xx=rev32(&bmInfo[4]); yy=rev32(&bmInfo[8]); bits=rev16(&bmInfo[14]); //fprintf(stderr, "wx = %d wy = %d\n",xx,yy); if(!buf3[0])buf3[0]=malloc(xx*yy); if(!buf3[1])buf3[1]=malloc(xx*yy); if(!buf3[2])buf3[2]=malloc(xx*yy); ofbits = rev32(&bmHead[10]); if(bits==24){ fseek(fp, ofbits, SEEK_SET); b0=malloc(xx*yy*3); fread(b0,1,3*xx*yy,fp); fclose(fp); j=0; for(y0=yy-1;y0>=0;y0--){ for(x0=0;x0<xx;x0++){ i=y0*xx+x0; k=b0[j];j++; buf3[2][i]=k; k=b0[j];j++; buf3[1][i]=k; k=b0[j];j++; buf3[0][i]=k; }} free(b0); *x=xx;*y=yy; return(0); } if(bits==4){ b0=malloc(xx*yy/2); k=ofbits -54; k/=4; fread(pbuf,1,k*4,fp); fread(b0,1,xx*yy/2,fp); fclose(fp); j=0; for(y0=yy-1;y0>=0;y0--){ for(x0=0;x0<xx;x0++){i=y0*xx+x0; if(j&1) k=b0[j/2]&0x0f; else k=b0[j/2]>>4; j++; buf3[0][i]=pbuf[ k*4+2 ]; buf3[1][i]=pbuf[ k*4+1 ]; buf3[2][i]=pbuf[ k*4+0 ]; }} free(b0); *x=xx;*y=yy; return(0); }
// note that PRN is not created with security in mind - just using a simple seed BOOL hitag2_crypto_auth(BYTE *response, BYTE *hexkey) { BYTE tmp[65], tmphex[9]; unsigned long long key; unsigned long uid; unsigned long initvec; // use default transport key if none specified if(strlen(hexkey) == 0) hexkey= HITAG2_KEY_DEFAULT; // get UID for initialisation if(!hitag2_get_uid(tmp)) return FALSE; // convert to numerics for crypto routines uid= hexreversetoulong(tmp); key= hexreversetoulonglong(hexkey); // generate 32 bit PRN for challenge srand(Led_Count); initvec= rand(); initvec <<= 16; initvec += rand(); // prepare to send IV in the clear to tag ulongtobinstring(tmp, initvec, 32); // convert IV to MSB for crypto routines binstringtohex(tmphex, tmp); initvec= hexreversetoulong(tmphex); // initialise crypto hitag2_init(&Hitag_Crypto_State, rev64(key), rev32(uid), rev32(initvec)); // send inverse of 1st 32bits of keystream to tag for authentication ulongtobinstring(tmp + 32, hitag2_crypt(0xFFFFFFFF, 32), 32); // restart the tag & auth process if(!hitag2_get_uid(TmpBuff)) return FALSE; // wait for RX->TX period, then send PRN+secret if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) return FALSE; // skip 1/2 bit to synchronise manchester HW_Skip_Bits= 1; // get 37 bit response: sync + config byte + 24 bit TAG pwd if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 37) { // check sync bits if (memcmp(tmp, Hitag2Sync, 5) != 0) return FALSE; CryptoActive= TRUE; // decrypt binarraytohex(response, tmp + 5, 32); return hitag2_hex_crypt(response, response); } return FALSE; }
void scp256_unpack(scp256 *r, const unsigned char x[32]){ unsigned char t[32]; rev32(t, x); scp256_from32bytes(r, t); }
void scp256_pack(unsigned char x[32], scp256 *r){ unsigned char t[32]; scp256_to32bytes(t, r); rev32(x, t); }