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

google / OpenSK / 4745439440

pending completion
4745439440

push

github

GitHub
Cryptographic Secret type (#615)

231 of 231 new or added lines in 15 files covered. (100.0%)

13243 of 13747 relevant lines covered (96.33%)

10222.45 hits per line

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

99.07
/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::aes256::Aes256;
16
use crate::api::crypto::hkdf256::Hkdf256;
17
use crate::api::crypto::hmac256::Hmac256;
18
use crate::api::crypto::sha256::Sha256;
19
use crate::api::crypto::{
20
    ecdh, ecdsa, Crypto, AES_BLOCK_SIZE, AES_KEY_SIZE, EC_FIELD_SIZE, EC_SIGNATURE_SIZE, HASH_SIZE,
21
    HMAC_KEY_SIZE, TRUNCATED_HMAC_SIZE,
22
};
23
use crate::api::rng::Rng;
24
use alloc::vec::Vec;
25
use crypto::Hash256;
26
use zeroize::Zeroize;
27

28
/// Cryptography implementation using our own library of primitives.
29
///
30
/// Warning: The used library does not implement zeroization.
31
pub struct SoftwareCrypto;
32
pub struct SoftwareEcdh;
33
pub struct SoftwareEcdsa;
34

35
impl Crypto for SoftwareCrypto {
36
    type Aes256 = SoftwareAes256;
37
    type Ecdh = SoftwareEcdh;
38
    type Ecdsa = SoftwareEcdsa;
39
    type Sha256 = SoftwareSha256;
40
    type Hmac256 = SoftwareHmac256;
41
    type Hkdf256 = SoftwareHkdf256;
42
}
43

44
impl ecdh::Ecdh for SoftwareEcdh {
45
    type SecretKey = SoftwareEcdhSecretKey;
46
    type PublicKey = SoftwareEcdhPublicKey;
47
    type SharedSecret = SoftwareEcdhSharedSecret;
48
}
49

50
pub struct SoftwareEcdhSecretKey {
51
    sec_key: crypto::ecdh::SecKey,
52
}
53

54
impl ecdh::SecretKey for SoftwareEcdhSecretKey {
55
    type PublicKey = SoftwareEcdhPublicKey;
56
    type SharedSecret = SoftwareEcdhSharedSecret;
57

58
    fn random(rng: &mut impl Rng) -> Self {
668✔
59
        let sec_key = crypto::ecdh::SecKey::gensk(rng);
668✔
60
        Self { sec_key }
668✔
61
    }
668✔
62

63
    fn public_key(&self) -> Self::PublicKey {
190✔
64
        let pub_key = self.sec_key.genpk();
190✔
65
        SoftwareEcdhPublicKey { pub_key }
190✔
66
    }
190✔
67

68
    fn diffie_hellman(&self, public_key: &SoftwareEcdhPublicKey) -> Self::SharedSecret {
186✔
69
        let shared_secret = self.sec_key.exchange_x(&public_key.pub_key);
186✔
70
        SoftwareEcdhSharedSecret { shared_secret }
186✔
71
    }
186✔
72
}
73

74
pub struct SoftwareEcdhPublicKey {
75
    pub_key: crypto::ecdh::PubKey,
76
}
77

78
impl ecdh::PublicKey for SoftwareEcdhPublicKey {
79
    fn from_coordinates(x: &[u8; EC_FIELD_SIZE], y: &[u8; EC_FIELD_SIZE]) -> Option<Self> {
186✔
80
        crypto::ecdh::PubKey::from_coordinates(x, y).map(|k| Self { pub_key: k })
279✔
81
    }
186✔
82

83
    fn to_coordinates(&self, x: &mut [u8; EC_FIELD_SIZE], y: &mut [u8; EC_FIELD_SIZE]) {
190✔
84
        self.pub_key.to_coordinates(x, y);
190✔
85
    }
190✔
86
}
87

88
#[derive(Zeroize)]
×
89
pub struct SoftwareEcdhSharedSecret {
90
    shared_secret: [u8; EC_FIELD_SIZE],
91
}
92

93
impl ecdh::SharedSecret for SoftwareEcdhSharedSecret {
94
    fn raw_secret_bytes(&self, secret: &mut [u8; EC_FIELD_SIZE]) {
186✔
95
        secret.copy_from_slice(&self.shared_secret);
186✔
96
    }
186✔
97
}
98

99
impl ecdsa::Ecdsa for SoftwareEcdsa {
100
    type SecretKey = SoftwareEcdsaSecretKey;
101
    type PublicKey = SoftwareEcdsaPublicKey;
102
    type Signature = SoftwareEcdsaSignature;
103
}
104

105
pub struct SoftwareEcdsaSecretKey {
106
    sec_key: crypto::ecdsa::SecKey,
107
}
108

109
impl ecdsa::SecretKey for SoftwareEcdsaSecretKey {
110
    type PublicKey = SoftwareEcdsaPublicKey;
111
    type Signature = SoftwareEcdsaSignature;
112

113
    fn random(rng: &mut impl Rng) -> Self {
1,120✔
114
        let sec_key = crypto::ecdsa::SecKey::gensk(rng);
1,120✔
115
        Self { sec_key }
1,120✔
116
    }
1,120✔
117

118
    fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option<Self> {
540✔
119
        crypto::ecdsa::SecKey::from_bytes(bytes).map(|k| Self { sec_key: k })
810✔
120
    }
540✔
121

122
    fn public_key(&self) -> Self::PublicKey {
114✔
123
        let pub_key = self.sec_key.genpk();
114✔
124
        SoftwareEcdsaPublicKey { pub_key }
114✔
125
    }
114✔
126

127
    fn sign(&self, message: &[u8]) -> Self::Signature {
164✔
128
        let signature = self.sec_key.sign_rfc6979::<crypto::sha256::Sha256>(message);
164✔
129
        SoftwareEcdsaSignature { signature }
164✔
130
    }
164✔
131

132
    fn to_slice(&self, bytes: &mut [u8; EC_FIELD_SIZE]) {
1,118✔
133
        self.sec_key.to_bytes(bytes);
1,118✔
134
    }
1,118✔
135
}
136

137
pub struct SoftwareEcdsaPublicKey {
138
    pub_key: crypto::ecdsa::PubKey,
139
}
140

141
impl ecdsa::PublicKey for SoftwareEcdsaPublicKey {
142
    type Signature = SoftwareEcdsaSignature;
143

144
    fn from_coordinates(x: &[u8; EC_FIELD_SIZE], y: &[u8; EC_FIELD_SIZE]) -> Option<Self> {
2✔
145
        crypto::ecdsa::PubKey::from_coordinates(x, y).map(|k| Self { pub_key: k })
3✔
146
    }
2✔
147

148
    fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
2✔
149
        self.pub_key
2✔
150
            .verify_vartime::<crypto::sha256::Sha256>(message, &signature.signature)
2✔
151
    }
2✔
152

153
    fn verify_prehash(&self, prehash: &[u8; HASH_SIZE], signature: &Self::Signature) -> bool {
2✔
154
        self.pub_key
2✔
155
            .verify_hash_vartime(prehash, &signature.signature)
2✔
156
    }
2✔
157

158
    fn to_coordinates(&self, x: &mut [u8; EC_FIELD_SIZE], y: &mut [u8; EC_FIELD_SIZE]) {
110✔
159
        self.pub_key.to_coordinates(x, y);
110✔
160
    }
110✔
161
}
162

