Skip to content

Commit 7dc8b56

Browse files
made file name encryption work with 256 bit keys
1 parent 9b0049b commit 7dc8b56

File tree

3 files changed

+141
-12
lines changed

3 files changed

+141
-12
lines changed

CryptoLib/AesSiv.swift

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//
88

99
import Foundation
10-
import CryptoSwift
1110
import CommonCrypto
1211

1312
enum AesSivError: Error {
@@ -53,16 +52,16 @@ public class AesSiv {
5352
return plaintext
5453
}
5554

56-
internal static func aesCtr(aesKey: [UInt8], iv: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
57-
assert(aesKey.count == kCCKeySizeAES256 || aesKey.count == kCCKeySizeAES128, "aesKey expected to be 128 or 256 bit")
55+
internal static func aesCtr(aesKey key: [UInt8], iv: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
56+
assert(key.count == kCCKeySizeAES256 || key.count == kCCKeySizeAES128, "aesKey expected to be 128 or 256 bit")
5857

5958
// clear out the 31st and 63rd bit (see https://tools.ietf.org/html/rfc5297#section-2.5)
6059
var ctr = iv
6160
ctr[8] &= 0x7F
6261
ctr[12] &= 0x7F
6362

6463
var cryptor: CCCryptorRef?
65-
var status = CCCryptorCreateWithMode(CCOperation(kCCEncrypt), CCMode(kCCModeCTR), CCAlgorithm(kCCAlgorithmAES), CCPadding(ccNoPadding), ctr, aesKey, aesKey.count, nil, 0, 0, CCModeOptions(kCCModeOptionCTR_BE), &cryptor)
64+
var status = CCCryptorCreateWithMode(CCOperation(kCCEncrypt), CCMode(kCCModeCTR), CCAlgorithm(kCCAlgorithmAES), CCPadding(ccNoPadding), ctr, key, key.count, nil, 0, 0, CCModeOptions(kCCModeOptionCTR_BE), &cryptor)
6665
guard status == kCCSuccess, cryptor != nil else {
6766
throw AesSivError.invalidParameter("failed to initialize cryptor")
6867
}
@@ -93,16 +92,14 @@ public class AesSiv {
9392
throw AesSivError.invalidParameter("too many ad")
9493
}
9594

96-
let mac = try CMAC.init(key: macKey)
97-
9895
// RFC 5297 defines a n == 0 case here. Where n is the length of the input vector:
9996
// S1 = associatedData1, S2 = associatedData2, ... Sn = plaintext
10097
// Since this method is invoked only by encrypt/decrypt, we always have a plaintext.
10198
// Thus n > 0
10299

103-
var d = try mac.authenticate(zero)
100+
var d = try cmac(macKey: macKey, data: zero)
104101
for s in ad {
105-
d = xor(dbl(d), try mac.authenticate(s))
102+
d = xor(dbl(d), try cmac(macKey: macKey, data: s))
106103
}
107104

108105
let t: [UInt8]
@@ -112,7 +109,61 @@ public class AesSiv {
112109
t = xor(dbl(d), pad(plaintext))
113110
}
114111

115-
return try mac.authenticate(t)
112+
return try cmac(macKey: macKey, data: t)
113+
}
114+
115+
internal static func cmac(macKey key: [UInt8], data: [UInt8]) throws -> [UInt8] {
116+
// subkey generation:
117+
let l = try aes(key: key, plaintext: zero)
118+
let k1 = l[0] & 0x80 == 0x00 ? shiftLeft(l) : dbl(l)
119+
let k2 = k1[0] & 0x80 == 0x00 ? shiftLeft(k1) : dbl(k1)
120+
121+
// determine number of blocks:
122+
let n = (data.count + 15) / 16
123+
let lastBlockIdx: Int
124+
let lastBlockComplete: Bool
125+
if n == 0 {
126+
lastBlockIdx = 0
127+
lastBlockComplete = false
128+
} else {
129+
lastBlockIdx = n - 1
130+
lastBlockComplete = data.count % 16 == 0
131+
}
132+
133+
// blocks 0..<n:
134+
var mac = [UInt8](repeating: 0x00, count: 16)
135+
for i in 0..<lastBlockIdx {
136+
let block = Array(data[(16*i)..<(16*(i+1))])
137+
let y = xor(mac, block)
138+
mac = try aes(key: key, plaintext: y)
139+
}
140+
141+
// block n:
142+
var lastBlock = Array(data[(16*lastBlockIdx)...])
143+
if lastBlockComplete {
144+
lastBlock = xor(lastBlock, k1)
145+
} else {
146+
lastBlock = xor(pad(lastBlock), k2)
147+
}
148+
let y = xor(mac, lastBlock)
149+
mac = try aes(key: key, plaintext: y)
150+
151+
return mac
152+
}
153+
154+
private static func aes(key: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
155+
assert(key.count == kCCKeySizeAES128 || key.count == kCCKeySizeAES192 || key.count == kCCKeySizeAES256)
156+
assert(plaintext.count == kCCBlockSizeAES128, "Attempt to run AES-ECB for plaintext != one single block")
157+
158+
var ciphertext = [UInt8](repeating: 0x00, count: kCCBlockSizeAES128)
159+
var ciphertextLen = 0
160+
let status = CCCrypt(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionECBMode), key, key.count, nil, plaintext, plaintext.count, &ciphertext, kCCBlockSizeAES128, &ciphertextLen)
161+
162+
guard status == kCCSuccess else {
163+
throw AesSivError.invalidParameter("AES failed")
164+
}
165+
166+
return ciphertext
116167
}
117168

118169
private static func shiftLeft(_ input: [UInt8]) -> [UInt8] {

CryptoLibTests/AesSivTests.swift

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class AesSivTests: XCTestCase {
4141
]
4242

4343
let result = try? AesSiv.encrypt(aesKey: aesKey, macKey: macKey, plaintext: plaintext, ad: ad)
44-
44+
4545
XCTAssertEqual(expected, result)
4646
}
4747

@@ -105,5 +105,83 @@ class AesSivTests: XCTestCase {
105105

106106
XCTAssertEqual(expected, result)
107107
}
108+
109+
func testCmac1() {
110+
let macKey: [UInt8] = [
111+
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
112+
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
113+
]
114+
let message: [UInt8] = []
115+
let expected: [UInt8] = [
116+
0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
117+
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
118+
]
119+
let result = try? AesSiv.cmac(macKey: macKey, data: message)
120+
121+
XCTAssertEqual(expected, result)
122+
}
123+
124+
func testCmac2() {
125+
let macKey: [UInt8] = [
126+
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
127+
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
128+
]
129+
let message: [UInt8] = [
130+
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
131+
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a
132+
]
133+
let expected: [UInt8] = [
134+
0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
135+
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
136+
]
137+
let result = try? AesSiv.cmac(macKey: macKey, data: message)
138+
139+
XCTAssertEqual(expected, result)
140+
}
141+
142+
func testCmac3() {
143+
let macKey: [UInt8] = [
144+
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
145+
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
146+
]
147+
let message: [UInt8] = [
148+
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
149+
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
150+
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
151+
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
152+
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11
153+
]
154+
let expected: [UInt8] = [
155+
0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
156+
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27,
157+
]
158+
let result = try? AesSiv.cmac(macKey: macKey, data: message)
159+
160+
XCTAssertEqual(expected, result)
161+
}
162+
163+
func testCmac4() {
164+
let macKey: [UInt8] = [
165+
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
166+
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
167+
]
168+
let message: [UInt8] = [
169+
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
170+
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
171+
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
172+
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
173+
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
174+
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
175+
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
176+
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
177+
]
178+
let expected: [UInt8] = [
179+
0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
180+
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
181+
]
182+
let result = try? AesSiv.cmac(macKey: macKey, data: message)
183+
184+
XCTAssertEqual(expected, result)
185+
}
108186

109187
}

CryptoLibTests/CryptorTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class CryptorTests: XCTestCase {
1414
var masterkey: Masterkey!
1515

1616
override func setUp() {
17-
let aesKey: [UInt8] = Array(repeating: 0x55, count: 16)
18-
let macKey: [UInt8] = Array(repeating: 0x77, count: 16)
17+
let aesKey: [UInt8] = Array(repeating: 0x55, count: 32)
18+
let macKey: [UInt8] = Array(repeating: 0x77, count: 32)
1919
masterkey = Masterkey.createFromRaw(aesMasterKey: aesKey, macMasterKey: macKey)
2020

2121
XCTAssertNotNil(masterkey)

0 commit comments

Comments
 (0)