◐ Shell
clean mode source ↗

test,crypto: skip unsupported ciphers · nodejs/node@319df38

@@ -248,57 +248,61 @@ for (const test of TEST_CASES) {

248248

// Test that create(De|C)ipheriv throws if the mode is CCM and an invalid

249249

// authentication tag length has been specified.

250250

{

251-

for (const authTagLength of [-1, true, false, NaN, 5.5]) {

252-

assert.throws(() => {

253-

crypto.createCipheriv('aes-256-ccm',

254-

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

255-

'qkuZpJWCewa6S',

256-

{

257-

authTagLength

258-

});

259-

}, {

260-

name: 'TypeError',

261-

code: 'ERR_INVALID_ARG_VALUE',

262-

message: "The property 'options.authTagLength' is invalid. " +

263-

`Received ${inspect(authTagLength)}`

264-

});

265-266-

assert.throws(() => {

267-

crypto.createDecipheriv('aes-256-ccm',

251+

if (!ciphers.includes('aes-256-ccm')) {

252+

common.printSkipMessage(`unsupported aes-256-ccm test`);

253+

} else {

254+

for (const authTagLength of [-1, true, false, NaN, 5.5]) {

255+

assert.throws(() => {

256+

crypto.createCipheriv('aes-256-ccm',

268257

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

269258

'qkuZpJWCewa6S',

270259

{

271260

authTagLength

272261

});

273-

}, {

274-

name: 'TypeError',

275-

code: 'ERR_INVALID_ARG_VALUE',

276-

message: "The property 'options.authTagLength' is invalid. " +

277-

`Received ${inspect(authTagLength)}`

278-

});

279-

}

280-281-

// The following values will not be caught by the JS layer and thus will not

282-

// use the default error codes.

283-

for (const authTagLength of [0, 1, 2, 3, 5, 7, 9, 11, 13, 15, 17, 18]) {

284-

assert.throws(() => {

285-

crypto.createCipheriv('aes-256-ccm',

286-

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

287-

'qkuZpJWCewa6S',

288-

{

289-

authTagLength

290-

});

291-

}, errMessages.authTagLength);

262+

}, {

263+

name: 'TypeError',

264+

code: 'ERR_INVALID_ARG_VALUE',

265+

message: "The property 'options.authTagLength' is invalid. " +

266+

`Received ${inspect(authTagLength)}`

267+

});

292268293-

if (!isFipsEnabled) {

294269

assert.throws(() => {

295270

crypto.createDecipheriv('aes-256-ccm',

296271

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

297272

'qkuZpJWCewa6S',

298273

{

299274

authTagLength

300275

});

276+

}, {

277+

name: 'TypeError',

278+

code: 'ERR_INVALID_ARG_VALUE',

279+

message: "The property 'options.authTagLength' is invalid. " +

280+

`Received ${inspect(authTagLength)}`

281+

});

282+

}

283+284+

// The following values will not be caught by the JS layer and thus will not

285+

// use the default error codes.

286+

for (const authTagLength of [0, 1, 2, 3, 5, 7, 9, 11, 13, 15, 17, 18]) {

287+

assert.throws(() => {

288+

crypto.createCipheriv('aes-256-ccm',

289+

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

290+

'qkuZpJWCewa6S',

291+

{

292+

authTagLength

293+

});

301294

}, errMessages.authTagLength);

295+296+

if (!isFipsEnabled) {

297+

assert.throws(() => {

298+

crypto.createDecipheriv('aes-256-ccm',

299+

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

300+

'qkuZpJWCewa6S',

301+

{

302+

authTagLength

303+

});

304+

}, errMessages.authTagLength);

305+

}

302306

}

303307

}

304308

}

@@ -307,6 +311,11 @@ for (const test of TEST_CASES) {

307311

// authentication tag length has been specified.

308312

{

309313

for (const mode of ['ccm', 'ocb']) {

314+

if (!ciphers.includes(`aes-256-${mode}`)) {

315+

common.printSkipMessage(`unsupported aes-256-${mode} test`);

316+

continue;

317+

}

318+310319

assert.throws(() => {

311320

crypto.createCipheriv(`aes-256-${mode}`,

312321

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

@@ -330,84 +339,96 @@ for (const test of TEST_CASES) {

330339331340

// Test that setAAD throws if an invalid plaintext length has been specified.

332341

{

333-

const cipher = crypto.createCipheriv('aes-256-ccm',

334-

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

335-

'qkuZpJWCewa6S',

336-

{

337-

authTagLength: 10

338-

});

339-340-

for (const plaintextLength of [-1, true, false, NaN, 5.5]) {

341-

assert.throws(() => {

342-

cipher.setAAD(Buffer.from('0123456789', 'hex'), { plaintextLength });

343-

}, {

344-

name: 'TypeError',

345-

code: 'ERR_INVALID_ARG_VALUE',

346-

message: "The property 'options.plaintextLength' is invalid. " +

347-

`Received ${inspect(plaintextLength)}`

348-

});

342+

if (!ciphers.includes('aes-256-ccm')) {

343+

common.printSkipMessage(`unsupported aes-256-ccm test`);

344+

} else {

345+

const cipher = crypto.createCipheriv('aes-256-ccm',

346+

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

347+

'qkuZpJWCewa6S',

348+

{

349+

authTagLength: 10

350+

});

351+352+

for (const plaintextLength of [-1, true, false, NaN, 5.5]) {

353+

assert.throws(() => {

354+

cipher.setAAD(Buffer.from('0123456789', 'hex'), { plaintextLength });

355+

}, {

356+

name: 'TypeError',

357+

code: 'ERR_INVALID_ARG_VALUE',

358+

message: "The property 'options.plaintextLength' is invalid. " +

359+

`Received ${inspect(plaintextLength)}`

360+

});

361+

}

349362

}

350363

}

351364352365

// Test that setAAD and update throw if the plaintext is too long.

353366

{

354-

for (const ivLength of [13, 12]) {

355-

const maxMessageSize = (1 << (8 * (15 - ivLength))) - 1;

356-

const key = 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8';

357-

const cipher = () => crypto.createCipheriv('aes-256-ccm', key,

358-

'0'.repeat(ivLength),

359-

{

360-

authTagLength: 10

361-

});

367+

if (!ciphers.includes('aes-256-ccm')) {

368+

common.printSkipMessage(`unsupported aes-256-ccm test`);

369+

} else {

370+

for (const ivLength of [13, 12]) {

371+

const maxMessageSize = (1 << (8 * (15 - ivLength))) - 1;

372+

const key = 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8';

373+

const cipher = () => crypto.createCipheriv('aes-256-ccm', key,

374+

'0'.repeat(ivLength),

375+

{

376+

authTagLength: 10

377+

});

362378363-

assert.throws(() => {

364-

cipher().setAAD(Buffer.alloc(0), {

365-

plaintextLength: maxMessageSize + 1

366-

});

367-

}, /Invalid message length$/);

379+

assert.throws(() => {

380+

cipher().setAAD(Buffer.alloc(0), {

381+

plaintextLength: maxMessageSize + 1

382+

});

383+

}, /Invalid message length$/);

368384369-

const msg = Buffer.alloc(maxMessageSize + 1);

370-

assert.throws(() => {

371-

cipher().update(msg);

372-

}, /Invalid message length/);

385+

const msg = Buffer.alloc(maxMessageSize + 1);

386+

assert.throws(() => {

387+

cipher().update(msg);

388+

}, /Invalid message length/);

373389374-

const c = cipher();

375-

c.setAAD(Buffer.alloc(0), {

376-

plaintextLength: maxMessageSize

377-

});

378-

c.update(msg.slice(1));

390+

const c = cipher();

391+

c.setAAD(Buffer.alloc(0), {

392+

plaintextLength: maxMessageSize

393+

});

394+

c.update(msg.slice(1));

395+

}

379396

}

380397

}

381398382399

// Test that setAAD throws if the mode is CCM and the plaintext length has not

383400

// been specified.

384401

{

385-

assert.throws(() => {

386-

const cipher = crypto.createCipheriv('aes-256-ccm',

387-

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

388-

'qkuZpJWCewa6S',

389-

{

390-

authTagLength: 10

391-

});

392-

cipher.setAAD(Buffer.from('0123456789', 'hex'));

393-

}, /options\.plaintextLength required for CCM mode with AAD/);

394-395-

if (!isFipsEnabled) {

402+

if (!ciphers.includes('aes-256-ccm')) {

403+

common.printSkipMessage(`unsupported aes-256-ccm test`);

404+

} else {

396405

assert.throws(() => {

397-

const cipher = crypto.createDecipheriv('aes-256-ccm',

398-

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

399-

'qkuZpJWCewa6S',

400-

{

401-

authTagLength: 10

402-

});

406+

const cipher = crypto.createCipheriv('aes-256-ccm',

407+

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

408+

'qkuZpJWCewa6S',

409+

{

410+

authTagLength: 10

411+

});

403412

cipher.setAAD(Buffer.from('0123456789', 'hex'));

404413

}, /options\.plaintextLength required for CCM mode with AAD/);

414+415+

if (!isFipsEnabled) {

416+

assert.throws(() => {

417+

const cipher = crypto.createDecipheriv('aes-256-ccm',

418+

'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8',

419+

'qkuZpJWCewa6S',

420+

{

421+

authTagLength: 10

422+

});

423+

cipher.setAAD(Buffer.from('0123456789', 'hex'));

424+

}, /options\.plaintextLength required for CCM mode with AAD/);

425+

}

405426

}

406427

}

407428408429

// Test that final() throws in CCM mode when no authentication tag is provided.

409430

{

410-

if (!isFipsEnabled) {

431+

if (!isFipsEnabled && ciphers.includes('aes-128-ccm')) {

411432

const key = Buffer.from('1ed2233fa2223ef5d7df08546049406c', 'hex');

412433

const iv = Buffer.from('7305220bca40d4c90e1791e9', 'hex');

413434

const ct = Buffer.from('8beba09d4d4d861f957d51c0794f4abf8030848e', 'hex');

@@ -439,12 +460,16 @@ for (const test of TEST_CASES) {

439460440461

// Test that an IV length of 11 does not overflow max_message_size_.

441462

{

442-

const key = 'x'.repeat(16);

443-

const iv = Buffer.from('112233445566778899aabb', 'hex');

444-

const options = { authTagLength: 8 };

445-

const encrypt = crypto.createCipheriv('aes-128-ccm', key, iv, options);

446-

encrypt.update('boom'); // Should not throw 'Message exceeds maximum size'.

447-

encrypt.final();

463+

if (!ciphers.includes('aes-128-ccm')) {

464+

common.printSkipMessage(`unsupported aes-128-ccm test`);

465+

} else {

466+

const key = 'x'.repeat(16);

467+

const iv = Buffer.from('112233445566778899aabb', 'hex');

468+

const options = { authTagLength: 8 };

469+

const encrypt = crypto.createCipheriv('aes-128-ccm', key, iv, options);

470+

encrypt.update('boom'); // Should not throw 'Message exceeds maximum size'.

471+

encrypt.final();

472+

}

448473

}

449474450475

// Test that the authentication tag can be set at any point before calling

@@ -499,6 +524,11 @@ for (const test of TEST_CASES) {

499524

}

500525501526

for (const alg of ['aes-256-gcm', 'aes-256-ocb', 'chacha20-poly1305']) {

527+

if (!ciphers.includes(alg)) {

528+

common.printSkipMessage(`unsupported ${alg} test`);

529+

continue;

530+

}

531+502532

for (const authTagLength of alg === 'aes-256-gcm' ? [undefined, 8] : [8]) {

503533

for (const [useAAD, useMessage] of [

504534

[false, false], // No AAD, no update.

@@ -520,6 +550,11 @@ for (const test of TEST_CASES) {

520550

const opts = { authTagLength: 8 };

521551522552

for (const mode of ['gcm', 'ccm', 'ocb']) {

553+

if (!ciphers.includes(`aes-128-${mode}`)) {

554+

common.printSkipMessage(`unsupported aes-128-${mode} test`);

555+

continue;

556+

}

557+523558

const cipher = crypto.createCipheriv(`aes-128-${mode}`, key, iv, opts);

524559

const ciphertext = Buffer.concat([cipher.update(plain), cipher.final()]);

525560

const tag = cipher.getAuthTag();

@@ -563,25 +598,29 @@ for (const test of TEST_CASES) {

563598

tampered: false,

564599

};

565600566-

// Invalid IV lengths should be detected:

567-

// - 12 and below are valid.

568-

// - 13-16 are not detected as invalid by some OpenSSL versions.

569-

check(13);

570-

check(14);

571-

check(15);

572-

check(16);

573-

// - 17 and above were always detected as invalid by OpenSSL.

574-

check(17);

575-576-

function check(ivLength) {

577-

const prefix = ivLength - valid.iv.length / 2;

578-

assert.throws(() => crypto.createCipheriv(

579-

valid.algo,

580-

Buffer.from(valid.key, 'hex'),

581-

Buffer.from(H(prefix) + valid.iv, 'hex')

582-

), errMessages.length, `iv length ${ivLength} was not rejected`);

583-584-

function H(length) { return '00'.repeat(length); }

601+

if (!ciphers.includes(valid.algo)) {

602+

common.printSkipMessage(`unsupported ${valid.algo} test`);

603+

} else {

604+

// Invalid IV lengths should be detected:

605+

// - 12 and below are valid.

606+

// - 13-16 are not detected as invalid by some OpenSSL versions.

607+

check(13);

608+

check(14);

609+

check(15);

610+

check(16);

611+

// - 17 and above were always detected as invalid by OpenSSL.

612+

check(17);

613+614+

function check(ivLength) {

615+

const prefix = ivLength - valid.iv.length / 2;

616+

assert.throws(() => crypto.createCipheriv(

617+

valid.algo,

618+

Buffer.from(valid.key, 'hex'),

619+

Buffer.from(H(prefix) + valid.iv, 'hex')

620+

), errMessages.length, `iv length ${ivLength} was not rejected`);

621+622+

function H(length) { return '00'.repeat(length); }

623+

}

585624

}

586625

}

587626