Skip to main content

rns_core/link/
crypto.rs

1use alloc::vec::Vec;
2
3use rns_crypto::token::Token;
4use rns_crypto::Rng;
5
6use super::types::LinkError;
7
8/// Create a Token from a derived session key.
9///
10/// 32 bytes → AES-128-CBC, 64 bytes → AES-256-CBC.
11pub fn create_session_token(derived_key: &[u8]) -> Result<Token, LinkError> {
12    Token::new(derived_key).map_err(|_| LinkError::CryptoError)
13}
14
15/// Encrypt plaintext for link transmission.
16pub fn link_encrypt(token: &Token, plaintext: &[u8], rng: &mut dyn Rng) -> Vec<u8> {
17    token.encrypt(plaintext, rng)
18}
19
20/// Decrypt ciphertext received on link.
21pub fn link_decrypt(token: &Token, ciphertext: &[u8]) -> Result<Vec<u8>, LinkError> {
22    token.decrypt(ciphertext).map_err(|_| LinkError::CryptoError)
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28    use rns_crypto::FixedRng;
29
30    #[test]
31    fn test_encrypt_decrypt_roundtrip_aes128() {
32        let key = [0x42u8; 32];
33        let token = create_session_token(&key).unwrap();
34        let mut rng = FixedRng::new(&[0xAA; 16]);
35        let plaintext = b"Hello, Link!";
36        let encrypted = link_encrypt(&token, plaintext, &mut rng);
37        let decrypted = link_decrypt(&token, &encrypted).unwrap();
38        assert_eq!(decrypted, plaintext);
39    }
40
41    #[test]
42    fn test_encrypt_decrypt_roundtrip_aes256() {
43        let key = [0x42u8; 64];
44        let token = create_session_token(&key).unwrap();
45        let mut rng = FixedRng::new(&[0xBB; 16]);
46        let plaintext = b"Hello, Link AES-256!";
47        let encrypted = link_encrypt(&token, plaintext, &mut rng);
48        let decrypted = link_decrypt(&token, &encrypted).unwrap();
49        assert_eq!(decrypted, plaintext);
50    }
51
52    #[test]
53    fn test_wrong_key_fails() {
54        let key1 = [0x42u8; 64];
55        let key2 = [0x43u8; 64];
56        let token1 = create_session_token(&key1).unwrap();
57        let token2 = create_session_token(&key2).unwrap();
58        let mut rng = FixedRng::new(&[0xCC; 16]);
59        let encrypted = link_encrypt(&token1, b"secret", &mut rng);
60        assert!(link_decrypt(&token2, &encrypted).is_err());
61    }
62
63    #[test]
64    fn test_invalid_key_length() {
65        let key = [0u8; 48];
66        assert!(create_session_token(&key).is_err());
67    }
68
69    #[test]
70    fn test_mode_detection() {
71        // 32-byte key → AES-128
72        assert!(create_session_token(&[0u8; 32]).is_ok());
73        // 64-byte key → AES-256
74        assert!(create_session_token(&[0u8; 64]).is_ok());
75    }
76}