Skip to content

Review UnsafeRawPointer projections in C# for CryptoKit dev templates #2529

Closed

Description

Description

This issue is intended to discuss projections of UnsafeRawPointers in C# and their marshalling, with a focus on evaluating correctness and scalability. The goal is to review and confirm the design of the projections and use them to create CryptoKit dev templates.

Projections of Swift unsafe raw pointers in C#:

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Runtime.InteropServices;

namespace Swift.Runtime {
    /// <summary>
    /// Represents a Swift value type.
    /// </summary>
    public unsafe interface ISwiftValueType {
        byte* SwiftData { get; set; }
    }

    /// <summary>
    /// Represents a Swift enum.
    /// </summary>
    public interface ISwiftEnum : ISwiftValueType {
    }

    /// <summary>
    /// Represents a Swift struct.
    /// </summary>
    public interface ISwiftStruct : ISwiftValueType {
    }

    // <summary>
    // Represents Swift Unsafe[Mutable]RawPointer in C#.
    // </summary>
    public unsafe struct Unsafe[Mutable]RawPointer : ISwiftStruct
    {
        public byte* SwiftData { get; set; }
        public Unsafe[Mutable]RawPointer(void* p)
        {
            SwiftData = (byte*)p;
        }
    }

    // <summary>
    // Represents Swift Unsafe[Mutable]RawBufferPointer in C#.
    // </summary>
    public unsafe struct Unsafe[Mutable]RawBufferPointer : ISwiftStruct
    {
        public byte* SwiftData { get; set; }
        public Unsafe[Mutable]RawBufferPointer(void* start, int count)
        {
            SwiftData = (byte*)_Initialize(start, count);
        }

        ~Unsafe[Mutable]RawBufferPointer()
        {
            // Release memory
         }

        // <summary>
        // Represents init(start: UnsafeRawPointer?, count: Int)
        // https://developer.apple.com/documentation/swift/unsaferawbufferpointer/init(start:count:)
        // </summary>
        [DllImport("libSwiftCore.dylib", EntryPoint = "$sSR5start5countSRyxGSPyxGSg_Sitcfc")]
        internal static extern void* _Initialize (void* start, int count);
    }
}

Generated C# bindings:

[DllImport("libHelloLibrary.dylib", EntryPoint = "$s12HelloLibrary41AppleCryptoNative_ChaCha20Poly1305Encrypt6keyPtr0J6Length05nonceK00mL009plaintextK00nL016ciphertextBuffer0opL003tagP00qpL003aadK00rL0s5Int32VSv_APSvAPSvAPSvAPSvAPSvAPtF")]
internal static extern Int32 PIfunc_AppleCryptoNative_ChaCha20Poly1305Encrypt(void* keyPtr, Int32 keyLength, void* noncePtr, Int32 nonceLength, void* plaintextPtr, Int32 plaintextLength, void* ciphertextBuffer, Int32 ciphertextBufferLength, void* tagBuffer, Int32 tagBufferLength, void* aadPtr, Int32 aadLength);

public static unsafe Int32 AppleCryptoNative_ChaCha20Poly1305Encrypt(
    UnsafeRawPointer keyPtr, Int32 keyLength,
    UnsafeMutableRawPointer noncePtr, Int32 nonceLength,
    UnsafeMutableRawPointer plaintextPtr, Int32 plaintextLength,
    UnsafeMutableRawPointer ciphertextPtr, Int32 ciphertexLength,
    UnsafeMutableRawPointer tagPtr, Int32 tagLength,
    UnsafeMutableRawPointer aadPtr, Int32 aadLength)
{
    int result;

    fixed (void* pKeyPtr = keyPtr.SwiftData)
    fixed (void* pNoncePtr = noncePtr.SwiftData)
    fixed (void* pPlaintextPtr = plaintextPtr.SwiftData)
    fixed (void* pCiphertextBuffer = ciphertextPtr.SwiftData)
    fixed (void* pTagBuffer = tagPtr.SwiftData)
    fixed (void* pAadPtr = aadPtr.SwiftData)
    {
        result = PIfunc_AppleCryptoNative_ChaCha20Poly1305Encrypt(
            pKeyPtr, keyLength,
            pNoncePtr, nonceLength,
            pPlaintextPtr, plaintextLength,
            pCiphertextBuffer, ciphertextBufferLength,
            pTagBuffer, tagBufferLength,
            pAadPtr, aadLength);
    }

    return result;
}

User's C# code:

var keyBuffer = new UnsafeMutableRawPointer(keyPtr);
var nonceBuffer = new UnsafeMutableRawPointer(noncePtr);
var plaintextBuffer = new UnsafeMutableRawPointer(plaintextPtr);
var ciphertextBuffer = new UnsafeMutableRawPointer(keyPtr);
var tagBuffer = new UnsafeMutableRawPointer(tagPtr);
var aadBuffer = new UnsafeMutableRawPointer(aadPtr);

int result = HelloLibrary.AppleCryptoNative_ChaCha20Poly1305Encrypt(
                    keyBuffer, key.Length,
                    nonceBuffer, nonce.Length,
                    plaintextBuffer, plaintext.Length,
                    ciphertextBuffer, ciphertext.Length,
                    tagBuffer, tag.Length,
                    aadBuffer, aad.Length);

/cc: @stephen-hawley @rolfbjarne @AaronRobinsonMSFT @jkoritzinsky @vitek-karas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions