• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / OpenSK / 4470983680

pending completion
4470983680

Pull #606

github

GitHub
Merge 128d694c9 into 6d5ea16f2
Pull Request #606: Adds a trait for crypto, porting EC first

301 of 301 new or added lines in 14 files covered. (100.0%)

13267 of 13743 relevant lines covered (96.54%)

2982.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.2
/libraries/opensk/src/api/crypto/software_crypto.rs
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 crate::api::crypto::{ecdh, ecdsa, Crypto, EC_FIELD_BYTE_SIZE, EC_SIGNATURE_SIZE};
16
use alloc::vec::Vec;
17
use rng256::Rng256;
18

19
pub struct SoftwareCrypto;
20
pub struct SoftwareEcdh;
21
pub struct SoftwareEcdsa;
22

23
impl Crypto for SoftwareCrypto {
24
    type Ecdh = SoftwareEcdh;
25
    type Ecdsa = SoftwareEcdsa;
26
}
27

28
impl ecdh::Ecdh for SoftwareEcdh {
29
    type SecretKey = SoftwareEcdhSecretKey;
30
    type PublicKey = SoftwareEcdhPublicKey;
31
    type SharedSecret = SoftwareEcdhSharedSecret;
32
}
33

34
pub struct SoftwareEcdhSecretKey {
35
    sec_key: crypto::ecdh::SecKey,
36
}
37

38
impl ecdh::SecretKey for SoftwareEcdhSecretKey {
39
    type PublicKey = SoftwareEcdhPublicKey;
40
    type SharedSecret = SoftwareEcdhSharedSecret;
41

42
    fn random(rng: &mut impl Rng256) -> Self {
342✔
43
        let sec_key = crypto::ecdh::SecKey::gensk(rng);
342✔
44
        Self { sec_key }
342✔
45
    }
342✔
46

47
    fn public_key(&self) -> Self::PublicKey {
95✔
48
        let pub_key = self.sec_key.genpk();
95✔
49
        SoftwareEcdhPublicKey { pub_key }
95✔
50
    }
95✔
51

52
    fn diffie_hellman(&self, public_key: &SoftwareEcdhPublicKey) -> Self::SharedSecret {
93✔
53
        let shared_secret = self.sec_key.exchange_x(&public_key.pub_key);
93✔
54
        SoftwareEcdhSharedSecret { shared_secret }
93✔
55
    }
93✔
56
}
57

58
pub struct SoftwareEcdhPublicKey {
59
    pub_key: crypto::ecdh::PubKey,
60
}
61

62
impl ecdh::PublicKey for SoftwareEcdhPublicKey {
63
    fn from_coordinates(
93✔
64
        x: &[u8; EC_FIELD_BYTE_SIZE],
93✔
65
        y: &[u8; EC_FIELD_BYTE_SIZE],
93✔
66
    ) -> Option<Self> {
93✔
67
        crypto::ecdh::PubKey::from_coordinates(x, y).map(|k| Self { pub_key: k })
93✔
68
    }
93✔
69

70
    fn to_coordinates(&self, x: &mut [u8; EC_FIELD_BYTE_SIZE], y: &mut [u8; EC_FIELD_BYTE_SIZE]) {
95✔
71
        self.pub_key.to_coordinates(x, y);
95✔
72
    }
95✔
73
}
74

75
pub struct SoftwareEcdhSharedSecret {
76
    shared_secret: [u8; EC_FIELD_BYTE_SIZE],
77
}
78

79
impl ecdh::SharedSecret for SoftwareEcdhSharedSecret {
80
    fn raw_secret_bytes(&self) -> [u8; EC_FIELD_BYTE_SIZE] {
93✔
81
        self.shared_secret
93✔
82
    }
93✔
83
}
84

85
impl ecdsa::Ecdsa for SoftwareEcdsa {
86
    type SecretKey = SoftwareEcdsaSecretKey;
87
    type PublicKey = SoftwareEcdsaPublicKey;
88
    type Signature = SoftwareEcdsaSignature;
89
}
90

91
pub struct SoftwareEcdsaSecretKey {
92
    sec_key: crypto::ecdsa::SecKey,
93
}
94

95
impl ecdsa::SecretKey for SoftwareEcdsaSecretKey {
96
    type PublicKey = SoftwareEcdsaPublicKey;
97
    type Signature = SoftwareEcdsaSignature;
98

99
    fn random(rng: &mut impl Rng256) -> Self {
558✔
100
        let sec_key = crypto::ecdsa::SecKey::gensk(rng);
558✔
101
        Self { sec_key }
558✔
102
    }
558✔
103

104
    fn from_slice(bytes: &[u8; EC_FIELD_BYTE_SIZE]) -> Option<Self> {
269✔
105
        crypto::ecdsa::SecKey::from_bytes(bytes).map(|k| Self { sec_key: k })
269✔
106
    }
269✔
107

108
    fn public_key(&self) -> Self::PublicKey {
56✔
109
        let pub_key = self.sec_key.genpk();
56✔
110
        SoftwareEcdsaPublicKey { pub_key }
56✔
111
    }
56✔
112

113
    fn sign(&self, message: &[u8]) -> Self::Signature {
79✔
114
        let signature = self.sec_key.sign_rfc6979::<crypto::sha256::Sha256>(message);
79✔
115
        SoftwareEcdsaSignature { signature }
79✔
116
    }
79✔
117

118
    fn to_slice(&self, bytes: &mut [u8; EC_FIELD_BYTE_SIZE]) {
559✔
119
        self.sec_key.to_bytes(bytes);
559✔
120
    }
559✔
121
}
122

