acvp_parser/
util.rs

1use json::JsonValue;
2
3use crate::{AcvpError, AcvpResult};
4
5const HASHES: &[&str; 11] = &[
6    "SHA-1",
7    "SHA2-224",
8    "SHA2-256",
9    "SHA2-384",
10    "SHA2-512",
11    "SHA3-224",
12    "SHA3-256",
13    "SHA3-384",
14    "SHA3-512",
15    "SHAKE-128",
16    "SHAKE-256",
17];
18
19const BLKCIPHERS: &[&str; 8] = &[
20    "ACVP-AES-CBC",
21    "ACVP-AES-CTR",
22    "ACVP-AES-ECB",
23    "ACVP-AES-GCM",
24    "ACVP-TDES-ECB",
25    "ACVP-TDES-CBC",
26    "ACVP-TDES-CTR",
27    "ACVP-AES-XTS",
28];
29
30const MACS: &[&str; 14] = &[
31    "HMAC-SHA-1",
32    "HMAC-SHA2-224",
33    "HMAC-SHA2-256",
34    "HMAC-SHA2-384",
35    "HMAC-SHA2-512",
36    "HMAC-SHA3-224",
37    "HMAC-SHA3-256",
38    "HMAC-SHA3-384",
39    "HMAC-SHA3-512",
40    "CMAC-AES",
41    "CMAC-TDES",
42    "ACVP-AES-GCM",
43    "ACVP-AES-GMAC",
44    "ACVP-AES-CCM",
45];
46
47const RNGS: &[&str; 3] = &["hashDRBG", "ctrDRBG", "hmacDRBG"];
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum AcvpAlgorithm {
51    Hash,
52    MsgAuth,
53    BlockCipher,
54    Rng,
55    Nil,
56}
57
58impl AcvpAlgorithm {
59    pub fn alg_type(alg: &str) -> AcvpResult<Self> {
60        if str_lookup(alg, HASHES) {
61            return Ok(Self::Hash);
62        }
63        if str_lookup(alg, MACS) {
64            return Ok(Self::MsgAuth);
65        }
66        if str_lookup(alg, BLKCIPHERS) {
67            return Ok(Self::BlockCipher);
68        }
69        if str_lookup(alg, RNGS) {
70            return Ok(Self::Rng);
71        }
72        Err(AcvpError {
73            code: -libc::EINVAL,
74            message: format!("Uknown type for algorithm '{}'", alg),
75        })
76    }
77}
78
79#[derive(Debug, Clone, Copy, Eq, PartialEq)]
80pub enum TestType {
81    AFT,
82    CTR,
83    MCT,
84    LDT,
85    Nil,
86}
87
88impl TestType {
89    pub fn from_string(ttype: &str) -> AcvpResult<Self> {
90        let test_type = match ttype {
91            "AFT" => TestType::AFT,
92            "CTR" => TestType::CTR,
93            "MCT" => TestType::MCT,
94            "LDT" => TestType::LDT,
95            _ => {
96                return Err(AcvpError {
97                    code: -libc::EINVAL,
98                    message: format!("Invalid test type '{}'", ttype),
99                });
100            }
101        };
102        Ok(test_type)
103    }
104}
105
106#[derive(Debug, Clone, Copy, Eq, PartialEq)]
107pub enum Direction {
108    Encrypt,
109    Decrypt,
110    Generate,
111    Verify,
112    Nil,
113}
114
115impl Direction {
116    pub fn from_string(direction: &str) -> AcvpResult<Self> {
117        let dir = match direction {
118            "encrypt" => Direction::Encrypt,
119            "decrypt" => Direction::Decrypt,
120            "gen" => Direction::Generate,
121            "ver" => Direction::Verify,
122            _ => {
123                return Err(AcvpError {
124                    code: -libc::EINVAL,
125                    message: format!("Invalid direction '{}'", direction),
126                });
127            }
128        };
129        Ok(dir)
130    }
131}
132
133#[derive(Debug, Clone, Copy, Eq, PartialEq)]
134pub enum IVMode {
135    Internal,
136    External,
137    Nil,
138}
139
140impl IVMode {
141    pub fn from_string(mode: &str) -> AcvpResult<Self> {
142        let ivmode = match mode {
143            "internal" => IVMode::Internal,
144            "external" => IVMode::External,
145            _ => {
146                return Err(AcvpError {
147                    code: -libc::EINVAL,
148                    message: format!("Invalid IVGenMode '{}'", mode),
149                });
150            }
151        };
152        Ok(ivmode)
153    }
154}
155
156fn str_lookup(key: &str, arr: &[&str]) -> bool {
157    if let Some(_str) = arr.iter().find(|&s| *s == key) {
158        return true;
159    }
160    false
161}
162
163pub fn get_acvp_str(key: &str, json: &JsonValue) -> AcvpResult<String> {
164    let value = match json[key].as_str() {
165        Some(val) => val,
166        None => {
167            return Err(AcvpError {
168                code: -libc::EINVAL,
169                message: format!("Failed to obtain str value associated with key '{}'", key,),
170            });
171        }
172    };
173    Ok(value.to_string())
174}
175
176pub fn get_acvp_u32(key: &str, json: &JsonValue) -> AcvpResult<u32> {
177    let value = match json[key].as_u32() {
178        Some(val) => val,
179        None => {
180            return Err(AcvpError {
181                code: -libc::EINVAL,
182                message: format!("Failed to obtain u32 value associated with key '{}'", key,),
183            });
184        }
185    };
186    Ok(value)
187}
188
189pub fn get_acvp_bool(key: &str, json: &JsonValue) -> AcvpResult<bool> {
190    let value = match json[key].as_bool() {
191        Some(val) => val,
192        None => {
193            return Err(AcvpError {
194                code: -libc::EINVAL,
195                message: format!(
196                    "Failed to obtain boolean value associated with key '{}'",
197                    key,
198                ),
199            });
200        }
201    };
202    Ok(value)
203}
204
205pub(crate) fn hex2bin(hex: &str) -> AcvpResult<Vec<u8>> {
206    let bin = match hex::decode(hex) {
207        Ok(bin) => bin,
208        Err(_e) => {
209            return Err(AcvpError {
210                code: -libc::EINVAL,
211                message: format!("Invalid hex string '{}'", hex),
212            });
213        }
214    };
215    Ok(bin)
216}
217
218pub fn get_algorithm_type(vector: &str) -> AcvpResult<AcvpAlgorithm> {
219    let vec = match json::parse(vector) {
220        Ok(vec) => vec,
221        Err(_e) => {
222            return Err(AcvpError {
223                code: -libc::EINVAL,
224                message: "Invalid input vector, failed to get algorithm type".to_string(),
225            });
226        }
227    };
228
229    let mut alg_type = AcvpAlgorithm::Nil;
230    for v in vec.members() {
231        if v.has_key("algorithm") {
232            let alg = get_acvp_str("algorithm", v)?;
233            alg_type = AcvpAlgorithm::alg_type(&alg)?;
234        }
235    }
236    if alg_type == AcvpAlgorithm::Nil {
237        return Err(AcvpError {
238            code: -libc::EINVAL,
239            message: "No 'algorithm' key present in input vector".to_string(),
240        });
241    }
242
243    Ok(alg_type)
244}