Skip to content

Commit

Permalink
add loading spinner to provision and firmware hash steps
Browse files Browse the repository at this point in the history
  • Loading branch information
liamcottle committed Dec 19, 2024
1 parent 5eb0e96 commit 5807073
Showing 1 changed file with 190 additions and 145 deletions.
335 changes: 190 additions & 145 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
<div class="h-2 rounded-full bg-blue-600" :style="{ 'width': `${flashingProgress}%`}"></div>
</div>
</div>

</div>

<div class="border-t px-2 py-1 text-sm">
Expand Down Expand Up @@ -135,9 +136,18 @@
</div>

<div class="p-3">
<button @click="provision" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
<button v-if="!isProvisioning" @click="provision" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
Provision
</button>
<div v-else class="flex items-center space-x-1">
<div class="mr-1">
<svg class="animate-spin h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
<div>Provisioning: please wait...</div>
</div>
</div>

</div>
Expand All @@ -149,9 +159,18 @@
</div>

<div class="p-3">
<button @click="setFirmwareHash" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
<button v-if="!isSettingFirmwareHash" @click="setFirmwareHash" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
Set Firmware Hash
</button>
<div v-else class="flex items-center space-x-1">
<div class="mr-1">
<svg class="animate-spin h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
<div>Setting Firmware Hash: please wait...</div>
</div>
</div>

</div>
Expand Down Expand Up @@ -295,6 +314,9 @@
isFlashing: false,
flashingProgress: 0,

isProvisioning: false,
isSettingFirmwareHash: false,

rnodeDisplayImage: null,

selectedProduct: null,
Expand Down Expand Up @@ -1293,142 +1315,154 @@

console.log("device is not provisioned yet, doing it now...");

// determine device info
// todo implement ui to configure these values
const product = this.selectedProduct.id;
// use mapped_id if available, else fallback to id, some devices use the same model, but different firmware file
const model = this.selectedModel.mapped_id ?? this.selectedModel.id;
const hardwareRevision = 0x1;
const serialNumber = 1;
const timestampInSeconds = Math.floor(Date.now() / 1000);
const serialBytes = this.packInt(serialNumber);
const timestampBytes = this.packInt(timestampInSeconds);

// compute device info checksum
const checksum = Utils.md5([
product,
model,
hardwareRevision,
...serialBytes,
...timestampBytes,
]);

console.log("checksum", checksum);

// write device info to eeprom
console.log("writing device info");
await rnode.writeRom(ROM.ADDR_PRODUCT, product);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_MODEL, model);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_HW_REV, hardwareRevision);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_SERIAL, serialBytes[0]);
await rnode.writeRom(ROM.ADDR_SERIAL + 1, serialBytes[1]);
await rnode.writeRom(ROM.ADDR_SERIAL + 2, serialBytes[2]);
await rnode.writeRom(ROM.ADDR_SERIAL + 3, serialBytes[3]);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_MADE, timestampBytes[0]);
await rnode.writeRom(ROM.ADDR_MADE + 1, timestampBytes[1]);
await rnode.writeRom(ROM.ADDR_MADE + 2, timestampBytes[2]);
await rnode.writeRom(ROM.ADDR_MADE + 3, timestampBytes[3]);
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing device info: done");

// write checksum to eeprom
console.log("writing checksum");
for(var i = 0; i < 16; i++){
await rnode.writeRom(ROM.ADDR_CHKSUM + i, checksum[i]);
}
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing checksum: done");