163
pub struct SoftwareEcdsaSignature {
164
    signature: crypto::ecdsa::Signature,
165
}
166

167
impl ecdsa::Signature for SoftwareEcdsaSignature {
168
    fn from_slice(bytes: &[u8; EC_SIGNATURE_SIZE]) -> Option<Self> {
2✔
169
        crypto::ecdsa::Signature::from_bytes(bytes).map(|s| SoftwareEcdsaSignature { signature: s })
3✔
170
    }
2✔
171

172
    #[cfg(feature = "std")]
173
    fn to_slice(&self, bytes: &mut [u8; EC_SIGNATURE_SIZE]) {
4✔
174
        self.signature.to_bytes(bytes);
4✔
175
    }
4✔
176

177
    fn to_der(&self) -> Vec<u8> {
158✔
178
        self.signature.to_asn1_der()
158✔
179
    }
158✔
180
}
181

182
pub struct SoftwareSha256 {
183
    hasher: crypto::sha256::Sha256,
184
}
185

186
impl Sha256 for SoftwareSha256 {
187
    fn new() -> Self {
476✔
188
        let hasher = crypto::sha256::Sha256::new();
476✔
189
        Self { hasher }
476✔
190
    }
476✔
191

192
    /// Digest the next part of the message to hash.
193
    fn update(&mut self, data: &[u8]) {
476✔
194
        self.hasher.update(data);
476✔
195
    }
476✔
196

197
    /// Finalizes the hashing process, returns the hash value.
198
    fn finalize(self, output: &mut [u8; HASH_SIZE]) {
476✔
199
        self.hasher.finalize(output)
476✔
200
    }
476✔
201
}
202

