MobileCoin-Swift/Sources/Crypto/VersionedCryptoBox.swift
Kyle Fleming 74a5c6f3fe
Continued logging cleanup (#17)
Co-authored-by: Eran Rundstein <eran@rundste.in>
2021-04-05 11:06:57 -07:00

89 lines
3.2 KiB
Swift

//
// Copyright (c) 2020-2021 MobileCoin. All rights reserved.
//
// swiftlint:disable multiline_function_chains
import Foundation
import LibMobileCoin
enum VersionedCryptoBoxError: Error {
case invalidInput(String)
case unsupportedVersion(String)
}
extension VersionedCryptoBoxError: CustomStringConvertible {
var description: String {
"Versioned CryptoBox error: " + {
switch self {
case .invalidInput(let reason):
return "Invalid input: \(reason)"
case .unsupportedVersion(let reason):
return "Unsupported version: \(reason)"
}
}()
}
}
enum VersionedCryptoBox {
static func encrypt(
plaintext: Data,
publicKey: RistrettoPublic,
rng: (@convention(c) (UnsafeMutableRawPointer?) -> UInt64)?,
rngContext: Any?
) -> Result<Data, InvalidInputError> {
publicKey.asMcBuffer { viewPublicKeyPtr in
plaintext.asMcBuffer { plaintextPtr in
withMcRngCallback(rng: rng, rngContext: rngContext) { rngCallbackPtr in
Data.make(withMcMutableBuffer: { bufferPtr, errorPtr in
mc_versioned_crypto_box_encrypt(
viewPublicKeyPtr,
plaintextPtr,
rngCallbackPtr,
bufferPtr,
&errorPtr)
}).mapError {
switch $0.errorCode {
case .aead:
return InvalidInputError("\(redacting: $0.description)")
default:
// Safety: mc_versioned_crypto_box_encrypt should not throw
// non-documented errors.
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
}
}
}
}
}
}
static func decrypt(
ciphertext: Data,
privateKey: RistrettoPrivate
) -> Result<Data, VersionedCryptoBoxError> {
privateKey.asMcBuffer { privateKeyPtr in
ciphertext.asMcBuffer { ciphertextPtr in
Data.make(withEstimatedLengthMcMutableBuffer: ciphertext.count)
{ bufferPtr, errorPtr in
mc_versioned_crypto_box_decrypt(
privateKeyPtr,
ciphertextPtr,
bufferPtr,
&errorPtr)
}.mapError {
switch $0.errorCode {
case .aead, .invalidInput:
return .invalidInput("\(redacting: $0.description)")
case .unsupportedCryptoBoxVersion:
return .unsupportedVersion("\(redacting: $0.description)")
default:
// Safety: mc_versioned_crypto_box_decrypt should not throw non-documented
// errors.
logger.fatalError("Unhandled LibMobileCoin error: \(redacting: $0)")
}
}
}
}
}
}