• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crypto_provider::elliptic_curve::{EcdhProvider, EphemeralSecret, PublicKey};
16 use crypto_provider::x25519::X25519;
17 
18 /// The BoringSSL implementation of X25519 ECDH.
19 pub struct X25519Ecdh;
20 
21 impl EcdhProvider<X25519> for X25519Ecdh {
22     type PublicKey = X25519PublicKey;
23     type EphemeralSecret = X25519EphemeralSecret;
24     type SharedSecret = [u8; 32];
25 }
26 
27 /// A X25519 ephemeral secret used for Diffie-Hellman.
28 pub struct X25519EphemeralSecret {
29     public_key: bssl_crypto::x25519::PublicKey,
30     secret: bssl_crypto::x25519::PrivateKey,
31 }
32 
33 impl EphemeralSecret<X25519> for X25519EphemeralSecret {
34     type Impl = X25519Ecdh;
35     type Error = Error;
36     type Rng = ();
37     type EncodedPublicKey = [u8; 32];
38 
generate_random(_rng: &mut Self::Rng) -> Self39     fn generate_random(_rng: &mut Self::Rng) -> Self {
40         let key_pair = bssl_crypto::x25519::PrivateKey::generate();
41         Self { public_key: key_pair.0, secret: key_pair.1 }
42     }
43 
public_key_bytes(&self) -> Self::EncodedPublicKey44     fn public_key_bytes(&self) -> Self::EncodedPublicKey {
45         self.public_key
46     }
47 
diffie_hellman( self, other_pub: &<X25519Ecdh as EcdhProvider<X25519>>::PublicKey, ) -> Result<<X25519Ecdh as EcdhProvider<X25519>>::SharedSecret, Self::Error>48     fn diffie_hellman(
49         self,
50         other_pub: &<X25519Ecdh as EcdhProvider<X25519>>::PublicKey,
51     ) -> Result<<X25519Ecdh as EcdhProvider<X25519>>::SharedSecret, Self::Error> {
52         self.secret.compute_shared_key(&other_pub.0).ok_or(Error::WrongSize)
53     }
54 }
55 
56 #[cfg(test)]
57 impl crypto_provider_test::elliptic_curve::EphemeralSecretForTesting<X25519>
58     for X25519EphemeralSecret
59 {
from_private_components( private_bytes: &[u8; 32], public_key: &X25519PublicKey, ) -> Result<Self, Self::Error>60     fn from_private_components(
61         private_bytes: &[u8; 32],
62         public_key: &X25519PublicKey,
63     ) -> Result<Self, Self::Error> {
64         Ok(Self {
65             public_key: public_key.0,
66             secret: bssl_crypto::x25519::PrivateKey(*private_bytes),
67         })
68     }
69 }
70 
71 /// A X25519 public key.
72 #[derive(Debug, PartialEq, Eq)]
73 pub struct X25519PublicKey(bssl_crypto::x25519::PublicKey);
74 
75 impl PublicKey<X25519> for X25519PublicKey {
76     type EncodedPublicKey = [u8; 32];
77     type Error = Error;
78 
from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>79     fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
80         let byte_arr: [u8; 32] = bytes.try_into().map_err(|_| Error::WrongSize)?;
81         Ok(Self(bssl_crypto::x25519::PublicKey::from(byte_arr)))
82     }
83 
to_bytes(&self) -> Self::EncodedPublicKey84     fn to_bytes(&self) -> Self::EncodedPublicKey {
85         self.0
86     }
87 }
88 
89 /// Error type for the BoringSSL implementation of x25519.
90 #[derive(Debug)]
91 pub enum Error {
92     /// Unexpected size for the given input.
93     WrongSize,
94 }
95 
96 #[cfg(test)]
97 mod tests {
98     use super::X25519Ecdh;
99     use core::marker::PhantomData;
100     use crypto_provider_test::x25519::*;
101 
102     #[apply(x25519_test_cases)]
x25519_tests(testcase: CryptoProviderTestCase<X25519Ecdh>)103     fn x25519_tests(testcase: CryptoProviderTestCase<X25519Ecdh>) {
104         testcase(PhantomData::<X25519Ecdh>)
105     }
106 }
107