void WaspAES::ECBDecrypt(uint8_t *original_data,uint16_t size,uint16_t keySize){ // In ECB mode is separated from message in blocks of 16 bytes and cipher each one individually uint16_t index,index2; index = 0; index2 = 0; while(index<size){ for (int i =0; i<16;i++){ block_data[i]=original_data[index]; index++; } // Decrypt switch(keySize){ case 128: aes128_dec(block_data, &ctx128); break; case 192: aes192_dec(block_data, &ctx192); break; case 256: aes256_dec(block_data, &ctx256); break; } for (int i = 0; i<16;i++){ original_data[index2] = block_data[i]; index2++; } } }
int do_aes_internal(unsigned char bEncryptFlag,unsigned char * pIN, int nINLen, unsigned char *pOUT, int * pOUTLen) { int nRet = -1; int nAESblkLen=16; aes256_ctx_t ctx; unsigned char blk_buf[64]; int nLoadLen = nAESblkLen; //check if(!pIN || !nINLen || !pOUT || !pOUTLen) return nRet; //clear memory first? memset(pOUT,0,nINLen); memset(&ctx,0,sizeof(ctx)); memcpy(ctx.key,g_AESkey,14*sizeof(aes_roundkey_t)); *pOUTLen = 0; do{ memset(blk_buf,0,sizeof(blk_buf)); memcpy(blk_buf,pIN+*pOUTLen,nLoadLen); if(bEncryptFlag) aes256_enc(blk_buf,&ctx); else aes256_dec(blk_buf,&ctx); memcpy(pOUT+*pOUTLen,blk_buf,nLoadLen); *pOUTLen += nLoadLen; if(*pOUTLen + nLoadLen > nINLen) nLoadLen = nINLen - *pOUTLen; }while(*pOUTLen != nINLen); nRet = 0; return nRet; }
// decrypt single 128bit block. data is assumed to be 16 uint8_t's // key is assumed to be 256bit thus 32 uint8_t's void aes256_dec_single(const uint8_t* key, void* data){ aes256_ctx_t ctx; aes256_init(key, &ctx); aes256_dec(data, &ctx); }
void WaspAES::CBCDecrypt(uint8_t *original_data,uint16_t size, uint8_t *InitialVector,uint16_t keySize){ /////////////////////////// // In CBC mode the message is divided into blocks of 16 bytes, to 1 block // Applied to the XOR and calculated its block cipher with block // Encryption XOR obtained is applied to the second data block in clear // And the result is encrypted with AES given, the result will be the 2nd block // Encryption, so on. // // This function is: // 1 - separated data block of 16 bytes, // 2 - XOR operation is performed with the IV / block precesor // 3 - was called to the encryption function // 4 - Once all blocks are encrypted will join // 5 - forms the encrypted message and returns // /////////////////////////// uint8_t IV[16]; uint8_t Plain_text[16]; uint8_t Previous_block[16]; uint16_t index,index2; index = 0; index2 = 0; //Assign Initial Vector to IV variable assignBlock(IV,InitialVector); while(index < size){ //Decrypt for (int i =0; i<16;i++){ block_data[i]= original_data[index]; index++; } assignBlock(Previous_block,block_data); switch(keySize){ case 128: aes128_dec(block_data, &ctx128); break; case 192: aes192_dec(block_data, &ctx192); break; case 256: aes256_dec(block_data, &ctx256); break; } if (index == 16){ XOR(block_data,IV,Plain_text); }else { XOR(block_data,Previous_block,Plain_text); } for (int i = 0; i<16;i++){ original_data[index2] = Plain_text[i]; index2++; } } }
/** Event handler for the library USB Control Request reception event. */ void EVENT_USB_Device_ControlRequest(void) { static uint8_t success = 1; uint8_t bmRequestType = USB_ControlRequest.bmRequestType; uint8_t bRequest = USB_ControlRequest.bRequest; //uint8_t wValue = USB_ControlRequest.wValue; char data[51]; HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE)) { char lock; uint16_t wLength = USB_ControlRequest.wLength; char pw[32]; success = 1; /* default */ eeprom_read(ADDR_LOCK, &lock, 1); if(lock == 0 || lock == 255) lock = 0; else { if(bRequest != OPENKUBUS_GET_NONCE && bRequest != OPENKUBUS_SET_TIMESTAMP && bRequest != OPENKUBUS_RESET) { success = 0; return; } } // read data if(wLength) { Endpoint_ClearSETUP(); Endpoint_Read_Control_Stream_LE(data, MIN(sizeof(data), wLength)); Endpoint_ClearIN(); } switch(bRequest) { case OPENKUBUS_SET_LOCK: lock = 1; eeprom_write(ADDR_LOCK, &lock, 1); break; case OPENKUBUS_SET_OWNER: if(wLength) eeprom_write(ADDR_OWNER, data, wLength); else success = 0; break; case OPENKUBUS_SET_COMPANY: if(wLength) eeprom_write(ADDR_COMPANY, data, wLength); else success = 0; break; case OPENKUBUS_SET_DESCRIPTION: if(wLength) eeprom_write(ADDR_DESCRIPTION, data, wLength); else success = 0; break; case OPENKUBUS_SET_ID: if(wLength == 4) eeprom_write(ADDR_ID, data, wLength); else success = 0; break; case OPENKUBUS_SET_TIMESTAMP: if(wLength == 16) { aes256_ctx_t ctx; memset(&ctx, 0, sizeof(aes256_ctx_t)); eeprom_read(ADDR_SEED, pw, sizeof(pw)); aes256_init(pw, &ctx); aes256_dec(data, &ctx); if(strncmp(nonce, data, sizeof(nonce)) == 0) { set_timestamp(array2int((uint8_t *)&data[12])); update_nonce(); } else success = 0; } else success = 0; break; case OPENKUBUS_RESET: if(wLength == 16) { aes256_ctx_t ctx; memset(&ctx, 0, sizeof(aes256_ctx_t)); memcpy_P(pw, MASTER_PASSWORD, sizeof(pw)); aes256_init(pw, &ctx); aes256_dec(data, &ctx); if(strncmp(nonce, data, sizeof(nonce)) == 0) { clear_eeprom(); wdt_enable(WDTO_15MS); while(1); } else success = 0; } else success = 0; break; case OPENKUBUS_SET_SEED: if(wLength == LEN_SEED) eeprom_write(ADDR_SEED, data, LEN_SEED); else success = 0; break; case OPENKUBUS_SET_COUNTER: if(wLength == LEN_COUNTER) eeprom_write(ADDR_COUNTER, data, LEN_COUNTER); else success = 0; break; default: success = 0; break; } } else if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) { uint8_t length = 0; uint8_t i; uint32_t temp32 = 0; char c; switch(bRequest) { case OPENKUBUS_GET_SUCCESS: data[length++] = success; break; case OPENKUBUS_GET_NONCE: for(i = 0; i < sizeof(nonce); i++) data[length++] = nonce[i]; break; case OPENKUBUS_GET_TEMPERATURE: #ifdef RTC data[length++] = rtc_get_temperature(); #else data[length++] = 0xFF; #endif break; case OPENKUBUS_GET_ID: for(i = 0; i < LEN_ID; i++) { eeprom_read(ADDR_ID+i, &c, 1); data[length++] = c; } break; case OPENKUBUS_GET_TIME: temp32 = get_timestamp(); data[length++] = temp32 >> 24; data[length++] = temp32 >> 16; data[length++] = temp32 >> 8; data[length++] = temp32; break; case OPENKUBUS_GET_SERIAL: for(i = 0x0e; i <= 0x18; i++) data[length++] = boot_signature_byte_get(i); break; case OPENKUBUS_GET_DESCRIPTION: for(i = 0; i < LEN_DESCRIPTION; i++) { eeprom_read(ADDR_DESCRIPTION+i, &c, 1); data[length++] = c; if(c == 0) break; } break; case OPENKUBUS_GET_COMPANY: for(i = 0; i < LEN_COMPANY; i++) { eeprom_read(ADDR_COMPANY+i, &c, 1); data[length++] = c; if(c == 0) break; } break; case OPENKUBUS_GET_OWNER: for(i = 0; i < LEN_OWNER; i++) { eeprom_read(ADDR_OWNER+i, &c, 1); data[length++] = c; if(c == 0) break; } break; default: data[length++] = 0; } // send data Endpoint_ClearSETUP(); Endpoint_Write_Control_Stream_LE(data, length); Endpoint_ClearOUT(); }