Skip to content

Commit 609f92c

Browse files
authored
Merge pull request #13870 from geoffw0/commoncrypto1
Swift: CommonCrypto test cases for the BrokenCryptoAlgorithm query
2 parents 4d6521f + 06c19fd commit 609f92c

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

swift/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/Security/CWE-327/BrokenCryptoAlgorithm.ql
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// --- stubs ---
2+
3+
struct Data {
4+
func withUnsafeBytes<ResultType>(
5+
_ body: (UnsafeRawBufferPointer) throws -> ResultType
6+
) rethrows -> ResultType { return 0 as! ResultType }
7+
mutating func withUnsafeMutableBytes<ResultType>(
8+
_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType
9+
) rethrows -> ResultType { return 0 as! ResultType }
10+
}
11+
12+
// --- CommonCryptor ---
13+
// (real world projects will import the CommonCryptor headers which get
14+
// converted to Swift by the compiler; the following is an approximation
15+
// of that derived from QL queries and the CommonCryptor header files)
16+
17+
var kCCSuccess : Int = 0
18+
typealias CCCryptorStatus = Int32
19+
20+
typealias CCCryptorRef = OpaquePointer
21+
22+
var kCCEncrypt : Int = 0
23+
var kCCDecrypt : Int = 1
24+
typealias CCOperation = UInt32
25+
26+
var kCCAlgorithmAES128 : Int = 0
27+
var kCCAlgorithmAES : Int = 0
28+
var kCCAlgorithmDES : Int = 1
29+
var kCCAlgorithm3DES : Int = 2
30+
var kCCAlgorithmCAST : Int = 3
31+
var kCCAlgorithmRC4 : Int = 4
32+
var kCCAlgorithmRC2 : Int = 5
33+
var kCCAlgorithmBlowfish : Int = 6
34+
typealias CCAlgorithm = UInt32
35+
36+
var kCCOptionPKCS7Padding : Int = 1
37+
var kCCOptionECBMode : Int = 2
38+
typealias CCOptions = UInt32
39+
40+
var kCCModeECB : Int = 1
41+
var kCCModeCBC : Int = 2
42+
var kCCModeCFB : Int = 3
43+
var kCCModeCTR : Int = 4
44+
var kCCModeOFB : Int = 7
45+
var kCCModeRC4 : Int = 9
46+
var kCCModeCFB8 : Int = 10
47+
typealias CCMode = UInt32
48+
49+
typealias CCPadding = UInt32
50+
51+
typealias CCModeOptions = UInt32
52+
53+
func CCCryptorCreate(
54+
_ op: CCOperation,
55+
_ alg: CCAlgorithm,
56+
_ options: CCOptions,
57+
_ key: UnsafeRawPointer?,
58+
_ keyLength: Int,
59+
_ iv: UnsafeRawPointer?,
60+
_ cryptorRef: UnsafeMutablePointer<CCCryptorRef?>?
61+
) -> CCCryptorStatus { return 0 }
62+
63+
func CCCryptorCreateFromData(
64+
_ op: CCOperation,
65+
_ alg: CCAlgorithm,
66+
_ options: CCOptions,
67+
_ key: UnsafeRawPointer?,
68+
_ keyLength: Int,
69+
_ iv: UnsafeRawPointer?,
70+
_ data: UnsafeRawPointer?,
71+
_ dataLength: Int,
72+
_ cryptorRef: UnsafeMutablePointer<CCCryptorRef?>?,
73+
_ dataUsed: UnsafeMutablePointer<Int>?
74+
) -> CCCryptorStatus { return 0 }
75+
76+
func CCCryptorCreateWithMode(
77+
_ op: CCOperation,
78+
_ mode: CCMode,
79+
_ alg: CCAlgorithm,
80+
_ padding: CCPadding,
81+
_ iv: UnsafeRawPointer?,
82+
_ key: UnsafeRawPointer?,
83+
_ keyLength: Int,
84+
_ tweak: UnsafeRawPointer?,
85+
_ tweakLength: Int,
86+
_ numRounds: Int32,
87+
_ options: CCModeOptions,
88+
_ cryptorRef: UnsafeMutablePointer<CCCryptorRef?>?
89+
) -> CCCryptorStatus { return 0 }
90+
91+
func CCCryptorUpdate(
92+
_ cryptorRef: CCCryptorRef?,
93+
_ dataIn: UnsafeRawPointer?,
94+
_ dataInLength: Int,
95+
_ dataOut: UnsafeMutableRawPointer?,
96+
_ dataOutAvailable: Int,
97+
_ dataOutMoved: UnsafeMutablePointer<Int>?
98+
) -> CCCryptorStatus { return 0 }
99+
100+
func CCCryptorFinal(
101+
_ cryptorRef: CCCryptorRef?,
102+
_ dataOut: UnsafeMutableRawPointer?,
103+
_ dataOutAvailable: Int,
104+
_ dataOutMoved: UnsafeMutablePointer<Int>?
105+
) -> CCCryptorStatus { return 0 }
106+
107+
func CCCrypt(
108+
_ op: CCOperation,
109+
_ alg: CCAlgorithm,
110+
_ options: CCOptions,
111+
_ key: UnsafeRawPointer?,
112+
_ keyLength: Int,
113+
_ iv: UnsafeRawPointer?,
114+
_ dataIn: UnsafeRawPointer?,
115+
_ dataInLength: Int,
116+
_ dataOut: UnsafeMutableRawPointer?,
117+
_ dataOutAvailable: Int,
118+
_ dataOutMoved: UnsafeMutablePointer<Int>?
119+
) -> CCCryptorStatus { return 0 }
120+
121+
// --- tests ---
122+
123+
func cond() -> Bool { return true }
124+
125+
func test_commoncrypto1(key: Data, iv: Data, dataIn: Data, dataOut: inout Data) {
126+
// semi-realistic test case
127+
var myCryptor: CCCryptorRef?
128+
var dataOutWritten = 0
129+
130+
key.withUnsafeBytes({
131+
keyPtr in
132+
iv.withUnsafeBytes({
133+
// create the cryptor object
134+
ivPtr in
135+
let result1 = CCCryptorCreate(
136+
CCOperation(kCCEncrypt),
137+
CCAlgorithm(kCCAlgorithm3DES), // BAD [NOT DETECTED]
138+
CCOptions(0),
139+
keyPtr.baseAddress!,
140+
keyPtr.count,
141+
ivPtr.baseAddress!,
142+
&myCryptor
143+
)
144+
guard result1 == CCCryptorStatus(kCCSuccess) else {
145+
return // fail
146+
}
147+
148+
dataIn.withUnsafeBytes({
149+
dataInPtr in
150+
dataOut.withUnsafeMutableBytes({
151+
dataOutPtr in
152+
// encrypt data
153+
while (cond()) {
154+
let result2 = CCCryptorUpdate(
155+
myCryptor,
156+
dataInPtr.baseAddress!,
157+
dataInPtr.count,
158+
dataOutPtr.baseAddress!,
159+
dataOutPtr.count,
160+
&dataOutWritten)
161+
guard result2 == CCCryptorStatus(kCCSuccess) else {
162+
return // fail
163+
}
164+
}
165+
166+
// finish
167+
let result3 = CCCryptorFinal(
168+
myCryptor,
169+
dataOutPtr.baseAddress!,
170+
dataOutPtr.count,
171+
&dataOutWritten)
172+
guard result3 == CCCryptorStatus(kCCSuccess) else {
173+
return // fail
174+
}
175+
})
176+
})
177+
})
178+
})
179+
}
180+
181+
func test_commoncrypto2(
182+
key: UnsafeRawPointer, keyLen: Int,
183+
iv: UnsafeRawPointer,
184+
dataIn: UnsafeRawPointer, dataInLen: Int,
185+
dataOut: UnsafeMutableRawPointer, dataOutAvail: Int) {
186+
var myCryptor: CCCryptorRef?
187+
var dataOutWritten = 0
188+
189+
// algorithms
190+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES128), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
191+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
192+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmDES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED]
193+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED]
194+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmCAST), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
195+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmRC4), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED]
196+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmRC2), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED]
197+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmBlowfish), 0, key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
198+
_ = CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, &myCryptor) // BAD [NOT DETECTED]
199+
_ = CCCryptorCreateFromData(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED]
200+
_ = CCCryptorCreateFromData(CCOperation(kCCDecrypt), CCAlgorithm(kCCAlgorithm3DES), 0, key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED]
201+
202+
// block modes (the default is CBC)
203+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(0), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
204+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionPKCS7Padding), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil)
205+
_ = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionECBMode), key, keyLen, iv, dataIn, dataInLen, dataOut, dataOutAvail, nil) // BAD [NOT DETECTED]
206+
_ = CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), CCOptions(kCCOptionECBMode), key, keyLen, iv, &myCryptor) // BAD [NOT DETECTED]
207+
_ = CCCryptorCreateFromData(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithm3DES), CCOptions(kCCOptionECBMode), key, keyLen, iv, dataIn, dataInLen, &myCryptor, &dataOutWritten) // BAD [NOT DETECTED]
208+
209+
// modes
210+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeECB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor) // BAD [NOT DETECTED]
211+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCBC), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
212+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCFB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
213+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCTR), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
214+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeOFB), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
215+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeRC4), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
216+
_ = CCCryptorCreateWithMode(CCOperation(kCCAlgorithmAES), CCMode(kCCModeCFB8), CCAlgorithm(kCCAlgorithm3DES), CCPadding(0), iv, key, keyLen, nil, 0, 0, CCModeOptions(0), &myCryptor)
217+
}

0 commit comments

Comments
 (0)