Skip to main content

osdp/command/
scrypt.rs

1//! `osdp_SCRYPT` (`0x77`) — server cryptogram.
2//!
3//! # Spec: §6.18, Annex D.4
4//!
5//! Body is the 16-byte server cryptogram. Packet carries SCB of type `SCS_13`.
6
7use crate::error::Error;
8use crate::payload_util::require_exact_len;
9use alloc::vec::Vec;
10
11/// `osdp_SCRYPT` body.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct SCrypt {
14    /// Server cryptogram.
15    pub server_cryptogram: [u8; 16],
16}
17
18impl SCrypt {
19    /// New.
20    pub const fn new(c: [u8; 16]) -> Self {
21        Self {
22            server_cryptogram: c,
23        }
24    }
25
26    /// Encode.
27    pub fn encode(&self) -> Result<Vec<u8>, Error> {
28        Ok(self.server_cryptogram.to_vec())
29    }
30
31    /// Decode.
32    pub fn decode(data: &[u8]) -> Result<Self, Error> {
33        require_exact_len(data, 16, 0x77)?;
34        let mut c = [0u8; 16];
35        c.copy_from_slice(data);
36        Ok(Self {
37            server_cryptogram: c,
38        })
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn roundtrip() {
48        let body = SCrypt::new([0x42u8; 16]);
49        let bytes = body.encode().unwrap();
50        assert_eq!(bytes.len(), 16);
51        assert_eq!(SCrypt::decode(&bytes).unwrap(), body);
52    }
53
54    #[test]
55    fn decode_rejects_wrong_length() {
56        assert!(matches!(
57            SCrypt::decode(&[0; 15]),
58            Err(Error::PayloadLength { code: 0x77, .. })
59        ));
60    }
61}