11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciif (!common.hasCrypto) 41cb0ef41Sopenharmony_ci common.skip('missing crypto'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciconst assert = require('assert'); 71cb0ef41Sopenharmony_ciconst crypto = require('crypto'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_cifunction testCipher1(key, iv) { 101cb0ef41Sopenharmony_ci // Test encryption and decryption with explicit key and iv 111cb0ef41Sopenharmony_ci const plaintext = 121cb0ef41Sopenharmony_ci '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + 131cb0ef41Sopenharmony_ci 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + 141cb0ef41Sopenharmony_ci 'jAfaFg**'; 151cb0ef41Sopenharmony_ci const cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); 161cb0ef41Sopenharmony_ci let ciph = cipher.update(plaintext, 'utf8', 'hex'); 171cb0ef41Sopenharmony_ci ciph += cipher.final('hex'); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci const decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); 201cb0ef41Sopenharmony_ci let txt = decipher.update(ciph, 'hex', 'utf8'); 211cb0ef41Sopenharmony_ci txt += decipher.final('utf8'); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci assert.strictEqual(txt, plaintext, 241cb0ef41Sopenharmony_ci `encryption/decryption with key ${key} and iv ${iv}`); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci // Streaming cipher interface 271cb0ef41Sopenharmony_ci // NB: In real life, it's not guaranteed that you can get all of it 281cb0ef41Sopenharmony_ci // in a single read() like this. But in this case, we know it's 291cb0ef41Sopenharmony_ci // quite small, so there's no harm. 301cb0ef41Sopenharmony_ci const cStream = crypto.createCipheriv('des-ede3-cbc', key, iv); 311cb0ef41Sopenharmony_ci cStream.end(plaintext); 321cb0ef41Sopenharmony_ci ciph = cStream.read(); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci const dStream = crypto.createDecipheriv('des-ede3-cbc', key, iv); 351cb0ef41Sopenharmony_ci dStream.end(ciph); 361cb0ef41Sopenharmony_ci txt = dStream.read().toString('utf8'); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci assert.strictEqual(txt, plaintext, 391cb0ef41Sopenharmony_ci `streaming cipher with key ${key} and iv ${iv}`); 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cifunction testCipher2(key, iv) { 441cb0ef41Sopenharmony_ci // Test encryption and decryption with explicit key and iv 451cb0ef41Sopenharmony_ci const plaintext = 461cb0ef41Sopenharmony_ci '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + 471cb0ef41Sopenharmony_ci 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + 481cb0ef41Sopenharmony_ci 'jAfaFg**'; 491cb0ef41Sopenharmony_ci const cipher = crypto.createCipheriv('des-ede3-cbc', key, iv); 501cb0ef41Sopenharmony_ci let ciph = cipher.update(plaintext, 'utf8', 'buffer'); 511cb0ef41Sopenharmony_ci ciph = Buffer.concat([ciph, cipher.final('buffer')]); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci const decipher = crypto.createDecipheriv('des-ede3-cbc', key, iv); 541cb0ef41Sopenharmony_ci let txt = decipher.update(ciph, 'buffer', 'utf8'); 551cb0ef41Sopenharmony_ci txt += decipher.final('utf8'); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci assert.strictEqual(txt, plaintext, 581cb0ef41Sopenharmony_ci `encryption/decryption with key ${key} and iv ${iv}`); 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_cifunction testCipher3(key, iv) { 631cb0ef41Sopenharmony_ci // Test encryption and decryption with explicit key and iv. 641cb0ef41Sopenharmony_ci // AES Key Wrap test vector comes from RFC3394 651cb0ef41Sopenharmony_ci const plaintext = Buffer.from('00112233445566778899AABBCCDDEEFF', 'hex'); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci const cipher = crypto.createCipheriv('id-aes128-wrap', key, iv); 681cb0ef41Sopenharmony_ci let ciph = cipher.update(plaintext, 'utf8', 'buffer'); 691cb0ef41Sopenharmony_ci ciph = Buffer.concat([ciph, cipher.final('buffer')]); 701cb0ef41Sopenharmony_ci const ciph2 = Buffer.from('1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5', 711cb0ef41Sopenharmony_ci 'hex'); 721cb0ef41Sopenharmony_ci assert(ciph.equals(ciph2)); 731cb0ef41Sopenharmony_ci const decipher = crypto.createDecipheriv('id-aes128-wrap', key, iv); 741cb0ef41Sopenharmony_ci let deciph = decipher.update(ciph, 'buffer'); 751cb0ef41Sopenharmony_ci deciph = Buffer.concat([deciph, decipher.final()]); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci assert(deciph.equals(plaintext), 781cb0ef41Sopenharmony_ci `encryption/decryption with key ${key} and iv ${iv}`); 791cb0ef41Sopenharmony_ci} 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci{ 821cb0ef41Sopenharmony_ci const Cipheriv = crypto.Cipheriv; 831cb0ef41Sopenharmony_ci const key = '123456789012345678901234'; 841cb0ef41Sopenharmony_ci const iv = '12345678'; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci const instance = Cipheriv('des-ede3-cbc', key, iv); 871cb0ef41Sopenharmony_ci assert(instance instanceof Cipheriv, 'Cipheriv is expected to return a new ' + 881cb0ef41Sopenharmony_ci 'instance when called without `new`'); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci assert.throws( 911cb0ef41Sopenharmony_ci () => crypto.createCipheriv(null), 921cb0ef41Sopenharmony_ci { 931cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 941cb0ef41Sopenharmony_ci name: 'TypeError', 951cb0ef41Sopenharmony_ci message: 'The "cipher" argument must be of type string. ' + 961cb0ef41Sopenharmony_ci 'Received null' 971cb0ef41Sopenharmony_ci }); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci assert.throws( 1001cb0ef41Sopenharmony_ci () => crypto.createCipheriv('des-ede3-cbc', null), 1011cb0ef41Sopenharmony_ci { 1021cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1031cb0ef41Sopenharmony_ci name: 'TypeError', 1041cb0ef41Sopenharmony_ci }); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci assert.throws( 1071cb0ef41Sopenharmony_ci () => crypto.createCipheriv('des-ede3-cbc', key, 10), 1081cb0ef41Sopenharmony_ci { 1091cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1101cb0ef41Sopenharmony_ci name: 'TypeError', 1111cb0ef41Sopenharmony_ci }); 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci{ 1151cb0ef41Sopenharmony_ci const Decipheriv = crypto.Decipheriv; 1161cb0ef41Sopenharmony_ci const key = '123456789012345678901234'; 1171cb0ef41Sopenharmony_ci const iv = '12345678'; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci const instance = Decipheriv('des-ede3-cbc', key, iv); 1201cb0ef41Sopenharmony_ci assert(instance instanceof Decipheriv, 'Decipheriv expected to return a new' + 1211cb0ef41Sopenharmony_ci ' instance when called without `new`'); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci assert.throws( 1241cb0ef41Sopenharmony_ci () => crypto.createDecipheriv(null), 1251cb0ef41Sopenharmony_ci { 1261cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1271cb0ef41Sopenharmony_ci name: 'TypeError', 1281cb0ef41Sopenharmony_ci message: 'The "cipher" argument must be of type string. ' + 1291cb0ef41Sopenharmony_ci 'Received null' 1301cb0ef41Sopenharmony_ci }); 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci assert.throws( 1331cb0ef41Sopenharmony_ci () => crypto.createDecipheriv('des-ede3-cbc', null), 1341cb0ef41Sopenharmony_ci { 1351cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1361cb0ef41Sopenharmony_ci name: 'TypeError', 1371cb0ef41Sopenharmony_ci }); 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci assert.throws( 1401cb0ef41Sopenharmony_ci () => crypto.createDecipheriv('des-ede3-cbc', key, 10), 1411cb0ef41Sopenharmony_ci { 1421cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1431cb0ef41Sopenharmony_ci name: 'TypeError', 1441cb0ef41Sopenharmony_ci }); 1451cb0ef41Sopenharmony_ci} 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_citestCipher1('0123456789abcd0123456789', '12345678'); 1481cb0ef41Sopenharmony_citestCipher1('0123456789abcd0123456789', Buffer.from('12345678')); 1491cb0ef41Sopenharmony_citestCipher1(Buffer.from('0123456789abcd0123456789'), '12345678'); 1501cb0ef41Sopenharmony_citestCipher1(Buffer.from('0123456789abcd0123456789'), Buffer.from('12345678')); 1511cb0ef41Sopenharmony_citestCipher2(Buffer.from('0123456789abcd0123456789'), Buffer.from('12345678')); 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ciif (!common.hasFipsCrypto) { 1541cb0ef41Sopenharmony_ci testCipher3(Buffer.from('000102030405060708090A0B0C0D0E0F', 'hex'), 1551cb0ef41Sopenharmony_ci Buffer.from('A6A6A6A6A6A6A6A6', 'hex')); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci// Zero-sized IV or null should be accepted in ECB mode. 1591cb0ef41Sopenharmony_cicrypto.createCipheriv('aes-128-ecb', Buffer.alloc(16), Buffer.alloc(0)); 1601cb0ef41Sopenharmony_cicrypto.createCipheriv('aes-128-ecb', Buffer.alloc(16), null); 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ciconst errMessage = /Invalid initialization vector/; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci// But non-empty IVs should be rejected. 1651cb0ef41Sopenharmony_cifor (let n = 1; n < 256; n += 1) { 1661cb0ef41Sopenharmony_ci assert.throws( 1671cb0ef41Sopenharmony_ci () => crypto.createCipheriv('aes-128-ecb', Buffer.alloc(16), 1681cb0ef41Sopenharmony_ci Buffer.alloc(n)), 1691cb0ef41Sopenharmony_ci errMessage); 1701cb0ef41Sopenharmony_ci} 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci// Correctly sized IV should be accepted in CBC mode. 1731cb0ef41Sopenharmony_cicrypto.createCipheriv('aes-128-cbc', Buffer.alloc(16), Buffer.alloc(16)); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci// But all other IV lengths should be rejected. 1761cb0ef41Sopenharmony_cifor (let n = 0; n < 256; n += 1) { 1771cb0ef41Sopenharmony_ci if (n === 16) continue; 1781cb0ef41Sopenharmony_ci assert.throws( 1791cb0ef41Sopenharmony_ci () => crypto.createCipheriv('aes-128-cbc', Buffer.alloc(16), 1801cb0ef41Sopenharmony_ci Buffer.alloc(n)), 1811cb0ef41Sopenharmony_ci errMessage); 1821cb0ef41Sopenharmony_ci} 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci// And so should null be. 1851cb0ef41Sopenharmony_ciassert.throws(() => { 1861cb0ef41Sopenharmony_ci crypto.createCipheriv('aes-128-cbc', Buffer.alloc(16), null); 1871cb0ef41Sopenharmony_ci}, /Invalid initialization vector/); 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci// Zero-sized IV should be rejected in GCM mode. 1901cb0ef41Sopenharmony_ciassert.throws( 1911cb0ef41Sopenharmony_ci () => crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), 1921cb0ef41Sopenharmony_ci Buffer.alloc(0)), 1931cb0ef41Sopenharmony_ci errMessage); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci// But all other IV lengths should be accepted. 1961cb0ef41Sopenharmony_ciconst minIvLength = common.hasOpenSSL3 ? 8 : 1; 1971cb0ef41Sopenharmony_ciconst maxIvLength = common.hasOpenSSL3 ? 64 : 256; 1981cb0ef41Sopenharmony_cifor (let n = minIvLength; n < maxIvLength; n += 1) { 1991cb0ef41Sopenharmony_ci if (common.hasFipsCrypto && n < 12) continue; 2001cb0ef41Sopenharmony_ci crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(n)); 2011cb0ef41Sopenharmony_ci} 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci{ 2041cb0ef41Sopenharmony_ci // Passing an invalid cipher name should throw. 2051cb0ef41Sopenharmony_ci assert.throws( 2061cb0ef41Sopenharmony_ci () => crypto.createCipheriv('aes-127', Buffer.alloc(16), null), 2071cb0ef41Sopenharmony_ci { 2081cb0ef41Sopenharmony_ci name: 'Error', 2091cb0ef41Sopenharmony_ci code: 'ERR_CRYPTO_UNKNOWN_CIPHER', 2101cb0ef41Sopenharmony_ci message: 'Unknown cipher' 2111cb0ef41Sopenharmony_ci }); 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci // Passing a key with an invalid length should throw. 2141cb0ef41Sopenharmony_ci assert.throws( 2151cb0ef41Sopenharmony_ci () => crypto.createCipheriv('aes-128-ecb', Buffer.alloc(17), null), 2161cb0ef41Sopenharmony_ci /Invalid key length/); 2171cb0ef41Sopenharmony_ci} 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci{ 2201cb0ef41Sopenharmony_ci // https://github.com/nodejs/node/issues/45757 2211cb0ef41Sopenharmony_ci // eslint-disable-next-line no-restricted-syntax 2221cb0ef41Sopenharmony_ci assert.throws(() => 2231cb0ef41Sopenharmony_ci crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(12)) 2241cb0ef41Sopenharmony_ci .update(Buffer.allocUnsafeSlow(2 ** 31 - 1))); 2251cb0ef41Sopenharmony_ci} 226