kopia lustrzana https://github.com/solokeys/solo1
				
				
				
			Add initial STATE migration code
							rodzic
							
								
									ee351421cb
								
							
						
					
					
						commit
						6c60a37e8a
					
				|  | @ -0,0 +1,87 @@ | |||
| // Copyright 2019 SoloKeys Developers
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 | ||||
| // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
 | ||||
| // http://opensource.org/licenses/MIT>, at your option. This file may not be
 | ||||
| // copied, modified, or distributed except according to those terms.
 | ||||
| 
 | ||||
| #include "data_migration.h" | ||||
| #include "log.h" | ||||
| #include "device.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| // TODO move from macro to function/assert for better readability?
 | ||||
| #define check(x) assert(state_prev_0xff->x == state_tmp_ptr->x); | ||||
| #define check_buf(x) assert(memcmp(state_prev_0xff->x, state_tmp_ptr->x, sizeof(state_tmp_ptr->x)) == 0); | ||||
| 
 | ||||
| bool migrate_from_FF_to_01(AuthenticatorState* state_previous_ptr, AuthenticatorState* state_tmp_ptr){ | ||||
|     // Calculate PIN hash, and replace PIN raw storage with it; add version to structure
 | ||||
|     // other ingredients do not change
 | ||||
|     if (state_tmp_ptr->data_version != 0xFF) | ||||
|         return false; | ||||
| 
 | ||||
|     static_assert(sizeof(AuthenticatorState_0xFF) <= sizeof(AuthenticatorState), "New state structure is smaller, than current one, which is not handled"); | ||||
| 
 | ||||
|     AuthenticatorState_0xFF* state_prev_0xff = (AuthenticatorState_0xFF *) state_previous_ptr; | ||||
| 
 | ||||
|     if (ctap_generate_rng(state_tmp_ptr->PIN_SALT, sizeof(state_tmp_ptr->PIN_SALT)) != 1) { | ||||
|         printf2(TAG_ERR, "Error, rng failed\n"); | ||||
|         return false; | ||||
|     } | ||||
|     if (state_prev_0xff->is_pin_set){ | ||||
|         crypto_sha256_init(); | ||||
|         crypto_sha256_update(state_prev_0xff->pin_code, state_prev_0xff->pin_code_length); | ||||
|         uint8_t intermediateHash[32]; | ||||
|         crypto_sha256_final(intermediateHash); | ||||
| 
 | ||||
|         crypto_sha256_init(); | ||||
|         crypto_sha256_update(intermediateHash, 16); | ||||
|         memset(intermediateHash, 0, sizeof(intermediateHash)); | ||||
|         crypto_sha256_update(state_tmp_ptr->PIN_SALT, sizeof(state_tmp_ptr->PIN_SALT)); | ||||
|         crypto_sha256_final(state_tmp_ptr->PIN_CODE_HASH); | ||||
|     } | ||||
| 
 | ||||
|     state_tmp_ptr->_reserved = 0xFF; | ||||
|     state_tmp_ptr->data_version = 1; | ||||
| 
 | ||||
|     check(is_pin_set); | ||||
|     check(rk_stored); | ||||
|     check(remaining_tries); | ||||
|     check_buf(key_lens); | ||||
|     check_buf(key_space); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void save_migrated_state(AuthenticatorState *state_tmp_ptr) { | ||||
|     memmove(&STATE, state_tmp_ptr, sizeof(AuthenticatorState)); | ||||
|     authenticator_write_state(state_tmp_ptr, 0); | ||||
|     authenticator_write_state(state_tmp_ptr, 1); | ||||
| } | ||||
| 
 | ||||
| void do_migration_if_required(AuthenticatorState* state_current){ | ||||
|     // Currently handles only state structures with the same size, or bigger
 | ||||
|     // FIXME rework to raw buffers with fixed size to allow state structure size decrease
 | ||||
|     if(!state_current->is_initialized) | ||||
|         return; | ||||
| 
 | ||||
|     AuthenticatorState state_tmp; | ||||
|     AuthenticatorState state_previous; | ||||
|     authenticator_read_state(&state_previous); | ||||
|     authenticator_read_state(&state_tmp); | ||||
|     if(state_current->data_version == 0xFF){ | ||||
|         printf2(TAG_ERR, "Running migration\n"); | ||||
|         bool success = migrate_from_FF_to_01(&state_previous, &state_tmp); | ||||
|         if (!success){ | ||||
|             printf2(TAG_ERR, "Failed migration from 0xFF to 1\n"); | ||||
|             // FIXME discuss migration failure behavior
 | ||||
|             goto return_cleanup; | ||||
|         } | ||||
|         dump_hex1(TAG_ERR, (void*)&state_tmp, sizeof(state_tmp)); | ||||
|         dump_hex1(TAG_ERR, (void*)&state_previous, sizeof(state_previous)); | ||||
|         save_migrated_state(&state_tmp); | ||||
|     } | ||||
|     return_cleanup: | ||||
|     memset(&state_tmp, 0, sizeof(AuthenticatorState)); | ||||
|     memset(&state_previous, 0, sizeof(AuthenticatorState)); | ||||
| } | ||||
|  | @ -0,0 +1,15 @@ | |||
| // Copyright 2019 SoloKeys Developers
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
 | ||||
| // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
 | ||||
| // http://opensource.org/licenses/MIT>, at your option. This file may not be
 | ||||
| // copied, modified, or distributed except according to those terms.
 | ||||
| 
 | ||||
| #ifndef FIDO2_PR_DATA_MIGRATION_H | ||||
| #define FIDO2_PR_DATA_MIGRATION_H | ||||
| 
 | ||||
| #include "storage.h" | ||||
| 
 | ||||
| void do_migration_if_required(AuthenticatorState* state_current); | ||||
| 
 | ||||
| #endif //FIDO2_PR_DATA_MIGRATION_H
 | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Szczepan Zalega
						Szczepan Zalega