Skip to content

Commit

Permalink
Fix mls-rs-crypto-cryptokit not building for iOS (#206)
Browse files Browse the repository at this point in the history
* Fix mls-rs-crypto-cryptokit not building for iOS

* cargo fmt

---------

Co-authored-by: Tom Leavy <tomleavy@amazon.com>
  • Loading branch information
CaioSym and tomleavy authored Nov 27, 2024
1 parent 474dc47 commit b9f0eae
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
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

0 comments on commit b9f0eae

Please sign in to comment.