1use core::ops::{Deref, DerefMut};
2
3use heapless::Vec;
4
5use crate::{
6 KEY_EXCHANGE_PUBLIC_KEY_MAX_SIZE, KEY_EXCHANGE_SECRET_KEY_MAX_SIZE, KEY_EXCHANGE_SHARED_SECRET_MAX_SIZE,
7 MAX_HASH_SIZE, SIGNATURE_MAX_SIZE, errors::Error,
8};
9
10#[derive(Clone)]
16#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
17pub struct Hash {
18 buf: [u8; Self::MAX_LEN],
19 len: u8,
20}
21
22impl Hash {
23 pub const MAX_LEN: usize = MAX_HASH_SIZE;
24
25 pub fn new_zeroed(len: u8) -> Self {
26 assert!((len as usize) <= Self::MAX_LEN);
27 Self {
28 buf: [0u8; Self::MAX_LEN],
29 len,
30 }
31 }
32
33 pub fn from_slice(data: &[u8]) -> Self {
34 assert!(data.len() <= Self::MAX_LEN);
35 let mut buf = [0u8; Self::MAX_LEN];
36 buf[..data.len()].copy_from_slice(data);
37 Self {
38 buf,
39 len: data.len() as u8,
40 }
41 }
42
43 pub const fn zeroed() -> Self {
44 Self {
45 buf: [0u8; Self::MAX_LEN],
46 len: 0,
47 }
48 }
49
50 pub fn len(&self) -> usize {
51 self.len as usize
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.len == 0
56 }
57
58 pub fn clear(&mut self) {
59 self.buf = [0u8; Self::MAX_LEN];
60 self.len = 0;
61 }
62}
63
64impl Deref for Hash {
65 type Target = [u8];
66 fn deref(&self) -> &[u8] {
67 &self.buf[..self.len as usize]
68 }
69}
70
71impl DerefMut for Hash {
72 fn deref_mut(&mut self) -> &mut [u8] {
73 &mut self.buf[..self.len as usize]
74 }
75}
76
77pub trait CryptoProvider: Clone + Send + Sync {
78 type Hasher: Clone + Unpin;
80
81 type AeadKey: Unpin;
84
85 fn cipher_suites() -> &'static [CipherSuite];
90 fn signature_schemes() -> &'static [SignatureScheme];
91 fn key_exchange_groups() -> &'static [KeyExchangeGroup];
92
93 fn secure_random(&self, buf: &mut [u8]);
94
95 fn new_hash(&self, suite: CipherSuite) -> Self::Hasher;
99 fn hash_update(&self, state: &mut Self::Hasher, data: &[u8]);
101 fn hash_finalize(&self, state: Self::Hasher) -> Result<Hash, Error>;
103
104 fn hash(&self, suite: CipherSuite, data: &[u8]) -> Result<Hash, Error> {
106 let mut state = self.new_hash(suite);
107 self.hash_update(&mut state, data);
108 self.hash_finalize(state)
109 }
110
111 fn hmac(&self, suite: CipherSuite, key: &Hash, data: &[u8]) -> Result<Hash, Error>;
112 fn hkdf_extract(&self, suite: CipherSuite, salt: &Hash, ikm: &[u8]) -> Result<Hash, Error>;
113 fn hkdf_expand_label(
114 &self,
115 out: &mut [u8],
116 suite: CipherSuite,
117 secret: &Hash,
118 label: &[u8],
119 context: &[u8],
120 ) -> Result<(), Error>;
121
122 fn new_aead_key(&self, suite: CipherSuite, key: &[u8]) -> Self::AeadKey;
124 fn aead_encrypt(
125 &self,
126 key: &Self::AeadKey,
127 nonce: &[u8],
128 aad: &[u8],
129 data: &mut [u8],
130 plaintext_len: usize,
131 ) -> Result<usize, Error>;
132 fn aead_decrypt(&self, key: &Self::AeadKey, nonce: &[u8], aad: &[u8], data: &mut [u8]) -> Result<usize, Error>;
133
134 fn key_exchange_generate_keypair(
136 &self,
137 group: KeyExchangeGroup,
138 ) -> Result<(KeyExchangeSecretKey, KeyExchangePublicKey), Error>;
139 fn key_exchange(
140 &self,
141 secret: &KeyExchangeSecretKey,
142 peer_public: &[u8],
143 ) -> Result<Vec<u8, KEY_EXCHANGE_SHARED_SECRET_MAX_SIZE>, Error>;
144
145 fn sign(
147 &self,
148 scheme: SignatureScheme,
149 secret_key: &[u8],
150 data: &[u8],
151 ) -> Result<Vec<u8, SIGNATURE_MAX_SIZE>, Error>;
152 fn verify(&self, scheme: SignatureScheme, public_key: &[u8], data: &[u8], signature: &[u8]) -> Result<(), Error>;
153}
154
155#[derive(Clone, Copy, PartialEq, Eq, Hash)]
162pub enum CipherSuite {
163 TlsAes128GcmSha256,
165 TlsAes256GcmSha384,
167 TlsChaCha20Poly1305Sha256,
169}
170
171impl core::fmt::Debug for CipherSuite {
172 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
173 match self {
174 Self::TlsAes128GcmSha256 => write!(f, "TLS13_AES_128_GCM_SHA256"),
175 Self::TlsAes256GcmSha384 => write!(f, "TLS13_AES_256_GCM_SHA384"),
176 Self::TlsChaCha20Poly1305Sha256 => write!(f, "TLS13_CHACHA20_POLY1305_SHA256"),
177 }
178 }
179}
180
181impl CipherSuite {
182 pub const fn to_wire(self) -> [u8; 2] {
184 match self {
185 Self::TlsAes128GcmSha256 => [0x13, 0x01],
186 Self::TlsAes256GcmSha384 => [0x13, 0x02],
187 Self::TlsChaCha20Poly1305Sha256 => [0x13, 0x03],
188 }
189 }
190
191 pub const fn from_wire(bytes: [u8; 2]) -> Option<Self> {
193 match bytes {
194 [0x13, 0x01] => Some(Self::TlsAes128GcmSha256),
195 [0x13, 0x02] => Some(Self::TlsAes256GcmSha384),
196 [0x13, 0x03] => Some(Self::TlsChaCha20Poly1305Sha256),
197 _ => None,
198 }
199 }
200
201 pub const fn key_size(self) -> usize {
203 match self {
204 Self::TlsAes128GcmSha256 => 16,
205 Self::TlsAes256GcmSha384 => 32,
206 Self::TlsChaCha20Poly1305Sha256 => 32,
207 }
208 }
209
210 pub const fn hash_size(self) -> usize {
212 match self {
213 Self::TlsAes128GcmSha256 => 32,
214 Self::TlsAes256GcmSha384 => 48,
215 Self::TlsChaCha20Poly1305Sha256 => 32,
216 }
217 }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
222pub enum KeyExchangeGroup {
223 X25519,
225 X25519MlKem768,
228 Secp256r1,
230 Secp384r1,
232 Secp521r1,
234 X448,
236 Secp256r1MlKem768,
239 Secp384r1MlKem1024,
242}
243
244impl KeyExchangeGroup {
245 pub const fn to_wire(self) -> [u8; 2] {
247 match self {
248 Self::X25519 => [0x00, 0x1D],
249 Self::X25519MlKem768 => [0x11, 0xEC],
250 Self::Secp256r1 => [0x00, 0x17],
251 Self::Secp384r1 => [0x00, 0x18],
252 Self::Secp521r1 => [0x00, 0x19],
253 Self::X448 => [0x00, 0x1E],
254 Self::Secp256r1MlKem768 => [0x11, 0xEB],
255 Self::Secp384r1MlKem1024 => [0x11, 0xED],
256 }
257 }
258
259 pub const fn from_wire(bytes: [u8; 2]) -> Option<Self> {
261 match bytes {
262 [0x00, 0x1D] => Some(Self::X25519),
263 [0x11, 0xEC] => Some(Self::X25519MlKem768),
264 [0x00, 0x17] => Some(Self::Secp256r1),
265 [0x00, 0x18] => Some(Self::Secp384r1),
266 [0x00, 0x19] => Some(Self::Secp521r1),
267 [0x00, 0x1E] => Some(Self::X448),
268 [0x11, 0xEB] => Some(Self::Secp256r1MlKem768),
269 [0x11, 0xED] => Some(Self::Secp384r1MlKem1024),
270 _ => None,
271 }
272 }
273
274 pub const fn public_key_size_client(self) -> usize {
276 match self {
277 Self::X25519 => 32,
278 Self::X25519MlKem768 => 1216,
279 Self::Secp256r1 => 65,
280 Self::Secp384r1 => 97,
281 Self::Secp521r1 => 133,
282 Self::X448 => 56,
283 Self::Secp256r1MlKem768 => 1249,
284 Self::Secp384r1MlKem1024 => 1665,
285 }
286 }
287
288 pub const fn public_key_size_server(self) -> usize {
293 match self {
294 Self::X25519 => 32,
295 Self::X25519MlKem768 => 1120,
296 Self::Secp256r1 => 65,
297 Self::Secp384r1 => 97,
298 Self::Secp521r1 => 133,
299 Self::X448 => 56,
300 Self::Secp256r1MlKem768 => 1153,
301 Self::Secp384r1MlKem1024 => 1665,
302 }
303 }
304}
305
306pub struct KeyExchangeSecretKey {
307 bytes: Vec<u8, KEY_EXCHANGE_SECRET_KEY_MAX_SIZE>,
308 group: KeyExchangeGroup,
309}
310
311impl KeyExchangeSecretKey {
312 #[inline]
313 pub fn new(group: KeyExchangeGroup, bytes: &[u8]) -> Self {
314 Self {
315 bytes: bytes.try_into().unwrap(),
316 group,
317 }
318 }
319
320 #[inline]
321 pub fn bytes(&self) -> &[u8] {
322 &self.bytes
323 }
324
325 #[inline]
326 pub fn group(&self) -> KeyExchangeGroup {
327 self.group
328 }
329}
330
331#[derive(Debug)]
332pub struct KeyExchangePublicKey {
333 bytes: Vec<u8, KEY_EXCHANGE_PUBLIC_KEY_MAX_SIZE>,
334 group: KeyExchangeGroup,
335}
336
337impl KeyExchangePublicKey {
338 #[inline]
339 pub fn new(group: KeyExchangeGroup, bytes: &[u8]) -> Self {
340 Self {
341 bytes: bytes.try_into().unwrap(),
342 group,
343 }
344 }
345
346 #[inline]
347 pub fn bytes(&self) -> &[u8] {
348 &self.bytes
349 }
350
351 #[inline]
352 pub fn group(&self) -> KeyExchangeGroup {
353 self.group
354 }
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
361pub enum SignatureScheme {
362 Ed25519,
364 EcdsaP256Sha256,
366 EcdsaP384Sha384,
368 RsaPkcs1Sha256,
370 RsaPkcs1Sha384,
372 RsaPkcs1Sha512,
374 RsaPssRsaSha256,
376 RsaPssRsaSha384,
378 RsaPssRsaSha512,
380}
381
382impl SignatureScheme {
383 pub fn to_wire(self) -> [u8; 2] {
385 match self {
386 Self::Ed25519 => [0x08, 0x07],
387 Self::EcdsaP256Sha256 => [0x04, 0x03],
388 Self::EcdsaP384Sha384 => [0x05, 0x03],
389 Self::RsaPkcs1Sha256 => [0x04, 0x01],
390 Self::RsaPkcs1Sha384 => [0x05, 0x01],
391 Self::RsaPkcs1Sha512 => [0x06, 0x01],
392 Self::RsaPssRsaSha256 => [0x08, 0x04],
393 Self::RsaPssRsaSha384 => [0x08, 0x05],
394 Self::RsaPssRsaSha512 => [0x08, 0x06],
395 }
396 }
397
398 pub fn from_wire(bytes: [u8; 2]) -> Option<Self> {
400 match bytes {
401 [0x08, 0x07] => Some(Self::Ed25519),
402 [0x04, 0x03] => Some(Self::EcdsaP256Sha256),
403 [0x05, 0x03] => Some(Self::EcdsaP384Sha384),
404 [0x04, 0x01] => Some(Self::RsaPkcs1Sha256),
405 [0x05, 0x01] => Some(Self::RsaPkcs1Sha384),
406 [0x06, 0x01] => Some(Self::RsaPkcs1Sha512),
407 [0x08, 0x04] => Some(Self::RsaPssRsaSha256),
408 [0x08, 0x05] => Some(Self::RsaPssRsaSha384),
409 [0x08, 0x06] => Some(Self::RsaPssRsaSha512),
410 _ => None,
411 }
412 }
413
414 pub fn secret_key_size(self) -> usize {
416 match self {
417 Self::Ed25519 => 32,
418 Self::EcdsaP256Sha256 => 32,
419 Self::EcdsaP384Sha384 => 48,
420 Self::RsaPkcs1Sha256 => 256, Self::RsaPkcs1Sha384 => 256,
422 Self::RsaPkcs1Sha512 => 256,
423 Self::RsaPssRsaSha256 => 256,
424 Self::RsaPssRsaSha384 => 256,
425 Self::RsaPssRsaSha512 => 256,
426 }
427 }
428
429 pub fn public_key_size(self) -> usize {
431 match self {
432 Self::Ed25519 => 32,
433 Self::EcdsaP256Sha256 => 65,
434 Self::EcdsaP384Sha384 => 97,
435 Self::RsaPkcs1Sha256 => 294, Self::RsaPkcs1Sha384 => 294,
437 Self::RsaPkcs1Sha512 => 294,
438 Self::RsaPssRsaSha256 => 294,
439 Self::RsaPssRsaSha384 => 294,
440 Self::RsaPssRsaSha512 => 294,
441 }
442 }
443
444 pub fn signature_size(self) -> usize {
446 match self {
447 Self::Ed25519 => 64,
448 Self::EcdsaP256Sha256 => 64,
449 Self::EcdsaP384Sha384 => 96,
450 Self::RsaPkcs1Sha256 => 256, Self::RsaPkcs1Sha384 => 256,
452 Self::RsaPkcs1Sha512 => 256,
453 Self::RsaPssRsaSha256 => 256,
454 Self::RsaPssRsaSha384 => 256,
455 Self::RsaPssRsaSha512 => 256,
456 }
457 }
458}
459
460#[derive(Debug, Clone, Copy, PartialEq, Eq)]
466#[repr(u8)]
467pub enum CertType {
468 X509 = 0,
470 RawPublicKey = 1,
472}
473
474impl CertType {
475 pub fn from_u8(v: u8) -> Option<Self> {
476 match v {
477 0 => Some(Self::X509),
478 1 => Some(Self::RawPublicKey),
479 _ => None,
480 }
481 }
482
483 pub fn name(&self) -> &'static str {
484 match self {
485 Self::X509 => "X.509",
486 Self::RawPublicKey => "RawPublicKey",
487 }
488 }
489}