webrtc_dtls/cipher_suite/
cipher_suite_aes_128_ccm.rs

1use super::*;
2use crate::client_certificate_type::ClientCertificateType;
3use crate::crypto::crypto_ccm::{CryptoCcm, CryptoCcmTagLen};
4use crate::prf::*;
5
6#[derive(Clone)]
7pub struct CipherSuiteAes128Ccm {
8    ccm: Option<CryptoCcm>,
9    client_certificate_type: ClientCertificateType,
10    id: CipherSuiteId,
11    psk: bool,
12    crypto_ccm_tag_len: CryptoCcmTagLen,
13}
14
15impl CipherSuiteAes128Ccm {
16    const PRF_MAC_LEN: usize = 0;
17    const PRF_KEY_LEN: usize = 16;
18    const PRF_IV_LEN: usize = 4;
19
20    pub fn new(
21        client_certificate_type: ClientCertificateType,
22        id: CipherSuiteId,
23        psk: bool,
24        crypto_ccm_tag_len: CryptoCcmTagLen,
25    ) -> Self {
26        CipherSuiteAes128Ccm {
27            ccm: None,
28            client_certificate_type,
29            id,
30            psk,
31            crypto_ccm_tag_len,
32        }
33    }
34}
35
36impl CipherSuite for CipherSuiteAes128Ccm {
37    fn to_string(&self) -> String {
38        format!("{}", self.id)
39    }
40
41    fn id(&self) -> CipherSuiteId {
42        self.id
43    }
44
45    fn certificate_type(&self) -> ClientCertificateType {
46        self.client_certificate_type
47    }
48
49    fn hash_func(&self) -> CipherSuiteHash {
50        CipherSuiteHash::Sha256
51    }
52
53    fn is_psk(&self) -> bool {
54        self.psk
55    }
56
57    fn is_initialized(&self) -> bool {
58        self.ccm.is_some()
59    }
60
61    fn init(
62        &mut self,
63        master_secret: &[u8],
64        client_random: &[u8],
65        server_random: &[u8],
66        is_client: bool,
67    ) -> Result<()> {
68        let keys = prf_encryption_keys(
69            master_secret,
70            client_random,
71            server_random,
72            CipherSuiteAes128Ccm::PRF_MAC_LEN,
73            CipherSuiteAes128Ccm::PRF_KEY_LEN,
74            CipherSuiteAes128Ccm::PRF_IV_LEN,
75            self.hash_func(),
76        )?;
77
78        if is_client {
79            self.ccm = Some(CryptoCcm::new(
80                &self.crypto_ccm_tag_len,
81                &keys.client_write_key,
82                &keys.client_write_iv,
83                &keys.server_write_key,
84                &keys.server_write_iv,
85            ));
86        } else {
87            self.ccm = Some(CryptoCcm::new(
88                &self.crypto_ccm_tag_len,
89                &keys.server_write_key,
90                &keys.server_write_iv,
91                &keys.client_write_key,
92                &keys.client_write_iv,
93            ));
94        }
95
96        Ok(())
97    }
98
99    fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
100        if let Some(ccm) = &self.ccm {
101            ccm.encrypt(pkt_rlh, raw)
102        } else {
103            Err(Error::Other(
104                "CipherSuite has not been initialized, unable to encrypt".to_owned(),
105            ))
106        }
107    }
108
109    fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
110        if let Some(ccm) = &self.ccm {
111            ccm.decrypt(input)
112        } else {
113            Err(Error::Other(
114                "CipherSuite has not been initialized, unable to decrypt".to_owned(),
115            ))
116        }
117    }
118}