Skip to content

Commit

Permalink
test: increase crypto strength for FIPS standard
Browse files Browse the repository at this point in the history
Use stronger crypto (larger keys, etc.) for arbitrary tests so
they will pass in both FIPS and non-FIPS mode without altering
the original intent of the test cases.

PR-URL: #3758
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
stefanmb authored and jasnell committed Dec 23, 2015
1 parent 0aa341b commit 9837387
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 48 deletions.
2 changes: 1 addition & 1 deletion test/parallel/test-crypto-binary-default.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ assert.throws(function() {

// Test Diffie-Hellman with two parties sharing a secret,
// using various encodings as we go along
var dh1 = crypto.createDiffieHellman(256);
var dh1 = crypto.createDiffieHellman(1024);
var p1 = dh1.getPrime('buffer');
var dh2 = crypto.createDiffieHellman(p1, 'base64');
var key1 = dh1.generateKeys();
Expand Down
19 changes: 14 additions & 5 deletions test/parallel/test-crypto-dh-odd-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ if (!common.hasCrypto) {
}
var crypto = require('crypto');

var odd = new Buffer(39);
odd.fill('A');
function test() {
var odd = new Buffer(39);
odd.fill('A');

var c = crypto.createDiffieHellman(32);
c.setPrivateKey(odd);
c.generateKeys();
var c = crypto.createDiffieHellman(32);
c.setPrivateKey(odd);
c.generateKeys();
}

// FIPS requires a length of at least 1024
if (!common.hasFipsCrypto) {
assert.doesNotThrow(function() { test(); });
} else {
assert.throws(function() { test(); }, /key size too small/);
}
69 changes: 37 additions & 32 deletions test/parallel/test-crypto-dh.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var crypto = require('crypto');

// Test Diffie-Hellman with two parties sharing a secret,
// using various encodings as we go along
var dh1 = crypto.createDiffieHellman(256);
var dh1 = crypto.createDiffieHellman(1024);
var p1 = dh1.getPrime('buffer');
var dh2 = crypto.createDiffieHellman(p1, 'buffer');
var key1 = dh1.generateKeys();
Expand Down Expand Up @@ -82,9 +82,11 @@ assert.equal(aSecret, bSecret);
assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);

// Ensure specific generator (buffer) works as expected.
var modp1 = crypto.createDiffieHellmanGroup('modp1');
var modp1buf = new Buffer([
/* Ensure specific generator (buffer) works as expected.
* The values below (modp2/modp2buf) are for a 1024 bits long prime from
* RFC 2412 E.2, see https://tools.ietf.org/html/rfc2412. */
var modp2 = crypto.createDiffieHellmanGroup('modp2');
var modp2buf = new Buffer([
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f,
0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67,
Expand All @@ -93,47 +95,50 @@ var modp1buf = new Buffer([
0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51,
0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff,
0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb,
0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b,
0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
]);
var exmodp1 = crypto.createDiffieHellman(modp1buf, new Buffer([2]));
modp1.generateKeys();
exmodp1.generateKeys();
var modp1Secret = modp1.computeSecret(exmodp1.getPublicKey()).toString('hex');
var exmodp1Secret = exmodp1.computeSecret(modp1.getPublicKey()).toString('hex');
assert.equal(modp1Secret, exmodp1Secret);
assert.equal(modp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(exmodp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
var exmodp2 = crypto.createDiffieHellman(modp2buf, new Buffer([2]));
modp2.generateKeys();
exmodp2.generateKeys();
var modp2Secret = modp2.computeSecret(exmodp2.getPublicKey()).toString('hex');
var exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey()).toString('hex');
assert.equal(modp2Secret, exmodp2Secret);
assert.equal(modp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(exmodp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);


// Ensure specific generator (string with encoding) works as expected.
var exmodp1_2 = crypto.createDiffieHellman(modp1buf, '02', 'hex');
exmodp1_2.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_2.getPublicKey()).toString('hex');
var exmodp1_2Secret = exmodp1_2.computeSecret(modp1.getPublicKey())
var exmodp2_2 = crypto.createDiffieHellman(modp2buf, '02', 'hex');
exmodp2_2.generateKeys();
modp2Secret = modp2.computeSecret(exmodp2_2.getPublicKey()).toString('hex');
var exmodp2_2Secret = exmodp2_2.computeSecret(modp2.getPublicKey())
.toString('hex');
assert.equal(modp1Secret, exmodp1_2Secret);
assert.equal(exmodp1_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(modp2Secret, exmodp2_2Secret);
assert.equal(exmodp2_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);


// Ensure specific generator (string without encoding) works as expected.
var exmodp1_3 = crypto.createDiffieHellman(modp1buf, '\x02');
exmodp1_3.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_3.getPublicKey()).toString('hex');
var exmodp1_3Secret = exmodp1_3.computeSecret(modp1.getPublicKey())
var exmodp2_3 = crypto.createDiffieHellman(modp2buf, '\x02');
exmodp2_3.generateKeys();
modp2Secret = modp2.computeSecret(exmodp2_3.getPublicKey()).toString('hex');
var exmodp2_3Secret = exmodp2_3.computeSecret(modp2.getPublicKey())
.toString('hex');
assert.equal(modp1Secret, exmodp1_3Secret);
assert.equal(exmodp1_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(modp2Secret, exmodp2_3Secret);
assert.equal(exmodp2_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);


// Ensure specific generator (numeric) works as expected.
var exmodp1_4 = crypto.createDiffieHellman(modp1buf, 2);
exmodp1_4.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_4.getPublicKey()).toString('hex');
var exmodp1_4Secret = exmodp1_4.computeSecret(modp1.getPublicKey())
var exmodp2_4 = crypto.createDiffieHellman(modp2buf, 2);
exmodp2_4.generateKeys();
modp2Secret = modp2.computeSecret(exmodp2_4.getPublicKey()).toString('hex');
var exmodp2_4Secret = exmodp2_4.computeSecret(modp2.getPublicKey())
.toString('hex');
assert.equal(modp1Secret, exmodp1_4Secret);
assert.equal(exmodp1_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(modp2Secret, exmodp2_4Secret);
assert.equal(exmodp2_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);


var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-crypto-ecb.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ if (!common.hasCrypto) {
console.log('1..0 # Skipped: missing crypto');
return;
}
if (common.hasFipsCrypto) {
console.log('1..0 # Skipped: BF-ECB is not FIPS 140-2 compatible');
return;
}
var crypto = require('crypto');

crypto.DEFAULT_ENCODING = 'buffer';
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ assert.throws(function() {
''
].join('\n');
crypto.createSign('RSA-SHA256').update('test').sign(priv);
}, /RSA_sign:digest too big for rsa key/);
}, /digest too big for rsa key/);

assert.throws(function() {
// The correct header inside `test_bad_rsa_privkey.pem` should have been
Expand Down
81 changes: 73 additions & 8 deletions test/parallel/test-dh-padding.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,83 @@ try {
return;
}

var prime = 'c51f7bf8f0e1cf899243cdf408b1bc7c09c010e33ef7f3fbe5bd5feaf906113b';
var apub = '6fe9f37037d8d017f908378c1ee04fe60e1cd3668bfc5075fac55c2f7153dd84';
var bpub = '31d83e167fdf956c9dae6b980140577a9f8868acbfcbdc19113e58bfb9223abc';
var apriv = '4fbfd4661f9181bbf574537b1a78adf473e8e771eef13c605e963c0f3094b697';
var secret = '25616eed33f1af7975bbd0a8071d98a014f538b243bef90d76c08e81a0b3c500';
/* This test verifies padding with leading zeroes for shared
* secrets that are strictly smaller than the modulus (prime).
* See:
* RFC 4346: https://www.ietf.org/rfc/rfc4346.txt
* https://github.com/nodejs/node-v0.x-archive/issues/7906
* https://github.com/nodejs/node-v0.x-archive/issues/5239
*
* In FIPS mode OPENSSL_DH_FIPS_MIN_MODULUS_BITS = 1024, meaning we need
* a FIPS-friendly >= 1024 bit prime, we can use MODP 14 from RFC 3526:
* https://www.ietf.org/rfc/rfc3526.txt
*
* We can generate appropriate values with this code:
*
* crypto = require('crypto');
*
* for (;;) {
* var a = crypto.getDiffieHellman('modp14'),
* var b = crypto.getDiffieHellman('modp14');
*
* a.generateKeys();
* b.generateKeys();
*
* var aSecret = a.computeSecret(b.getPublicKey()).toString('hex');
* console.log("A public: " + a.getPublicKey().toString('hex'));
* console.log("A private: " + a.getPrivateKey().toString('hex'));
* console.log("B public: " + b.getPublicKey().toString('hex'));
* console.log("B private: " + b.getPrivateKey().toString('hex'));
* console.log("A secret: " + aSecret);
* console.log('-------------------------------------------------');
* if(aSecret.substring(0,2) === "00") {
* console.log("found short key!");
* return;
* }
* }
*/

var p = crypto.createDiffieHellman(prime, 'hex');
var apub =
'5484455905d3eff34c70980e871f27f05448e66f5a6efbb97cbcba4e927196c2bd9ea272cded91\
10a4977afa8d9b16c9139a444ed2d954a794650e5d7cb525204f385e1af81530518563822ecd0f9\
524a958d02b3c269e79d6d69850f0968ad567a4404fbb0b19efc8bc73e267b6136b88cafb33299f\
f7c7cace3ffab1a88c2c9ee841f88b4c3679b4efc465f5c93cca11d487be57373e4c5926f634c4e\
efee6721d01db91cd66321615b2522f96368dbc818875d422140d0edf30bdb97d9721feddcb9ff6\
453741a4f687ee46fc54bf1198801f1210ac789879a5ee123f79e2d2ce1209df2445d32166bc9e4\
8f89e944ec9c3b2e16c8066cd8eebd4e33eb941';
var bpub =
'3fca64510e36bc7da8a3a901c7b74c2eabfa25deaf7cbe1d0c50235866136ad677317279e1fb0\
06e9c0a07f63e14a3363c8e016fbbde2b2c7e79fed1cc3e08e95f7459f547a8cd0523ee9dc744d\
e5a956d92b937db4448917e1f6829437f05e408ee7aea70c0362b37370c7c75d14449d8b2d2133\
04ac972302d349975e2265ca7103cfebd019d9e91234d638611abd049014f7abf706c1c5da6c88\
788a1fdc6cdf17f5fffaf024ce8711a2ebde0b52e9f1cb56224483826d6e5ac6ecfaae07b75d20\
6e8ac97f5be1a5b68f20382f2a7dac189cf169325c4cf845b26a0cd616c31fec905c5d9035e5f7\
8e9880c812374ac0f3ca3d365f06e4be526b5affd4b79';
var apriv =
'62411e34704637d99c6c958a7db32ac22fcafafbe1c33d2cfdb76e12ded41f38fc16b792b9041\
2e4c82755a3815ba52f780f0ee296ad46e348fc4d1dcd6b64f4eea1b231b2b7d95c5b1c2e26d34\
83520558b9860a6eb668f01422a54e6604aa7702b4e67511397ef3ecb912bff1a83899c5a5bfb2\
0ee29249a91b8a698e62486f7009a0e9eaebda69d77ecfa2ca6ba2db6c8aa81759c8c90c675979\
08c3b3e6fc60668f7be81cce6784482af228dd7f489005253a165e292802cfd0399924f6c56827\
7012f68255207722355634290acc7fddeefbba75650a85ece95b6a12de67eac016ba78960108dd\
5dbadfaa43cc9fed515a1f307b7d90ae0623bc7b8cefb';
var secret =
'00c37b1e06a436d6717816a40e6d72907a6f255638b93032267dcb9a5f0b4a9aa0236f3dce63b\
1c418c60978a00acd1617dfeecf1661d8a3fafb4d0d8824386750f4853313400e7e4afd22847e4\
fa56bc9713872021265111906673b38db83d10cbfa1dea3b6b4c97c8655f4ae82125281af7f234\
8916a15c6f95649367d169d587697480df4d10b381479e86d5518b520d9d8fb764084eab518224\
dc8fe984ddaf532fc1531ce43155fa0ab32532bf1ece5356b8a3447b5267798a904f16f3f4e635\
597adc0179d011132dcffc0bbcb0dd2c8700872f8663ec7ddd897c659cc2efebccc73f38f0ec96\
8612314311231f905f91c63a1aea52e0b60cead8b57df';

/* FIPS-friendly 2048 bit prime */
var p = crypto.createDiffieHellman(
crypto.getDiffieHellman('modp14').getPrime());

p.setPublicKey(apub, 'hex');
p.setPrivateKey(apriv, 'hex');

assert.equal(
p.computeSecret(bpub, 'hex', 'hex'),
'0025616eed33f1af7975bbd0a8071d98a014f538b243bef90d76c08e81a0b3c5'
p.computeSecret(bpub, 'hex', 'hex').toString('hex'),
secret
);
2 changes: 1 addition & 1 deletion test/pummel/test-dh-regr.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if (!common.hasCrypto) {
}
var crypto = require('crypto');

var p = crypto.createDiffieHellman(256).getPrime();
var p = crypto.createDiffieHellman(1024).getPrime();

for (var i = 0; i < 2000; i++) {
var a = crypto.createDiffieHellman(p),
Expand Down

0 comments on commit 9837387

Please sign in to comment.