// 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();
    var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec'));

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

    agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).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();
    var castedToIv = Java.cast(paramsec, Java.use('javax.crypto.spec.IvParameterSpec'));

    if(mode == 1)
        operation = "Encrypting";
    else if(mode == 2)
        operation = "Decrypting";
    
    agPacket({algorithm: algorithm, mode: mode, operation: operation, key: byteArraytoHexString(key.getEncoded()), iv: byteArraytoHexString(castedToIv.getIV())}).send();
    return this.init(mode, key, paramsec, secRnd); 
}


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

cipher.doFinal.overload('[B').implementation = function(byteArray) {
    var ret = this.doFinal(byteArray);
    agPacket({in: byteArray, ret: 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;
}