// Ripped from https://github.com/Ch0pin/medusa/ and modified to fit Androguard packets

colorLog("[+] LOADING ENCRYPTION/CIPHER.JS", { c: Color.Red });

var cipher = Java.use("javax.crypto.Cipher");

cipher.init.overload("int", "java.security.Key").implementation = function (
    mode,
    key,
) {
    var operation = "";
    var algorithm = this.getAlgorithm();

    if (mode == 1) operation = "Encrypting";
    else if (mode == 2) operation = "Decrypting";

    agPacket({
        algorithm: algorithm,
        operation: operation,
        mode: mode,
        key: byteArraytoHexString(key.getEncoded()),
    }).send();

    return this.init(mode, key);
};

cipher.init.overload(
    "int",
    "java.security.Key",
    "java.security.spec.AlgorithmParameterSpec",
).implementation = function (mode, key, paramsec) {
    var operation = "";
    var algorithm = this.getAlgorithm();

    if (mode == 1) operation = "Encrypting";
    else if (mode == 2) operation = "Decrypting";

    agPacket({
        algorithm: algorithm,
        mode: mode,
        operation: operation,
        key: byteArraytoHexString(key.getEncoded()),
        iv: paramsec,
    }).send();

    return this.init(mode, key, paramsec);
};

cipher.init.overload(
    "int",
    "java.security.Key",
    "java.security.AlgorithmParameters",
    "java.security.SecureRandom",
).implementation = function (mode, key, paramsec, secRnd) {
    var operation = "";
    var algorithm = this.getAlgorithm();

    if (mode == 1) operation = "Encrypting";
    else if (mode == 2) operation = "Decrypting";

    agPacket({
        algorithm: algorithm,
        mode: mode,
        operation: operation,
        key: byteArraytoHexString(key.getEncoded()),
        iv: paramsec,
        secRnd: secRnd,
    }).send();
    return this.init(mode, key, paramsec, secRnd);
};

//DO FINAL--------------------------------

cipher.doFinal.overload("[B").implementation = function (byteArray) {
    var ret = this.doFinal(byteArray);
    agPacket({
        in: byteArraytoHexString(byteArray),
        ret: byteArraytoHexString(ret),
    }).send();
    return ret;
};

cipher.doFinal.overload("[B", "int").implementation = function (
    byteArray,
    outputOffset,
) {
    var ret = this.doFinal(byteArray, outputOffset);
    agPacket({ in: byteArray, outputOffset: outputOffset, ret: ret }).send();
    return ret;
};

cipher.doFinal.overload("[B", "int", "int").implementation = function (
    byteArray,
    outputOffset,
    inputlen,
) {
    var ret = this.doFinal(byteArray, outputOffset, inputlen);
    agPacket({
        in: byteArray,
        outputOffset: outputOffset,
        inputlen: inputlen,
        ret: ret,
    }).send();
    return ret;
};

cipher.doFinal.overload("[B", "int", "int", "[B").implementation = function (
    byteArray,
    outputOffset,
    inputlen,
    output,
) {
    var ret = this.doFinal(byteArray, outputOffset, inputlen, output);
    agPacket({
        in: byteArray,
        out: output,
        outputOffset: outputOffset,
        inputlen: inputlen,
        ret: ret,
    }).send();
    return ret;
};

cipher.doFinal.overload("[B", "int", "int", "[B", "int").implementation =
    function (byteArray, outputOffset, inputlen, output, outoffset) {
        var ret = this.doFinal(
            byteArray,
            outputOffset,
            inputlen,
            output,
            outoffset,
        );
        agPacket({
            in: byteArray,
            out: output,
            outputOffset: outputOffset,
            inputlen: inputlen,
            outoffset: outoffset,
            ret: ret,
        }).send();
        return ret;
    };
