aboutsummaryrefslogtreecommitdiff
path: root/source/storage/Record.mc
diff options
context:
space:
mode:
Diffstat (limited to 'source/storage/Record.mc')
-rw-r--r--source/storage/Record.mc33
1 files changed, 29 insertions, 4 deletions
diff --git a/source/storage/Record.mc b/source/storage/Record.mc
index b26a4ba..2cfc046 100644
--- a/source/storage/Record.mc
+++ b/source/storage/Record.mc
@@ -63,12 +63,24 @@ module Record {
// Seal an entry into record bytes. keyRef is KEY_DEVICE or KEY_MASTER and
// must match `keys`. The plaintext TLV is wiped before returning.
function seal(entry as Entry, keyRef as Number, keys as SealedBox.Keys) as ByteArray {
+ return sealWith(entry, keyRef, keys, null);
+ }
+
+ // As seal(), but the plaintext TLV goes to `wiper` when given: wiping a
+ // large code's contents is a step of its own (the watchdog).
+ function sealWith(entry as Entry, keyRef as Number, keys as SealedBox.Keys, wiper as Jobs.Wiper?) as ByteArray {
var header = encodeHeader(entry);
var record = [VERSION, keyRef, (header.size() >> 8) & 0xFF, header.size() & 0xFF]b;
record.addAll(header);
var plain = encodeSecret(entry);
- var box = SealedBox.seal(keys, aad(entry.id, record), plain);
- Bytes.wipe(plain);
+ var leftovers = wiper != null ? [] as Array<ByteArray> : null;
+ var box = SealedBox.sealKeep(keys, aad(entry.id, record), plain, leftovers);
+ if (wiper != null) {
+ wiper.add(plain);
+ wiper.addAll(leftovers as Array<ByteArray>);
+ } else {
+ Bytes.wipe(plain);
+ }
record.addAll(box);
return record;
}
@@ -119,17 +131,30 @@ module Record {
// keys, stored under another ID, or changed in any way. The decrypted
// TLV is wiped; the caller must call entry.wipeSecrets() when done.
function open(record as ByteArray, id as String, keys as SealedBox.Keys) as Entry? {
+ return openWith(record, id, keys, null);
+ }
+
+ // As open(), but the decrypted TLV goes to `wiper` when given.
+ function openWith(record as ByteArray, id as String, keys as SealedBox.Keys, wiper as Jobs.Wiper?) as Entry? {
var entry = decodeHeader(record);
var end = headerEnd(record);
if (entry == null || end == null || !entry.id.equals(id)) {
return null;
}
- var plain = SealedBox.open(keys, aad(id, record.slice(0, end)), record.slice(end, record.size()));
+ var leftovers = wiper != null ? [] as Array<ByteArray> : null;
+ var plain = SealedBox.openKeep(keys, aad(id, record.slice(0, end)), record.slice(end, record.size()), leftovers);
+ if (wiper != null) {
+ wiper.addAll(leftovers as Array<ByteArray>);
+ }
if (plain == null) {
return null;
}
var map = Codec.decode(plain);
- Bytes.wipe(plain);
+ if (wiper != null) {
+ wiper.add(plain);
+ } else {
+ Bytes.wipe(plain);
+ }
if (map == null) {
return null;
}