-
Notifications
You must be signed in to change notification settings - Fork 215
Description
Objective
Our goal is to generate CryptoKit
APIs bindings used for encryption and decryption. We aim to replace the existing Objective-C bindings with direct calls into Swift.
Dev template
The CryptoKit
framework implements enum types with inner structs. Besides the Swift primitive types, the framework depends on Data
frozen struct from Foundation
framework. Additionally, the implementation contains generics and optional parameters in function signatures. To implement the C# projections, we identified the following implementation phases.
Frozen structs: Utilize runtime lowering support within the runtime to project parameters as UnsafeRawBufferPointer/UnsafeMutableBufferPointer<T>
and call into a Swift wrapper that calls the CryptoKit API.
import CryptoKit
import Foundation
public func AppleCryptoNative_ChaCha20Poly1305Encrypt(
keyBuffer: UnsafeRawBufferPointer,
nonceBuffer: UnsafeRawBufferPointer,
plaintextBuffer: UnsafeRawBufferPointer,
ciphertextBuffer: UnsafeMutableBufferPointer<UInt8>,
tagBuffer: UnsafeMutableBufferPointer<UInt8>,
aadBuffer: UnsafeRawBufferPointer
) -> Int32 {
let nonce = try! ChaChaPoly.Nonce(data: nonceBuffer)
let symmetricKey = SymmetricKey(data: keyBuffer)
guard let result = try? ChaChaPoly.seal(plaintextBuffer, using: symmetricKey, nonce: nonce, authenticating: aadBuffer) else {
return 0
}
assert(ciphertextBuffer.count >= result.ciphertext.count)
assert(tagBuffer.count >= result.tag.count)
result.ciphertext.copyBytes(to: ciphertextBuffer, count: result.ciphertext.count)
result.tag.copyBytes(to: tagBuffer, count: result.tag.count)
return 1
}
Surface type constructors: Surface type constructors for symmetric key and nonce, making them accessible as C# types. This requires support for SwiftSelf
in instance methods and SwiftError
for methods that can throw errors.
let nonce = try! ChaChaPoly.Nonce(data: nonceBuffer)
let symmetricKey = SymmetricKey(data: keyBuffer)
guard let result = try! ChaChaPoly.seal(plaintextBuffer, using: symmetricKey, nonce: nonce, authenticating: aadBuffer)
Implement optional and generics projections: Implement direct calls into Swift methods by adding implicit metadata parameters and protocol witness tables for generics. This includes changes from dotnet/runtime#100543.