acvp_parser/
blkcipher.rs

1use json::JsonValue;
2
3use crate::{
4    parser::{TestCase, TestGroupData, TestResult},
5    util::{Direction, TestType},
6    AcvpError, AcvpResult,
7};
8
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub struct BlockCipher {
11    algorithm: String,
12    test_type: TestType,
13    direction: Direction,
14    tcid: u32,
15    res_json: JsonValue,
16    pub iv: Vec<u8>,
17    pub input: Vec<u8>,
18    pub key: Vec<u8>,
19    pub key1: Vec<u8>,
20    pub key2: Vec<u8>,
21    pub key3: Vec<u8>,
22}
23
24impl TestCase for BlockCipher {
25    fn new(testjson: &str, tgdata: &TestGroupData) -> AcvpResult<Self> {
26        let test = match json::parse(testjson) {
27            Ok(test) => test,
28            Err(_e) => {
29                return Err(AcvpError {
30                    code: -libc::EINVAL,
31                    message: "Failed to parse testcase JSON for SKCipher".to_string(),
32                });
33            }
34        };
35        let tcid = crate::util::get_acvp_u32("tcId", &test)?;
36
37        let mut iv = Vec::new();
38        if test.has_key("iv") {
39            let ivhex = crate::util::get_acvp_str("iv", &test)?;
40            iv = crate::util::hex2bin(&ivhex)?;
41        } else if test.has_key("tweakValue") {
42            let ivhex = crate::util::get_acvp_str("tweakValue", &test)?;
43            iv = crate::util::hex2bin(&ivhex)?;
44        }
45
46        let mut key = Vec::new();
47        let mut key1 = Vec::new();
48        let mut key2 = Vec::new();
49        let mut key3 = Vec::new();
50        if test.has_key("key1") && test.has_key("key2") && test.has_key("key3") {
51            let key1hex = crate::util::get_acvp_str("key1", &test)?;
52            key1 = crate::util::hex2bin(&key1hex)?;
53            key.extend(key1.iter().copied());
54
55            let key2hex = crate::util::get_acvp_str("key2", &test)?;
56            key2 = crate::util::hex2bin(&key2hex)?;
57            key.extend(key2.iter().copied());
58
59            let key3hex = crate::util::get_acvp_str("key3", &test)?;
60            key3 = crate::util::hex2bin(&key3hex)?;
61            key.extend(key3.iter().copied());
62        } else if test.has_key("key") {
63            let keyhex = crate::util::get_acvp_str("key", &test)?;
64            key = crate::util::hex2bin(&keyhex)?;
65        }
66
67        let inphex = match tgdata.direction {
68            Direction::Encrypt => crate::util::get_acvp_str("pt", &test)?,
69            Direction::Decrypt => crate::util::get_acvp_str("ct", &test)?,
70            _ => {
71                return Err(AcvpError {
72                    code: -libc::EINVAL,
73                    message: "Invalid direction for block cipher operaion".to_string(),
74                });
75            }
76        };
77        let input = crate::util::hex2bin(&inphex)?;
78
79        Ok(BlockCipher {
80            algorithm: tgdata.algorithm.to_string(),
81            test_type: tgdata.test_type,
82            direction: tgdata.direction,
83            tcid,
84            res_json: JsonValue::new_object(),
85            iv,
86            input,
87            key,
88            key1,
89            key2,
90            key3,
91        })
92    }
93
94    fn get_result(&self) -> AcvpResult<JsonValue> {
95        if self.res_json.is_empty() {
96            return Err(AcvpError {
97                code: -libc::EINVAL,
98                message: "The result is not yet set, call set_*_result APIs".to_string(),
99            });
100        }
101        Ok(self.res_json.clone())
102    }
103
104    fn dump_result(&self) -> AcvpResult<String> {
105        if self.res_json.is_empty() {
106            return Err(AcvpError {
107                code: -libc::EINVAL,
108                message: "The result is not yet set, call set_*_result APIs".to_string(),
109            });
110        }
111        Ok(self.res_json.dump())
112    }
113
114    fn pretty_result(&self) -> AcvpResult<String> {
115        if self.res_json.is_empty() {
116            return Err(AcvpError {
117                code: -libc::EINVAL,
118                message: "The result is not yet set, call set_*_result APIs".to_string(),
119            });
120        }
121        Ok(self.res_json.pretty(3))
122    }
123}
124
125impl TestResult<Vec<u8>> for BlockCipher {
126    fn set_result(&mut self, res: Vec<u8>) -> AcvpResult<()> {
127        self.set_aft_result(res);
128        Ok(())
129    }
130}
131
132impl TestResult<Vec<BlkCipherMCTOutput>> for BlockCipher {
133    fn set_result(&mut self, res: Vec<BlkCipherMCTOutput>) -> AcvpResult<()> {
134        self.set_mct_result(res)
135    }
136}
137
138#[derive(Debug, Clone)]
139pub struct BlkCipherMCTOutput {
140    pub key: Vec<u8>,
141    pub key1: Vec<u8>,
142    pub key2: Vec<u8>,
143    pub key3: Vec<u8>,
144    pub iv: Vec<u8>,
145    pub inp: Vec<u8>,
146    pub out: Vec<u8>,
147}
148
149impl BlkCipherMCTOutput {
150    pub fn new_aes(key: Vec<u8>, iv: Vec<u8>, inp: Vec<u8>, out: Vec<u8>) -> Self {
151        BlkCipherMCTOutput {
152            key,
153            key1: Vec::new(),
154            key2: Vec::new(),
155            key3: Vec::new(),
156            iv,
157            inp,
158            out,
159        }
160    }
161
162    pub fn new_tdes(
163        key1: Vec<u8>,
164        key2: Vec<u8>,
165        key3: Vec<u8>,
166        iv: Vec<u8>,
167        inp: Vec<u8>,
168        out: Vec<u8>,
169    ) -> Self {
170        BlkCipherMCTOutput {
171            key: Vec::new(),
172            key1,
173            key2,
174            key3,
175            iv,
176            inp,
177            out,
178        }
179    }
180}
181
182impl BlockCipher {
183    pub fn set_aft_result(&mut self, out: Vec<u8>) {
184        let mut res = JsonValue::new_object();
185        res["tcId"] = self.tcid.into();
186        match self.direction {
187            Direction::Decrypt => {
188                res["pt"] = hex::encode(out).to_ascii_uppercase().into();
189            }
190            Direction::Encrypt => {
191                res["ct"] = hex::encode(out).to_ascii_uppercase().into();
192            }
193            _ => {}
194        }
195        self.res_json = res;
196    }
197
198    pub fn set_mct_result(&mut self, outvec: Vec<BlkCipherMCTOutput>) -> AcvpResult<()> {
199        let mut results = JsonValue::new_array();
200        for out in outvec {
201            let mut res = JsonValue::new_object();
202            if self.algorithm.contains("AES") {
203                res["key"] = hex::encode(out.key).to_ascii_uppercase().into();
204            }
205            if !out.iv.is_empty() {
206                res["iv"] = hex::encode(out.iv).to_ascii_uppercase().into();
207            }
208            match self.direction {
209                Direction::Decrypt => {
210                    res["pt"] = hex::encode(out.out).to_ascii_uppercase().into();
211                    res["ct"] = hex::encode(out.inp).to_ascii_uppercase().into();
212                }
213                Direction::Encrypt => {
214                    res["pt"] = hex::encode(out.inp).to_ascii_uppercase().into();
215                    res["ct"] = hex::encode(out.out).to_ascii_uppercase().into();
216                }
217                _ => {}
218            }
219            if self.algorithm.contains("TDES") {
220                res["key1"] = hex::encode(out.key1).to_ascii_uppercase().into();
221                res["key2"] = hex::encode(out.key2).to_ascii_uppercase().into();
222                res["key3"] = hex::encode(out.key3).to_ascii_uppercase().into();
223            }
224            match results.push(res) {
225                Ok(()) => {}
226                Err(_e) => {
227                    return Err(AcvpError {
228                        code: -1,
229                        message: "Unexpected error pushing to JsonValue array".to_string(),
230                    });
231                }
232            }
233        }
234        self.res_json = json::object! {
235            tcId: self.tcid,
236            resultsArray: results
237        };
238        Ok(())
239    }
240}