/*! \fn addNewUserAndNewSmartCard(volatile uint16_t* pin_code) * \brief Add a new user with a new smart card * \param pin_code The new pin code * \return success or not */ RET_TYPE addNewUserAndNewSmartCard(volatile uint16_t* pin_code) { uint8_t temp_buffer[AES_KEY_LENGTH/8]; uint8_t temp_nonce[AES256_CTR_LENGTH]; uint8_t new_user_id; // When inserting a new user and a new card, we need to setup the following elements // - AES encryption key, stored in the smartcard // - AES next available CTR, stored in the user profile // - AES nonce, stored in the eeprom along with the user ID // - Smartcard CPZ, randomly generated and stored in our eeprom along with user id & nonce // The next part can take quite a while guiDisplayProcessingScreen(); // Get new user id if possible if (findAvailableUserId(&new_user_id) == RETURN_NOK) { return RETURN_NOK; } // Create user profile in flash, CTR is set to 0 by the library formatUserProfileMemory(new_user_id); // Initialize user flash context, that inits the node mgmt handle and the ctr value initUserFlashContext(new_user_id); // Generate random CPZ value fillArrayWithRandomBytes(temp_buffer, SMARTCARD_CPZ_LENGTH); // Generate random nonce to be stored in the eeprom fillArrayWithRandomBytes(temp_nonce, AES256_CTR_LENGTH); // Store User ID <> SMC CPZ & AES CTR <> user id if (writeSmartCardCPZForUserId(temp_buffer, temp_nonce, new_user_id) != RETURN_OK) { return RETURN_NOK; } // Write random bytes in the code protected zone in the smart card writeCodeProtectedZone(temp_buffer); // Generate a new random AES key, write it in the smartcard fillArrayWithRandomBytes(temp_buffer, AES_KEY_LENGTH/8); writeAES256BitsKey(temp_buffer); // Initialize encryption handling initEncryptionHandling(temp_buffer, temp_nonce); // Write new pin code writeSecurityCode(pin_code); return RETURN_OK; }
/*! \fn guiScreenLoop(uint8_t input_interface_result) * \brief Function called to handle screen changes * \param input_interface_result Touch detection result */ void guiScreenLoop(uint8_t input_interface_result) { // If no press, you can return! if ((input_interface_result == WHEEL_ACTION_NONE) || (currentScreen == SCREEN_DEFAULT_INSERTED_INVALID) || (currentScreen == SCREEN_DEFAULT_INSERTED_UNKNOWN)) { return; } if (currentScreen == SCREEN_DEFAULT_NINSERTED) { // No smart card inserted, ask the user to insert one guiDisplayInsertSmartCardScreenAndWait(); } else if (currentScreen == SCREEN_MEMORY_MGMT) { // Currently in memory management mode, tell the user to finish it via the plugin/app guiDisplayInformationOnScreenAndWait(ID_STRING_CLOSEMEMMGMT); guiGetBackToCurrentScreen(); miniWheelClearDetections(); } else if (currentScreen == SCREEN_DEFAULT_INSERTED_LCK) { // Locked screen and a detection happened, check that the user hasn't removed his card, launch unlocking process if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0, TRUE) == RETURN_VCARD_OK)) { // User approved his pin unlockFeatureCheck(); currentScreen = SCREEN_DEFAULT_INSERTED_NLCK; } // Go to the new screen guiGetBackToCurrentScreen(); } else { if (input_interface_result == WHEEL_ACTION_UP) { // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) if (currentScreen == SCREEN_LOCK) { currentScreen = SCREEN_SETTINGS; } else if (currentScreen == SCREEN_SETTINGS_CHANGE_PIN) { currentScreen = SCREEN_SETTINGS_ERASE; } else { currentScreen--; } // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION; i++) { miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+NB_BMPS_PER_TRANSITION-1-i, OLED_SCROLL_FLIP); timerBasedDelayMs(12); } } else if (input_interface_result == WHEEL_ACTION_DOWN) { // We can do that because of defines and bitmap order (see logic_fw_flash_storage and gui.h) for (uint8_t i = 0; i < NB_BMPS_PER_TRANSITION-1; i++) { miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK+1+i, OLED_SCROLL_FLIP); timerBasedDelayMs(12); } if (currentScreen == SCREEN_SETTINGS) { currentScreen = SCREEN_LOCK; } else if (currentScreen == SCREEN_SETTINGS_ERASE) { currentScreen = SCREEN_SETTINGS_CHANGE_PIN; } else { currentScreen++; } miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_FLIP); } else if (input_interface_result == WHEEL_ACTION_LONG_CLICK) { // Long press in main menu : lock, long press in settings menu: go back to login screen if ((currentScreen >= SCREEN_SETTINGS_CHANGE_PIN) && (currentScreen <= SCREEN_SETTINGS_ERASE)) { currentScreen = SCREEN_LOGIN; miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); } } else if (input_interface_result == WHEEL_ACTION_SHORT_CLICK) { switch(currentScreen) { case SCREEN_LOCK: { // User wants to lock his mooltipass currentScreen = SCREEN_DEFAULT_INSERTED_LCK; handleSmartcardRemoved(); guiGetBackToCurrentScreen(); break; } case SCREEN_LOGIN: { // User wants to go to the login menu if (getStartingParentAddress() != NODE_ADDR_NULL) { loginSelectLogic(); } else { guiDisplayInformationOnScreenAndWait(ID_STRING_NO_CREDS); } guiGetBackToCurrentScreen(); break; } case SCREEN_FAVORITES: { // User wants to go to the favorite menu #if defined(ENABLE_CREDENTIAL_MANAGEMENT) && defined(REPLACE_FAVORITES_WITH_CREDENTIAL_MANAGEMENT) managementActionPickingLogic(); #else favoritePickingLogic(); #endif guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS: { currentScreen = SCREEN_SETTINGS_CHANGE_PIN; miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); break; } case SCREEN_SETTINGS_HOME: { currentScreen = SCREEN_LOGIN; miniOledBitmapDrawFlash(0, 0, (currentScreen-SCREEN_LOCK)*NB_BMPS_PER_TRANSITION+BITMAP_MAIN_LOCK, OLED_SCROLL_UP); break; } case SCREEN_SETTINGS_CHANGE_PIN: { // User wants to change his PIN code // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // User approved his pin, ask his new one volatile uint16_t pin_code; if (guiAskForNewPin(&pin_code, ID_STRING_NEW_PINQ) == RETURN_NEW_PIN_OK) { // User successfully entered a new pin writeSecurityCode(&pin_code); // Inform of success guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_CHANGED); } else { // Inform of fail guiDisplayInformationOnScreenAndWait(ID_STRING_PIN_NCGHANGED); } pin_code = 0x0000; } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS_BACKUP: { // User wants to clone his smartcard volatile uint16_t pin_code; RET_TYPE temp_rettype; // Reauth user if (removeCardAndReAuthUser() == RETURN_OK) { // Ask for new pin temp_rettype = guiAskForNewPin(&pin_code, ID_STRING_PIN_NEW_CARD); if (temp_rettype == RETURN_NEW_PIN_OK) { // Start the cloning process if (cloneSmartCardProcess(&pin_code) == RETURN_OK) { // Well it worked.... } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_TGT_CARD_NBL); } pin_code = 0x0000; } else if (temp_rettype == RETURN_NEW_PIN_DIFF) { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_PIN_DIFF); } else { guiGetBackToCurrentScreen(); return; } } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; guiDisplayInformationOnScreen(ID_STRING_FAILED); } userViewDelay(); guiGetBackToCurrentScreen(); break; } case SCREEN_SETTINGS_ERASE: { // User wants to delete his profile in flash / eeprom.... if ((guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOUSURE)) == RETURN_OK) && (removeCardAndReAuthUser() == RETURN_OK) && (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_AREYOURLSURE)) == RETURN_OK)) { uint8_t currentuserid = getCurrentUserID(); guiDisplayProcessingScreen(); deleteCurrentUserFromFlash(); if (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_ERASE_TCARD)) == RETURN_OK) { guiDisplayProcessingScreen(); eraseSmartCard(); // Erase other smartcards while (guiAskForConfirmation(1, (confirmationText_t*)readStoredStringToBuffer(ID_STRING_OTHECARDFUSER)) == RETURN_OK) { // Ask the user to insert other smartcards guiDisplayInformationOnScreen(ID_STRING_INSERT_OTHER); // Wait for the user to remove and enter another smartcard while (isCardPlugged() != RETURN_JRELEASED); // Wait for the user to insert a new smart card while (isCardPlugged() != RETURN_JDETECT); guiDisplayProcessingScreen(); // Check the card type & ask user to enter his pin, check that the new user id loaded by validCardDetectedFunction is still the same if ((cardDetectedRoutine() == RETURN_MOOLTIPASS_USER) && (validCardDetectedFunction(0, FALSE) == RETURN_VCARD_OK) && (currentuserid == getCurrentUserID())) { eraseSmartCard(); } } } // Delete LUT entries guiDisplayProcessingScreen(); deleteUserIdFromSMCUIDLUT(currentuserid); // Go to invalid screen currentScreen = SCREEN_DEFAULT_INSERTED_INVALID; } else { currentScreen = SCREEN_DEFAULT_INSERTED_LCK; } userViewDelay(); handleSmartcardRemoved(); guiGetBackToCurrentScreen(); break; } default: break; } } } }