New Uint8Arrays are sometimes filled with garbage #2930
Description
Unfortunately, I don't have a neat small test case, so please bear with me.
One TweetNaCl-js test with Node.js 4.1 fails, while succeeding with 0.12 and io.js v3.3.1. The test is encrypting a message and comparing the result with a known good value.
To reproduce:
mkdir reproduce
cd reproduce
git clone https://github.com/dchest/tweetnacl-js.git
cd tweetnacl-js
npm install tape
NACL_SRC=nacl.js node ./test/04-secretbox.js | more
Output:
TAP version 13
# nacl.secretbox random test vectors
ok 1 box should be created
ok 2 should be equal
ok 3 box should open
ok 4 should be equal
ok 5 box should be created
not ok 6 should be equal
---
operator: equal
expected: 'VJViVugBhKeaOvfSlHkTzUQ='
actual: 'ZpRiVugBhKeaOvfSlHkTzUQ='
at: Test.<anonymous> (/Users/dchest/reproduce/tweetnacl-js/test/04-secretbox.js:10:17)
...
(actual
may be different for you)
The cause is in this function in nacl.js
:
https://github.com/dchest/tweetnacl-js/blob/master/nacl.js#L990
nacl.secretbox = function(msg, nonce, key) {
checkArrayTypes(msg, nonce, key);
checkLengths(key, nonce);
var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); // <-- BUG HERE
var c = new Uint8Array(m.length);
for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
crypto_secretbox(c, m, m.length, nonce, key);
return c.subarray(crypto_secretbox_BOXZEROBYTES);
};
This function requires that m
must be zero-filled.
If I add console.log
after creating m
to see what's there:
nacl.secretbox = function(msg, nonce, key) {
checkArrayTypes(msg, nonce, key);
checkLengths(key, nonce);
var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); // <-- BUG HERE
console.log(m); // <--- ADDED
var c = new Uint8Array(m.length);
for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
crypto_secretbox(c, m, m.length, nonce, key);
return c.subarray(crypto_secretbox_BOXZEROBYTES);
};
and run the test again, I see that m
contains some garbage data (results differ from time to time):
Uint8Array {
'0': 0,
'1': 0,
'2': 0,
'3': 0,
'4': 0,
'5': 0,
'6': 0,
'7': 0,
'8': 0,
'9': 0,
'10': 0,
'11': 0,
'12': 0,
'13': 0,
'14': 0,
'15': 0,
'16': 232,
'17': 0,
'18': 0,
'19': 0,
'20': 0,
'21': 0,
'22': 0,
'23': 0,
'24': 64,
'25': 231,
'26': 96,
'27': 1,
'28': 1,
'29': 0,
'30': 0,
'31': 0,
'32': 0 }
This only happens for this particular 33-byte Uint8Array in this particular setting (e.g. I couldn't reproduce this outside of this test). I can work around this by manually zeroing the array after creating it.
Any ideas? As I said, io.js v3.3.1 and previous Node versions doesn't have this bug.
Activity