Skip to content

Commit

Permalink
Fix gchq#578 by refactoring and implementing the modes
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeuw committed Sep 25, 2019
1 parent 928f1c3 commit db29488
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 584 deletions.
42 changes: 17 additions & 25 deletions src/core/operations/BlowfishDecrypt.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,9 @@

import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import forge from "node-forge/dist/forge.min.js"
import OperationError from "../errors/OperationError.mjs";
import { Blowfish } from "../vendor/Blowfish.mjs";
import { toBase64 } from "../lib/Base64.mjs";
import { toHexFast } from "../lib/Hex.mjs";

/**
* Lookup table for Blowfish output types.
*/
const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
Base64: 0, Hex: 1, String: 2, Raw: 3
};
/**
* Lookup table for Blowfish modes.
*/
const BLOWFISH_MODE_LOOKUP = {
ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
};

/**
* Blowfish Decrypt operation
Expand Down Expand Up @@ -57,7 +43,7 @@ class BlowfishDecrypt extends Operation {
{
"name": "Mode",
"type": "option",
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
},
{
"name": "Input",
Expand All @@ -79,21 +65,27 @@ class BlowfishDecrypt extends Operation {
*/
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
[,, mode, inputType, outputType] = args;
iv = Utils.convertToByteString(args[1].string, args[1].option),
mode = args[2],
inputType = args[3],
outputType = args[4];

if (key.length === 0) throw new OperationError("Enter a key");

input = inputType === "Raw" ? Utils.strToByteArray(input) : input;

Blowfish.setIV(toBase64(iv), 0);
input = Utils.convertToByteString(input, inputType);

const result = Blowfish.decrypt(input, key, {
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
var decipher = Blowfish.createDecipher(key,mode);
decipher.start({
iv: iv.length === 0 ? "" : iv,
});
decipher.update(forge.util.createBuffer(input));
const result = decipher.finish();

return outputType === "Hex" ? toHexFast(Utils.strToByteArray(result)) : result;
if (result) {
return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
} else {
throw new OperationError("Unable to decrypt input with these parameters.");
}
}

}
Expand Down
41 changes: 15 additions & 26 deletions src/core/operations/BlowfishEncrypt.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,9 @@

import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import forge from "node-forge/dist/forge.min.js";
import OperationError from "../errors/OperationError.mjs";
import { Blowfish } from "../vendor/Blowfish.mjs";
import { toBase64 } from "../lib/Base64.mjs";

/**
* Lookup table for Blowfish output types.
*/
const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
Base64: 0, Hex: 1, String: 2, Raw: 3
};

/**
* Lookup table for Blowfish modes.
*/
const BLOWFISH_MODE_LOOKUP = {
ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
};


/**
* Blowfish Encrypt operation
Expand Down Expand Up @@ -58,7 +43,7 @@ class BlowfishEncrypt extends Operation {
{
"name": "Mode",
"type": "option",
"value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
"value": ["CBC", "CFB", "OFB", "CTR", "ECB"]
},
{
"name": "Input",
Expand All @@ -80,21 +65,25 @@ class BlowfishEncrypt extends Operation {
*/
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteArray(args[1].string, args[1].option),
[,, mode, inputType, outputType] = args;
iv = Utils.convertToByteString(args[1].string, args[1].option),
mode = args[2],
inputType = args[3],
outputType = args[4];

if (key.length === 0) throw new OperationError("Enter a key");

input = Utils.convertToByteString(input, inputType);

Blowfish.setIV(toBase64(iv), 0);

const enc = Blowfish.encrypt(input, key, {
outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
cipherMode: BLOWFISH_MODE_LOOKUP[mode]
});
var cipher = Blowfish.createCipher(key,mode)
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(input));
cipher.finish();

return outputType === "Raw" ? Utils.byteArrayToChars(enc) : enc;
if (outputType === "Hex") {
return cipher.output.toHex();
} else {
return cipher.output.getBytes();
}
}

}
Expand Down
Loading

0 comments on commit db29488

Please sign in to comment.