Skip to content

Commit e5d8880

Browse files
Merge pull request #565 from Foundation-Devices/dev-v2.3.5
v2.3.5
2 parents 457e740 + 3c2c750 commit e5d8880

File tree

5 files changed

+66
-22
lines changed

5 files changed

+66
-22
lines changed

extmod/foundation-rust/include/foundation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ typedef enum {
171171
* The second signature verification failed.
172172
*/
173173
FIRMWARE_RESULT_FAILED_SIGNATURE2,
174+
/**
175+
* Missing user public key
176+
*/
177+
FIRMWARE_RESULT_MISSING_USER_PUBLIC_KEY,
178+
/**
179+
* Invalid hash length
180+
*/
181+
FIRMWARE_RESULT_INVALID_HASH_LENGTH,
174182
} FirmwareResult_Tag;
175183

176184
typedef struct {

extmod/foundation-rust/src/firmware.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ pub enum FirmwareResult {
5353
FailedSignature1,
5454
/// The second signature verification failed.
5555
FailedSignature2,
56+
/// Missing user public key
57+
MissingUserPublicKey,
58+
/// Invalid hash length
59+
InvalidHashLength,
5660
}
5761

5862
impl From<VerifyHeaderError> for FirmwareResult {
@@ -85,9 +89,7 @@ impl From<VerifySignatureError> for FirmwareResult {
8589
}
8690
VerifySignatureError::FailedSignature1 { .. } => FailedSignature1,
8791
VerifySignatureError::FailedSignature2 { .. } => FailedSignature2,
88-
// No need to implement this, see comment on
89-
// verify_update_signatures.
90-
VerifySignatureError::MissingUserPublicKey => unimplemented!(),
92+
VerifySignatureError::MissingUserPublicKey => MissingUserPublicKey,
9193
}
9294
}
9395
}
@@ -159,8 +161,13 @@ pub extern "C" fn verify_update_signatures(
159161
result: &mut FirmwareResult,
160162
) {
161163
let header = unsafe { slice::from_raw_parts(header, header_len) };
162-
let firmware_hash = sha256d::Hash::from_slice(hash)
163-
.expect("hash should be of correct length");
164+
let firmware_hash = match sha256d::Hash::from_slice(hash) {
165+
Ok(v) => v,
166+
Err(_) => {
167+
*result = FirmwareResult::InvalidHashLength;
168+
return;
169+
}
170+
};
164171

165172
let user_public_key = user_public_key
166173
.map(|v| {
@@ -169,8 +176,10 @@ pub extern "C" fn verify_update_signatures(
169176
(&mut buf[1..]).copy_from_slice(v);
170177
buf
171178
})
172-
.map(|v| {
173-
PublicKey::from_slice(&v).expect("user public key should be valid")
179+
.and_then(|v| {
180+
// If we fail to parse the public key, it means that the user
181+
// installed an invalid public key to the secure element.
182+
PublicKey::from_slice(&v).ok()
174183
});
175184

176185
let header =
@@ -188,15 +197,6 @@ pub extern "C" fn verify_update_signatures(
188197
Ok(()) => {
189198
*result = FirmwareResult::SignaturesOk;
190199
}
191-
// The code calling this function must make sure that there's an user
192-
// public key provided to us before verifying signatures.
193-
//
194-
// When verifying signatures is because we are committed to the
195-
// update, i.e. the user has accepted to do it, so we must have
196-
// presented an error if there was not an user public key earlier.
197-
Err(VerifySignatureError::MissingUserPublicKey) => {
198-
unreachable!("we always provide a user public key")
199-
}
200200
Err(e) => *result = FirmwareResult::from(e),
201201
}
202202
}

ports/stm32/boards/Passport/modpassport.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ STATIC mp_obj_t mod_passport_verify_update_header(mp_obj_t header) {
135135
MP_ERROR_TEXT("Same Public Key was used for both signatures (%"PRIu32")."),
136136
result.SAME_PUBLIC_KEY.index);
137137
break;
138+
case FIRMWARE_RESULT_MISSING_USER_PUBLIC_KEY:
139+
mp_raise_msg(&mp_type_InvalidFirmwareUpdate,
140+
MP_ERROR_TEXT("Missing user public key"));
141+
break;
142+
case FIRMWARE_RESULT_INVALID_HASH_LENGTH:
143+
mp_raise_msg(&mp_type_InvalidFirmwareUpdate,
144+
MP_ERROR_TEXT("Invalid hash length"));
145+
break;
138146
default:
139147
break;
140148
}
@@ -145,9 +153,21 @@ STATIC mp_obj_t mod_passport_verify_update_header(mp_obj_t header) {
145153
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_passport_verify_update_header_obj,
146154
mod_passport_verify_update_header);
147155

156+
STATIC bool array_is_zero(uint8_t *buf, size_t size)
157+
{
158+
for (int i = 0; i < size; i++) {
159+
if (buf[i] != 0) {
160+
return false;
161+
}
162+
}
163+
164+
return true;
165+
}
166+
167+
148168
STATIC mp_obj_t mod_passport_verify_update_signatures(mp_obj_t header, mp_obj_t validation_hash) {
149-
uint8_t buf[72];
150-
uint8_t public_key[64];
169+
uint8_t buf[72] = {0};
170+
uint8_t public_key[64] = {0};
151171

152172
mp_buffer_info_t header_info;
153173
mp_get_buffer_raise(header, &header_info, MP_BUFFER_READ);
@@ -163,9 +183,16 @@ STATIC mp_obj_t mod_passport_verify_update_signatures(mp_obj_t header, mp_obj_t
163183
uint32_t firmware_timestamp = se_get_firmware_timestamp(current_board_hash);
164184

165185
se_pair_unlock();
166-
bool has_user_key = se_read_data_slot(KEYNUM_user_fw_pubkey, buf, sizeof(buf)) == 0;
167-
memcpy(public_key, buf, sizeof(public_key));
186+
bool has_user_key = false;
187+
if (se_read_data_slot(KEYNUM_user_fw_pubkey, buf, sizeof(buf)) == 0) {
188+
memcpy(public_key, buf, sizeof(public_key));
189+
190+
has_user_key = !array_is_zero(public_key, sizeof(public_key));
191+
}
168192

193+
// If we fail reading the user key from the secure element just pass NULL
194+
// and the verification won't take into account the user key and will
195+
// return an error if it is an user signed firmware.
169196
FirmwareResult result = {0};
170197
foundation_firmware_verify_update_signatures(header_info.buf,
171198
header_info.len,
@@ -232,6 +259,15 @@ STATIC mp_obj_t mod_passport_verify_update_signatures(mp_obj_t header, mp_obj_t
232259
case FIRMWARE_RESULT_FAILED_SIGNATURE2:
233260
mp_raise_msg(&mp_type_InvalidFirmwareUpdate,
234261
MP_ERROR_TEXT("Second signature verification failed"));
262+
break;
263+
case FIRMWARE_RESULT_MISSING_USER_PUBLIC_KEY:
264+
mp_raise_msg(&mp_type_InvalidFirmwareUpdate,
265+
MP_ERROR_TEXT("Missing user public key"));
266+
break;
267+
case FIRMWARE_RESULT_INVALID_HASH_LENGTH:
268+
mp_raise_msg(&mp_type_InvalidFirmwareUpdate,
269+
MP_ERROR_TEXT("Invalid hash length"));
270+
break;
235271
default:
236272
break;
237273
}

ports/stm32/boards/Passport/modules/flows/update_firmware_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async def show_firmware_details(self):
106106
async def verify_firmware_signature(self):
107107
from common import ui
108108

109-
self.progress_page = ProgressPage(text='Veryfing Signatures', left_micron=None, right_micron=None)
109+
self.progress_page = ProgressPage(text='Verifying signatures', left_micron=None, right_micron=None)
110110

111111
self.verify_task = start_task(verify_firmware_signature_task(
112112
self.update_file_path, self.size, self.progress_page.set_progress, self.on_done))

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.3.4
1+
2.3.5

0 commit comments

Comments
 (0)