skf_api/native/
helper.rs

1use crate::native::types::{
2    DeviceInfo, ECCCipherBlob, ECCPrivateKeyBlob, ECCPublicKeyBlob, ECCSignatureBlob, Version, BYTE,
3};
4
5impl Default for DeviceInfo {
6    fn default() -> Self {
7        Self {
8            version: Version::default(),
9            manufacturer: [0; 64],
10            issuer: [0; 64],
11            label: [0; 32],
12            serial_number: [0; 32],
13            hw_version: Version::default(),
14            firmware_version: Version::default(),
15            alg_sym_cap: 0,
16            alg_asym_cap: 0,
17            alg_hash_cap: 0,
18            dev_auth_alg_id: 0,
19            total_space: 0,
20            free_space: 0,
21            max_ecc_buffer_size: 0,
22            max_buffer_size: 0,
23            reserved: [0; 64],
24        }
25    }
26}
27
28impl ECCPublicKeyBlob {
29    /// crate `ECCPublicKeyBlob` with 256 bit x and y
30    /// ## Panics
31    /// this function will panic if `x.len() != 32 || y.len() != 32`
32    pub fn new_256(x: &[u8], y: &[u8]) -> Self {
33        if x.len() != 32 || y.len() != 32 {
34            panic!("x.len() != 32 || y.len() != 32");
35        }
36        let mut xc = vec![0u8 as BYTE; 32];
37        xc.extend(x);
38        let mut yc = vec![0u8 as BYTE; 32];
39        yc.extend(y);
40        Self {
41            bit_len: 256,
42            x_coordinate: xc.try_into().unwrap(),
43            y_coordinate: yc.try_into().unwrap(),
44        }
45    }
46    pub fn x_value(&self) -> &[u8] {
47        &self.x_coordinate[self.bit_len as usize / 8..]
48    }
49    pub fn y_value(&self) -> &[u8] {
50        &self.y_coordinate[self.bit_len as usize / 8..]
51    }
52}
53impl Default for ECCPublicKeyBlob {
54    fn default() -> Self {
55        Self::new_256(&[0u8; 32], &[0u8; 32])
56    }
57}
58impl ECCPrivateKeyBlob {
59    /// crate `ECCPrivateKeyBlob` with 256 key
60    /// ## Panics
61    /// this function will panic if `key.len() != 32`
62    pub fn new_256(key: &[u8]) -> Self {
63        if key.len() != 32 {
64            panic!("key.len() != 32");
65        }
66        let mut k = vec![0u8 as BYTE; 32];
67        k.extend(key);
68        Self {
69            bit_len: 256,
70            private_key: k.try_into().unwrap(),
71        }
72    }
73}
74impl Default for ECCPrivateKeyBlob {
75    fn default() -> Self {
76        Self::new_256(&[0u8; 32])
77    }
78}
79impl ECCCipherBlob {
80    /// cipher filed offset in ECCCipherBlob
81    pub const CIPHER_INDEX: usize = std::mem::size_of::<Self>() - 1;
82
83    /// The size of ECCCipherBlob,include dynamic size of cipher
84    pub fn size_of(cipher_len: usize) -> usize {
85        Self::CIPHER_INDEX + cipher_len
86    }
87
88    /// dynamic size of ECCCipherBlob
89    #[inline]
90    pub fn dst_size(&self) -> usize {
91        Self::CIPHER_INDEX + self.cipher_len as usize
92    }
93
94    /// raw pointer of cipher filed
95    pub fn cipher_ptr(&self) -> *const BYTE {
96        self.cipher.as_ptr() as *const BYTE
97    }
98
99    /// raw bytes of ECCCipherBlob,include dynamic size of cipher
100    ///
101    /// # Safety
102    ///
103    /// This function will copy `cipher_len` bytes data from `cipher` pointer
104    pub unsafe fn raw_bytes(&self) -> Vec<u8> {
105        let mut v: Vec<u8> = Vec::with_capacity(self.dst_size());
106        unsafe {
107            std::ptr::copy(
108                self.x_coordinate.as_ptr(),
109                v.as_mut_ptr(),
110                Self::CIPHER_INDEX,
111            );
112            std::ptr::copy(
113                self.cipher.as_ptr(),
114                v.as_mut_ptr().add(Self::CIPHER_INDEX),
115                self.cipher_len as usize,
116            );
117            v.set_len(self.dst_size());
118        }
119        v
120    }
121}
122
123impl Default for ECCSignatureBlob {
124    fn default() -> Self {
125        Self {
126            r: [0u8; 64],
127            s: [0u8; 64],
128        }
129    }
130}
131#[cfg(test)]
132mod test {
133    use crate::native::types::{
134        ECCCipherBlob, BYTE, ECC_MAX_X_COORDINATE_BITS_LEN, ECC_MAX_Y_COORDINATE_BITS_LEN, ULONG,
135    };
136
137    #[test]
138    fn cipher_blob_layout_test() {
139        #[derive(Debug, Copy, Clone)]
140        #[repr(C, packed(1))]
141        struct SizedBlob<const SIZE: usize> {
142            pub x_coordinate: [BYTE; ECC_MAX_X_COORDINATE_BITS_LEN / 8],
143            pub y_coordinate: [BYTE; ECC_MAX_Y_COORDINATE_BITS_LEN / 8],
144            pub hash: [BYTE; 32],
145            pub cipher_len: ULONG,
146            pub cipher: [BYTE; SIZE],
147        }
148
149        let x = SizedBlob::<100> {
150            x_coordinate: [1u8; 64],
151            y_coordinate: [2u8; 64],
152            hash: [3u8; 32],
153            cipher_len: 100,
154            cipher: [4u8; 100],
155        };
156        let blob: *const SizedBlob<100> = &x;
157        let blob = unsafe { &*(blob as *const ECCCipherBlob) };
158
159        assert_eq!(blob.x_coordinate, [1u8; 64]);
160        assert_eq!(blob.y_coordinate, [2u8; 64]);
161        assert_eq!(blob.hash, [3u8; 32]);
162        assert_eq!(
163            unsafe { std::ptr::addr_of!(blob.cipher_len).read_unaligned() },
164            100
165        );
166        assert_eq!(blob.cipher, [4u8; 1]);
167
168        let bytes = unsafe { blob.raw_bytes() };
169        assert_eq!(bytes.len(), blob.dst_size());
170        println!("raw bytes of ECCCipherBlob = {:?}", bytes);
171    }
172}