Skip to content

Commit

Permalink
avoid nonce reuse for large payloads
Browse files Browse the repository at this point in the history
due to using a counter size of 32bits in the stream cipher, only up to
256TB may be encrypted before a nonce reuse would occur.
This solution checks if the counter has reached the limit on every
increment.
This _may_ add overhead or _may_ be free on some engines and I haven't
benchmarked it
  • Loading branch information
CluEleSsUK committed Jan 18, 2023
1 parent 14f712d commit 843389a
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/age/stream-cipher.ts
Expand Up @@ -12,6 +12,10 @@ const TAG_SIZE = 16 // Poly1305 MAC size
const ENCRYPTED_CHUNK_SIZE = CHUNK_SIZE + TAG_SIZE
const NONCE_SIZE = 12 // STREAM nonce size

// due to using a 32bit uint for the counter, this is the max
// value the counter can be without risking a nonce reuse
const COUNTER_MAX = Math.pow(2, 32)

type ui8a = Uint8Array

export class STREAM {
Expand Down Expand Up @@ -85,6 +89,10 @@ export class STREAM {
// Increments Big Endian Uint8Array-based counter.
// [0, 0, 0] => [0, 0, 1] ... => [0, 0, 255] => [0, 1, 0]
incrementCounter() {
if (this.counter == COUNTER_MAX) {
throw new Error("Stream cipher counter has already hit max value! Aborting to avoid nonce reuse - tlock only supports payloads up to 256TB")
}

this.counter += 1
this.nonceView.setUint32(7, this.counter, false)
}
Expand Down

0 comments on commit 843389a

Please sign in to comment.