//**************************[system_bootloader_info]*************************** 27.09.2015 void system_bootloader_info() { // system_bootloader_wait_char('i') && if (system_bootloader_wait_char('n') && system_bootloader_wait_char( 'f') && system_bootloader_wait_char( 'o')) { bootloader_data_out('I'); #if (defined(boot_signature_byte_get) && defined(SIGRD)) bootloader_data_out(boot_signature_byte_get(0)); bootloader_data_out(boot_signature_byte_get(2)); bootloader_data_out(boot_signature_byte_get(4)); #else // #if (defined(boot_signature_byte_get) && defined(SIGRD)) bootloader_data_out(SIGNATURE_0); bootloader_data_out(SIGNATURE_1); bootloader_data_out(SIGNATURE_2); #endif // #if (defined(boot_signature_byte_get) && defined(SIGRD)) bootloader_data_out( SPM_PAGESIZE & 0xFF); bootloader_data_out((SPM_PAGESIZE >> 8) & 0xFF); bootloader_data_out( BOOTSTART & 0xFF); bootloader_data_out((BOOTSTART >> 8) & 0xFF); #if (BOOTSTART > 0xFFFF) bootloader_data_out(((uint32_t) BOOTSTART >> 16) & 0xFF); #else bootloader_data_out(0x00); #endif bootloader_data_out(13); }
static void USB_Device_GetInternalSerialDescriptor(void) { struct { USB_Descriptor_Header_t Header; wchar_t UnicodeString[20]; } SignatureDescriptor; SignatureDescriptor.Header.Type = DTYPE_String; SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor); ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { uint8_t SigReadAddress = 0x0E; for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++) { uint8_t SerialByte = boot_signature_byte_get(SigReadAddress); if (SerialCharNum & 0x01) { SerialByte >>= 4; SigReadAddress++; } SerialByte &= 0x0F; SignatureDescriptor.UnicodeString[SerialCharNum] = (SerialByte >= 10) ? (('A' - 10) + SerialByte) : ('0' + SerialByte); } }
static void USB_Device_GetInternalSerialDescriptor(void) { struct { USB_Descriptor_Header_t Header; int16_t UnicodeString[20]; } SignatureDescriptor; SignatureDescriptor.Header.Type = DTYPE_String; SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor); uint8_t SigReadAddress = 0x0E; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++) { uint8_t SerialByte = boot_signature_byte_get(SigReadAddress); if (SerialCharNum & 0x01) { SerialByte >>= 4; SigReadAddress++; } SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte); } }
bool check_controller_id (void) { uint8_t sigbyte, eepcontent = 0; eep_read(BLD_eExtEEPAddr_CtrlID + 0, 1, &eepcontent); sigbyte = boot_signature_byte_get(ADDR_SIGNATURE_BYTE0); if (sigbyte != eepcontent) return false; eep_read(BLD_eExtEEPAddr_CtrlID + 1, 1, &eepcontent); sigbyte = boot_signature_byte_get(ADDR_SIGNATURE_BYTE1); if (sigbyte != eepcontent) return false; eep_read(BLD_eExtEEPAddr_CtrlID + 2, 1, &eepcontent); sigbyte = boot_signature_byte_get(ADDR_SIGNATURE_BYTE2); if (sigbyte != eepcontent) return false; return true; }
bool hwUniqueID(unique_id_t *uniqueID) { // padding (void)memset(uniqueID, MY_HWID_PADDING_BYTE, sizeof(unique_id_t)); // no unique ID for non-PB AVR, use HW specifics for diversification *((uint8_t *)uniqueID) = boot_signature_byte_get(0x00); *((uint8_t *)uniqueID + 1) = boot_signature_byte_get(0x02); *((uint8_t *)uniqueID + 2) = boot_signature_byte_get(0x04); *((uint8_t *)uniqueID + 3) = boot_signature_byte_get(0x01); //OSCCAL #if defined(__AVR_ATmega328PB__) // ATMEGA328PB specifics, has unique ID for(uint8_t idx = 0; idx < 10; idx++) { *((uint8_t *)uniqueID + 4 + idx) = boot_signature_byte_get(0xE + idx); } return true; // unique ID returned #else return false; // no unique ID returned #endif }
void Signature_Write(void) { FRESULT res; res = f_open(&Main_file, "flysight.txt", FA_WRITE | FA_CREATE_ALWAYS); if (res != FR_OK) return; // ignore failures Signature_WriteString(SignatureHeader); uint8_t offset; for (offset = 0x0e; offset <= 0x18; offset++) { uint8_t byte = boot_signature_byte_get(offset); Signature_WriteHexNibble(byte >> 4); Signature_WriteHexNibble(byte & 0x0f); } Signature_WriteString(SignatureFooter); f_close(&Main_file); }
/* * enc28j60_atmega644p_get_mac * @device: Ethernet device instance for which MAC address is needed to * be assigned. * @return: Returns the start of random MAC address generated. * This function will generate a MAC address using the device serial. */ uint8_t *enc28j60_atmega644p_get_mac(ETH_DEVICE *device) { /* Push ENC28j60 OUI bytes. */ device->mac[0] = ENC28J60_OUI_B0; device->mac[1] = ENC28J60_OUI_B1; device->mac[2] = ENC28J60_OUI_B2; /* Assign remaining MAC address using the device serial. */ device->mac[3] = NET_CSUM_BYTE(NET_CSUM_BYTE(boot_signature_byte_get(0x000E), boot_signature_byte_get(0x000F)), boot_signature_byte_get(0x0010)); device->mac[4] = NET_CSUM_BYTE(NET_CSUM_BYTE(boot_signature_byte_get(0x0011), boot_signature_byte_get(0x0012)), boot_signature_byte_get(0x0013)); device->mac[5] = NET_CSUM_BYTE(NET_CSUM_BYTE(boot_signature_byte_get(0x0015), boot_signature_byte_get(0x0016)), boot_signature_byte_get(0x0017)); /* Return the generated MAC address. */ return (device->mac); } /* enc28j60_atmega644p_get_mac */
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address) { return boot_signature_byte_get(Address); }
// ---------------------------------------------------------------------- // Handle a non-standard SETUP packet. // ---------------------------------------------------------------------- uchar usbFunctionSetup ( uchar data[8] ) { uchar req; usbRequest_t *rq = (void *)data; idle_cnt = idle_cnt2 = 0; // Generic requests req = data[1]; if ( req == USBTINY_READ) { // do nothing return 1; } else if ( req == USBTINY_POWERDOWN ) { usb_maybe_finalizing = 1; #ifndef ENABLE_WRITE_WHEN_TOLD finalize_flash_if_dirty(); #endif return 0; } else if ( req == USBTINY_SPI ) { usb_maybe_finalizing = 1; #ifndef ENABLE_WRITE_WHEN_TOLD finalize_flash_if_dirty(); // partial page writes are not fully written unless this is called here, it must be HERE #endif usbMsgPtr = (usbMsgPtr_t)buffer; buffer[2] = data[3]; // this tricks "usbtiny_cmd" into succeeding buffer[3] = 0; // fools safemode into succeeding // for the commands, refer to ATmega datasheet under "Serial Programming Instruction Set" // usage of avr/boot.h here is experimental if (0) { } // fools the C preprocessor #ifdef ENABLE_SIG_READING else if (data[2] == 0x30 && data[3] == 0x00) { // read signature byte #ifdef ENABLE_SIG_FAKING buffer[3] = 0x01; #else buffer[3] = boot_signature_byte_get(data[4] * 2); #endif } #endif #ifdef ENABLE_FUSE_READING else if (data[2] == 0x50 && data[3] == 0x00 && data[4] == 0x00) { // read LFUSE buffer[3] = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); } else if (data[2] == 0x58 && data[3] == 0x08 && data[4] == 0x00) { // read HFUSE buffer[3] = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); } else if (data[2] == 0x50 && data[3] == 0x08 && data[4] == 0x00) { // read EFUSE buffer[3] = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); } else if (data[2] == 0x58 && data[3] == 0x00 && data[4] == 0x00) { // read lock bits buffer[3] = boot_lock_fuse_bits_get(GET_LOCK_BITS); } else if (data[2] == 0x38 && data[3] == 0x00 && data[4] == 0x00) { // read calibration buffer[3] = boot_signature_byte_get(0); } #endif #ifdef ENABLE_CHIP_ERASE else if (data[2] == 0xAC && data[3] == 0x80 && data[4] == 0x00 && data[5] == 0x00) { // chip erase, will erase all pages except the first page and the bootloader region full_erase_requested = 1; } #endif #ifdef ENABLE_WRITE_WHEN_TOLD else if (data[2] == 0x4C && data[5] == 0x00) { // write memory page // page is data[3] as MSB and data[4] as LSB need_write_page = 1; } #endif // all other commands are unhandled return 4; } /* else if ( req == USBTINY_SPI1 ) { // I don't know what this is used for, there are no single SPI transactions in the ISP protocol usb_maybe_finalizing = 1; #ifndef ENABLE_WRITE_WHEN_TOLD finalize_flash_if_dirty(); #endif return 1; } */ else if ( req == USBTINY_POLL_BYTES ) { usb_maybe_finalizing = 1; #ifndef ENABLE_WRITE_WHEN_TOLD finalize_flash_if_dirty(); #endif return 0; } CUR_ADDR = *((uint16_t*)(&data[4])); remaining = rq->wLength.bytes[0]; if ( req >= USBTINY_FLASH_READ && req <= USBTINY_EEPROM_WRITE ) { #ifdef ENABLE_LED_BLINK OCR0B = 0x7F; #endif usb_has_activity = 1; cmd0 = req; if ( cmd0 != USBTINY_FLASH_WRITE ) { usb_maybe_finalizing = 1; #ifndef ENABLE_WRITE_WHEN_TOLD finalize_flash_if_dirty(); #endif } return USB_NO_MSG; // usbFunctionRead() or usbFunctionWrite() will be called to handle the data } // do nothing if nothing done return 0; }
/** 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(); }