void testencrypt(uint8_t *block, uint8_t *key){ cli_putstr("\r\n==testy-encrypt==\r\n key: "); cli_hexdump(key,10); cli_putstr("\r\n plain: "); cli_hexdump(block,8); skipjack_enc(block,key); cli_putstr("\r\n crypt: "); cli_hexdump(block,8); }
int main() { iu8 inp[8] = { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }; iu8 key[10] = { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; iu8 enc[8], dec[8]; iu8 chk[8] = { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 }; iu8 tab[10][256]; long i; clock_t elapsed; memcpy( enc, inp, 8 ); skipjack_enc( enc, key ); printf((memcmp(enc, chk, 8) == 0) ? "encryption OK!\n" : "encryption failure!\n"); memcpy( dec, enc, 8 ); skipjack_dec( dec, key ); printf((memcmp(dec, inp, 8) == 0) ? "decryption OK!\n" : "decryption failure!\n"); elapsed = -clock(); for (i = 0; i < 1000000L; i++) { skipjack_enc( enc, key ); } elapsed += clock(); printf ("elapsed time: %.1f s.\n", (float)elapsed/CLOCKS_PER_SEC); return 0; }
int test_enc(const void *buffer, void *key){ uint8_t data[8]; int r; memcpy(data, buffer, 8); skipjack_enc(data, key); cli_putstr_P(PSTR(" key = ")); cli_hexdump(key, 10); cli_putstr_P(PSTR(" plaintext = ")); cli_hexdump(buffer, 8); cli_putstr_P(PSTR(" ciphertext = ")); cli_hexdump(data, 8); skipjack_dec(data, key); r = memcmp(data, buffer, 8); cli_putstr_P(PSTR(" decrypt: ")); if(r){ cli_putstr_P(PSTR("fail")); }else{ cli_putstr_P(PSTR("ok")); } return r; }
void tftp_handle_packet(void) { #ifdef SKIPJACK_SUPPORT unsigned char key[10] = CONF_TFTP_KEY; #endif /* * overwrite udp connection information (i.e. take from incoming packet) */ uip_ipaddr_copy(uip_udp_conn->ripaddr, BUF->srcipaddr); uip_udp_conn->rport = BUF->srcport; /* * care for incoming tftp packet now ... */ uint16_t i, base; struct tftp_hdr *pk = uip_appdata; switch(HTONS(pk->type)) { #ifndef TFTP_UPLOAD_ONLY /* * streaming data back to the client (download) ... */ case 1: /* read request */ uip_udp_conn->appstate.tftp.download = 1; uip_udp_conn->appstate.tftp.transfered = 0; uip_udp_conn->appstate.tftp.finished = 0; bootload_delay = 0; /* Stop bootloader. */ goto send_data; case 4: /* acknowledgement */ if(uip_udp_conn->appstate.tftp.download != 1) goto error_out; if(HTONS(pk->u.ack.block) < uip_udp_conn->appstate.tftp.transfered || (HTONS(pk->u.ack.block) > uip_udp_conn->appstate.tftp.transfered + 1)) goto error_out; /* ack out of order */ uip_udp_conn->appstate.tftp.transfered = HTONS(pk->u.ack.block); send_data: if(uip_udp_conn->appstate.tftp.finished) { bootload_delay = CONF_BOOTLOAD_DELAY; /* Restart bootloader. */ return; /* nothing more to do */ } pk->type = HTONS(3); /* data packet */ pk->u.data.block = HTONS(uip_udp_conn->appstate.tftp.transfered + 1); base = 512 * uip_udp_conn->appstate.tftp.transfered; #if FLASHEND == 0xFFFF if(uip_udp_conn->appstate.tftp.transfered && base == 0) /* base overflowed ! */ #else if(base > FLASHEND) #endif { uip_udp_send(4); /* send empty packet to finish transfer */ uip_udp_conn->appstate.tftp.finished = 1; return; } for(i = 0; i < 512; i ++) #if defined(SKIPJACK_SUPPORT) pk->u.data.data[i + 8] = #else pk->u.data.data[i] = #endif pgm_read_byte_near(base + i); #if defined(SKIPJACK_SUPPORT) for(i = 0; i < 8; i ++) { /* prepend 8 bytes IV */ pk->u.data.data[i] = rand() & 0xFF; /* prepare to append CBC-MAC, i.e. initialize to zero, * so we can XOR the CBC carry and afterwards encrypt. */ pk->u.data.data[i + 512 + 8] = 0; } /* perform skipjack-cbc encryption: * leave the first block (iv) untouched, * encrypt blocks 1..64 (data) * then encrypt block 65 (cbc-mac) */ for(i = 1; i <= 65; i ++) { /* carry cbc forward (xor) */ for(int j = 0; j < 8; j ++) { pk->u.data.data[(i << 3) + j] ^= pk->u.data.data[(i << 3) + j - 8]; } /* encrypt data */ skipjack_enc(&pk->u.data.data[i << 3], key); } uip_udp_send(4 + 16 + 512); #else /* !SKIPJACK_SUPPORT */ uip_udp_send(4 + 512); #endif uip_udp_conn->appstate.tftp.transfered ++; break; #endif /* not TFTP_UPLOAD_ONLY */ /* * streaming data from the client (firmware upload) ... */ case 2: /* write request */ uip_udp_conn->appstate.tftp.download = 0; uip_udp_conn->appstate.tftp.transfered = 0; uip_udp_conn->appstate.tftp.finished = 0; pk->u.ack.block = HTONS(0); goto send_ack; case 3: /* data packet */ bootload_delay = 0; /* Stop bootloader. */ if(uip_udp_conn->appstate.tftp.download != 0) goto error_out; if(HTONS(pk->u.ack.block) < uip_udp_conn->appstate.tftp.transfered) goto error_out; /* too early */ if(HTONS(pk->u.ack.block) == uip_udp_conn->appstate.tftp.transfered) goto send_ack; /* already handled */ if(HTONS(pk->u.ack.block) > uip_udp_conn->appstate.tftp.transfered + 1) goto error_out; /* too late */ #ifdef SKIPJACK_SUPPORT /* the packet looks like this: * 0..3 <packet preamble> * 4..11 IV <- pk->u.data.data[0] * 12..522 DATA (maybe shorter) --,- "decrypted" * 523..530 CBC-MAC --' */ for(i = 1; i < (uip_datalen() - 4) >> 3; i ++) { /* decrypt block (we actually encrypted, since used decrypt) */ unsigned char buf[8]; memmove(buf, pk->u.data.data + (i << 3), 8); skipjack_enc(buf, key); /* now XOR the decrypted data onto the block before, * which is still encrypted, i.e. our "cbc carry" */ for(int j = 0; j < 8; j ++) pk->u.data.data[(i << 3) + j - 8] ^= buf[j]; } uip_datalen() -= 16; /* lie about packet len */ /* verify our CBC-MAC (XOR'd to zeroes), which should reside right * after the last datablock, which we've moved 8 bytes to the left */ for(i = 0; i < 8; i ++) if(pk->u.data.data[i + uip_datalen() - 4]) goto error_out; #endif /* SKIPJACK_SUPPORT */ base = 512 * (HTONS(pk->u.ack.block) - 1); for(i = uip_datalen() - 4; i < 512; i ++) pk->u.data.data[i] = 0xFF; /* EOF reached, init rest */ for(i = 0; i < 512 / SPM_PAGESIZE; i ++) flash_page(base + i * SPM_PAGESIZE, pk->u.data.data + i * SPM_PAGESIZE); if(uip_datalen() < 512 + 4) { uip_udp_conn->appstate.tftp.finished = 1; # ifdef TFTPOMATIC_SUPPORT bootload_delay = 1; /* ack, then start app */ # else bootload_delay = CONF_BOOTLOAD_DELAY; /* Restart bootloader. */ # endif } uip_udp_conn->appstate.tftp.transfered = HTONS(pk->u.ack.block); send_ack: pk->type = HTONS(4); uip_udp_send(4); /* send ack */ break; /* * protocol errors */ error_out: case 5: /* error */ default: pk->type = HTONS(5); /* data packet */ pk->u.error.code = HTONS(0); /* undefined error code */ pk->u.error.msg[0] = 0; /* yes, really expressive */ uip_udp_send(5); break; } }