123
pub struct SoftwareEcdsaPublicKey {
124
    pub_key: crypto::ecdsa::PubKey,
125
}
126

127
impl ecdsa::PublicKey for SoftwareEcdsaPublicKey {
128
    type Signature = SoftwareEcdsaSignature;
129

130
    fn from_coordinates(
1✔
131
        x: &[u8; EC_FIELD_BYTE_SIZE],
1✔
132
        y: &[u8; EC_FIELD_BYTE_SIZE],
1✔
133
    ) -> Option<Self> {
1✔
134
        crypto::ecdsa::PubKey::from_coordinates(x, y).map(|k| Self { pub_key: k })
1✔
135
    }
1✔
136

137
    fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
1✔
138
        self.pub_key
1✔
139
            .verify_vartime::<crypto::sha256::Sha256>(message, &signature.signature)
1✔
140
    }
1✔
141

142
    fn to_coordinates(&self, x: &mut [u8; EC_FIELD_BYTE_SIZE], y: &mut [u8; EC_FIELD_BYTE_SIZE]) {
55✔
143
        self.pub_key.to_coordinates(x, y);
55✔
144
    }
55✔
145
}
146

147
pub struct SoftwareEcdsaSignature {
148
    signature: crypto::ecdsa::Signature,
149
}
150

151
impl ecdsa::Signature for SoftwareEcdsaSignature {
152
    fn from_slice(bytes: &[u8; EC_SIGNATURE_SIZE]) -> Option<Self> {
×
153
        crypto::ecdsa::Signature::from_bytes(bytes).map(|s| SoftwareEcdsaSignature { signature: s })
×
154
    }
×
155

156
    fn to_der(&self) -> Vec<u8> {
78✔
157
        self.signature.to_asn1_der()
78✔
158
    }
78✔
159
}
160

161
#[cfg(test)]
162
mod test {
163
    use super::*;
164
    use crate::api::crypto::ecdh::{
165
        PublicKey as EcdhPublicKey, SecretKey as EcdhSecretKey, SharedSecret,
166
    };
167
    use crate::api::crypto::ecdsa::{PublicKey as EcdsaPublicKey, SecretKey as EcdsaSecretKey};
168
    use crate::env::test::TestEnv;
169

170
    #[test]
1✔
171
    fn test_shared_secret_symmetric() {
1✔
172
        let mut env = TestEnv::default();
1✔
173
        let private1 = SoftwareEcdhSecretKey::random(env.rng());
1✔
174
        let private2 = SoftwareEcdhSecretKey::random(env.rng());
1✔
175
        let pub1 = private1.public_key();
1✔
176
        let pub2 = private2.public_key();
1✔
177
        let shared1 = private1.diffie_hellman(&pub2);
1✔
178
        let shared2 = private2.diffie_hellman(&pub1);
1✔
179
        assert_eq!(shared1.raw_secret_bytes(), shared2.raw_secret_bytes());
1✔
180
    }
1✔
181

182
    #[test]
1✔
183
    fn test_ecdh_public_key_from_to_bytes() {
1✔
184
        let mut env = TestEnv::default();
1✔
185
        let first_key = SoftwareEcdhSecretKey::random(env.rng());
1✔
186
        let first_public = first_key.public_key();
1✔
187
        let mut x = [0; EC_FIELD_BYTE_SIZE];
1✔
188
        let mut y = [0; EC_FIELD_BYTE_SIZE];
1✔
189
        first_public.to_coordinates(&mut x, &mut y);
1✔
190
        let new_public = SoftwareEcdhPublicKey::from_coordinates(&x, &y).unwrap();
1✔
191
        let mut new_x = [0; EC_FIELD_BYTE_SIZE];
1✔
192
        let mut new_y = [0; EC_FIELD_BYTE_SIZE];
1✔
193
        new_public.to_coordinates(&mut new_x, &mut new_y);
1✔
194
        assert_eq!(x, new_x);
1✔
195
        assert_eq!(y, new_y);
1✔
196
    }
1✔
197

198
    #[test]
1✔
199
    fn test_sign_verify() {
1✔
200
        let mut env = TestEnv::default();
1✔
201
        let private_key = SoftwareEcdsaSecretKey::random(env.rng());
1✔
202
        let public_key = private_key.public_key();
1✔
203
        let message = [0x12, 0x34, 0x56, 0x78];
1✔
204
        let signature = private_key.sign(&message);
1✔
205
        assert!(public_key.verify(&message, &signature));
1✔
206
    }
1✔
207

208
    #[test]
1✔
209
    fn test_ecdsa_secret_key_from_to_bytes() {
1✔
210
        let mut env = TestEnv::default();
1✔
211
        let first_key = SoftwareEcdsaSecretKey::random(env.rng());
1✔
212
        let mut key_bytes = [0; EC_FIELD_BYTE_SIZE];
1✔
213
        first_key.to_slice(&mut key_bytes);
1✔
214
        let second_key = SoftwareEcdsaSecretKey::from_slice(&key_bytes).unwrap();
1✔
215
        let mut new_bytes = [0; EC_FIELD_BYTE_SIZE];
1✔
216
        second_key.to_slice(&mut new_bytes);
1✔
217
        assert_eq!(key_bytes, new_bytes);
1✔
218
    }
1✔
219
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc