1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24if (!common.hasCrypto) 25 common.skip('missing crypto'); 26 27const assert = require('assert'); 28const crypto = require('crypto'); 29 30// Input data. 31const ODD_LENGTH_PLAIN = 'Hello node world!'; 32const EVEN_LENGTH_PLAIN = 'Hello node world!AbC09876dDeFgHi'; 33 34const KEY_PLAIN = 'S3c.r.e.t.K.e.Y!'; 35const IV_PLAIN = 'blahFizz2011Buzz'; 36 37const CIPHER_NAME = 'aes-128-cbc'; 38 39// Expected result data. 40 41// echo -n 'Hello node world!' | \ 42// openssl enc -aes-128-cbc -e -K 5333632e722e652e742e4b2e652e5921 \ 43// -iv 626c616846697a7a3230313142757a7a | xxd -p -c256 44const ODD_LENGTH_ENCRYPTED = 45 '7f57859550d4d2fdb9806da2a750461a9fe77253cd1cbd4b07beee4e070d561f'; 46 47// echo -n 'Hello node world!AbC09876dDeFgHi' | \ 48// openssl enc -aes-128-cbc -e -K 5333632e722e652e742e4b2e652e5921 \ 49// -iv 626c616846697a7a3230313142757a7a | xxd -p -c256 50const EVEN_LENGTH_ENCRYPTED = 51 '7f57859550d4d2fdb9806da2a750461ab46e71b3d78ebe2d9684dfc87f7575b988' + 52 '6119866912cb8c7bcaf76c5ebc2378'; 53 54// echo -n 'Hello node world!AbC09876dDeFgHi' | \ 55// openssl enc -aes-128-cbc -e -K 5333632e722e652e742e4b2e652e5921 \ 56// -iv 626c616846697a7a3230313142757a7a -nopad | xxd -p -c256 57const EVEN_LENGTH_ENCRYPTED_NOPAD = 58 '7f57859550d4d2fdb9806da2a750461ab46e71b3d78ebe2d9684dfc87f7575b9'; 59 60 61// Helper wrappers. 62function enc(plain, pad) { 63 const encrypt = crypto.createCipheriv(CIPHER_NAME, KEY_PLAIN, IV_PLAIN); 64 encrypt.setAutoPadding(pad); 65 let hex = encrypt.update(plain, 'ascii', 'hex'); 66 hex += encrypt.final('hex'); 67 return hex; 68} 69 70function dec(encd, pad) { 71 const decrypt = crypto.createDecipheriv(CIPHER_NAME, KEY_PLAIN, IV_PLAIN); 72 decrypt.setAutoPadding(pad); 73 let plain = decrypt.update(encd, 'hex'); 74 plain += decrypt.final('latin1'); 75 return plain; 76} 77 78// Test encryption 79assert.strictEqual(enc(ODD_LENGTH_PLAIN, true), ODD_LENGTH_ENCRYPTED); 80assert.strictEqual(enc(EVEN_LENGTH_PLAIN, true), EVEN_LENGTH_ENCRYPTED); 81 82assert.throws(function() { 83 // Input must have block length %. 84 enc(ODD_LENGTH_PLAIN, false); 85}, common.hasOpenSSL3 ? { 86 message: 'error:1C80006B:Provider routines::wrong final block length', 87 code: 'ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH', 88 reason: 'wrong final block length', 89} : { 90 message: 'error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:' + 91 'data not multiple of block length', 92 code: 'ERR_OSSL_EVP_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH', 93 reason: 'data not multiple of block length', 94} 95); 96 97assert.strictEqual( 98 enc(EVEN_LENGTH_PLAIN, false), EVEN_LENGTH_ENCRYPTED_NOPAD 99); 100 101// Test decryption. 102assert.strictEqual(dec(ODD_LENGTH_ENCRYPTED, true), ODD_LENGTH_PLAIN); 103assert.strictEqual(dec(EVEN_LENGTH_ENCRYPTED, true), EVEN_LENGTH_PLAIN); 104 105// Returns including original padding. 106assert.strictEqual(dec(ODD_LENGTH_ENCRYPTED, false).length, 32); 107assert.strictEqual(dec(EVEN_LENGTH_ENCRYPTED, false).length, 48); 108 109assert.throws(function() { 110 // Must have at least 1 byte of padding (PKCS): 111 assert.strictEqual(dec(EVEN_LENGTH_ENCRYPTED_NOPAD, true), EVEN_LENGTH_PLAIN); 112}, common.hasOpenSSL3 ? { 113 message: 'error:1C800064:Provider routines::bad decrypt', 114 reason: 'bad decrypt', 115 code: 'ERR_OSSL_BAD_DECRYPT', 116} : { 117 message: 'error:06065064:digital envelope routines:EVP_DecryptFinal_ex:' + 118 'bad decrypt', 119 reason: 'bad decrypt', 120 code: 'ERR_OSSL_EVP_BAD_DECRYPT', 121}); 122 123// No-pad encrypted string should return the same: 124assert.strictEqual( 125 dec(EVEN_LENGTH_ENCRYPTED_NOPAD, false), EVEN_LENGTH_PLAIN 126); 127