Skip to content

fix(onetimeauth): prevent double final#246

Closed
tony-go wants to merge 3 commits intomainfrom
onetimeauth-prevent-double-final
Closed

fix(onetimeauth): prevent double final#246
tony-go wants to merge 3 commits intomainfrom
onetimeauth-prevent-double-final

Conversation

@tony-go
Copy link
Copy Markdown
Contributor

@tony-go tony-go commented Mar 10, 2026

 const sodium = require('sodium-native')                                                                   
                                                                                                           
 const state = Buffer.alloc(sodium.crypto_onetimeauth_STATEBYTES)                                          
 const key = Buffer.alloc(sodium.crypto_onetimeauth_KEYBYTES)                                            
 const out = Buffer.alloc(sodium.crypto_onetimeauth_BYTES)                                                 
                                                                                                           
 sodium.randombytes_buf(key)
 sodium.crypto_onetimeauth_init(state, key)
 sodium.crypto_onetimeauth_update(state, Buffer.from('hello'))

 sodium.crypto_onetimeauth_final(state, out)
 console.log('1st final (valid MAC):', out.toString('hex'))

 sodium.crypto_onetimeauth_final(state, out)
 console.log('2nd final (zero MAC) :', out.toString('hex'))

Output:

  # Before
  1st final (valid MAC): bade9f242a8dce16b18e8f4ef409b0fb
  2nd final (zero MAC) : 00000000000000000000000000000000

  # After
  1st final (valid MAC): bade9f242a8dce16b18e8f4ef409b0fb
  AssertionError: state has already been finalized

Signed-off-by: Tony Gorez <gorez.tony@gmail.com>
@tony-go tony-go requested a review from kasperisager March 10, 2026 13:15
Copy link
Copy Markdown
Contributor

@kasperisager kasperisager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd detach the state buffer instead, storing additional state in a global map isn't a little iffy.

@tony-go
Copy link
Copy Markdown
Contributor Author

tony-go commented Mar 10, 2026

I'd detach the state buffer instead, storing additional state in a global map isn't a little iffy.

Yeah I forgot to let a comment, but I was not sure about how to approach it.

tony-go added 2 commits March 10, 2026 14:28
Signed-off-by: Tony Gorez <gorez.tony@gmail.com>
Signed-off-by: Tony Gorez <gorez.tony@gmail.com>
Copy link
Copy Markdown
Contributor

@kasperisager kasperisager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, come to think of it we aren't actually allowed to detach the buffer as we might not own the full ArrayBuffer allocation. I wonder if we can zero the state instead.

@tony-go
Copy link
Copy Markdown
Contributor Author

tony-go commented Mar 10, 2026

Ah, come to think of it we aren't actually allowed to detach the buffer as we might not own the full ArrayBuffer allocation. I wonder if we can zero the state instead.

Oh ownership is an important point that I did not consider in the first place. Thanks for raising it! ;)

Lets try that approach :)

@tony-go
Copy link
Copy Markdown
Contributor Author

tony-go commented Mar 10, 2026

I wonder if we can zero the state instead

@kasperisager How would you check that?

assert(state.some((b) => b !== 0), 'state has already been finalized')

... but sounds like suboptimal ...

Maybe adding a new props to the object like ._finalized ?

@kasperisager
Copy link
Copy Markdown
Contributor

This is a case I'd leave as UB. We wouldn't be guarding against memory access violations in any event.

@tony-go
Copy link
Copy Markdown
Contributor Author

tony-go commented Mar 10, 2026

Yeah lets close it ;)

@tony-go tony-go closed this Mar 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants