const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
const require_forge$1 = require('./forge.cjs');
const require_aes$1 = require('./aes.cjs');
const require_tls$1 = require('./tls.cjs');

//#region ../../node_modules/node-forge/lib/aesCipherSuites.js
var require_aesCipherSuites = /* @__PURE__ */ require_rolldown_runtime.__commonJS({ "../../node_modules/node-forge/lib/aesCipherSuites.js": ((exports, module) => {
	/**
	* A Javascript implementation of AES Cipher Suites for TLS.
	*
	* @author Dave Longley
	*
	* Copyright (c) 2009-2015 Digital Bazaar, Inc.
	*
	*/
	var forge = require_forge$1.default;
	require_aes$1.default;
	require_tls$1.default;
	var tls = module.exports = forge.tls;
	/**
	* Supported cipher suites.
	*/
	tls.CipherSuites["TLS_RSA_WITH_AES_128_CBC_SHA"] = {
		id: [0, 47],
		name: "TLS_RSA_WITH_AES_128_CBC_SHA",
		initSecurityParameters: function(sp) {
			sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes;
			sp.cipher_type = tls.CipherType.block;
			sp.enc_key_length = 16;
			sp.block_length = 16;
			sp.fixed_iv_length = 16;
			sp.record_iv_length = 16;
			sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1;
			sp.mac_length = 20;
			sp.mac_key_length = 20;
		},
		initConnectionState
	};
	tls.CipherSuites["TLS_RSA_WITH_AES_256_CBC_SHA"] = {
		id: [0, 53],
		name: "TLS_RSA_WITH_AES_256_CBC_SHA",
		initSecurityParameters: function(sp) {
			sp.bulk_cipher_algorithm = tls.BulkCipherAlgorithm.aes;
			sp.cipher_type = tls.CipherType.block;
			sp.enc_key_length = 32;
			sp.block_length = 16;
			sp.fixed_iv_length = 16;
			sp.record_iv_length = 16;
			sp.mac_algorithm = tls.MACAlgorithm.hmac_sha1;
			sp.mac_length = 20;
			sp.mac_key_length = 20;
		},
		initConnectionState
	};
	function initConnectionState(state, c, sp) {
		var client = c.entity === forge.tls.ConnectionEnd.client;
		state.read.cipherState = {
			init: false,
			cipher: forge.cipher.createDecipher("AES-CBC", client ? sp.keys.server_write_key : sp.keys.client_write_key),
			iv: client ? sp.keys.server_write_IV : sp.keys.client_write_IV
		};
		state.write.cipherState = {
			init: false,
			cipher: forge.cipher.createCipher("AES-CBC", client ? sp.keys.client_write_key : sp.keys.server_write_key),
			iv: client ? sp.keys.client_write_IV : sp.keys.server_write_IV
		};
		state.read.cipherFunction = decrypt_aes_cbc_sha1;
		state.write.cipherFunction = encrypt_aes_cbc_sha1;
		state.read.macLength = state.write.macLength = sp.mac_length;
		state.read.macFunction = state.write.macFunction = tls.hmac_sha1;
	}
	/**
	* Encrypts the TLSCompressed record into a TLSCipherText record using AES
	* in CBC mode.
	*
	* @param record the TLSCompressed record to encrypt.
	* @param s the ConnectionState to use.
	*
	* @return true on success, false on failure.
	*/
	function encrypt_aes_cbc_sha1(record, s) {
		var rval = false;
		var mac = s.macFunction(s.macKey, s.sequenceNumber, record);
		record.fragment.putBytes(mac);
		s.updateSequenceNumber();
		var iv;
		if (record.version.minor === tls.Versions.TLS_1_0.minor) iv = s.cipherState.init ? null : s.cipherState.iv;
		else iv = forge.random.getBytesSync(16);
		s.cipherState.init = true;
		var cipher = s.cipherState.cipher;
		cipher.start({ iv });
		if (record.version.minor >= tls.Versions.TLS_1_1.minor) cipher.output.putBytes(iv);
		cipher.update(record.fragment);
		if (cipher.finish(encrypt_aes_cbc_sha1_padding)) {
			record.fragment = cipher.output;
			record.length = record.fragment.length();
			rval = true;
		}
		return rval;
	}
	/**
	* Handles padding for aes_cbc_sha1 in encrypt mode.
	*
	* @param blockSize the block size.
	* @param input the input buffer.
	* @param decrypt true in decrypt mode, false in encrypt mode.
	*
	* @return true on success, false on failure.
	*/
	function encrypt_aes_cbc_sha1_padding(blockSize, input, decrypt) {
		if (!decrypt) {
			var padding = blockSize - input.length() % blockSize;
			input.fillWithByte(padding - 1, padding);
		}
		return true;
	}
	/**
	* Handles padding for aes_cbc_sha1 in decrypt mode.
	*
	* @param blockSize the block size.
	* @param output the output buffer.
	* @param decrypt true in decrypt mode, false in encrypt mode.
	*
	* @return true on success, false on failure.
	*/
	function decrypt_aes_cbc_sha1_padding(blockSize, output, decrypt) {
		var rval = true;
		if (decrypt) {
			var len = output.length();
			var paddingLength = output.last();
			for (var i = len - 1 - paddingLength; i < len - 1; ++i) rval = rval && output.at(i) == paddingLength;
			if (rval) output.truncate(paddingLength + 1);
		}
		return rval;
	}
	/**
	* Decrypts a TLSCipherText record into a TLSCompressed record using
	* AES in CBC mode.
	*
	* @param record the TLSCipherText record to decrypt.
	* @param s the ConnectionState to use.
	*
	* @return true on success, false on failure.
	*/
	function decrypt_aes_cbc_sha1(record, s) {
		var rval = false;
		var iv;
		if (record.version.minor === tls.Versions.TLS_1_0.minor) iv = s.cipherState.init ? null : s.cipherState.iv;
		else iv = record.fragment.getBytes(16);
		s.cipherState.init = true;
		var cipher = s.cipherState.cipher;
		cipher.start({ iv });
		cipher.update(record.fragment);
		rval = cipher.finish(decrypt_aes_cbc_sha1_padding);
		var macLen = s.macLength;
		var mac = forge.random.getBytesSync(macLen);
		var len = cipher.output.length();
		if (len >= macLen) {
			record.fragment = cipher.output.getBytes(len - macLen);
			mac = cipher.output.getBytes(macLen);
		} else record.fragment = cipher.output.getBytes();
		record.fragment = forge.util.createBuffer(record.fragment);
		record.length = record.fragment.length();
		var mac2 = s.macFunction(s.macKey, s.sequenceNumber, record);
		s.updateSequenceNumber();
		rval = compareMacs(s.macKey, mac, mac2) && rval;
		return rval;
	}
	/**
	* Safely compare two MACs. This function will compare two MACs in a way
	* that protects against timing attacks.
	*
	* TODO: Expose elsewhere as a utility API.
	*
	* See: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
	*
	* @param key the MAC key to use.
	* @param mac1 as a binary-encoded string of bytes.
	* @param mac2 as a binary-encoded string of bytes.
	*
	* @return true if the MACs are the same, false if not.
	*/
	function compareMacs(key, mac1, mac2) {
		var hmac = forge.hmac.create();
		hmac.start("SHA1", key);
		hmac.update(mac1);
		mac1 = hmac.digest().getBytes();
		hmac.start(null, null);
		hmac.update(mac2);
		mac2 = hmac.digest().getBytes();
		return mac1 === mac2;
	}
}) });

//#endregion
Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function () {
    return require_aesCipherSuites();
  }
});
//# sourceMappingURL=aesCipherSuites.cjs.map