Browse Source

test: increase crypto strength for FIPS standard

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: https://github.com/nodejs/node/pull/3758
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
Reviewed-By: James M Snell <jasnell@gmail.com>
process-exit-stdio-flushing
Stefan Budeanu 9 years ago
committed by James M Snell
parent
commit
11ad744a92
  1. 2
      test/parallel/test-crypto-binary-default.js
  2. 9
      test/parallel/test-crypto-dh-odd-key.js
  3. 69
      test/parallel/test-crypto-dh.js
  4. 4
      test/parallel/test-crypto-ecb.js
  5. 2
      test/parallel/test-crypto.js
  6. 81
      test/parallel/test-dh-padding.js
  7. 2
      test/pummel/test-dh-regr.js

2
test/parallel/test-crypto-binary-default.js

@ -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();

9
test/parallel/test-crypto-dh-odd-key.js

@ -8,9 +8,18 @@ if (!common.hasCrypto) {
}
var crypto = require('crypto');
function test() {
var odd = new Buffer(39);
odd.fill('A');
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
test/parallel/test-crypto-dh.js

@ -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();
@ -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,
@ -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' +

4
test/parallel/test-crypto-ecb.js

@ -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';

2
test/parallel/test-crypto.js

@ -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

81
test/parallel/test-dh-padding.js

@ -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
test/pummel/test-dh-regr.js

@ -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),

Loading…
Cancel
Save