static int __maybe_unused stmp3xxx_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = &stmp3xxx_wdd; if (watchdog_active(wdd)) return wdt_stop(wdd); return 0; }
int board_early_init_f(void) { wdt_stop(); pmic_reset(); board_clock_init(); board_uart_init(); board_power_init(); return 0; }
static int mid_wdt_probe(struct platform_device *pdev) { struct watchdog_device *wdt_dev; struct intel_mid_wdt_pdata *pdata = pdev->dev.platform_data; int ret; if (!pdata) { dev_err(&pdev->dev, "missing platform data\n"); return -EINVAL; } if (pdata->probe) { ret = pdata->probe(pdev); if (ret) return ret; } wdt_dev = devm_kzalloc(&pdev->dev, sizeof(*wdt_dev), GFP_KERNEL); if (!wdt_dev) return -ENOMEM; wdt_dev->info = &mid_wdt_info; wdt_dev->ops = &mid_wdt_ops; wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN; wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX; wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT; wdt_dev->parent = &pdev->dev; watchdog_set_drvdata(wdt_dev, &pdev->dev); platform_set_drvdata(pdev, wdt_dev); ret = devm_request_irq(&pdev->dev, pdata->irq, mid_wdt_irq, IRQF_SHARED | IRQF_NO_SUSPEND, "watchdog", wdt_dev); if (ret) { dev_err(&pdev->dev, "error requesting warning irq %d\n", pdata->irq); return ret; } /* Make sure the watchdog is not running */ wdt_stop(wdt_dev); ret = watchdog_register_device(wdt_dev); if (ret) { dev_err(&pdev->dev, "error registering watchdog device\n"); return ret; } dev_info(&pdev->dev, "Intel MID watchdog device probed\n"); return 0; }
static int wdt_release(struct inode *inode, struct file *file) { /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ if (expect_close == 42) { wdt_stop(); clear_bit(0, &timer_alive); } else { wdt_keepalive(); pr_crit("unexpected close, not stopping watchdog!\n"); } expect_close = 0; return 0; }
static int wdt_release(struct inode *inode, struct file *file) { /* * Shut off the timer. * Lock it in if it's a module and we set nowayout */ if (expect_close == 42) { wdt_stop(); clear_bit(0, &timer_alive); } else { wdt_keepalive(); // printk(KERN_CRIT PFX ; } expect_close = 0; return 0; }
void wdt_start(unsigned int timeout) { struct s5p_watchdog *wdt = samsung_get_base_watchdog(); unsigned int wtcon; wdt_stop(); wtcon = readl(&wdt->wtcon); wtcon |= (WTCON_EN | WTCON_CLK(WTCON_CLK_128)); wtcon &= ~WTCON_INT; wtcon |= WTCON_RESET; wtcon |= WTCON_PRESCALER(PRESCALER_VAL); writel(timeout, &wdt->wtdat); writel(timeout, &wdt->wtcnt); writel(wtcon, &wdt->wtcon); }
int exynos_early_init_f(void) { wdt_stop(); return 0; }
static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int status; int new_options, retval = -EINVAL; int new_timeout; union { struct watchdog_info __user *ident; int __user *i; } uarg; uarg.i = (int __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdt_get_status(&status); return put_user(status, uarg.i); case WDIOC_GETBOOTSTATUS: return put_user(0, uarg.i); case WDIOC_SETOPTIONS: if (get_user(new_options, uarg.i)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { wdt_stop(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { wdt_start(); retval = 0; } return retval; case WDIOC_KEEPALIVE: wdt_keepalive(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_timeout, uarg.i)) return -EFAULT; if (wdt_set_timeout(new_timeout)) return -EINVAL; wdt_keepalive(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(timeout, uarg.i); default: return -ENOTTY; } }
void arch_preboot_os(void) { #ifdef CONFIG_WATCHDOG wdt_stop(gd->watchdog_dev); #endif }
static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; int new_heartbeat; int status; static struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT| WDIOF_MAGICCLOSE| WDIOF_KEEPALIVEPING, .firmware_version = 1, .identity = "WDT500/501", }; /* Add options according to the card we have */ ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2); #ifdef CONFIG_WDT_501 ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER); if (tachometer) ident.options |= WDIOF_FANFAULT; #endif /* CONFIG_WDT_501 */ switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdt_get_status(&status); return put_user(status, p); case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: wdt_ping(); return 0; case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdt_set_heartbeat(new_heartbeat)) return -EINVAL; wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); default: return -ENOTTY; } } /** * wdt_open: * @inode: inode of device * @file: file handle to device * * The watchdog device has been opened. The watchdog device is single * open and on opening we load the counters. Counter zero is a 100Hz * cascade, into counter 1 which downcounts to reboot. When the counter * triggers counter 2 downcounts the length of the reset pulse which * set set to be as long as possible. */ static int wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(0, &wdt_is_open)) return -EBUSY; /* * Activate */ wdt_start(); return nonseekable_open(inode, file); } /** * wdt_release: * @inode: inode to board * @file: file handle to board * * The watchdog has a configurable API. There is a religious dispute * between people who want their watchdog to be able to shut down and * those who want to be sure if the watchdog manager dies the machine * reboots. In the former case we disable the counters, in the latter * case you have to open it again very soon. */ static int wdt_release(struct inode *inode, struct file *file) { if (expect_close == 42) { wdt_stop(); clear_bit(0, &wdt_is_open); } else { printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); wdt_ping(); } expect_close = 0; return 0; } #ifdef CONFIG_WDT_501 /** * wdt_temp_read: * @file: file handle to the watchdog board * @buf: buffer to write 1 byte into * @count: length of buffer * @ptr: offset (no seek allowed) * * Temp_read reports the temperature in degrees Fahrenheit. The API is in * farenheit. It was designed by an imperial measurement luddite. */ static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; if (wdt_get_temperature(&temperature)) return -EFAULT; if (copy_to_user(buf, &temperature, 1)) return -EFAULT; return 1; }
/*! \fn main(void) * \brief Main function */ int main(void) { uint16_t current_bootkey_val = eeprom_read_word((uint16_t*)EEP_BOOTKEY_ADDR); RET_TYPE flash_init_result; RET_TYPE touch_init_result; RET_TYPE card_detect_ret; uint8_t fuse_ok = TRUE; // Disable JTAG to gain access to pins, set prescaler to 1 (fuses not set) #ifndef PRODUCTION_KICKSTARTER_SETUP disableJTAG(); CPU_PRESCALE(0); #endif // Check fuse settings: boot reset vector, 2k words, SPIEN, BOD 2.6V, programming & ver disabled if ((boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS) != 0xFF) || (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) != 0xD8) || (boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS) != 0xFB) || (boot_lock_fuse_bits_get(GET_LOCK_BITS) != 0xFC)) { fuse_ok = FALSE; } // Check if PB5 is low to start electrical test DDRB &= ~(1 << 5); PORTB |= (1 << 5); smallForLoopBasedDelay(); if (!(PINB & (1 << 5))) { // Test result, true by default uint8_t test_result = TRUE; // Leave flash nS off DDR_FLASH_nS |= (1 << PORTID_FLASH_nS); PORT_FLASH_nS |= (1 << PORTID_FLASH_nS); // Set PORTD as output, leave PORTID_OLED_SS high DDRD |= 0xFF; PORTD |= 0xFF; // All other pins are input by default, run our test for (uint8_t i = 0; i < 4; i++) { PORTD |= 0xFF; smallForLoopBasedDelay(); if (!(PINF & (0xC3)) || !(PINC & (1 << 6)) || !(PINE & (1 << 6)) || !(PINB & (1 << 4))) { test_result = FALSE; } PORTD &= (1 << PORTID_OLED_SS); smallForLoopBasedDelay(); if ((PINF & (0xC3)) || (PINC & (1 << 6)) || (PINE & (1 << 6)) || (PINB & (1 << 4))) { test_result = FALSE; } } // PB6 as test result output DDRB |= (1 << 6); // If test successful, light green LED if ((test_result == TRUE) && (fuse_ok == TRUE)) { PORTB |= (1 << 6); } else { PORTB &= ~(1 << 6); } while(1); } // This code will only be used for developers and beta testers #if !defined(PRODUCTION_SETUP) && !defined(PRODUCTION_KICKSTARTER_SETUP) // Check if we were reset and want to go to the bootloader if (current_bootkey_val == BOOTLOADER_BOOTKEY) { // Disable WDT wdt_reset(); wdt_clear_flag(); wdt_change_enable(); wdt_stop(); // Store correct bootkey eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, CORRECT_BOOTKEY); // Jump to bootloader start_bootloader(); } // Check if there was a change in the mooltipass setting storage to reset the parameters to their correct values if (getMooltipassParameterInEeprom(USER_PARAM_INIT_KEY_PARAM) != USER_PARAM_CORRECT_INIT_KEY) { mooltipassParametersInit(); setMooltipassParameterInEeprom(USER_PARAM_INIT_KEY_PARAM, USER_PARAM_CORRECT_INIT_KEY); } #endif // First time initializations for Eeprom (first boot at production or flash layout changes for beta testers) if (current_bootkey_val != CORRECT_BOOTKEY) { // Erase Mooltipass parameters mooltipassParametersInit(); // Set bootloader password bool to FALSE eeprom_write_byte((uint8_t*)EEP_BOOT_PWD_SET, FALSE); } /* Check if a card is inserted in the Mooltipass to go to the bootloader */ #ifdef AVR_BOOTLOADER_PROGRAMMING /* Disable JTAG to get access to the pins */ disableJTAG(); /* Init SMC port */ initPortSMC(); /* Delay for detection */ smallForLoopBasedDelay(); #if defined(HARDWARE_V1) if (PIN_SC_DET & (1 << PORTID_SC_DET)) #elif defined(HARDWARE_OLIVIER_V1) if (!(PIN_SC_DET & (1 << PORTID_SC_DET))) #endif { uint16_t tempuint16; /* What follows is a copy from firstDetectFunctionSMC() */ /* Enable power to the card */ PORT_SC_POW &= ~(1 << PORTID_SC_POW); /* Default state: PGM to 0 and RST to 1 */ PORT_SC_PGM &= ~(1 << PORTID_SC_PGM); DDR_SC_PGM |= (1 << PORTID_SC_PGM); PORT_SC_RST |= (1 << PORTID_SC_RST); DDR_SC_RST |= (1 << PORTID_SC_RST); /* Activate SPI port */ PORT_SPI_NATIVE &= ~((1 << SCK_SPI_NATIVE) | (1 << MOSI_SPI_NATIVE)); DDRB |= (1 << SCK_SPI_NATIVE) | (1 << MOSI_SPI_NATIVE); setSPIModeSMC(); /* Let the card come online */ smallForLoopBasedDelay(); /* Check smart card FZ */ readFabricationZone((uint8_t*)&tempuint16); if ((swap16(tempuint16)) != SMARTCARD_FABRICATION_ZONE) { removeFunctionSMC(); start_bootloader(); } else { removeFunctionSMC(); } } #endif initPortSMC(); // Initialize smart card port initPwm(); // Initialize PWM controller initIRQ(); // Initialize interrupts powerSettlingDelay(); // Let the power settle initUsb(); // Initialize USB controller powerSettlingDelay(); // Let the USB 3.3V LDO rise initI2cPort(); // Initialize I2C interface rngInit(); // Initialize avrentropy library oledInitIOs(); // Initialize OLED input/outputs spiUsartBegin(SPI_RATE_8_MHZ); // Start USART SPI at 8MHz // If offline mode isn't enabled, wait for device to be enumerated if (getMooltipassParameterInEeprom(OFFLINE_MODE_PARAM) == FALSE) { while(!isUsbConfigured()); // Wait for host to set configuration } // Set correct timeout_enabled val mp_timeout_enabled = getMooltipassParameterInEeprom(LOCK_TIMEOUT_ENABLE_PARAM); // Launch the before flash initialization tests #ifdef TESTS_ENABLED beforeFlashInitTests(); #endif // Check if we can initialize the Flash memory flash_init_result = initFlash(); // Launch the after flash initialization tests #ifdef TESTS_ENABLED afterFlashInitTests(); #endif // Set up OLED now that USB is receiving full 500mA. oledBegin(FONT_DEFAULT); // First time initializations for Flash (first time power up at production) if (current_bootkey_val != CORRECT_BOOTKEY) { // Erase everything non graphic in flash eraseFlashUsersContents(); // Erase # of cards and # of users firstTimeUserHandlingInit(); } // Check if we can initialize the touch sensing element touch_init_result = initTouchSensing(); // Enable proximity detection #ifndef HARDWARE_V1 activateProxDetection(); #endif // Launch the after touch initialization tests #ifdef TESTS_ENABLED afterTouchInitTests(); #endif // Test procedure to check that all HW is working #if defined(PRODUCTION_SETUP) || defined(PRODUCTION_KICKSTARTER_SETUP) if (current_bootkey_val != CORRECT_BOOTKEY) { RET_TYPE temp_rettype; // Wait for USB host to upload bundle, which then sets USER_PARAM_INIT_KEY_PARAM //#ifdef PRODUCTION_KICKSTARTER_SETUP while(getMooltipassParameterInEeprom(USER_PARAM_INIT_KEY_PARAM) != 0xF1) { usbProcessIncoming(USB_CALLER_MAIN); } //#endif // Bundle uploaded, start the screen oledBegin(FONT_DEFAULT); oledWriteActiveBuffer(); oledSetXY(0,0); // LEDs ON, to check setPwmDc(MAX_PWM_VAL); switchOnButtonWheelLeds(); guiDisplayRawString(ID_STRING_TEST_LEDS_CH); // Check flash init if (flash_init_result != RETURN_OK) { guiDisplayRawString(ID_STRING_TEST_FLASH_PB); } // Check touch init if (touch_init_result != RETURN_OK) { guiDisplayRawString(ID_STRING_TEST_TOUCH_PB); } // Touch instructions guiDisplayRawString(ID_STRING_TEST_INST_TCH); // Check prox while(!(touchDetectionRoutine(0) & RETURN_PROX_DETECTION)); guiDisplayRawString(ID_STRING_TEST_DET); activateGuardKey(); // Check left while(!(touchDetectionRoutine(0) & RETURN_LEFT_PRESSED)); guiDisplayRawString(ID_STRING_TEST_LEFT); // Check wheel while(!(touchDetectionRoutine(0) & RETURN_WHEEL_PRESSED)); guiDisplayRawString(ID_STRING_TEST_WHEEL); // Check right while(!(touchDetectionRoutine(0) & RETURN_RIGHT_PRESSED)); guiDisplayRawString(ID_STRING_TEST_RIGHT); // Insert card guiDisplayRawString(ID_STRING_TEST_CARD_INS); while(isCardPlugged() != RETURN_JDETECT); temp_rettype = cardDetectedRoutine(); // Check card if (!((temp_rettype == RETURN_MOOLTIPASS_BLANK) || (temp_rettype == RETURN_MOOLTIPASS_USER))) { guiDisplayRawString(ID_STRING_TEST_CARD_PB); } // Display result uint8_t script_return = RETURN_OK; if ((flash_init_result == RETURN_OK) && (touch_init_result == RETURN_OK) && ((temp_rettype == RETURN_MOOLTIPASS_BLANK) || (temp_rettype == RETURN_MOOLTIPASS_USER))) { // Inform script of success usbSendMessage(CMD_FUNCTIONAL_TEST_RES, 1, &script_return); // Wait for password to be set while(eeprom_read_byte((uint8_t*)EEP_BOOT_PWD_SET) != BOOTLOADER_PWDOK_KEY) { usbProcessIncoming(USB_CALLER_MAIN); } // Display test result guiDisplayRawString(ID_STRING_TEST_OK); timerBasedDelayMs(3000); } else { // Set correct bool script_return = RETURN_NOK; // Display test result guiDisplayRawString(ID_STRING_TEST_NOK); // Inform script of failure usbSendMessage(CMD_FUNCTIONAL_TEST_RES, 1, &script_return); while(1) { usbProcessIncoming(USB_CALLER_MAIN); } } } #endif // Stop the Mooltipass if we can't communicate with the flash or the touch interface #if defined(HARDWARE_OLIVIER_V1) #ifdef PRODUCTION_KICKSTARTER_SETUP while ((flash_init_result != RETURN_OK) || (touch_init_result != RETURN_OK) || (fuse_ok != TRUE)); #else while ((flash_init_result != RETURN_OK) || (touch_init_result != RETURN_OK)); #endif #endif // First time initializations done.... write correct value in eeprom if (current_bootkey_val != CORRECT_BOOTKEY) { // Store correct bootkey eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, CORRECT_BOOTKEY); } // Write inactive buffer & go to startup screen oledWriteInactiveBuffer(); guiSetCurrentScreen(SCREEN_DEFAULT_NINSERTED); guiGetBackToCurrentScreen(); // Launch the after HaD logo display tests #ifdef TESTS_ENABLED afterHadLogoDisplayTests(); #endif // Let's fade in the LEDs for (uint16_t i = 0; i < MAX_PWM_VAL; i++) { setPwmDc(i); timerBasedDelayMs(0); } activityDetectedRoutine(); launchCalibrationCycle(); touchClearCurrentDetections(); // Inhibit touch inputs for the first 3 seconds activateTimer(TIMER_TOUCH_INHIBIT, 3000); while (1) { // Process possible incoming USB packets usbProcessIncoming(USB_CALLER_MAIN); // Call GUI routine once the touch input inhibit timer is finished if (hasTimerExpired(TIMER_TOUCH_INHIBIT, FALSE) == TIMER_EXPIRED) { guiMainLoop(); } // Check if a card just got inserted / removed card_detect_ret = isCardPlugged(); // Do appropriate actions on smartcard insertion / removal if (card_detect_ret == RETURN_JDETECT) { // Light up the Mooltipass and call the dedicated function activityDetectedRoutine(); handleSmartcardInserted(); } else if (card_detect_ret == RETURN_JRELEASED) { // Light up the Mooltipass and call the dedicated function activityDetectedRoutine(); handleSmartcardRemoved(); // Set correct screen guiDisplayInformationOnScreen(ID_STRING_CARD_REMOVED); guiSetCurrentScreen(SCREEN_DEFAULT_NINSERTED); userViewDelay(); guiGetBackToCurrentScreen(); } // Two quick caps lock presses wakes up the device if ((hasTimerExpired(TIMER_CAPS, FALSE) == TIMER_EXPIRED) && (getKeyboardLeds() & HID_CAPS_MASK) && (wasCapsLockTimerArmed == FALSE)) { wasCapsLockTimerArmed = TRUE; activateTimer(TIMER_CAPS, CAPS_LOCK_DEL); } else if ((hasTimerExpired(TIMER_CAPS, FALSE) == TIMER_RUNNING) && !(getKeyboardLeds() & HID_CAPS_MASK)) { activityDetectedRoutine(); } else if ((hasTimerExpired(TIMER_CAPS, FALSE) == TIMER_EXPIRED) && !(getKeyboardLeds() & HID_CAPS_MASK)) { wasCapsLockTimerArmed = FALSE; } // If we have a timeout lock if ((mp_timeout_enabled == TRUE) && (hasTimerExpired(SLOW_TIMER_LOCKOUT, TRUE) == TIMER_EXPIRED)) { guiSetCurrentScreen(SCREEN_DEFAULT_INSERTED_LCK); guiGetBackToCurrentScreen(); handleSmartcardRemoved(); } } }
/*! \fn main(void) * \brief Main function * \note For our security chain to be valid, EEP_BOOT_PWD_SET in eeprom needs to be set to BOOTLOADER_PWDOK_KEY */ int main(void) { /* Fetch bootkey in eeprom */ uint16_t current_bootkey_val = eeprom_read_word((uint16_t*)EEP_BOOTKEY_ADDR); // Bootkey in EEPROM uint8_t new_aes_key[AES_KEY_LENGTH/8]; // New AES encryption key uint8_t cur_aes_key[AES_KEY_LENGTH/8]; // AES encryption key uint8_t firmware_data[SPM_PAGESIZE]; // One page of firmware data aes256_context temp_aes_context; // AES context uint8_t cur_cbc_mac[16]; // Current CBCMAC val uint8_t temp_data[16]; // Temporary 16 bytes array RET_TYPE flash_init_result; // Flash initialization result uint16_t firmware_start_address = UINT16_MAX - MAX_FIRMWARE_SIZE - sizeof(cur_cbc_mac) - sizeof(cur_aes_key) + 1; // Start address of firmware in external memory uint16_t firmware_end_address = UINT16_MAX - sizeof(cur_cbc_mac) - sizeof(cur_aes_key) + 1; // End address of firmware in external memory /* Just in case we are going to disable the watch dog timer and disable interrupts */ cli(); wdt_reset(); wdt_clear_flag(); wdt_change_enable(); wdt_stop(); /* Check fuses: 2k words, SPIEN, BOD 4.3V, BOOTRST programming & ver disabled >> http://www.engbedded.com/fusecalc/ */ if ((boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS) != 0xFF) || (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) != 0xD8) || (boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS) != 0xF8) || (boot_lock_fuse_bits_get(GET_LOCK_BITS) != 0xFC)) { while(1); } /* If security isn't set in place yet, no point in launching the bootloader */ if (eeprom_read_byte((uint8_t*)EEP_BOOT_PWD_SET) != BOOTLOADER_PWDOK_KEY) { start_firmware(); } /* Check if the device is booting normally, if the bootloader was called, or unknown state */ if (current_bootkey_val == CORRECT_BOOTKEY) { /* Security system set, correct bootkey for firmware */ start_firmware(); } else if (current_bootkey_val != BOOTLOADER_BOOTKEY) { /* Security system set, bootkey isn't the bootloader one nor the main fw one... */ while(1); } /* By default, brick the device so it's an all or nothing update procedure */ eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, BRICKED_BOOTKEY); /* Init IOs */ UHWCON = 0x01; // Enable USB 3.3V LDO initFlashIOs(); // Init EXT Flash IOs spiUsartBegin(); // Init SPI Controller DDR_ACC_SS |= (1 << PORTID_ACC_SS); // Setup PORT for the Accelerometer SS PORT_ACC_SS |= (1 << PORTID_ACC_SS); // Setup PORT for the Accelerometer SS DDR_OLED_SS |= (1 << PORTID_OLED_SS); // Setup PORT for the OLED SS PORT_OLED_SS |= (1 << PORTID_OLED_SS); // Setup PORT for the OLED SS for (uint16_t i = 0; i < 20000; i++) asm volatile ("NOP"); /* Disable I2C block of the Accelerometer */ PORT_ACC_SS &= ~(1 << PORTID_ACC_SS); spiUsartTransfer(0x23); spiUsartTransfer(0x02); PORT_ACC_SS |= (1 << PORTID_ACC_SS); /* Check Flash */ flash_init_result = checkFlashID(); if (flash_init_result != RETURN_OK) { while(1); } for (uint8_t pass_number = 0; pass_number < 2; pass_number++) { /* Init CBCMAC encryption context*/ eeprom_read_block((void*)cur_aes_key, (void*)EEP_BOOT_PWD, sizeof(cur_aes_key)); memset((void*)cur_cbc_mac, 0x00, sizeof(cur_cbc_mac)); memset((void*)temp_data, 0x00, sizeof(temp_data)); aes256_init_ecb(&temp_aes_context, cur_aes_key); // Compute CBCMAC for between the start of the graphics zone until the max addressing space (65536) - the size of the CBCMAC for (uint16_t i = GRAPHIC_ZONE_START; i < (UINT16_MAX - sizeof(cur_cbc_mac) + 1); i += sizeof(cur_cbc_mac)) { // Read data from external flash flashRawRead(temp_data, i, sizeof(temp_data)); // If we got to the part containing to firmware if ((i >= firmware_start_address) && (i < firmware_end_address)) { // Append firmware data to current buffer uint16_t firmware_data_address = i - firmware_start_address; memcpy(firmware_data + (firmware_data_address & SPM_PAGE_SIZE_BYTES_BM), temp_data, sizeof(temp_data)); // If we have a full page in buffer, flash it firmware_data_address += sizeof(cur_cbc_mac); if (((firmware_data_address & SPM_PAGE_SIZE_BYTES_BM) == 0x0000) && (pass_number == 1)) { boot_program_page(firmware_data_address - SPM_PAGESIZE, firmware_data); } } // If we got to the part containing the encrypted new aes key (end of the for()) if (i >= firmware_end_address) { memcpy(new_aes_key + i - firmware_end_address, temp_data, sizeof(temp_data)); } // Continue computation of CBCMAC aesXorVectors(cur_cbc_mac, temp_data, sizeof(temp_data)); aes256_encrypt_ecb(&temp_aes_context, cur_cbc_mac); } // Read CBCMAC in memory and compare it with the computed value flashRawRead(temp_data, (UINT16_MAX - sizeof(cur_cbc_mac) + 1), sizeof(cur_cbc_mac)); if (pass_number == 0) { // First pass, compare CBCMAC and see if we do the next pass or start the firmware if (sideChannelSafeMemCmp(temp_data, cur_cbc_mac, sizeof(cur_cbc_mac)) != 0) { // No match, start the main firmware eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, CORRECT_BOOTKEY); start_firmware(); } else { // Otherwise, next pass! } } else { // Second pass, compare CBCMAC and then update AES keys if (sideChannelSafeMemCmp(temp_data, cur_cbc_mac, sizeof(cur_cbc_mac)) == 0) { // Fetch the encrypted new aes key from flash, decrypt it, store it aes256_decrypt_ecb(&temp_aes_context, new_aes_key); aes256_decrypt_ecb(&temp_aes_context, new_aes_key+16); eeprom_write_block((void*)new_aes_key, (void*)EEP_BOOT_PWD, sizeof(new_aes_key)); eeprom_write_word((uint16_t*)EEP_BOOTKEY_ADDR, CORRECT_BOOTKEY); start_firmware(); } else { // Fail, erase everything! >> maybe just write a while(1) in the future? for (uint16_t i = 0; i < MAX_FIRMWARE_SIZE; i += SPM_PAGESIZE) { boot_page_erase(i); boot_spm_busy_wait(); } while(1); } } } }
int board_early_init_f(void) { wdt_stop(); return 0; }