@@ -160,69 +160,6 @@ static bool _copy_bip39_seed(uint8_t* bip39_seed_out)
160
160
return true;
161
161
}
162
162
163
- /**
164
- * Stretch the user password using the securechip, putting the result in `kdf_out`, which must be 32
165
- * bytes. `securechip_result_out`, if not NULL, will contain the error code from `securechip_kdf()`
166
- * if there was a secure chip error, and 0 otherwise.
167
- */
168
- static keystore_error_t _stretch_password (
169
- const char * password ,
170
- uint8_t * kdf_out ,
171
- int * securechip_result_out )
172
- {
173
- if (securechip_result_out != NULL ) {
174
- * securechip_result_out = 0 ;
175
- }
176
- uint8_t password_salted_hashed [32 ] = {0 };
177
- UTIL_CLEANUP_32 (password_salted_hashed );
178
- if (!salt_hash_data (
179
- (const uint8_t * )password ,
180
- strlen (password ),
181
- "keystore_seed_access_in" ,
182
- password_salted_hashed )) {
183
- return KEYSTORE_ERR_SALT ;
184
- }
185
-
186
- uint8_t kdf_in [32 ] = {0 };
187
- UTIL_CLEANUP_32 (kdf_in );
188
- memcpy (kdf_in , password_salted_hashed , 32 );
189
-
190
- // First KDF on rollkey increments the monotonic counter. Call only once!
191
- int securechip_result = securechip_kdf_rollkey (kdf_in , 32 , kdf_out );
192
- if (securechip_result ) {
193
- if (securechip_result_out != NULL ) {
194
- * securechip_result_out = securechip_result ;
195
- }
196
- return KEYSTORE_ERR_SECURECHIP ;
197
- }
198
- // Second KDF does not use the counter and we call it multiple times.
199
- for (int i = 0 ; i < KDF_NUM_ITERATIONS ; i ++ ) {
200
- memcpy (kdf_in , kdf_out , 32 );
201
- securechip_result = securechip_kdf (kdf_in , 32 , kdf_out );
202
- if (securechip_result ) {
203
- if (securechip_result_out != NULL ) {
204
- * securechip_result_out = securechip_result ;
205
- }
206
- return KEYSTORE_ERR_SECURECHIP ;
207
- }
208
- }
209
-
210
- if (!salt_hash_data (
211
- (const uint8_t * )password ,
212
- strlen (password ),
213
- "keystore_seed_access_out" ,
214
- password_salted_hashed )) {
215
- return KEYSTORE_ERR_SALT ;
216
- }
217
- if (wally_hmac_sha256 (
218
- password_salted_hashed , sizeof (password_salted_hashed ), kdf_out , 32 , kdf_out , 32 ) !=
219
- WALLY_OK ) {
220
- return KEYSTORE_ERR_HASH ;
221
- }
222
-
223
- return KEYSTORE_OK ;
224
- }
225
-
226
163
/**
227
164
* Retrieves the encrypted seed and attempts to decrypt it using the password.
228
165
*
@@ -243,9 +180,19 @@ static keystore_error_t _get_and_decrypt_seed(
243
180
}
244
181
uint8_t secret [32 ];
245
182
UTIL_CLEANUP_32 (secret );
246
- keystore_error_t result = _stretch_password (password , secret , securechip_result_out );
247
- if (result != KEYSTORE_OK ) {
248
- return result ;
183
+ int stretch_result = securechip_stretch_password (password , secret );
184
+ if (stretch_result ) {
185
+ if (stretch_result == SC_ERR_INCORRECT_PASSWORD ) {
186
+ // Our Optiga securechip implementation fails password stretching if the password is
187
+ // wrong, so we can early-abort here. The ATECC stretches the password without checking
188
+ // if the password is correct, and we determine if it is correct in the seed decryption
189
+ // step below.
190
+ return KEYSTORE_ERR_INCORRECT_PASSWORD ;
191
+ }
192
+ if (securechip_result_out != NULL ) {
193
+ * securechip_result_out = stretch_result ;
194
+ }
195
+ return KEYSTORE_ERR_SECURECHIP ;
249
196
}
250
197
if (encrypted_len < 49 ) {
251
198
Abort ("_get_and_decrypt_seed: underflow / zero size" );
@@ -299,17 +246,13 @@ keystore_error_t keystore_encrypt_and_store_seed(
299
246
if (!_validate_seed_length (seed_length )) {
300
247
return KEYSTORE_ERR_SEED_SIZE ;
301
248
}
302
- // Update the two kdf keys before setting a new password. This already
303
- // happens on a device reset, but we do it here again anyway so the keys are
304
- // initialized also on first use, reducing trust in the factory setup.
305
- if (!securechip_update_keys ()) {
249
+ if (securechip_init_new_password (password )) {
306
250
return KEYSTORE_ERR_SECURECHIP ;
307
251
}
308
252
uint8_t secret [32 ] = {0 };
309
253
UTIL_CLEANUP_32 (secret );
310
- keystore_error_t res = _stretch_password (password , secret , NULL );
311
- if (res != KEYSTORE_OK ) {
312
- return res ;
254
+ if (securechip_stretch_password (password , secret )) {
255
+ return KEYSTORE_ERR_SECURECHIP ;
313
256
}
314
257
315
258
size_t encrypted_seed_len = seed_length + 64 ;
0 commit comments