presets: add chacha20-ietf support for ss-stream-cipher
This commit is contained in:
parent
b7db7374c2
commit
d126b3c4db
@ -6,16 +6,21 @@ import { dumpHex, EVP_BytesToKey, hash } from '../utils';
|
||||
const ciphers = {
|
||||
'aes-128-ctr': [16, 16], 'aes-192-ctr': [24, 16], 'aes-256-ctr': [32, 16],
|
||||
'aes-128-cfb': [16, 16], 'aes-192-cfb': [24, 16], 'aes-256-cfb': [32, 16],
|
||||
'camellia-128-cfb': [16, 16], 'camellia-192-cfb': [24, 16], 'camellia-256-cfb': [32, 16],
|
||||
'rc4-md5': [16, 16], 'rc4-md5-6': [16, 6],
|
||||
'camellia-128-cfb': [16, 16],
|
||||
'camellia-192-cfb': [24, 16],
|
||||
'camellia-256-cfb': [32, 16],
|
||||
'rc4-md5': [16, 16],
|
||||
'rc4-md5-6': [16, 6],
|
||||
|
||||
// NOTE: "none" cipher is just prepared for "ssr-auth-chain-*" presets.
|
||||
// DO NOT use "none" without "ssr-auth-chain-*".
|
||||
'none': [16, 0]
|
||||
'none': [16, 0],
|
||||
|
||||
// 'chacha20-ietf': [32, 12], wait for libsodium-wrappers
|
||||
// require Node.js v10.x
|
||||
'chacha20-ietf': [32, 12],
|
||||
};
|
||||
|
||||
const DEFAULT_METHOD = 'aes-256-ctr';
|
||||
const NOOP = Buffer.alloc(0);
|
||||
|
||||
/**
|
||||
@ -73,7 +78,6 @@ export default class SsStreamCipherPreset extends IPreset {
|
||||
_key = null;
|
||||
_iv = null;
|
||||
|
||||
_keySize = 0;
|
||||
_ivSize = 0;
|
||||
|
||||
_cipher = null;
|
||||
@ -87,7 +91,7 @@ export default class SsStreamCipherPreset extends IPreset {
|
||||
return this._iv;
|
||||
}
|
||||
|
||||
static onCheckParams({ method }) {
|
||||
static onCheckParams({ method = DEFAULT_METHOD }) {
|
||||
if (typeof method !== 'string' || method === '') {
|
||||
throw Error('\'method\' must be set');
|
||||
}
|
||||
@ -95,16 +99,27 @@ export default class SsStreamCipherPreset extends IPreset {
|
||||
if (!cipherNames.includes(method)) {
|
||||
throw Error(`'method' must be one of [${cipherNames}]`);
|
||||
}
|
||||
if (method === 'chacha20-ietf' && !process.version.startsWith('v10')) {
|
||||
throw Error('require Node.js v10.x to run "chacha20-ietf"');
|
||||
}
|
||||
}
|
||||
|
||||
onInit({ method }) {
|
||||
onInit({ method = DEFAULT_METHOD }) {
|
||||
const [keySize, ivSize] = ciphers[method];
|
||||
const iv = crypto.randomBytes(ivSize);
|
||||
this._algorithm = ['rc4-md5', 'rc4-md5-6'].includes(method) ? 'rc4' : method;
|
||||
this._keySize = keySize;
|
||||
this._algorithm = method;
|
||||
this._ivSize = ivSize;
|
||||
this._key = EVP_BytesToKey(this._config.key, keySize, ivSize);
|
||||
this._iv = method === 'rc4-md5-6' ? iv.slice(0, 6) : iv;
|
||||
this._iv = iv;
|
||||
if (this._algorithm.startsWith('rc4')) {
|
||||
this._algorithm = 'rc4';
|
||||
if (this._algorithm === 'rc4-md5-6') {
|
||||
this._iv = this._iv.slice(0, 6);
|
||||
}
|
||||
}
|
||||
if (this._algorithm === 'chacha20-ietf') {
|
||||
this._algorithm = 'chacha20';
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
@ -124,9 +139,13 @@ export default class SsStreamCipherPreset extends IPreset {
|
||||
}
|
||||
else if (algorithm === 'none') {
|
||||
return {
|
||||
update: (buffer) => buffer
|
||||
update: (buffer) => buffer,
|
||||
};
|
||||
}
|
||||
else if (algorithm === 'chacha20') {
|
||||
// 4 bytes counter + 12 bytes nonce
|
||||
_iv = Buffer.concat([Buffer.alloc(4), _iv]);
|
||||
}
|
||||
return crypto.createCipheriv(algorithm, _key, _iv);
|
||||
}
|
||||
|
||||
@ -140,9 +159,13 @@ export default class SsStreamCipherPreset extends IPreset {
|
||||
}
|
||||
else if (algorithm === 'none') {
|
||||
return {
|
||||
update: (buffer) => buffer
|
||||
update: (buffer) => buffer,
|
||||
};
|
||||
}
|
||||
else if (algorithm === 'chacha20') {
|
||||
// 4 bytes counter + 12 bytes nonce
|
||||
_iv = Buffer.concat([Buffer.alloc(4), _iv]);
|
||||
}
|
||||
return crypto.createDecipheriv(algorithm, _key, _iv);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user