|
| 1 | + |
| 2 | +// --- stubs --- |
| 3 | + |
| 4 | +// These stubs roughly follows the same structure as classes from CryptoSwift |
| 5 | +class AES |
| 6 | +{ |
| 7 | + init(key: Array<UInt8>, blockMode: BlockMode, padding: Padding) { } |
| 8 | + init(key: Array<UInt8>, blockMode: BlockMode) { } |
| 9 | + init(key: String, iv: String) { } |
| 10 | + init(key: String, iv: String, padding: Padding) { } |
| 11 | +} |
| 12 | + |
| 13 | +class Blowfish |
| 14 | +{ |
| 15 | + init(key: Array<UInt8>, blockMode: BlockMode, padding: Padding) { } |
| 16 | + init(key: Array<UInt8>, blockMode: BlockMode) { } |
| 17 | + init(key: String, iv: String) { } |
| 18 | + init(key: String, iv: String, padding: Padding) { } |
| 19 | +} |
| 20 | + |
| 21 | +class ChaCha20 |
| 22 | +{ |
| 23 | + init(key: Array<UInt8>, iv: Array<UInt8>) { } |
| 24 | + init(key: String, iv: String) { } |
| 25 | +} |
| 26 | + |
| 27 | +class Rabbit |
| 28 | +{ |
| 29 | + init(key: Array<UInt8>) { } |
| 30 | + init(key: String) { } |
| 31 | + init(key: Array<UInt8>, iv: Array<UInt8>) { } |
| 32 | + init(key: String, iv: String) { } |
| 33 | +} |
| 34 | + |
| 35 | +protocol BlockMode { } |
| 36 | + |
| 37 | +struct CBC: BlockMode { |
| 38 | + init(iv: Array<UInt8>) { } |
| 39 | +} |
| 40 | + |
| 41 | +struct CFB: BlockMode { |
| 42 | + enum SegmentSize: Int { |
| 43 | + case cfb8 = 1 |
| 44 | + case cfb128 = 16 |
| 45 | + } |
| 46 | + |
| 47 | + init(iv: Array<UInt8>, segmentSize: SegmentSize = .cfb128) { } |
| 48 | +} |
| 49 | + |
| 50 | +final class GCM: BlockMode { |
| 51 | + enum Mode { case combined, detached } |
| 52 | + init(iv: Array<UInt8>, additionalAuthenticatedData: Array<UInt8>? = nil, tagLength: Int = 16, mode: Mode = .detached) { } |
| 53 | + convenience init(iv: Array<UInt8>, authenticationTag: Array<UInt8>, additionalAuthenticatedData: Array<UInt8>? = nil, mode: Mode = .detached) { |
| 54 | + self.init(iv: iv, additionalAuthenticatedData: additionalAuthenticatedData, tagLength: authenticationTag.count, mode: mode) |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +struct OFB: BlockMode { |
| 59 | + init(iv: Array<UInt8>) { } |
| 60 | +} |
| 61 | + |
| 62 | +struct PCBC: BlockMode { |
| 63 | + init(iv: Array<UInt8>) { } |
| 64 | +} |
| 65 | + |
| 66 | +typealias StreamMode = BlockMode |
| 67 | + |
| 68 | +struct CCM: StreamMode { |
| 69 | + init(iv: Array<UInt8>, tagLength: Int, messageLength: Int, additionalAuthenticatedData: Array<UInt8>? = nil) { } |
| 70 | + init(iv: Array<UInt8>, tagLength: Int, messageLength: Int, authenticationTag: Array<UInt8>, additionalAuthenticatedData: Array<UInt8>? = nil) { } |
| 71 | +} |
| 72 | + |
| 73 | +struct CTR: StreamMode { |
| 74 | + init(iv: Array<UInt8>, counter: Int = 0) { } |
| 75 | +} |
| 76 | + |
| 77 | +protocol PaddingProtocol { } |
| 78 | + |
| 79 | +enum Padding: PaddingProtocol { |
| 80 | + case noPadding, zeroPadding, pkcs7, pkcs5, eme_pkcs1v15, emsa_pkcs1v15, iso78164, iso10126 |
| 81 | +} |
| 82 | + |
| 83 | +// Helper functions |
| 84 | +func getConstantString() -> String { |
| 85 | + "this string is constant" |
| 86 | +} |
| 87 | + |
| 88 | +func getConstantArray() -> Array<UInt8> { |
| 89 | + [UInt8](getConstantString().utf8) |
| 90 | +} |
| 91 | + |
| 92 | +func getRandomArray() -> Array<UInt8> { |
| 93 | + (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) }) |
| 94 | +} |
| 95 | + |
| 96 | +// --- tests --- |
| 97 | + |
| 98 | +func test() { |
| 99 | + let iv: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05, 0xaf, 0x46, 0x58, 0x2d, 0x66, 0x52, 0x10, 0xae, 0x86, 0xd3, 0x8e, 0x8f] |
| 100 | + let iv2 = getConstantArray() |
| 101 | + let ivString = getConstantString() |
| 102 | + |
| 103 | + let randomArray = getRandomArray() |
| 104 | + let randomIv = getRandomArray() |
| 105 | + let randomIvString = String(cString: getRandomArray()) |
| 106 | + |
| 107 | + let padding = Padding.noPadding |
| 108 | + let key = getRandomArray() |
| 109 | + let keyString = String(cString: key) |
| 110 | + |
| 111 | + // AES test cases |
| 112 | + let ab1 = AES(key: keyString, iv: ivString) // BAD |
| 113 | + let ab2 = AES(key: keyString, iv: ivString, padding: padding) // BAD |
| 114 | + let ag1 = AES(key: keyString, iv: randomIvString) // GOOD |
| 115 | + let ag2 = AES(key: keyString, iv: randomIvString, padding: padding) // GOOD |
| 116 | + |
| 117 | + // ChaCha20 test cases |
| 118 | + let cb1 = ChaCha20(key: keyString, iv: ivString) // BAD |
| 119 | + let cg1 = ChaCha20(key: keyString, iv: randomIvString) // GOOD |
| 120 | + |
| 121 | + // Blowfish test cases |
| 122 | + let bb1 = Blowfish(key: keyString, iv: ivString) // BAD |
| 123 | + let bb2 = Blowfish(key: keyString, iv: ivString, padding: padding) // BAD |
| 124 | + let bg1 = Blowfish(key: keyString, iv: randomIvString) // GOOD |
| 125 | + let bg2 = Blowfish(key: keyString, iv: randomIvString, padding: padding) // GOOD |
| 126 | + |
| 127 | + // Rabbit |
| 128 | + let rb1 = Rabbit(key: key, iv: iv) // BAD |
| 129 | + let rb2 = Rabbit(key: key, iv: iv2) // BAD [NOT DETECTED] |
| 130 | + let rb3 = Rabbit(key: keyString, iv: ivString) // BAD |
| 131 | + let rg1 = Rabbit(key: key, iv: randomIv) // GOOD |
| 132 | + let rg2 = Rabbit(key: keyString, iv: randomIvString) // GOOD |
| 133 | + |
| 134 | + // CBC |
| 135 | + let cbcb1 = CBC(iv: iv) // BAD |
| 136 | + let cbcg1 = CBC(iv: randomIv) // GOOD |
| 137 | + |
| 138 | + // CFB |
| 139 | + let cfbb1 = CFB(iv: iv) // BAD |
| 140 | + let cfbb2 = CFB(iv: iv, segmentSize: CFB.SegmentSize.cfb8) // BAD |
| 141 | + let cfbg1 = CFB(iv: randomIv) // GOOD |
| 142 | + let cfbg2 = CFB(iv: randomIv, segmentSize: CFB.SegmentSize.cfb8) // GOOD |
| 143 | + |
| 144 | + // GCM |
| 145 | + let cgmb1 = GCM(iv: iv) // BAD |
| 146 | + let cgmb2 = GCM(iv: iv, additionalAuthenticatedData: randomArray, tagLength: 8, mode: GCM.Mode.combined) // BAD |
| 147 | + let cgmb3 = GCM(iv: iv, authenticationTag: randomArray, additionalAuthenticatedData: randomArray, mode: GCM.Mode.combined) // BAD |
| 148 | + let cgmg1 = GCM(iv: randomIv) // GOOD |
| 149 | + let cgmg2 = GCM(iv: randomIv, additionalAuthenticatedData: randomArray, tagLength: 8, mode: GCM.Mode.combined) // GOOD |
| 150 | + let cgmg3 = GCM(iv: randomIv, authenticationTag: randomArray, additionalAuthenticatedData: randomArray, mode: GCM.Mode.combined) // GOOD |
| 151 | + |
| 152 | + // OFB |
| 153 | + let ofbb1 = OFB(iv: iv) // BAD |
| 154 | + let ofbg1 = OFB(iv: randomIv) // GOOD |
| 155 | + |
| 156 | + // PCBC |
| 157 | + let pcbcb1 = PCBC(iv: iv) // BAD |
| 158 | + let pcbcg1 = PCBC(iv: randomIv) // GOOD |
| 159 | + |
| 160 | + // CCM |
| 161 | + let ccmb1 = CCM(iv: iv, tagLength: 0, messageLength: 0, additionalAuthenticatedData: randomArray) // BAD |
| 162 | + let ccmb2 = CCM(iv: iv, tagLength: 0, messageLength: 0, authenticationTag: randomArray, additionalAuthenticatedData: randomArray) // BAD |
| 163 | + let ccmg1 = CCM(iv: randomIv, tagLength: 0, messageLength: 0, additionalAuthenticatedData: randomArray) // GOOD |
| 164 | + let ccmg2 = CCM(iv: randomIv, tagLength: 0, messageLength: 0, authenticationTag: randomArray, additionalAuthenticatedData: randomArray) // GOOD |
| 165 | + |
| 166 | + // CTR |
| 167 | + let ctrb1 = CTR(iv: iv) // BAD |
| 168 | + let ctrb2 = CTR(iv: iv, counter: 0) // BAD |
| 169 | + let ctrg1 = CTR(iv: randomIv) // GOOD |
| 170 | + let ctrg2 = CTR(iv: randomIv, counter: 0) // GOOD |
| 171 | +} |
0 commit comments