picky_krb/crypto/
cipher.rs1use crate::constants::etypes::{AES128_CTS_HMAC_SHA1_96, AES256_CTS_HMAC_SHA1_96, DES3_CBC_SHA1_KD};
2
3use super::aes::{Aes128CtsHmacSha196, Aes256CtsHmacSha196};
4use super::des::Des3CbcSha1Kd;
5use super::{ChecksumSuite, DecryptWithoutChecksum, EncryptWithoutChecksum, KerberosCryptoError, KerberosCryptoResult};
6
7pub trait Cipher {
8 fn key_size(&self) -> usize;
9 fn seed_bit_len(&self) -> usize;
10 fn cipher_type(&self) -> CipherSuite;
11 fn checksum_type(&self) -> ChecksumSuite;
12
13 fn encrypt(&self, key: &[u8], key_usage: i32, payload: &[u8]) -> KerberosCryptoResult<Vec<u8>>;
14 fn decrypt(&self, key: &[u8], key_usage: i32, cipher_data: &[u8]) -> KerberosCryptoResult<Vec<u8>>;
15
16 fn encrypt_no_checksum(
17 &self,
18 key: &[u8],
19 key_usage: i32,
20 payload: &[u8],
21 ) -> KerberosCryptoResult<EncryptWithoutChecksum>;
22 fn decrypt_no_checksum(
23 &self,
24 key: &[u8],
25 key_usage: i32,
26 cipher_data: &[u8],
27 ) -> KerberosCryptoResult<DecryptWithoutChecksum>;
28
29 fn encryption_checksum(&self, key: &[u8], key_usage: i32, payload: &[u8]) -> KerberosCryptoResult<Vec<u8>>;
35
36 fn generate_key_from_password(&self, password: &[u8], salt: &[u8]) -> KerberosCryptoResult<Vec<u8>>;
37 fn random_to_key(&self, key: Vec<u8>) -> Vec<u8>;
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
41pub enum CipherSuite {
42 Aes128CtsHmacSha196,
43 Aes256CtsHmacSha196,
44 Des3CbcSha1Kd,
45}
46
47impl CipherSuite {
48 pub fn cipher(&self) -> Box<dyn Cipher> {
49 match self {
50 CipherSuite::Aes256CtsHmacSha196 => Box::new(Aes256CtsHmacSha196::new()),
51 CipherSuite::Aes128CtsHmacSha196 => Box::new(Aes128CtsHmacSha196::new()),
52 CipherSuite::Des3CbcSha1Kd => Box::new(Des3CbcSha1Kd::new()),
53 }
54 }
55}
56
57impl TryFrom<&[u8]> for CipherSuite {
58 type Error = KerberosCryptoError;
59
60 fn try_from(identifier: &[u8]) -> Result<Self, Self::Error> {
61 if identifier.len() != 1 {
62 return Err(KerberosCryptoError::AlgorithmIdentifierData(identifier.into()));
63 }
64
65 match u8::from_be_bytes(identifier.try_into().unwrap()) as usize {
66 AES256_CTS_HMAC_SHA1_96 => Ok(Self::Aes256CtsHmacSha196),
67 AES128_CTS_HMAC_SHA1_96 => Ok(Self::Aes128CtsHmacSha196),
68 DES3_CBC_SHA1_KD => Ok(Self::Des3CbcSha1Kd),
69 _ => Err(KerberosCryptoError::AlgorithmIdentifierData(identifier.into())),
70 }
71 }
72}
73
74impl TryFrom<usize> for CipherSuite {
75 type Error = KerberosCryptoError;
76
77 fn try_from(identifier: usize) -> Result<Self, Self::Error> {
78 match identifier {
79 AES256_CTS_HMAC_SHA1_96 => Ok(Self::Aes256CtsHmacSha196),
80 AES128_CTS_HMAC_SHA1_96 => Ok(Self::Aes128CtsHmacSha196),
81 DES3_CBC_SHA1_KD => Ok(Self::Des3CbcSha1Kd),
82 _ => Err(KerberosCryptoError::AlgorithmIdentifier(identifier)),
83 }
84 }
85}
86
87impl From<CipherSuite> for usize {
88 fn from(cipher: CipherSuite) -> Self {
89 match cipher {
90 CipherSuite::Aes256CtsHmacSha196 => AES256_CTS_HMAC_SHA1_96,
91 CipherSuite::Aes128CtsHmacSha196 => AES128_CTS_HMAC_SHA1_96,
92 CipherSuite::Des3CbcSha1Kd => DES3_CBC_SHA1_KD,
93 }
94 }
95}
96
97impl From<&CipherSuite> for u32 {
98 fn from(cipher: &CipherSuite) -> Self {
99 match cipher {
100 CipherSuite::Aes256CtsHmacSha196 => AES256_CTS_HMAC_SHA1_96 as u32,
101 CipherSuite::Aes128CtsHmacSha196 => AES128_CTS_HMAC_SHA1_96 as u32,
102 CipherSuite::Des3CbcSha1Kd => DES3_CBC_SHA1_KD as u32,
103 }
104 }
105}
106
107impl From<CipherSuite> for u8 {
108 fn from(cipher: CipherSuite) -> Self {
109 match cipher {
110 CipherSuite::Aes256CtsHmacSha196 => AES256_CTS_HMAC_SHA1_96 as u8,
111 CipherSuite::Aes128CtsHmacSha196 => AES128_CTS_HMAC_SHA1_96 as u8,
112 CipherSuite::Des3CbcSha1Kd => DES3_CBC_SHA1_KD as u8,
113 }
114 }
115}
116
117impl From<&CipherSuite> for u8 {
118 fn from(cipher: &CipherSuite) -> Self {
119 match cipher {
120 CipherSuite::Aes256CtsHmacSha196 => AES256_CTS_HMAC_SHA1_96 as u8,
121 CipherSuite::Aes128CtsHmacSha196 => AES128_CTS_HMAC_SHA1_96 as u8,
122 CipherSuite::Des3CbcSha1Kd => DES3_CBC_SHA1_KD as u8,
123 }
124 }
125}