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

Fix mls-rs-crypto-cryptokit not building for iOS #206

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions mls-rs-crypto-cryptokit/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ mod swift {
use serde::Deserialize;
use std::{env, process::Command};

/// Needed because of the min system reqs for HPKE in CryptoKit.
/// See https://developer.apple.com/documentation/cryptokit/hpke
const MIN_IOS_DEPLOYMENT_TARGET: &str = "17.0";
const MIN_OSX_DEPLOYMENT_TARGET: &str = "14.0";

#[derive(Debug, Deserialize)]
struct SwiftTargetInfo {
#[serde(rename = "unversionedTriple")]
Expand All @@ -35,15 +40,35 @@ mod swift {
}

fn get_target_info() -> SwiftTarget {
let target = get_target_triple();
let swift_target_info_str = Command::new("swift")
.args(["-print-target-info"])
.args(["-print-target-info", &format!("--target={}", &target)])
.output()
.unwrap()
.stdout;

serde_json::from_slice(&swift_target_info_str).unwrap()
}

fn get_target_triple() -> String {
// Have to do this dance because some of the rust triples dont match what swift build expects...
// Specifically x86_64-apple-ios seems to strugle.
// Got the triples from https://github.com/swiftlang/swift/blob/main/utils/build-script-impl
// We need to pass the MIN_OS var into these because for all platforms other than macOS, not doing so will cause
// libraries_require_rpath to be true and this build script has no support for RPaths.
match env::var("TARGET").unwrap().as_str() {
"aarch64-apple-ios" => format!("arm64-apple-ios{}", MIN_IOS_DEPLOYMENT_TARGET),
"x86_64-apple-ios" => {
format!("x86_64-apple-ios{}-simulator", MIN_IOS_DEPLOYMENT_TARGET)
}
"aarch64-apple-ios-sim" => {
format!("arm64-apple-ios{}-simulator", MIN_IOS_DEPLOYMENT_TARGET)
}
"aarch64-apple-darwin" => format!("arm64-apple-macosx{}", MIN_OSX_DEPLOYMENT_TARGET),
"x86_64-apple-darwin" => format!("x86_64-apple-macosx{}", MIN_OSX_DEPLOYMENT_TARGET),
unknown_target => panic!("Unsupported Arch for swift: {}", unknown_target), //
}
}

pub fn configure() {
let swift_target_info = get_target_info();
if swift_target_info.target.libraries_require_rpath {
Expand All @@ -59,11 +84,35 @@ mod swift {
});
}

fn get_sdk_root() -> String {
let sdk = match env::var("TARGET").unwrap().as_str() {
"aarch64-apple-ios" => "iphoneos",
"x86_64-apple-ios" => "iphonesimulator",
"aarch64-apple-ios-sim" => "iphonesimulator",
"aarch64-apple-darwin" => "macosx",
"x86_64-apple-darwin" => "macosx",
unknown_target => panic!("Unsupported Arch for swift: {}", unknown_target), //
};

let sdk_root = Command::new("xcrun")
.args(["--sdk", sdk, "--show-sdk-path"])
.output()
.unwrap()
.stdout;

let sdk_root = String::from_utf8(sdk_root).unwrap().trim().to_string();
sdk_root
}

pub fn link_package(package_name: &str, package_root: &str) {
let profile = env::var("PROFILE").unwrap();
let target = get_target_triple();

let sdk_root = get_sdk_root();
if !Command::new("swift")
.args(["build", "-c", &profile])
.args([
"build", "-c", &profile, "--sdk", &sdk_root, "--triple", &target,
])
.current_dir(package_root)
.status()
.unwrap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import CryptoKit

// The values in this enum MUST match those of the KemId enum in Rust:
// https://docs.rs/mls-rs-crypto-traits/latest/mls_rs_crypto_traits/enum.KemId.html
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
enum KemId : UInt16 {
case DhKemP256Sha256Aes128 = 1
case DhKemP384Sha384Aes256 = 2
Expand Down Expand Up @@ -94,7 +95,7 @@ enum KemId : UInt16 {
}
}
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
class SenderWrapper {
var sender: HPKE.Sender? = nil

Expand All @@ -103,6 +104,7 @@ class SenderWrapper {
}
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
class RecipientWrapper {
var recipient: HPKE.Recipient? = nil

Expand All @@ -115,6 +117,7 @@ class RecipientWrapper {
// &self
// ) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
@_cdecl("kem_generate")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func kem_generate(kemID: UInt16,
privPtr: UnsafeMutablePointer<UInt8>, privLen: UnsafeMutablePointer<UInt64>,
pubPtr: UnsafeMutablePointer<UInt8>, pubLen: UnsafeMutablePointer<UInt64>
Expand Down Expand Up @@ -160,12 +163,14 @@ public func kem_generate(kemID: UInt16,
return 1
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func unwrapBytes<B>(_ data: B) -> Data
where B: ContiguousBytes
{
return data.withUnsafeBytes { buffer in Data(buffer) }
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func LabeledExtract(kemID: KemId, salt: Data, label: Data, ikm: Data) -> Data {
// labeled_ikm = concat("HPKE-v1", suite_id, label, ikm)
var labeledIKM = "HPKE-v1".data(using: .utf8)!
Expand All @@ -191,6 +196,7 @@ func LabeledExtract(kemID: KemId, salt: Data, label: Data, ikm: Data) -> Data {
}
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func LabeledExpand(kemID: KemId, prk: Data, label: Data, info: Data, len: Int) -> Data {
// labeled_info = concat(I2OSP(L, 2), "HPKE-v1", suite_id, label, info)
var labeledInfo = Data([UInt8(len >> 8), UInt8(len)])
Expand All @@ -216,6 +222,7 @@ func LabeledExpand(kemID: KemId, prk: Data, label: Data, info: Data, len: Int) -
}
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func bigintLessThan(_ a: Data, _ b: Data) -> Bool {
// For big-endian a, b, a < b iff at the first digit at which a and b
// differ, the a digit is less than the b digit
Expand All @@ -229,6 +236,7 @@ func bigintLessThan(_ a: Data, _ b: Data) -> Bool {
return da < db
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func derive_key_pair_nist(kemID: KemId, ikm: Data) -> Data? {
let prkLabel = "dkp_prk".data(using: .utf8)!
let candidateLabel = "candidate".data(using: .utf8)!
Expand Down Expand Up @@ -260,6 +268,7 @@ func derive_key_pair_nist(kemID: KemId, ikm: Data) -> Data? {
return nil
}

@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
func derive_key_pair_x25519(kemID: KemId, ikm: Data) -> Data {
let Nsk = 32
let prkLabel = "dkp_prk".data(using: .utf8)!
Expand All @@ -274,6 +283,7 @@ func derive_key_pair_x25519(kemID: KemId, ikm: Data) -> Data {
// ikm: &[u8]
// ) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
@_cdecl("kem_derive")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func kem_derive(kemID: UInt16,
ikmPtr: UnsafePointer<UInt8>, ikmLen: UInt64,
privPtr: UnsafeMutablePointer<UInt8>, privLen: UnsafeMutablePointer<UInt64>,
Expand Down Expand Up @@ -331,6 +341,7 @@ public func kem_derive(kemID: UInt16,
// key: &HpkePublicKey
// ) -> Result<(), Self::Error>;
@_cdecl("kem_public_key_validate")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func kem_public_key_validate(kemID: UInt16,
pubPtr: UnsafePointer<UInt8>, pubLen: UInt64
) -> UInt64
Expand Down Expand Up @@ -381,6 +392,7 @@ public func kem_public_key_validate(kemID: UInt16,
// info: &[u8]
// ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>;
@_cdecl("hpke_setup_s")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_setup_s(kemID: UInt16,
pubPtr: UnsafePointer<UInt8>, pubLen: UInt64,
infoPtr: UnsafePointer<UInt8>, infoLen: UInt64,
Expand Down Expand Up @@ -439,6 +451,7 @@ public func hpke_setup_s(kemID: UInt16,
// data: &[u8]
// ) -> Result<Vec<u8>, Self::Error>;
@_cdecl("hpke_seal_s")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_seal_s(
senderPtr: UnsafeMutableRawPointer,
aadPtr: UnsafePointer<UInt8>, aadLen: UInt64,
Expand All @@ -465,6 +478,7 @@ public func hpke_seal_s(
// len: usize
// ) -> Result<Vec<u8>, Self::Error>;
@_cdecl("hpke_export_s")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_export_s(
senderPtr: UnsafeMutableRawPointer,
ctxPtr: UnsafePointer<UInt8>, ctxLen: UInt64,
Expand All @@ -485,6 +499,7 @@ public func hpke_export_s(

// fn hpke_drop_s()
@_cdecl("hpke_drop_s")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_drop_s(
senderPtr: UnsafeMutableRawPointer
)
Expand All @@ -500,6 +515,7 @@ public func hpke_drop_s(
// info: &[u8]
// ) -> Result<Self::HpkeContextR, Self::Error>;
@_cdecl("hpke_setup_r")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_setup_r(kemID: UInt16,
encPtr: UnsafePointer<UInt8>, encLen: UInt64,
privPtr: UnsafePointer<UInt8>, privLen: UInt64,
Expand Down Expand Up @@ -561,6 +577,7 @@ public func hpke_setup_r(kemID: UInt16,
// ciphertext: &[u8]
// ) -> Result<Vec<u8>, Self::Error>;
@_cdecl("hpke_open_r")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_open_r(
recipientPtr: UnsafeMutableRawPointer,
aadPtr: UnsafePointer<UInt8>, aadLen: UInt64,
Expand All @@ -587,6 +604,7 @@ public func hpke_open_r(
// len: usize
// ) -> Result<Vec<u8>, Self::Error>;
@_cdecl("hpke_export_r")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_export_r(
recipientPtr: UnsafeMutableRawPointer,
ctxPtr: UnsafePointer<UInt8>, ctxLen: UInt64,
Expand All @@ -607,6 +625,7 @@ public func hpke_export_r(

// fn hpke_drop_r()
@_cdecl("hpke_drop_r")
@available(iOS 17.0, macOS 14.0, watchOS 10.0, tvOS 17.0, *)
public func hpke_drop_r(
recipientPtr: UnsafeMutableRawPointer
)
Expand Down
Loading