// write signature to eeprom
// fixme: actually implement signature, for now it's just zeroed out
console.log("writing signature");
for(var i = 0; i < 128; i++){
// await rnode.writeRom(ROM.ADDR_SIGNATURE + i, signature[i]);
await rnode.writeRom(ROM.ADDR_SIGNATURE + i, 0x00); // fixme: fake signature
this.isProvisioning = true;

try {

// determine device info
// todo implement ui to configure these values
const product = this.selectedProduct.id;
// use mapped_id if available, else fallback to id, some devices use the same model, but different firmware file
const model = this.selectedModel.mapped_id ?? this.selectedModel.id;
const hardwareRevision = 0x1;
const serialNumber = 1;
const timestampInSeconds = Math.floor(Date.now() / 1000);
const serialBytes = this.packInt(serialNumber);
const timestampBytes = this.packInt(timestampInSeconds);

// compute device info checksum
const checksum = Utils.md5([
product,
model,
hardwareRevision,
...serialBytes,
...timestampBytes,
]);

console.log("checksum", checksum);

// write device info to eeprom
console.log("writing device info");
await rnode.writeRom(ROM.ADDR_PRODUCT, product);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_MODEL, model);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_HW_REV, hardwareRevision);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_SERIAL, serialBytes[0]);
await rnode.writeRom(ROM.ADDR_SERIAL + 1, serialBytes[1]);
await rnode.writeRom(ROM.ADDR_SERIAL + 2, serialBytes[2]);
await rnode.writeRom(ROM.ADDR_SERIAL + 3, serialBytes[3]);
console.log(Utils.bytesToHex(await rnode.getRom()));
await rnode.writeRom(ROM.ADDR_MADE, timestampBytes[0]);
await rnode.writeRom(ROM.ADDR_MADE + 1, timestampBytes[1]);
await rnode.writeRom(ROM.ADDR_MADE + 2, timestampBytes[2]);
await rnode.writeRom(ROM.ADDR_MADE + 3, timestampBytes[3]);
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing device info: done");

// write checksum to eeprom
console.log("writing checksum");
for(var i = 0; i < 16; i++){
await rnode.writeRom(ROM.ADDR_CHKSUM + i, checksum[i]);
}
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing checksum: done");

// write signature to eeprom
// fixme: actually implement signature, for now it's just zeroed out
console.log("writing signature");
for(var i = 0; i < 128; i++){
// await rnode.writeRom(ROM.ADDR_SIGNATURE + i, signature[i]);
await rnode.writeRom(ROM.ADDR_SIGNATURE + i, 0x00); // fixme: fake signature
}
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing signature: done");

// write info lock byte to eeprom
console.log("writing lock byte");
await rnode.writeRom(ROM.ADDR_INFO_LOCK, ROM.INFO_LOCK_BYTE);
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing lock byte: done");

// todo get partition hash from release.json OR directly from the firmware.bin
// partition_filename = fw_filename.replace(".zip", ".bin")
// partition_hash = get_partition_hash(rnode.platform, UPD_DIR+"/"+selected_version+"/"+partition_filename)

// todo set firmware hash in eeprom
// RNS.log("Setting firmware checksum...")
// rnode.set_firmware_hash(partition_hash)

// RNS.log("Generating a new device signing key...")
// device_signer = RNS.Identity()
// device_signer.to_file(FWD_DIR+"/device.key")
// RNS.log("Device signing key written to "+str(FWD_DIR+"/device.key"))

// if not os.path.isfile(FWD_DIR+"/signing.key"):
// RNS.log("Generating a new EEPROM signing key...")
// private_key = rsa.generate_private_key(
// public_exponent=65537,
// key_size=1024,
// backend=default_backend()
// )
// private_bytes = private_key.private_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PrivateFormat.PKCS8,
// encryption_algorithm=serialization.NoEncryption()
// )
// public_key = private_key.public_key()
// public_bytes = public_key.public_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PublicFormat.SubjectPublicKeyInfo
// )

// can get partition hash from releases.json
// partition_hash = bytes.fromhex(release_info.split()[1])

// await rnode.indicateFirmwareUpdate();
// await rnode.setFirmwareHash(partition_hash);

// todo get signing.key

// file = open(key_path, "rb")
// private_bytes = file.read()
// file.close()
// private_key = serialization.load_der_private_key(
// private_bytes,
// password=None,
// backend=default_backend()
// )
// public_key = private_key.public_key()
// public_bytes = public_key.public_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PublicFormat.SubjectPublicKeyInfo
// )
// signature = private_key.sign(
// checksum,
// padding.PSS(
// mgf=padding.MGF1(hashes.SHA256()),
// salt_length=padding.PSS.MAX_LENGTH
// ),
// hashes.SHA256()
// )

// wait a bit for eeprom writes to complete
await Utils.sleepMillis(5000);

// done
await rnode.reset();

alert("device has been provisioned!");

} catch(e) {
console.log(e);
alert("failed to provision, please try again");
}
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing signature: done");

// write info lock byte to eeprom
console.log("writing lock byte");
await rnode.writeRom(ROM.ADDR_INFO_LOCK, ROM.INFO_LOCK_BYTE);
console.log(Utils.bytesToHex(await rnode.getRom()));
console.log("writing lock byte: done");

// todo get partition hash from release.json OR directly from the firmware.bin
// partition_filename = fw_filename.replace(".zip", ".bin")
// partition_hash = get_partition_hash(rnode.platform, UPD_DIR+"/"+selected_version+"/"+partition_filename)

// todo set firmware hash in eeprom
// RNS.log("Setting firmware checksum...")
// rnode.set_firmware_hash(partition_hash)

// RNS.log("Generating a new device signing key...")
// device_signer = RNS.Identity()
// device_signer.to_file(FWD_DIR+"/device.key")
// RNS.log("Device signing key written to "+str(FWD_DIR+"/device.key"))

// if not os.path.isfile(FWD_DIR+"/signing.key"):
// RNS.log("Generating a new EEPROM signing key...")
// private_key = rsa.generate_private_key(
// public_exponent=65537,
// key_size=1024,
// backend=default_backend()
// )
// private_bytes = private_key.private_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PrivateFormat.PKCS8,
// encryption_algorithm=serialization.NoEncryption()
// )
// public_key = private_key.public_key()
// public_bytes = public_key.public_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PublicFormat.SubjectPublicKeyInfo
// )

// can get partition hash from releases.json
// partition_hash = bytes.fromhex(release_info.split()[1])

// await rnode.indicateFirmwareUpdate();
// await rnode.setFirmwareHash(partition_hash);

// todo get signing.key

// file = open(key_path, "rb")
// private_bytes = file.read()
// file.close()
// private_key = serialization.load_der_private_key(
// private_bytes,
// password=None,
// backend=default_backend()
// )
// public_key = private_key.public_key()
// public_bytes = public_key.public_bytes(
// encoding=serialization.Encoding.DER,
// format=serialization.PublicFormat.SubjectPublicKeyInfo
// )
// signature = private_key.sign(
// checksum,
// padding.PSS(
// mgf=padding.MGF1(hashes.SHA256()),
// salt_length=padding.PSS.MAX_LENGTH
// ),
// hashes.SHA256()
// )

// wait a bit for eeprom writes to complete
await Utils.sleepMillis(5000);
this.isProvisioning = false;

// done
await rnode.reset();
await rnode.close();

alert("device has been provisioned!");

},
async setFirmwareHash() {

Expand All @@ -1455,26 +1489,37 @@
return;
}

// todo: this works, but we should be calculating the firmware hash from the file, and not giving the board what it already knows
console.log("setting firmware hash");
await rnode.setFirmwareHash(await rnode.getFirmwareHash());
console.log("setting firmware hash: done");
this.isSettingFirmwareHash = true;

// wait a bit for eeprom writes to complete
await Utils.sleepMillis(5000);

// reset board if it didn't do it automatically
try {
await rnode.reset();

// todo: this works, but we should be calculating the firmware hash from the file, and not giving the board what it already knows
console.log("setting firmware hash");
await rnode.setFirmwareHash(await rnode.getFirmwareHash());
console.log("setting firmware hash: done");

// wait a bit for eeprom writes to complete
await Utils.sleepMillis(5000);

// reset board if it didn't do it automatically
try {
await rnode.reset();
} catch(e) {
console.log("couldn't auto reset board, probably did it automatically...");
}

alert("firmware hash has been set!");

} catch(e) {
console.log("couldn't auto reset board, probably did it automatically...");
console.log(e);
alert("failed to set firmware hash, please try again")
}

this.isSettingFirmwareHash = false;

// done
await rnode.close();

alert("firmware hash has been set!");

},
async enableTncMode() {

Expand Down

0 comments on commit 5807073

Please sign in to comment.