1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftCrypto open source project
//
// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.md for the list of SwiftCrypto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
@_exported import CryptoKit
#else
@_implementationOnly import CCryptoBoringSSL
@_implementationOnly import CCryptoBoringSSLShims
import Foundation
// For signing and verifying, we use BoringSSL's Ed25519, not the X25519 stuff.
extension Curve25519.Signing {
@usableFromInline
struct OpenSSLCurve25519PrivateKeyImpl {
/* private but @usableFromInline */ var _privateKey: SecureBytes
/* private but @usableFromInline */ @usableFromInline var _publicKey: [UInt8]
@usableFromInline
init() {
// BoringSSL's Ed25519 implementation stores the private key concatenated with the public key, so we do
// as well. We also store the public key because it makes our lives easier.
var publicKey = Array(repeating: UInt8(0), count: 32)
let privateKey = SecureBytes(unsafeUninitializedCapacity: 64) { privateKeyPtr, privateKeyBytes in
privateKeyBytes = 64
publicKey.withUnsafeMutableBytes { publicKeyPtr in
CCryptoBoringSSLShims_ED25519_keypair(publicKeyPtr.baseAddress, privateKeyPtr.baseAddress)
}
}
self._privateKey = privateKey
self._publicKey = publicKey
}
@usableFromInline
var publicKey: Curve25519.Signing.OpenSSLCurve25519PublicKeyImpl {
OpenSSLCurve25519PublicKeyImpl(self._publicKey)
}
var key: SecureBytes {
self._privateKey
}
init<D: ContiguousBytes>(rawRepresentation data: D) throws {
// What this calls "rawRepresentation" BoringSSL calls the "seed". Otherwise, this is
// the same as the above initializer.
var publicKey = Array(repeating: UInt8(0), count: 32)
let privateKey: SecureBytes = try data.withUnsafeBytes { seedPtr in
guard seedPtr.count == 32 else {
throw CryptoKitError.incorrectKeySize
}
let privateKey = SecureBytes(unsafeUninitializedCapacity: 64) { privateKeyPtr, privateKeyBytes in
privateKeyBytes = 64
publicKey.withUnsafeMutableBytes { publicKeyPtr in
CCryptoBoringSSLShims_ED25519_keypair_from_seed(publicKeyPtr.baseAddress, privateKeyPtr.baseAddress, seedPtr.baseAddress)
}
}
return privateKey
}
self._privateKey = privateKey
self._publicKey = publicKey
}
@usableFromInline
var rawRepresentation: Data {
// The "rawRepresentation" is what BoringSSL calls the "seed", and it's the first 32 bytes of our key.
Data(self._privateKey.prefix(32))
}
}
@usableFromInline
struct OpenSSLCurve25519PublicKeyImpl {
@usableFromInline
var keyBytes: [UInt8]
@inlinable
init<D: ContiguousBytes>(rawRepresentation: D) throws {
self.keyBytes = try rawRepresentation.withUnsafeBytes { keyBytesPtr in
guard keyBytesPtr.count == 32 else {
throw CryptoKitError.incorrectKeySize
}
return Array(keyBytesPtr)
}
}
init(_ keyBytes: [UInt8]) {
precondition(keyBytes.count == 32)
self.keyBytes = keyBytes
}
var rawRepresentation: Data {
Data(self.keyBytes)
}
}
}
#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API
|