Skip to content

Commit 9870213

Browse files
committed
Adjusted access control of several classes, enums, extensions, and methods
1 parent 48015ae commit 9870213

File tree

5 files changed

+45
-36
lines changed

5 files changed

+45
-36
lines changed

CryptoLib/AesCtr.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import CommonCrypto
1010
import Foundation
1111

12-
internal class AesCtr {
12+
class AesCtr {
1313
/**
1414
High-level AES-CTR wrapper around CommonCrypto primitives. Can be used for encryption and decryption (it is the same in CTR mode).
1515

@@ -18,7 +18,7 @@ internal class AesCtr {
1818
- Parameter data: data to be encrypted/decrypted
1919
- Returns: encrypted/decrypted data
2020
*/
21-
public static func compute(key: [UInt8], iv: [UInt8], data: [UInt8]) throws -> [UInt8] {
21+
static func compute(key: [UInt8], iv: [UInt8], data: [UInt8]) throws -> [UInt8] {
2222
assert(key.count == kCCKeySizeAES256 || key.count == kCCKeySizeAES128, "key expected to be 128 or 256 bit")
2323
assert(iv.count == kCCBlockSizeAES128, "iv expected to be 128 bit")
2424

CryptoLib/AesSiv.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import CommonCrypto
1010
import Foundation
1111

12-
internal class AesSiv {
12+
class AesSiv {
1313
static let cryptoSupport = CryptoSupport()
1414
static let zero = [UInt8](repeating: 0x00, count: 16)
1515
static let dblConst: UInt8 = 0x87
@@ -23,7 +23,7 @@ internal class AesSiv {
2323
- Parameter ad: Associated data, which gets authenticated but not encrypted.
2424
- Returns: IV + Ciphertext as a concatenated byte array.
2525
*/
26-
public static func encrypt(aesKey: [UInt8], macKey: [UInt8], plaintext: [UInt8], ad: [UInt8]...) throws -> [UInt8] {
26+
static func encrypt(aesKey: [UInt8], macKey: [UInt8], plaintext: [UInt8], ad: [UInt8]...) throws -> [UInt8] {
2727
if plaintext.count > UInt32.max - 16 {
2828
throw CryptoError.invalidParameter("plaintext must not be longer than 2^32 - 16 bytes")
2929
}
@@ -41,7 +41,7 @@ internal class AesSiv {
4141
- Parameter ad: Associated data, which needs to be authenticated during decryption.
4242
- Returns: Plaintext byte array.
4343
*/
44-
public static func decrypt(aesKey: [UInt8], macKey: [UInt8], ciphertext: [UInt8], ad: [UInt8]...) throws -> [UInt8] {
44+
static func decrypt(aesKey: [UInt8], macKey: [UInt8], ciphertext: [UInt8], ad: [UInt8]...) throws -> [UInt8] {
4545
if ciphertext.count < 16 {
4646
throw CryptoError.invalidParameter("ciphertext must be at least 16 bytes")
4747
}
@@ -55,15 +55,17 @@ internal class AesSiv {
5555
return plaintext
5656
}
5757

58-
internal static func ctr(aesKey key: [UInt8], iv: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
58+
// MARK: - Internal
59+
60+
static func ctr(aesKey key: [UInt8], iv: [UInt8], plaintext: [UInt8]) throws -> [UInt8] {
5961
// clear out the 31st and 63rd bit (see https://tools.ietf.org/html/rfc5297#section-2.5)
6062
var ctr = iv
6163
ctr[8] &= 0x7F
6264
ctr[12] &= 0x7F
6365
return try AesCtr.compute(key: key, iv: ctr, data: plaintext)
6466
}
6567

66-
internal static func s2v(macKey: [UInt8], plaintext: [UInt8], ad: [[UInt8]]) throws -> [UInt8] {
68+
static func s2v(macKey: [UInt8], plaintext: [UInt8], ad: [[UInt8]]) throws -> [UInt8] {
6769
// Maximum permitted AD length is the block size in bits - 2
6870
if ad.count > 126 {
6971
throw CryptoError.invalidParameter("too many ad")
@@ -89,7 +91,7 @@ internal class AesSiv {
8991
return try cmac(macKey: macKey, data: t)
9092
}
9193

92-
internal static func cmac(macKey key: [UInt8], data: [UInt8]) throws -> [UInt8] {
94+
static func cmac(macKey key: [UInt8], data: [UInt8]) throws -> [UInt8] {
9395
// subkey generation:
9496
let l = try aes(key: key, plaintext: zero)
9597
let k1 = l[0] & 0x80 == 0x00 ? shiftLeft(l) : dbl(l)

CryptoLib/CryptoSupport.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import Foundation
1010

11-
internal class CryptoSupport {
11+
class CryptoSupport {
1212
/**
1313
Creates an array of cryptographically secure random bytes.
1414

CryptoLib/Cryptor.swift

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,42 @@ import CryptoSwift
1111
import Foundation
1212
import SwiftBase32
1313

14-
extension Data {
15-
public init?(base64UrlEncoded base64String: String, options: Data.Base64DecodingOptions = []) {
14+
public extension Data {
15+
init?(base64UrlEncoded base64String: String, options: Data.Base64DecodingOptions = []) {
1616
self.init(base64Encoded: base64String.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/"), options: options)
1717
}
1818

19-
public func base64UrlEncodedString(options: Data.Base64EncodingOptions = []) -> String {
19+
func base64UrlEncodedString(options: Data.Base64EncodingOptions = []) -> String {
2020
return base64EncodedString(options: options).replacingOccurrences(of: "+", with: "-").replacingOccurrences(of: "/", with: "_")
2121
}
2222
}
2323

24-
extension FixedWidthInteger {
25-
public func byteArray() -> [UInt8] {
24+
public extension FixedWidthInteger {
25+
func byteArray() -> [UInt8] {
2626
return withUnsafeBytes(of: self, { [UInt8]($0) })
2727
}
2828
}
2929

30-
extension InputStream {
31-
public func read(maxLength: Int) throws -> [UInt8]? {
30+
public enum InputStreamError: Error {
31+
case readOperationFailed
32+
}
33+
34+
public extension InputStream {
35+
func read(maxLength: Int) throws -> [UInt8]? {
3236
var buffer = [UInt8](repeating: 0x00, count: maxLength)
3337
let length = read(&buffer, maxLength: maxLength)
34-
if length == 0 {
38+
switch length {
39+
case _ where length > 0:
40+
assert(length <= buffer.count)
41+
buffer.removeSubrange(length...)
42+
return buffer
43+
case 0:
3544
return nil
45+
case _ where length < 0:
46+
throw streamError ?? InputStreamError.readOperationFailed
47+
default:
48+
fatalError()
3649
}
37-
guard length > 0 else {
38-
throw streamError ?? CryptoError.ioError
39-
}
40-
assert(length <= buffer.count)
41-
buffer.removeSubrange(length...)
42-
return buffer
4350
}
4451
}
4552

@@ -137,13 +144,13 @@ public class Cryptor {
137144

138145
// MARK: - File Header Encryption and Decryption
139146

140-
internal func createHeader() throws -> FileHeader {
147+
func createHeader() throws -> FileHeader {
141148
let nonce = try cryptoSupport.createRandomBytes(size: kCCBlockSizeAES128)
142149
let contentKey = try cryptoSupport.createRandomBytes(size: kCCKeySizeAES256)
143150
return FileHeader(nonce: nonce, contentKey: contentKey)
144151
}
145152

146-
internal func encryptHeader(_ header: FileHeader) throws -> [UInt8] {
153+
func encryptHeader(_ header: FileHeader) throws -> [UInt8] {
147154
let cleartext = [UInt8](repeating: 0xFF, count: Cryptor.fileHeaderLegacyPayloadSize) + header.contentKey
148155
let ciphertext = try AesCtr.compute(key: masterkey.aesMasterKey, iv: header.nonce, data: cleartext)
149156
let toBeAuthenticated = header.nonce + ciphertext
@@ -152,7 +159,7 @@ public class Cryptor {
152159
return header.nonce + ciphertext + mac
153160
}
154161

155-
internal func decryptHeader(_ header: [UInt8]) throws -> FileHeader {
162+
func decryptHeader(_ header: [UInt8]) throws -> FileHeader {
156163
// decompose header:
157164
let beginOfMAC = header.count - Int(CC_SHA256_DIGEST_LENGTH)
158165
let nonce = [UInt8](header[0 ..< kCCBlockSizeAES128])
@@ -208,7 +215,7 @@ public class Cryptor {
208215
try encryptContent(from: cleartextStream, to: ciphertextStream, cleartextSize: cleartextSize)
209216
}
210217

211-
internal func encryptContent(from cleartextStream: InputStream, to ciphertextStream: OutputStream, cleartextSize: Int?) throws {
218+
func encryptContent(from cleartextStream: InputStream, to ciphertextStream: OutputStream, cleartextSize: Int?) throws {
212219
// create progress:
213220
let progress: Progress
214221
if let cleartextSize = cleartextSize {
@@ -269,7 +276,7 @@ public class Cryptor {
269276
try decryptContent(from: ciphertextStream, to: cleartextStream, ciphertextSize: ciphertextSize)
270277
}
271278

272-
internal func decryptContent(from ciphertextStream: InputStream, to cleartextStream: OutputStream, ciphertextSize: Int?) throws {
279+
func decryptContent(from ciphertextStream: InputStream, to cleartextStream: OutputStream, ciphertextSize: Int?) throws {
273280
// create progress:
274281
let progress: Progress
275282
if let ciphertextSize = ciphertextSize, let cleartextSize = try? calculateCleartextSize(ciphertextSize - Cryptor.fileHeaderSize) {
@@ -297,7 +304,7 @@ public class Cryptor {
297304
}
298305
}
299306

300-
internal func encryptSingleChunk(_ chunk: [UInt8], chunkNumber: UInt64, headerNonce: [UInt8], fileKey: [UInt8]) throws -> [UInt8] {
307+
func encryptSingleChunk(_ chunk: [UInt8], chunkNumber: UInt64, headerNonce: [UInt8], fileKey: [UInt8]) throws -> [UInt8] {
301308
let chunkNonce = try cryptoSupport.createRandomBytes(size: kCCBlockSizeAES128)
302309
let ciphertext = try AesCtr.compute(key: fileKey, iv: chunkNonce, data: chunk)
303310
let toBeAuthenticated = headerNonce + chunkNumber.bigEndian.byteArray() + chunkNonce + ciphertext
@@ -306,7 +313,7 @@ public class Cryptor {
306313
return chunkNonce + ciphertext + mac
307314
}
308315

309-
internal func decryptSingleChunk(_ chunk: [UInt8], chunkNumber: UInt64, headerNonce: [UInt8], fileKey: [UInt8]) throws -> [UInt8] {
316+
func decryptSingleChunk(_ chunk: [UInt8], chunkNumber: UInt64, headerNonce: [UInt8], fileKey: [UInt8]) throws -> [UInt8] {
310317
assert(chunk.count >= kCCBlockSizeAES128 + Int(CC_SHA256_DIGEST_LENGTH), "ciphertext chunk must at least contain nonce + mac")
311318

312319
// decompose chunk:

CryptoLib/Masterkey.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct MasterkeyJson: Codable {
2020
let version: Int
2121
}
2222

23-
enum MasterkeyError: Error, Equatable {
23+
public enum MasterkeyError: Error, Equatable {
2424
case malformedMasterkeyFile(_ reason: String)
2525
case invalidPassword
2626
case unwrapFailed(_ status: CCCryptorStatus)
@@ -92,7 +92,7 @@ public class Masterkey {
9292
return try createFromMasterkeyFile(jsonData: decoded, password: password, pepper: pepper)
9393
}
9494

95-
internal static func createFromMasterkeyFile(jsonData: MasterkeyJson, password: String, pepper: [UInt8]) throws -> Masterkey {
95+
private static func createFromMasterkeyFile(jsonData: MasterkeyJson, password: String, pepper: [UInt8]) throws -> Masterkey {
9696
let pw = [UInt8](password.precomposedStringWithCanonicalMapping.utf8)
9797
let salt = [UInt8](Data(base64Encoded: jsonData.scryptSalt)!)
9898
let saltAndPepper = salt + pepper
@@ -126,15 +126,15 @@ public class Masterkey {
126126
return createFromRaw(aesMasterKey: aesKey, macMasterKey: macKey, version: jsonData.version)
127127
}
128128

129-
internal static func createFromRaw(aesMasterKey: [UInt8], macMasterKey: [UInt8], version: Int) -> Masterkey {
129+
static func createFromRaw(aesMasterKey: [UInt8], macMasterKey: [UInt8], version: Int) -> Masterkey {
130130
assert(aesMasterKey.count == kCCKeySizeAES256)
131131
assert(macMasterKey.count == kCCKeySizeAES256)
132132
return Masterkey(aesMasterKey: aesMasterKey, macMasterKey: macMasterKey, version: version)
133133
}
134134

135135
// MARK: - RFC 3394 Key Wrapping
136136

137-
internal static func wrapMasterKey(rawKey: [UInt8], kek: [UInt8]) throws -> [UInt8] {
137+
static func wrapMasterKey(rawKey: [UInt8], kek: [UInt8]) throws -> [UInt8] {
138138
assert(kek.count == kCCKeySizeAES256)
139139
var wrappedKeyLen = CCSymmetricWrappedSize(CCWrappingAlgorithm(kCCWRAPAES), rawKey.count)
140140
var wrappedKey = [UInt8](repeating: 0x00, count: wrappedKeyLen)
@@ -146,7 +146,7 @@ public class Masterkey {
146146
}
147147
}
148148

149-
internal static func unwrapMasterKey(wrappedKey: [UInt8], kek: [UInt8]) throws -> [UInt8] {
149+
static func unwrapMasterKey(wrappedKey: [UInt8], kek: [UInt8]) throws -> [UInt8] {
150150
assert(kek.count == kCCKeySizeAES256)
151151
var unwrappedKeyLen = CCSymmetricUnwrappedSize(CCWrappingAlgorithm(kCCWRAPAES), wrappedKey.count)
152152
var unwrappedKey = [UInt8](repeating: 0x00, count: unwrappedKeyLen)
@@ -175,7 +175,7 @@ public class Masterkey {
175175
return try JSONEncoder().encode(masterkeyJson)
176176
}
177177

178-
internal func exportEncrypted(password: String, pepper: [UInt8], scryptCostParam: Int = Masterkey.defaultScryptCostParam, cryptoSupport: CryptoSupport = CryptoSupport()) throws -> MasterkeyJson {
178+
func exportEncrypted(password: String, pepper: [UInt8], scryptCostParam: Int = Masterkey.defaultScryptCostParam, cryptoSupport: CryptoSupport = CryptoSupport()) throws -> MasterkeyJson {
179179
let pw = [UInt8](password.precomposedStringWithCanonicalMapping.utf8)
180180
let salt = try cryptoSupport.createRandomBytes(size: Masterkey.defaultScryptSaltSize)
181181
let saltAndPepper = salt + pepper

0 commit comments

Comments
 (0)