Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Generate C# bindings for CryptoKit framework #2583

Closed
kotlarmilos opened this issue May 10, 2024 · 1 comment
Closed

[Discussion] Generate C# bindings for CryptoKit framework #2583

kotlarmilos opened this issue May 10, 2024 · 1 comment
Assignees
Labels
area-SwiftBindings Swift bindings for .NET

Comments

@kotlarmilos
Copy link
Member

kotlarmilos commented May 10, 2024

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.

@kotlarmilos kotlarmilos added the area-SwiftBindings Swift bindings for .NET label May 10, 2024
@kotlarmilos kotlarmilos self-assigned this May 10, 2024
@kotlarmilos kotlarmilos changed the title Generate C# bindings for CryptoKit framework [Discussion] Generate C# bindings for CryptoKit framework May 13, 2024
@kotlarmilos
Copy link
Member Author

Experimental Swift bindings for CryptoKit: #2704

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-SwiftBindings Swift bindings for .NET
Projects
None yet
Development

No branches or pull requests

1 participant