From 45080ec9f0c546ba169bd2bcfa77557a53eefabd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Dec 2023 12:05:04 +0000 Subject: [PATCH 1/4] C++: Create an abstract class to control debug 'toString' output for dataflow nodes. --- .../ir/dataflow/internal/DataFlowPrivate.qll | 13 +--- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 11 ++- .../ir/dataflow/internal/DebugPrinting.qll | 9 +++ .../ir/dataflow/internal/Node0ToString.qll | 75 +++++++++++++++++++ 4 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DebugPrinting.qll create mode 100644 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index cd387d5137a..9391282411b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -6,6 +6,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Unit +import Node0ToString cached private module Cached { @@ -138,11 +139,7 @@ abstract class InstructionNode0 extends Node0Impl { override DataFlowType getType() { result = getInstructionType(instr, _) } - override string toStringImpl() { - if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable - then result = "this" - else result = instr.getAst().toString() - } + override string toStringImpl() { result = instructionToString(instr) } override Location getLocationImpl() { if exists(instr.getAst().getLocation()) @@ -187,11 +184,7 @@ abstract class OperandNode0 extends Node0Impl { override DataFlowType getType() { result = getOperandType(op, _) } - override string toStringImpl() { - if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable - then result = "this" - else result = op.getDef().getAst().toString() - } + override string toStringImpl() { result = operandToString(op) } override Location getLocationImpl() { if exists(op.getDef().getAst().getLocation()) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 392ccde1ae4..3e3517513ae 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -486,10 +486,13 @@ class Node extends TIRDataFlowNode { } private string toExprString(Node n) { - result = n.asExpr(0).toString() - or - not exists(n.asExpr()) and - result = n.asIndirectExpr(0, 1).toString() + " indirection" + isDebugMode() and + ( + result = n.asExpr(0).toString() + or + not exists(n.asExpr()) and + result = n.asIndirectExpr(0, 1).toString() + " indirection" + ) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DebugPrinting.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DebugPrinting.qll new file mode 100644 index 00000000000..1c958cf78d6 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DebugPrinting.qll @@ -0,0 +1,9 @@ +/** + * This file activates debugging mode for dataflow node printing. + */ + +private import Node0ToString + +private class DebugNode0ToString extends Node0ToString { + final override predicate isDebugMode() { any() } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll new file mode 100644 index 00000000000..e43bff16b10 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll @@ -0,0 +1,75 @@ +/** + * This file contains the abstract class that serves as the base class for + * dataflow node printing. + * + * By default, a non-debug string is produced. However, a debug-friendly + * string can be produced by importing `DebugPrinting.qll`. + */ + +private import semmle.code.cpp.ir.IR +private import codeql.util.Unit + +/** + * A class to control whether a debugging version of instructions and operands + * should be printed as part of the `toString` output of dataflow nodes. + * + * To enable debug printing import the `DebugPrinting.ql` file. By default, + * non-debug output will be used. + */ +class Node0ToString extends Unit { + abstract predicate isDebugMode(); + + private string normalInstructionToString(Instruction i) { + not this.isDebugMode() and + if i.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable + then result = "this" + else result = i.getAst().toString() + } + + private string normalOperandToString(Operand op) { + not this.isDebugMode() and + if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable + then result = "this" + else result = op.getDef().getAst().toString() + } + + /** + * Gets the string that should be used by `InstructionNode.toString` + */ + string instructionToString(Instruction i) { + if this.isDebugMode() + then result = i.getDumpString() + else result = this.normalInstructionToString(i) + } + + /** + * Gets the string that should be used by `OperandNode.toString`. + */ + string operandToString(Operand op) { + if this.isDebugMode() + then result = op.getDumpString() + " @ " + op.getUse().getResultId() + else result = this.normalOperandToString(op) + } +} + +private class NoDebugNode0ToString extends Node0ToString { + final override predicate isDebugMode() { none() } +} + +/** + * Gets the string that should be used by `OperandNode.toString`. + */ +string operandToString(Operand op) { result = any(Node0ToString nts).operandToString(op) } + +/** + * Gets the string that should be used by `InstructionNode.toString` + */ +string instructionToString(Instruction i) { result = any(Node0ToString nts).instructionToString(i) } + +/** + * Holds if debugging mode is enabled. + * + * In debug mode the `toString` on dataflow nodes is more expensive to compute, + * but gives more precise information about the different dataflow nodes. + */ +predicate isDebugMode() { not any(Node0ToString nts).isDebugMode() } From fcc3113bfc7b0a543e670f2866345d2356a2cf1a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Dec 2023 14:31:02 +0000 Subject: [PATCH 2/4] C++: Privately import 'Node0ToString'. --- .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 9391282411b..8c66aad6680 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -6,7 +6,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Unit -import Node0ToString +private import Node0ToString cached private module Cached { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 3e3517513ae..e50cac3f4e6 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -15,6 +15,7 @@ private import ModelUtil private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon private import codeql.util.Unit +private import Node0ToString /** * The IR dataflow graph consists of the following nodes: From 401ab3b0358708838912824dcb1316baad02f038 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Dec 2023 14:31:45 +0000 Subject: [PATCH 3/4] C++: Fix 'isDebugMode'. It was computing 'isNotDebugMode' (oops). --- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index e50cac3f4e6..4fa0754de91 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -487,7 +487,7 @@ class Node extends TIRDataFlowNode { } private string toExprString(Node n) { - isDebugMode() and + not isDebugMode() and ( result = n.asExpr(0).toString() or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll index e43bff16b10..a271e93355a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/Node0ToString.qll @@ -72,4 +72,4 @@ string instructionToString(Instruction i) { result = any(Node0ToString nts).inst * In debug mode the `toString` on dataflow nodes is more expensive to compute, * but gives more precise information about the different dataflow nodes. */ -predicate isDebugMode() { not any(Node0ToString nts).isDebugMode() } +predicate isDebugMode() { any(Node0ToString nts).isDebugMode() } From a478980e489977b4e6358463f8febd33fa01b7b5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 13 Dec 2023 15:40:09 +0000 Subject: [PATCH 4/4] Revert "Swift: CommonCrypto test cases for the BrokenCryptoAlgorithm query" --- .../CWE-327/BrokenCryptoAlgorithm.expected | 0 .../BrokenCryptoAlgorithm.qlref.disabled | 1 - .../Security/CWE-327/test_commoncrypto.swift | 217 ------------------ 3 files changed, 218 deletions(-) delete mode 100644 swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected delete mode 100644 swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.qlref.disabled delete mode 100644 swift/ql/test/query-tests/Security/CWE-327/test_commoncrypto.swift diff --git a/swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected b/swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.qlref.disabled b/swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.qlref.disabled deleted file mode 100644 index af059fc9e2b..00000000000 --- a/swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.qlref.disabled +++ /dev/null @@ -1 +0,0 @@ -queries/Security/CWE-327/BrokenCryptoAlgorithm.ql \ No newline at end of file diff --git a/swift/ql/test/query-tests/Security/CWE-327/test_commoncrypto.swift b/swift/ql/test/query-tests/Security/CWE-327/test_commoncrypto.swift deleted file mode 100644 index 499686557fe..00000000000 --- a/swift/ql/test/query-tests/Security/CWE-327/test_commoncrypto.swift +++ /dev/null @@ -1,217 +0,0 @@ -// --- stubs --- - -struct Data { - func withUnsafeBytes( - _ body: (UnsafeRawBufferPointer) throws -> ResultType - ) rethrows -> ResultType { return 0 as! ResultType } - mutating func withUnsafeMutableBytes( - _ body: (UnsafeMutableRawBufferPointer) throws -> ResultType - ) rethrows -> ResultType { return 0 as! ResultType } -} - -// --- CommonCryptor --- -// (real world projects will import the CommonCryptor headers which get -// converted to Swift by the compiler; the following is an approximation -// of that derived from QL queries and the CommonCryptor header files) - -var kCCSuccess : Int = 0 -typealias CCCryptorStatus = Int32 - -typealias CCCryptorRef = OpaquePointer - -var kCCEncrypt : Int = 0 -var kCCDecrypt : Int = 1 -typealias CCOperation = UInt32 - -var kCCAlgorithmAES128 : Int = 0 -var kCCAlgorithmAES : Int = 0 -var kCCAlgorithmDES : Int = 1 -var kCCAlgorithm3DES : Int = 2 -var kCCAlgorithmCAST : Int = 3 -var kCCAlgorithmRC4 : Int = 4 -var kCCAlgorithmRC2 : Int = 5 -var kCCAlgorithmBlowfish : Int = 6 -typealias CCAlgorithm = UInt32 - -var kCCOptionPKCS7Padding : Int = 1 -var kCCOptionECBMode : Int = 2 -typealias CCOptions = UInt32 - -var kCCModeECB : Int = 1 -var kCCModeCBC : Int = 2 -var kCCModeCFB : Int = 3 -var kCCModeCTR : Int = 4 -var kCCModeOFB : Int = 7 -var kCCModeRC4 : Int = 9 -var kCCModeCFB8 : Int = 10 -typealias CCMode = UInt32 - -typealias CCPadding = UInt32 - -typealias CCModeOptions = UInt32 - -func CCCryptorCreate( - _ op: CCOperation, - _ alg: CCAlgorithm, - _ options: CCOptions, - _ key: UnsafeRawPointer?, - _ keyLength: Int, - _ iv: UnsafeRawPointer?, - _ cryptorRef: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -func CCCryptorCreateFromData( - _ op: CCOperation, - _ alg: CCAlgorithm, - _ options: CCOptions, - _ key: UnsafeRawPointer?, - _ keyLength: Int, - _ iv: UnsafeRawPointer?, - _ data: UnsafeRawPointer?, - _ dataLength: Int, - _ cryptorRef: UnsafeMutablePointer?, - _ dataUsed: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -func CCCryptorCreateWithMode( - _ op: CCOperation, - _ mode: CCMode, - _ alg: CCAlgorithm, - _ padding: CCPadding, - _ iv: UnsafeRawPointer?, - _ key: UnsafeRawPointer?, - _ keyLength: Int, - _ tweak: UnsafeRawPointer?, - _ tweakLength: Int, - _ numRounds: Int32, - _ options: CCModeOptions, - _ cryptorRef: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -func CCCryptorUpdate( - _ cryptorRef: CCCryptorRef?, - _ dataIn: UnsafeRawPointer?, - _ dataInLength: Int, - _ dataOut: UnsafeMutableRawPointer?, - _ dataOutAvailable: Int, - _ dataOutMoved: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -func CCCryptorFinal( - _ cryptorRef: CCCryptorRef?, - _ dataOut: UnsafeMutableRawPointer?, - _ dataOutAvailable: Int, - _ dataOutMoved: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -func CCCrypt( - _ op: CCOperation, - _ alg: CCAlgorithm, - _ options: CCOptions, - _ key: UnsafeRawPointer?, - _ keyLength: Int, - _ iv: UnsafeRawPointer?, - _ dataIn: UnsafeRawPointer?, - _ dataInLength: Int, - _ dataOut: UnsafeMutableRawPointer?, - _ dataOutAvailable: Int, - _ dataOutMoved: UnsafeMutablePointer? - ) -> CCCryptorStatus { return 0 } - -// --- tests --- - -func cond() -> Bool { return true } - -func test_commoncrypto1(key: Data, iv: Data, dataIn: Data, dataOut: inout Data) { - // semi-realistic test case - var myCryptor: CCCryptorRef? - var dataOutWritten = 0 - - key.withUnsafeBytes({ - keyPtr in - iv.withUnsafeBytes({ - // create the cryptor object - ivPtr in - let result1 = CCCryptorCreate( - CCOperation(kCCEncrypt), - CCAlgorithm(kCCAlgorithm3DES), // BAD [NOT DETECTED] - CCOptions(0), - keyPtr.baseAddress!, - keyPtr.count, - ivPtr.baseAddress!, - &myCryptor - ) - guard result1 == CCCryptorStatus(kCCSuccess) else { - return // fail - } - - dataIn.withUnsafeBytes({ - dataInPtr in - dataOut.withUnsafeMutableBytes({ - dataOutPtr in - // encrypt data - while (cond()) { - let result2 = CCCryptorUpdate( - myCryptor, - dataInPtr.baseAddress!, - dataInPtr.count, - dataOutPtr.baseAddress!, - dataOutPtr.count, - &dataOutWritten) - guard result2 == CCCryptorStatus(kCCSuccess) else { - return // fail - } - } - - // finish - let result3 = CCCryptorFinal( - myCryptor, - dataOutPtr.baseAddress!, - dataOutPtr.count, - &dataOutWritten) - guard result3 == CCCryptorStatus(kCCSuccess) else { - return // fail - } - }) - }) - }) - }) -} - -func test_commoncrypto2( - key: UnsafeRawPointer, keyLen: Int, - iv: UnsafeRawPointer, - dataIn: UnsafeRawPointer, dataInLen: Int, - dataOut: UnsafeMutableRawPointer, dataOutAvail: Int) { - var myCryptor: CCCryptorRef? - var dataOutWritten = 0 - - // algorithms - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmDES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED] - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED] - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmCAST), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmRC4), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED] - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmRC2), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED] - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmBlowfish), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, &myCryptor) // BAD [NOT DETECTED] - _ = CCCryptorCreateFromData(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED] - _ = CCCryptorCreateFromData(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED] - - // block modes (the default is CBC) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(0), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionPKCS7Padding), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) - _ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionECBMode), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED] - _ = CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), CCOptions(kCCOptionECBMode), key, keyLen, iv, &myCryptor) // BAD [NOT DETECTED] - _ = CCCryptorCreateFromData(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), CCOptions(kCCOptionECBMode), key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED] - - // modes - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeECB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) // BAD [NOT DETECTED] - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCBC), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCFB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCTR), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeOFB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeRC4), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) - _ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCFB8), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) -}