203
pub struct SoftwareHmac256;
204

205
impl Hmac256 for SoftwareHmac256 {
206
    fn mac(key: &[u8; HMAC_KEY_SIZE], data: &[u8], output: &mut [u8; HASH_SIZE]) {
226✔
207
        crypto::hmac::hmac_256::<crypto::sha256::Sha256>(key, data, output)
226✔
208
    }
226✔
209

210
    fn verify(key: &[u8; HMAC_KEY_SIZE], data: &[u8], mac: &[u8; HASH_SIZE]) -> bool {
1,100✔
211
        crypto::hmac::verify_hmac_256::<crypto::sha256::Sha256>(key, data, mac)
1,100✔
212
    }
1,100✔
213

214
    fn verify_truncated_left(
88✔
215
        key: &[u8; HMAC_KEY_SIZE],
88✔
216
        data: &[u8],
88✔
217
        mac: &[u8; TRUNCATED_HMAC_SIZE],
88✔
218
    ) -> bool {
88✔
219
        crypto::hmac::verify_hmac_256_first_128bits::<crypto::sha256::Sha256>(key, data, mac)
88✔
220
    }
88✔
221
}
222

223
pub struct SoftwareHkdf256;
224

225
impl Hkdf256 for SoftwareHkdf256 {
226
    fn hkdf_256(ikm: &[u8], salt: &[u8; HASH_SIZE], info: &[u8], okm: &mut [u8; HASH_SIZE]) {
214✔
227
        crypto::hkdf::hkdf_256::<crypto::sha256::Sha256>(ikm, salt, info, okm);
214✔
228
    }
214✔
229
}
230

231
pub struct SoftwareAes256 {
232
    enc_key: crypto::aes256::EncryptionKey,
233
}
234

235
impl Aes256 for SoftwareAes256 {
236
    fn new(key: &[u8; AES_KEY_SIZE]) -> Self {
318✔
237
        let enc_key = crypto::aes256::EncryptionKey::new(key);
318✔
238
        SoftwareAes256 { enc_key }
318✔
239
    }
318✔
240

241
    fn encrypt_block(&self, block: &mut [u8; AES_BLOCK_SIZE]) {
2✔
242
        self.enc_key.encrypt_block(block);
2✔
243
    }
2✔
244

245
    fn decrypt_block(&self, block: &mut [u8; AES_BLOCK_SIZE]) {
2✔
246
        let dec_key = crypto::aes256::DecryptionKey::new(&self.enc_key);
2✔
247
        dec_key.decrypt_block(block);
2✔
248
    }
2✔
249

250
    fn encrypt_cbc(&self, iv: &[u8; AES_BLOCK_SIZE], plaintext: &mut [u8]) {
274✔
251
        crypto::cbc::cbc_encrypt(&self.enc_key, *iv, plaintext);
274✔
252
    }
274✔
253

254
    fn decrypt_cbc(&self, iv: &[u8; AES_BLOCK_SIZE], ciphertext: &mut [u8]) {
196✔
255
        let dec_key = crypto::aes256::DecryptionKey::new(&self.enc_key);
196✔
256
        crypto::cbc::cbc_decrypt(&dec_key, *iv, ciphertext);
196✔
257
    }
196✔
258
}
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

© 2026 Coveralls, Inc