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. 19
      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, // Test Diffie-Hellman with two parties sharing a secret,
// using various encodings as we go along // using various encodings as we go along
var dh1 = crypto.createDiffieHellman(256); var dh1 = crypto.createDiffieHellman(1024);
var p1 = dh1.getPrime('buffer'); var p1 = dh1.getPrime('buffer');
var dh2 = crypto.createDiffieHellman(p1, 'base64'); var dh2 = crypto.createDiffieHellman(p1, 'base64');
var key1 = dh1.generateKeys(); var key1 = dh1.generateKeys();

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

@ -8,9 +8,18 @@ if (!common.hasCrypto) {
} }
var crypto = require('crypto'); var crypto = require('crypto');
var odd = new Buffer(39); function test() {
odd.fill('A'); var odd = new Buffer(39);
odd.fill('A');
var c = crypto.createDiffieHellman(32); var c = crypto.createDiffieHellman(32);
c.setPrivateKey(odd); c.setPrivateKey(odd);
c.generateKeys(); 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, // Test Diffie-Hellman with two parties sharing a secret,
// using various encodings as we go along // using various encodings as we go along
var dh1 = crypto.createDiffieHellman(256); var dh1 = crypto.createDiffieHellman(1024);
var p1 = dh1.getPrime('buffer'); var p1 = dh1.getPrime('buffer');
var dh2 = crypto.createDiffieHellman(p1, 'buffer'); var dh2 = crypto.createDiffieHellman(p1, 'buffer');
var key1 = dh1.generateKeys(); var key1 = dh1.generateKeys();
@ -82,9 +82,11 @@ assert.equal(aSecret, bSecret);
assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(alice.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(bob.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
// Ensure specific generator (buffer) works as expected. /* Ensure specific generator (buffer) works as expected.
var modp1 = crypto.createDiffieHellmanGroup('modp1'); * The values below (modp2/modp2buf) are for a 1024 bits long prime from
var modp1buf = new Buffer([ * 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f,
0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 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, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51,
0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 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])); var exmodp2 = crypto.createDiffieHellman(modp2buf, new Buffer([2]));
modp1.generateKeys(); modp2.generateKeys();
exmodp1.generateKeys(); exmodp2.generateKeys();
var modp1Secret = modp1.computeSecret(exmodp1.getPublicKey()).toString('hex'); var modp2Secret = modp2.computeSecret(exmodp2.getPublicKey()).toString('hex');
var exmodp1Secret = exmodp1.computeSecret(modp1.getPublicKey()).toString('hex'); var exmodp2Secret = exmodp2.computeSecret(modp2.getPublicKey()).toString('hex');
assert.equal(modp1Secret, exmodp1Secret); assert.equal(modp2Secret, exmodp2Secret);
assert.equal(modp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(modp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
assert.equal(exmodp1.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(exmodp2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
// Ensure specific generator (string with encoding) works as expected. // Ensure specific generator (string with encoding) works as expected.
var exmodp1_2 = crypto.createDiffieHellman(modp1buf, '02', 'hex'); var exmodp2_2 = crypto.createDiffieHellman(modp2buf, '02', 'hex');
exmodp1_2.generateKeys(); exmodp2_2.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_2.getPublicKey()).toString('hex'); modp2Secret = modp2.computeSecret(exmodp2_2.getPublicKey()).toString('hex');
var exmodp1_2Secret = exmodp1_2.computeSecret(modp1.getPublicKey()) var exmodp2_2Secret = exmodp2_2.computeSecret(modp2.getPublicKey())
.toString('hex'); .toString('hex');
assert.equal(modp1Secret, exmodp1_2Secret); assert.equal(modp2Secret, exmodp2_2Secret);
assert.equal(exmodp1_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(exmodp2_2.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
// Ensure specific generator (string without encoding) works as expected. // Ensure specific generator (string without encoding) works as expected.
var exmodp1_3 = crypto.createDiffieHellman(modp1buf, '\x02'); var exmodp2_3 = crypto.createDiffieHellman(modp2buf, '\x02');
exmodp1_3.generateKeys(); exmodp2_3.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_3.getPublicKey()).toString('hex'); modp2Secret = modp2.computeSecret(exmodp2_3.getPublicKey()).toString('hex');
var exmodp1_3Secret = exmodp1_3.computeSecret(modp1.getPublicKey()) var exmodp2_3Secret = exmodp2_3.computeSecret(modp2.getPublicKey())
.toString('hex'); .toString('hex');
assert.equal(modp1Secret, exmodp1_3Secret); assert.equal(modp2Secret, exmodp2_3Secret);
assert.equal(exmodp1_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(exmodp2_3.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
// Ensure specific generator (numeric) works as expected. // Ensure specific generator (numeric) works as expected.
var exmodp1_4 = crypto.createDiffieHellman(modp1buf, 2); var exmodp2_4 = crypto.createDiffieHellman(modp2buf, 2);
exmodp1_4.generateKeys(); exmodp2_4.generateKeys();
modp1Secret = modp1.computeSecret(exmodp1_4.getPublicKey()).toString('hex'); modp2Secret = modp2.computeSecret(exmodp2_4.getPublicKey()).toString('hex');
var exmodp1_4Secret = exmodp1_4.computeSecret(modp1.getPublicKey()) var exmodp2_4Secret = exmodp2_4.computeSecret(modp2.getPublicKey())
.toString('hex'); .toString('hex');
assert.equal(modp1Secret, exmodp1_4Secret); assert.equal(modp2Secret, exmodp2_4Secret);
assert.equal(exmodp1_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR); assert.equal(exmodp2_4.verifyError, constants.DH_NOT_SUITABLE_GENERATOR);
var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + var p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' +

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

@ -6,6 +6,10 @@ if (!common.hasCrypto) {
console.log('1..0 # Skipped: missing crypto'); console.log('1..0 # Skipped: missing crypto');
return; return;
} }
if (common.hasFipsCrypto) {
console.log('1..0 # Skipped: BF-ECB is not FIPS 140-2 compatible');
return;
}
var crypto = require('crypto'); var crypto = require('crypto');
crypto.DEFAULT_ENCODING = 'buffer'; crypto.DEFAULT_ENCODING = 'buffer';

2
test/parallel/test-crypto.js

@ -122,7 +122,7 @@ assert.throws(function() {
'' ''
].join('\n'); ].join('\n');
crypto.createSign('RSA-SHA256').update('test').sign(priv); 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() { assert.throws(function() {
// The correct header inside `test_bad_rsa_privkey.pem` should have been // 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; return;
} }
var prime = 'c51f7bf8f0e1cf899243cdf408b1bc7c09c010e33ef7f3fbe5bd5feaf906113b'; /* This test verifies padding with leading zeroes for shared
var apub = '6fe9f37037d8d017f908378c1ee04fe60e1cd3668bfc5075fac55c2f7153dd84'; * secrets that are strictly smaller than the modulus (prime).
var bpub = '31d83e167fdf956c9dae6b980140577a9f8868acbfcbdc19113e58bfb9223abc'; * See:
var apriv = '4fbfd4661f9181bbf574537b1a78adf473e8e771eef13c605e963c0f3094b697'; * RFC 4346: https://www.ietf.org/rfc/rfc4346.txt
var secret = '25616eed33f1af7975bbd0a8071d98a014f538b243bef90d76c08e81a0b3c500'; * 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.setPublicKey(apub, 'hex');
p.setPrivateKey(apriv, 'hex'); p.setPrivateKey(apriv, 'hex');
assert.equal( assert.equal(
p.computeSecret(bpub, 'hex', 'hex'), p.computeSecret(bpub, 'hex', 'hex').toString('hex'),
'0025616eed33f1af7975bbd0a8071d98a014f538b243bef90d76c08e81a0b3c5' secret
); );

2
test/pummel/test-dh-regr.js

@ -8,7 +8,7 @@ if (!common.hasCrypto) {
} }
var crypto = require('crypto'); var crypto = require('crypto');
var p = crypto.createDiffieHellman(256).getPrime(); var p = crypto.createDiffieHellman(1024).getPrime();
for (var i = 0; i < 2000; i++) { for (var i = 0; i < 2000; i++) {
var a = crypto.createDiffieHellman(p), var a = crypto.createDiffieHellman(p),

Loading…
Cancel
Save