Overlapping accesses to 'salt', but modification requires exclusive access; consider copying to a local variable

Hello,


I am developing a highly secured iOS application with sensitive data. I'm trying to use an AES256 encryption system to secure Data.

I followed the tutorial here https://code.tutsplus.com/tutorials/securing-ios-data-at-rest-encryption--cms-28786

Xcode 11 (Swift 5) tells me "Overlapping accesses to 'salt', but modification requires exclusive access; consider copying to a local variable"

Could you please tell how can I solve this issue please ?


Here's my code :


var key = Data(repeating:0, count:kCCKeySizeAES256)
var salt = Data(count: 8)  
salt.withUnsafeMutableBytes {
  (saltBytes: UnsafeMutablePointer<UInt8>) in//-> Void in
  let saltStatus = SecRandomCopyBytes(kSecRandomDefault, salt.count, saltBytes)
  if saltStatus == errSecSuccess
  {
  let passwordData = password.data(using:String.Encoding.utf8)!
  key.withUnsafeMutableBytes { (keyBytes : UnsafeMutablePointer<UInt8>) in
  let derivationStatus = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, passwordData.count, saltBytes, salt.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA512), 14271, keyBytes, key.count)
  if derivationStatus != Int32(kCCSuccess)
  {
  setupSuccess = false
  }
  }
  }
  else
  {
  setupSuccess = false
  }
  }

The error is located on the lines 3 and 9.


Thank you for your help.

Accepted Reply

The linked article shows the timestamp 2017, which is very old in Swift history. You should better find an article up-to-date.


When you use `withUnsafeMutableBytes` on a Data, all access rights are posessed by the method and any other accesses are not permitted.


And the `withUnsafeMutableBytes` taking `UnsafeMutablePointer` is deprecated.


To avoid those, you can write something like this:

salt.withUnsafeMutableBytes { (saltBuffer: UnsafeMutableRawBufferPointer) in
    let saltBytes = saltBuffer.bindMemory(to: UInt8.self)
    let saltStatus = SecRandomCopyBytes(kSecRandomDefault, saltBytes.count, saltBytes.baseAddress!)
    if saltStatus == errSecSuccess {
        let passwordData = password.data(using: .utf8)!
        key.withUnsafeMutableBytes { (keyBuffer: UnsafeMutableRawBufferPointer) in
            let keyBytes = keyBuffer.bindMemory(to: UInt8.self)
            let derivationStatus = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, passwordData.count, saltBytes.baseAddress!, saltBytes.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA512), 14271, keyBytes.baseAddress!, keyBytes.count)
            if derivationStatus != Int32(kCCSuccess) {
                setupSuccess = false
            }
        }
    } else {
        setupSuccess = false
    }
}

Replies

The linked article shows the timestamp 2017, which is very old in Swift history. You should better find an article up-to-date.


When you use `withUnsafeMutableBytes` on a Data, all access rights are posessed by the method and any other accesses are not permitted.


And the `withUnsafeMutableBytes` taking `UnsafeMutablePointer` is deprecated.


To avoid those, you can write something like this:

salt.withUnsafeMutableBytes { (saltBuffer: UnsafeMutableRawBufferPointer) in
    let saltBytes = saltBuffer.bindMemory(to: UInt8.self)
    let saltStatus = SecRandomCopyBytes(kSecRandomDefault, saltBytes.count, saltBytes.baseAddress!)
    if saltStatus == errSecSuccess {
        let passwordData = password.data(using: .utf8)!
        key.withUnsafeMutableBytes { (keyBuffer: UnsafeMutableRawBufferPointer) in
            let keyBytes = keyBuffer.bindMemory(to: UInt8.self)
            let derivationStatus = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), password, passwordData.count, saltBytes.baseAddress!, saltBytes.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA512), 14271, keyBytes.baseAddress!, keyBytes.count)
            if derivationStatus != Int32(kCCSuccess) {
                setupSuccess = false
            }
        }
    } else {
        setupSuccess = false
    }
}

I am developing a highly secured iOS application with sensitive data.

Are you able to design your own crypto here? Or do you have to implement some existing crypto design? If it’s the former I strongly encourage you to look at Apple CryptoKit. It has a Swift-friendly interface to a recommended set of crypto algorithms.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you very much for your help, I'll try this code. 🙂

As the app I'm developing is highly sensitive for data management, I'm trying my own crypto.

But for password manager implementation is it better to use an existing crypto design ?

As the app I'm developing is highly sensitive for data management, I'm trying my own crypto.

Don’t do that. For example, the tutorial you referenced seems to use encryption without authentication, which is one of the classic “I know enough about crypto to be dangerous” newbie mistakes )-:

To avoid these problems I recommend that you implement an existing data-at-rest container format. You don’t necessarily have to use someone else’s code for this, but you should definitely use a design created by a crypto expert.

Speaking personally I’d use

AES.GCM.SealedBox
for this, but there are lots of other choices.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you very much to this answer. I'm discovering encryption world so I wanted to secure data at any cost. I'll check your link.

I'll check your link.

Cool.

btw The subject of PBKDF2 came up recently on another thread and I posted a

CCKeyDerivationPBKDF
wrapper there.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for sharing your thread.

I have another need : I want to encrypt each password data stored in a realm database.

Decrypt it when the user needs to see it using a password.

I have already encrypted the database itself using a SHA512 key.

I want to give more security encrypting the password itself which is a string.

How can I store it on my database ?


The AES sealedBox is it sufficient for this purpose ?

As this subject is different, I have created a new thread with my needs here :

https://forums.developer.apple.com/message/421793#421793

Could you please read it and give me an answer ? Thank you.