Merge branch 'MShwed-feature/streebog-hash'
This commit is contained in:
commit
2ba6a3fd8d
12 changed files with 9139 additions and 4 deletions
|
@ -197,8 +197,8 @@
|
|||
"Remove null bytes",
|
||||
"To Upper case",
|
||||
"To Lower case",
|
||||
"To Case Insensitive Regex",
|
||||
"From Case Insensitive Regex",
|
||||
"To Case Insensitive Regex",
|
||||
"From Case Insensitive Regex",
|
||||
"Add line numbers",
|
||||
"Remove line numbers",
|
||||
"To Table",
|
||||
|
@ -302,6 +302,8 @@
|
|||
"Snefru",
|
||||
"BLAKE2b",
|
||||
"BLAKE2s",
|
||||
"GOST hash",
|
||||
"Streebog",
|
||||
"SSDEEP",
|
||||
"CTPH",
|
||||
"Compare SSDEEP hashes",
|
||||
|
|
|
@ -12,7 +12,7 @@ import Utils from "../Utils";
|
|||
/**
|
||||
* Convert a byte array into a hex string.
|
||||
*
|
||||
* @param {Uint8Array|byteArray} data
|
||||
* @param {byteArray|Uint8Array|ArrayBuffer} data
|
||||
* @param {string} [delim=" "]
|
||||
* @param {number} [padding=2]
|
||||
* @returns {string}
|
||||
|
@ -26,6 +26,7 @@ import Utils from "../Utils";
|
|||
*/
|
||||
export function toHex(data, delim=" ", padding=2) {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
|
||||
let output = "";
|
||||
|
||||
|
@ -47,7 +48,7 @@ export function toHex(data, delim=" ", padding=2) {
|
|||
/**
|
||||
* Convert a byte array into a hex string as efficiently as possible with no options.
|
||||
*
|
||||
* @param {byteArray} data
|
||||
* @param {byteArray|Uint8Array|ArrayBuffer} data
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
|
@ -56,6 +57,7 @@ export function toHex(data, delim=" ", padding=2) {
|
|||
*/
|
||||
export function toHexFast(data) {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
|
||||
const output = [];
|
||||
|
||||
|
|
71
src/core/operations/GOSTHash.mjs
Normal file
71
src/core/operations/GOSTHash.mjs
Normal file
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import OperationError from "../errors/OperationError";
|
||||
import GostDigest from "../vendor/gost/gostDigest";
|
||||
import {toHexFast} from "../lib/Hex";
|
||||
|
||||
/**
|
||||
* GOST hash operation
|
||||
*/
|
||||
class GOSTHash extends Operation {
|
||||
|
||||
/**
|
||||
* GOSTHash constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "GOST hash";
|
||||
this.module = "Hashing";
|
||||
this.description = "The GOST hash function, defined in the standards GOST R 34.11-94 and GOST 34.311-95 is a 256-bit cryptographic hash function. It was initially defined in the Russian national standard GOST R 34.11-94 <i>Information Technology – Cryptographic Information Security – Hash Function</i>. The equivalent standard used by other member-states of the CIS is GOST 34.311-95.<br><br>This function must not be confused with a different Streebog hash function, which is defined in the new revision of the standard GOST R 34.11-2012.<br><br>The GOST hash function is based on the GOST block cipher.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/GOST_(hash_function)";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "S-Box",
|
||||
"type": "option",
|
||||
"value": [
|
||||
"D-A",
|
||||
"D-SC",
|
||||
"E-TEST",
|
||||
"E-A",
|
||||
"E-B",
|
||||
"E-C",
|
||||
"E-D",
|
||||
"E-SC",
|
||||
"E-Z",
|
||||
"D-TEST"
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
const sBox = args[1];
|
||||
const gostDigest = new GostDigest({
|
||||
name: "GOST R 34.11",
|
||||
version: 1994,
|
||||
sBox: sBox
|
||||
});
|
||||
|
||||
return toHexFast(gostDigest.digest(input));
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GOSTHash;
|
60
src/core/operations/Streebog.mjs
Normal file
60
src/core/operations/Streebog.mjs
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @author mshwed [m@ttshwed.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import OperationError from "../errors/OperationError";
|
||||
import GostDigest from "../vendor/gost/gostDigest";
|
||||
import {toHexFast} from "../lib/Hex";
|
||||
|
||||
/**
|
||||
* Streebog operation
|
||||
*/
|
||||
class Streebog extends Operation {
|
||||
|
||||
/**
|
||||
* Streebog constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Streebog";
|
||||
this.module = "Hashing";
|
||||
this.description = "Streebog is a cryptographic hash function defined in the Russian national standard GOST R 34.11-2012 <i>Information Technology \u2013 Cryptographic Information Security \u2013 Hash Function</i>. It was created to replace an obsolete GOST hash function defined in the old standard GOST R 34.11-94, and as an asymmetric reply to SHA-3 competition by the US National Institute of Standards and Technology.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Streebog";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Size",
|
||||
"type": "option",
|
||||
"value": ["256", "512"]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ArrayBuffer} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
const length = parseInt(args[0], 10);
|
||||
const gostDigest = new GostDigest({
|
||||
name: "GOST R 34.11",
|
||||
version: 2012,
|
||||
length: length
|
||||
});
|
||||
|
||||
return toHexFast(gostDigest.digest(input));
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Streebog;
|
2259
src/core/vendor/gost/gostCipher.mjs
vendored
Normal file
2259
src/core/vendor/gost/gostCipher.mjs
vendored
Normal file
File diff suppressed because it is too large
Load diff
1160
src/core/vendor/gost/gostCoding.mjs
vendored
Normal file
1160
src/core/vendor/gost/gostCoding.mjs
vendored
Normal file
File diff suppressed because it is too large
Load diff
1653
src/core/vendor/gost/gostCrypto.mjs
vendored
Normal file
1653
src/core/vendor/gost/gostCrypto.mjs
vendored
Normal file
File diff suppressed because it is too large
Load diff
1260
src/core/vendor/gost/gostDigest.mjs
vendored
Normal file
1260
src/core/vendor/gost/gostDigest.mjs
vendored
Normal file
File diff suppressed because it is too large
Load diff
451
src/core/vendor/gost/gostEngine.mjs
vendored
Executable file
451
src/core/vendor/gost/gostEngine.mjs
vendored
Executable file
|
@ -0,0 +1,451 @@
|
|||
/**
|
||||
* @file GOST 34.10-2012 signature function with 1024/512 bits digest
|
||||
* @version 1.76
|
||||
* @copyright 2014-2016, Rudolf Nickolaev. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
import GostRandom from './gostRandom';
|
||||
import GostCipher from './gostCipher';
|
||||
import GostDigest from './gostDigest';
|
||||
import GostSign from './gostSign';
|
||||
|
||||
/*
|
||||
* Engine definition base on normalized algorithm identifier
|
||||
*
|
||||
*/ // <editor-fold defaultstate="collapsed">
|
||||
|
||||
var root = {};
|
||||
|
||||
// Define engine
|
||||
function defineEngine(method, algorithm) {
|
||||
if (!algorithm)
|
||||
throw new (root.SyntaxError || Error)('Algorithm not defined');
|
||||
|
||||
if (!algorithm.name)
|
||||
throw new (root.SyntaxError || Error)('Algorithm name not defined');
|
||||
|
||||
var name = algorithm.name, mode = algorithm.mode;
|
||||
if ((name === 'GOST 28147' || name === 'GOST R 34.12' || name === 'RC2') && (method === 'generateKey' ||
|
||||
(mode === 'MAC' && (method === 'sign' || method === 'verify')) ||
|
||||
((mode === 'KW' || mode === 'MASK') && (method === 'wrapKey' || method === 'unwrapKey')) ||
|
||||
((!mode || mode === 'ES') && (method === 'encrypt' || method === 'decrypt')))) {
|
||||
return 'GostCipher';
|
||||
|
||||
} else if ((name === 'GOST R 34.11' || name === 'SHA') && (method === 'digest' ||
|
||||
(mode === 'HMAC' && (method === 'sign' || method === 'verify' || method === 'generateKey')) ||
|
||||
((mode === 'KDF' || mode === 'PBKDF2' || mode === 'PFXKDF' || mode === 'CPKDF') &&
|
||||
(method === 'deriveKey' || method === 'deriveBits' || method === 'generateKey')))) {
|
||||
return 'GostDigest';
|
||||
|
||||
} else if (name === 'GOST R 34.10' && (method === 'generateKey' ||
|
||||
((!mode || mode === 'SIGN') && (method === 'sign' || method === 'verify')) ||
|
||||
(mode === 'MASK' && (method === 'wrapKey' || method === 'unwrapKey')) ||
|
||||
(mode === 'DH' && (method === 'deriveKey' || method === 'deriveBits')))) {
|
||||
return 'GostSign';
|
||||
} else
|
||||
throw new (root.NotSupportedError || Error)('Algorithm ' + name + '-' + mode + ' is not valid for ' + method);
|
||||
} // </editor-fold>
|
||||
|
||||
/**
|
||||
* Object implements dedicated Web Workers and provide a simple way to create
|
||||
* and run GOST cryptographic algorithms in background thread.
|
||||
*
|
||||
* Object provide interface to GOST low-level cryptogric classes:
|
||||
* <ul>
|
||||
* <li>GostCipher - implementation of GOST 28147, GOST R 34.12, GOST R 34.13 Encryption algorithms. Reference {@link http://tools.ietf.org/html/rfc5830}</li>
|
||||
* <li>GostDigest - implementation of GOST R 34.11 Hash Function algorithms. References {@link http://tools.ietf.org/html/rfc5831} and {@link http://tools.ietf.org/html/rfc6986}</li>
|
||||
* <li>GostSign - implementation of GOST R 34.10 Digital Signature algorithms. References {@link http://tools.ietf.org/html/rfc5832} and {@link http://tools.ietf.org/html/rfc7091}</li>
|
||||
* </ul>
|
||||
* @namespace gostEngine
|
||||
*/
|
||||
var gostEngine = {
|
||||
/**
|
||||
* gostEngine.execute(algorithm, method, args) Entry point to execution
|
||||
* all low-level GOST cryptographic methods
|
||||
*
|
||||
* <ul>
|
||||
* <li>Determine the appropriate engine for a given execution method</li>
|
||||
* <li>Create cipher object for determineted engine</li>
|
||||
* <li>Execute method of cipher with given args</li>
|
||||
* </ul>
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @param {AlgorithmIndentifier} algorithm Algorithm identifier
|
||||
* @param {string} method Crypto method for execution
|
||||
* @param {Array} args Method arguments (keys, data, additional parameters)
|
||||
* @returns {(CryptoOperationData|Key|KeyPair|boolean)} Result of method execution
|
||||
*/
|
||||
execute: function (algorithm, method, args) // <editor-fold defaultstate="collapsed">
|
||||
{
|
||||
// Define engine for GOST algorithms
|
||||
var engine = defineEngine(method, algorithm);
|
||||
// Create cipher
|
||||
var cipher = this['get' + engine](algorithm);
|
||||
// Execute method
|
||||
return cipher[method].apply(cipher, args);
|
||||
}, // </editor-fold>
|
||||
/**
|
||||
* gostEngine.getGostCipher(algorithm) returns GOST 28147 / GOST R 34.12 cipher instance<br><br>
|
||||
*
|
||||
* GOST 28147-89 / GOST R 34.12-15 Encryption Algorithm<br><br>
|
||||
* When keys and initialization vectors are converted to/from byte arrays,
|
||||
* little-endian byte order is assumed.<br><br>
|
||||
*
|
||||
* Normalized algorithm identifier common parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>name</b> Algorithm name 'GOST 28147' or 'GOST R 34.12'</li>
|
||||
* <li><b>version</b> Algorithm version, number
|
||||
* <ul>
|
||||
* <li><b>1989</b> Current version of standard</li>
|
||||
* <li><b>2015</b> New draft version of standard</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>length</b> Block length
|
||||
* <ul>
|
||||
* <li><b>64</b> 64 bits length (default)</li>
|
||||
* <li><b>128</b> 128 bits length (only for version 2015)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>mode</b> Algorithm mode, string
|
||||
* <ul>
|
||||
* <li><b>ES</b> Encryption mode (default)</li>
|
||||
* <li><b>MAC</b> "imitovstavka" (MAC) mode</li>
|
||||
* <li><b>KW</b> Key wrapping mode</li>
|
||||
* <li><b>MASK</b> Key mask mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>sBox</b> Paramset sBox for GOST 28147-89, string. Used only if version = 1989</li>
|
||||
* </ul>
|
||||
*
|
||||
* Supported algorithms, modes and parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Encript/Decrypt mode (ES)
|
||||
* <ul>
|
||||
* <li><b>block</b> Block mode, string. Default ECB</li>
|
||||
* <li><b>keyMeshing</b> Key meshing mode, string. Default NO</li>
|
||||
* <li><b>padding</b> Padding mode, string. Default NO for CFB and CTR modes, or ZERO for others</li>
|
||||
* <li><b>iv</b> {@link CryptoOperationData} Initial vector with length of block. Default - zero block</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Sign/Verify mode (MAC)
|
||||
* <ul>
|
||||
* <li><b>macLength</b> Length of mac in bits (default - 32 bits)</li>
|
||||
* <li><b>iv</b> {@link CryptoOperationData} Initial vector with length of block. Default - zero block</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Wrap/Unwrap key mode (KW)
|
||||
* <ul>
|
||||
* <li><b>keyWrapping</b> Mode of keywrapping, string. Default NO - standard GOST key wrapping</li>
|
||||
* <li><b>ukm</b> {@link CryptoOperationData} User key material. Default - random generated value</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Wrap/Unwrap key mode (MASK)</li>
|
||||
* </ul>
|
||||
*
|
||||
* Supported paramters values:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Block modes (parameter 'block')
|
||||
* <ul>
|
||||
* <li><b>ECB</b> "prostaya zamena" (ECB) mode (default)</li>
|
||||
* <li><b>CFB</b> "gammirovanie s obratnoj svyaziyu" (64-bit CFB) mode</li>
|
||||
* <li><b>CTR</b> "gammirovanie" (counter) mode</li>
|
||||
* <li><b>CBC</b> Cipher-Block-Chaining (CBC) mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Key meshing modes (parameter 'keyMeshing')
|
||||
* <ul>
|
||||
* <li><b>NO</b> No key wrapping (default)</li>
|
||||
* <li><b>CP</b> CryptoPor Key key meshing</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Padding modes (parameter 'padding')
|
||||
* <ul>
|
||||
* <li><b>NO</b> No padding only for CFB and CTR modes</li>
|
||||
* <li><b>PKCS5</b> PKCS#5 padding mode</li>
|
||||
* <li><b>ZERO</b> Zero bits padding mode</li>
|
||||
* <li><b>RANDOM</b> Random bits padding mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Wrapping key modes (parameter 'keyWrapping')
|
||||
* <ul>
|
||||
* <li><b>NO</b> Ref. rfc4357 6.1 GOST 28147-89 Key wrapping</li>
|
||||
* <li><b>CP</b> CryptoPro Key wrapping mode</li>
|
||||
* <li><b>SC</b> SignalCom Key wrapping mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @param {AlgorithmIndentifier} algorithm Algorithm identifier
|
||||
* @returns {GostCipher} Instance of GostCipher
|
||||
*/
|
||||
getGostCipher: function (algorithm) // <editor-fold defaultstate="collapsed">
|
||||
{
|
||||
return new (GostCipher || (GostCipher = root.GostCipher))(algorithm);
|
||||
}, // </editor-fold>
|
||||
/**
|
||||
* gostEngine.getGostDigest(algorithm) returns GOST R 34.11 cipher instance<br><br>
|
||||
*
|
||||
* Normalized algorithm identifier common parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>name</b> Algorithm name 'GOST R 34.11'</li>
|
||||
* <li><b>version</b> Algorithm version
|
||||
* <ul>
|
||||
* <li><b>1994</b> old-style 256 bits digest based on GOST 28147-89</li>
|
||||
* <li><b>2012</b> 256 ro 512 bits digest algorithm "Streebog" GOST R 34.11-2012 (default)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>length</b> Digest length
|
||||
* <ul>
|
||||
* <li><b>256</b> 256 bits digest</li>
|
||||
* <li><b>512</b> 512 bits digest, valid only for algorithm "Streebog"</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>mode</b> Algorithm mode
|
||||
* <ul>
|
||||
* <li><b>HASH</b> simple digest mode (default)</li>
|
||||
* <li><b>HMAC</b> HMAC algorithm based on GOST R 34.11</li>
|
||||
* <li><b>KDF</b> Derive bits for KEK deversification</li>
|
||||
* <li><b>PBKDF2</b> Password based key dirivation algorithms PBKDF2 (based on HMAC)</li>
|
||||
* <li><b>PFXKDF</b> PFX key dirivation algorithms PFXKDF</li>
|
||||
* <li><b>CPKDF</b> CryptoPro Password based key dirivation algorithms</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>sBox</b> Paramset sBox for GOST 28147-89. Used only if version = 1994</li>
|
||||
* </ul>
|
||||
*
|
||||
* Supported algorithms, modes and parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Digest HASH mode (default)</li>
|
||||
* <li>Sign/Verify HMAC modes parameters depends on version and length
|
||||
* <ul>
|
||||
* <li><b>version: 1994</b> HMAC parameters (B = 32, L = 32)</li>
|
||||
* <li><b>version: 2012, length: 256</b> HMAC parameters (B = 64, L = 32)</li>
|
||||
* <li><b>version: 2012, length: 512</b> HMAC parameters (B = 64, L = 64)</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>DeriveBits/DeriveKey KDF mode
|
||||
* <ul>
|
||||
* <li><b>context</b> {@link CryptoOperationData} Context of the key derivation</li>
|
||||
* <li><b>label</b> {@link CryptoOperationData} Label that identifies the purpose for the derived keying material</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>DeriveBits/DeriveKey PBKDF2 mode
|
||||
* <ul>
|
||||
* <li><b>salt</b> {@link CryptoOperationData} Random salt as input for HMAC algorithm</li>
|
||||
* <li><b>iterations</b> Iteration count. GOST recomended value 1000 (default) or 2000</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>DeriveBits/DeriveKey PFXKDF mode
|
||||
* <ul>
|
||||
* <li><b>salt</b> {@link CryptoOperationData} Random salt as input for HMAC algorithm</li>
|
||||
* <li><b>iterations</b> Iteration count. GOST recomended value 1000 (default) or 2000</li>
|
||||
* <li><b>diversifier</b> Deversifier, ID=1 - key material for performing encryption or decryption,
|
||||
* ID=2 - IV (Initial Value) for encryption or decryption, ID=3 - integrity key for MACing</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>DeriveBits/DeriveKey CPKDF mode
|
||||
* <ul>
|
||||
* <li><b>salt</b> {@link CryptoOperationData} Random salt as input for HMAC algorithm</li>
|
||||
* <li><b>iterations</b> Iteration count. GOST recomended value 1000 (default) or 2000</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @param {AlgorithmIndentifier} algorithm Algorithm identifier
|
||||
* @returns {GostDigest} Instance of GostDigest
|
||||
*/
|
||||
getGostDigest: function (algorithm) // <editor-fold defaultstate="collapsed">
|
||||
{
|
||||
return new (GostDigest || (GostDigest = root.GostDigest))(algorithm);
|
||||
}, // </editor-fold>
|
||||
/**
|
||||
* gostEngine.getGostSign(algorithm) returns GOST R 34.10 cipher instance<br><br>
|
||||
*
|
||||
* Normalized algorithm identifier common parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>name</b> Algorithm name 'GOST R 34.10'</li>
|
||||
* <li><b>version</b> Algorithm version
|
||||
* <ul>
|
||||
* <li><b>1994</b> - Old-style GOST R 34.10-94 ExpMod algorithm with GOST R 34.11-94 hash</li>
|
||||
* <li><b>2001</b> - GOST R 34.10-2001 Eliptic curve algorithm with old GOST R 34.11-94 hash</li>
|
||||
* <li><b>2012</b> - GOST R 34.10-2012 Eliptic curve algorithm with GOST R 34.11-12 hash, default mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>length</b> Length of hash and signature. Key length == hash length for EC algorithms and 2 * hash length for ExpMod algorithm
|
||||
* <ul>
|
||||
* <li><b>GOST R 34.10-256</b> - 256 bits digest, default mode</li>
|
||||
* <li><b>GOST R 34.10-512</b> - 512 bits digest only for GOST R 34.11-2012 hash</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>mode</b> Algorithm mode
|
||||
* <ul>
|
||||
* <li><b>SIGN</b> Digital signature mode (default)</li>
|
||||
* <li><b>DH</b> Diffie-Hellman key generation and key agreement mode</li>
|
||||
* <li><b>MASK</b> Key mask mode</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>sBox</b> Paramset sBox for GOST 34.11-94. Used only if version = 1994 or 2001</li>
|
||||
* </ul>
|
||||
*
|
||||
* Supported algorithms, modes and parameters:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Sign/Verify mode (SIGN)</li>
|
||||
* <li>Wrap/Unwrap mode (MASK)</li>
|
||||
* <li>DeriveKey/DeriveBits mode (DH)
|
||||
* <ul>
|
||||
* <li>{@link CryptoOperationData} <b>ukm</b> User key material. Default - random generated value</li>
|
||||
* <li>{@link CryptoOperationData} <b>public</b> The peer's EC public key data</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>GenerateKey mode (SIGN and DH and MASK) version = 1994
|
||||
* <ul>
|
||||
* <li><b>namedParam</b> Paramset for key generation algorithm. If specified no additianal parameters required</li>
|
||||
* </ul>
|
||||
* Additional parameters, if namedParam not specified
|
||||
* <ul>
|
||||
* <li><b>modulusLength</b> Bit length of p (512 or 1024 bits). Default = 1024</li>
|
||||
* <li><b>p</b> {@link CryptoOperationData} Modulus, prime number, 2^(t-1)<p<2^t</li>
|
||||
* <li><b>q</b> {@link CryptoOperationData} Order of cyclic group, prime number, 2^254<q<2^256, q is a factor of p-1</li>
|
||||
* <li><b>a</b> {@link CryptoOperationData} Generator, integer, 1<a<p-1, at that aq (mod p) = 1</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>GenerateKey mode (SIGN and DH and MASK) version = 2001 or 2012
|
||||
* <ul>
|
||||
* <li><b>namedCurve</b> Paramset for key generation algorithm. If specified no additianal parameters required</li>
|
||||
* </ul>
|
||||
* Additional EC parameters, if namedCurve not specified
|
||||
* <ul>
|
||||
* <li><b>p</b> {@link CryptoOperationData} Prime number - elliptic curve modulus</li>
|
||||
* <li><b>a</b> {@link CryptoOperationData} Coefficients a of the elliptic curve E</li>
|
||||
* <li><b>b</b> {@link CryptoOperationData} Coefficients b of the elliptic curve E</li>
|
||||
* <li><b>q</b> {@link CryptoOperationData} Prime number - order of cyclic group</li>
|
||||
* <li><b>x</b> {@link CryptoOperationData} Base point p x-coordinate</li>
|
||||
* <li><b>y</b> {@link CryptoOperationData} Base point p y-coordinate</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @param {AlgorithmIndentifier} algorithm Algorithm identifier
|
||||
* @returns {GostSign} Instance of GostSign
|
||||
*/
|
||||
getGostSign: function (algorithm) // <editor-fold defaultstate="collapsed">
|
||||
{
|
||||
return new (GostSign || (GostSign = root.GostSign))(algorithm);
|
||||
} // </editor-fold>
|
||||
};
|
||||
|
||||
/*
|
||||
* Worker method execution
|
||||
*
|
||||
*/ // <editor-fold defaultstate="collapsed">
|
||||
|
||||
// Worker for gostCripto method execution
|
||||
if (root.importScripts) {
|
||||
|
||||
/**
|
||||
* Method called when {@link SubtleCrypto} calls its own postMessage()
|
||||
* method with data parameter: algorithm, method and arg.<br>
|
||||
* Call method execute and postMessage() results to onmessage event handler
|
||||
* in the main process.<br>
|
||||
* If error occured onerror event handler executed in main process.
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @name onmessage
|
||||
* @param {MessageEvent} event Message event with data {algorithm, method, args}
|
||||
*/
|
||||
root.onmessage = function (event) {
|
||||
try {
|
||||
postMessage({
|
||||
id: event.data.id,
|
||||
result: gostEngine.execute(event.data.algorithm,
|
||||
event.data.method, event.data.args)});
|
||||
} catch (e) {
|
||||
postMessage({
|
||||
id: event.data.id,
|
||||
error: e.message
|
||||
});
|
||||
}
|
||||
};
|
||||
} else {
|
||||
|
||||
// Load dependens
|
||||
var baseUrl = '', nameSuffix = '';
|
||||
// Try to define from DOM model
|
||||
if (typeof document !== 'undefined') {
|
||||
(function () {
|
||||
var regs = /^(.*)gostCrypto(.*)\.js$/i;
|
||||
var list = document.querySelectorAll('script');
|
||||
for (var i = 0, n = list.length; i < n; i++) {
|
||||
var value = list[i].getAttribute('src');
|
||||
var test = regs.exec(value);
|
||||
if (test) {
|
||||
baseUrl = test[1];
|
||||
nameSuffix = test[2];
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
// Local importScripts procedure for include dependens
|
||||
var importScripts = function () {
|
||||
for (var i = 0, n = arguments.length; i < n; i++) {
|
||||
var name = arguments[i].split('.'),
|
||||
src = baseUrl + name[0] + nameSuffix + '.' + name[1];
|
||||
var el = document.querySelector('script[src="' + src + '"]');
|
||||
if (!el) {
|
||||
el = document.createElement('script');
|
||||
el.setAttribute('src', src);
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Import engines
|
||||
if (!GostRandom)
|
||||
importScripts('gostRandom.js');
|
||||
if (!GostCipher)
|
||||
importScripts('gostCipher.js');
|
||||
if (!GostDigest)
|
||||
importScripts('gostDigest.js');
|
||||
if (!GostSign)
|
||||
importScripts('gostSign.js');
|
||||
} // </editor-fold>
|
||||
|
||||
export default gostEngine;
|
||||
|
128
src/core/vendor/gost/gostRandom.mjs
vendored
Normal file
128
src/core/vendor/gost/gostRandom.mjs
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* Implementation Web Crypto random generatore for GOST algorithms
|
||||
* 1.76
|
||||
* 2014-2016, Rudolf Nickolaev. All rights reserved.
|
||||
*
|
||||
* Exported for CyberChef by mshwed [m@ttshwed.com]
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
import crypto from 'crypto';
|
||||
|
||||
|
||||
/**
|
||||
* The gostCrypto provide general purpose cryptographic functionality for
|
||||
* GOST standards including a cryptographically strong pseudo-random number
|
||||
* generator seeded with truly random values.
|
||||
*
|
||||
* @Class GostRandom
|
||||
*
|
||||
*/ // <editor-fold defaultstate="collapsed">
|
||||
|
||||
var root = {};
|
||||
var rootCrypto = crypto;
|
||||
|
||||
var TypeMismatchError = Error;
|
||||
var QuotaExceededError = Error;
|
||||
|
||||
// Initialize mouse and time counters for random generator
|
||||
var randomRing = {
|
||||
seed: new Uint8Array(1024),
|
||||
getIndex: 0,
|
||||
setIndex: 0,
|
||||
set: function (x) {
|
||||
if (this.setIndex >= 1024)
|
||||
this.setIndex = 0;
|
||||
this.seed[this.setIndex++] = x;
|
||||
},
|
||||
get: function () {
|
||||
if (this.getIndex >= 1024)
|
||||
this.getIndex = 0;
|
||||
return this.seed[this.getIndex++];
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
try {
|
||||
// Mouse move event to fill random array
|
||||
document.addEventListener('mousemove', function (e) {
|
||||
randomRing.set((new Date().getTime() & 255) ^
|
||||
((e.clientX || e.pageX) & 255) ^
|
||||
((e.clientY || e.pageY) & 255));
|
||||
}, false);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
try {
|
||||
// Keypress event to fill random array
|
||||
document.addEventListener('keydown', function (e) {
|
||||
randomRing.set((new Date().getTime() & 255) ^
|
||||
(e.keyCode & 255));
|
||||
}, false);
|
||||
} catch (e) {
|
||||
}
|
||||
} // </editor-fold>
|
||||
|
||||
function GostRandom() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The getRandomValues method generates cryptographically random values. <br><br>
|
||||
*
|
||||
* Random generator based on JavaScript Web Crypto random genereator
|
||||
* (if it is possible) or Math.random mixed with time and parameters of
|
||||
* mouse and keyboard events
|
||||
*
|
||||
* @memberOf GostRandom
|
||||
* @param {(ArrayBuffer|ArrayBufferView)} array Destination buffer for random data
|
||||
*/
|
||||
GostRandom.prototype.getRandomValues = function (array) // <editor-fold defaultstate="collapsed">
|
||||
{
|
||||
|
||||
if (!array.byteLength)
|
||||
throw new TypeMismatchError('Array is not of an integer type (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, or Uint32Array)');
|
||||
|
||||
if (array.byteLength > 65536)
|
||||
throw new QuotaExceededError('Byte length of array can\'t be greate then 65536');
|
||||
|
||||
var u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
||||
if (rootCrypto && rootCrypto.getRandomValues) {
|
||||
// Native window cryptographic interface
|
||||
rootCrypto.getRandomValues(u8);
|
||||
} else {
|
||||
// Standard Javascript method
|
||||
for (var i = 0, n = u8.length; i < n; i++)
|
||||
u8[i] = Math.floor(256 * Math.random()) & 255;
|
||||
}
|
||||
|
||||
// Mix bio randomizator
|
||||
for (var i = 0, n = u8.length; i < n; i++)
|
||||
u8[i] = u8[i] ^ randomRing.get();
|
||||
return array;
|
||||
}; // </editor-fold>
|
||||
|
||||
export default GostRandom;
|
2023
src/core/vendor/gost/gostSign.mjs
vendored
Executable file
2023
src/core/vendor/gost/gostSign.mjs
vendored
Executable file
File diff suppressed because it is too large
Load diff
|
@ -1033,6 +1033,72 @@ TestRegister.addTests([
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Streebog-256: Test Case 1",
|
||||
input: "",
|
||||
expectedOutput: "3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Streebog",
|
||||
args: ["256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Streebog-256: Test Case 2",
|
||||
input: "The quick brown fox jumps over the lazy dog",
|
||||
expectedOutput: "3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Streebog",
|
||||
args: ["256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Streebog-512: Test Case 1",
|
||||
input: "",
|
||||
expectedOutput: "8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Streebog",
|
||||
args: ["512"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Streebog-512: Test Case 2",
|
||||
input: "The quick brown fox jumps over the lazy dog",
|
||||
expectedOutput: "d2b793a0bb6cb5904828b5b6dcfb443bb8f33efc06ad09368878ae4cdc8245b97e60802469bed1e7c21a64ff0b179a6a1e0bb74d92965450a0adab69162c00fe",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Streebog",
|
||||
args: ["512"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.11-94: Test Case 1",
|
||||
input: "",
|
||||
expectedOutput: "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "GOST hash",
|
||||
args: ["D-A"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "GOST R 34.11-94: Test Case 2",
|
||||
input: "This is message, length=32 bytes",
|
||||
expectedOutput: "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "GOST hash",
|
||||
args: ["D-A"]
|
||||
}
|
||||
]
|
||||
}
|
||||
/*{ // This takes a LONG time to run (over a minute usually).
|
||||
name: "Scrypt: RFC test vector 4",
|
||||
input: "pleaseletmein",
|
||||
|
|
Loading…
Reference in a new issue