parsec_interface/operations_protobuf/
convert_psa_verify_hash.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use super::generated_ops::psa_verify_hash::{Operation as OperationProto, Result as ResultProto};
4use crate::operations::psa_verify_hash::{Operation, Result};
5use crate::requests::ResponseStatus;
6use log::error;
7use std::convert::{TryFrom, TryInto};
8use zeroize::Zeroizing;
9
10impl TryFrom<OperationProto> for Operation {
11    type Error = ResponseStatus;
12
13    fn try_from(proto_op: OperationProto) -> std::result::Result<Self, Self::Error> {
14        let hash = Zeroizing::new(proto_op.hash);
15        let signature = Zeroizing::new(proto_op.signature);
16        Ok(Operation {
17            key_name: proto_op.key_name,
18            alg: proto_op
19                .alg
20                .ok_or_else(|| {
21                    error!("The alg field of psa_verify_hash::Operation message is not set (mandatory field).");
22                    ResponseStatus::InvalidEncoding
23                })?
24                .try_into()?,
25            hash,
26            signature,
27        })
28    }
29}
30
31impl TryFrom<Operation> for OperationProto {
32    type Error = ResponseStatus;
33
34    fn try_from(op: Operation) -> std::result::Result<Self, Self::Error> {
35        let alg = Some(op.alg.try_into()?);
36        Ok(OperationProto {
37            key_name: op.key_name,
38            alg,
39            hash: op.hash.to_vec(),
40            signature: op.signature.to_vec(),
41        })
42    }
43}
44
45impl TryFrom<ResultProto> for Result {
46    type Error = ResponseStatus;
47
48    fn try_from(_proto_result: ResultProto) -> std::result::Result<Self, Self::Error> {
49        Ok(Result {})
50    }
51}
52
53impl TryFrom<Result> for ResultProto {
54    type Error = ResponseStatus;
55
56    fn try_from(_result: Result) -> std::result::Result<Self, Self::Error> {
57        Ok(ResultProto {})
58    }
59}
60
61#[cfg(test)]
62mod test {
63    use super::super::generated_ops::psa_algorithm as algorithm_proto;
64    use super::super::generated_ops::psa_verify_hash::{
65        Operation as OperationProto, Result as ResultProto,
66    };
67    use super::super::{Convert, ProtobufConverter};
68    use crate::operations::psa_algorithm::AsymmetricSignature;
69    use crate::operations::psa_verify_hash::{Operation, Result};
70    use crate::operations::{NativeOperation, NativeResult};
71    use crate::requests::{request::RequestBody, response::ResponseBody, Opcode};
72    use std::convert::TryInto;
73
74    static CONVERTER: ProtobufConverter = ProtobufConverter {};
75
76    #[test]
77    fn asym_proto_to_op() {
78        let mut proto: OperationProto = Default::default();
79        let hash = vec![0x11, 0x22, 0x33];
80        let key_name = "test name".to_string();
81        let signature = vec![0x11, 0x22, 0x33];
82        proto.hash = hash.clone();
83        proto.alg = Some(algorithm_proto::algorithm::AsymmetricSignature {
84            variant: Some(
85                algorithm_proto::algorithm::asymmetric_signature::Variant::RsaPkcs1v15Sign(
86                    algorithm_proto::algorithm::asymmetric_signature::RsaPkcs1v15Sign {
87                        hash_alg: Some(algorithm_proto::algorithm::asymmetric_signature::SignHash {
88                            variant: Some(algorithm_proto::algorithm::asymmetric_signature::sign_hash::Variant::Specific(
89                                algorithm_proto::algorithm::Hash::Sha1.into(),
90                            )),
91                        }),
92                    },
93                ),
94            ),
95        });
96        proto.key_name = key_name.clone();
97        proto.signature = signature.clone();
98
99        let op: Operation = proto.try_into().expect("Failed to convert");
100
101        assert_eq!(op.hash, hash.into());
102        assert_eq!(op.key_name, key_name);
103        assert_eq!(op.signature, signature.into());
104    }
105
106    #[test]
107    fn asym_op_to_proto() {
108        let hash = vec![0x11, 0x22, 0x33];
109        let key_name = "test name".to_string();
110        let signature = vec![0x11, 0x22, 0x33];
111
112        let op = Operation {
113            hash: hash.clone().into(),
114            alg: AsymmetricSignature::RsaPkcs1v15SignRaw,
115            key_name: key_name.clone(),
116            signature: signature.clone().into(),
117        };
118
119        let proto: OperationProto = op.try_into().expect("Failed to convert");
120
121        assert_eq!(proto.hash, hash);
122        assert_eq!(proto.key_name, key_name);
123        assert_eq!(proto.signature, signature);
124    }
125
126    #[test]
127    fn asym_proto_to_resp() {
128        let proto: ResultProto = Default::default();
129
130        let _result: Result = proto.try_into().expect("Failed to convert");
131    }
132
133    #[test]
134    fn asym_resp_to_proto() {
135        let result = Result {};
136
137        let _proto: ResultProto = result.try_into().expect("Failed to convert");
138    }
139
140    #[test]
141    fn op_asym_sign_e2e() {
142        let op = Operation {
143            hash: vec![0x11, 0x22, 0x33].into(),
144            alg: AsymmetricSignature::RsaPkcs1v15SignRaw,
145            key_name: "test name".to_string(),
146            signature: vec![0x11, 0x22, 0x33].into(),
147        };
148        let body = CONVERTER
149            .operation_to_body(NativeOperation::PsaVerifyHash(op))
150            .expect("Failed to convert request");
151
152        assert!(CONVERTER
153            .body_to_operation(body, Opcode::PsaVerifyHash)
154            .is_ok());
155    }
156
157    #[test]
158    fn resp_asym_sign_e2e() {
159        let result = Result {};
160        let body = CONVERTER
161            .result_to_body(NativeResult::PsaVerifyHash(result))
162            .expect("Failed to convert request");
163
164        assert!(CONVERTER
165            .body_to_result(body, Opcode::PsaVerifyHash)
166            .is_ok());
167    }
168
169    #[test]
170    fn result_from_mangled_resp_body() {
171        let resp_body =
172            ResponseBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
173        assert!(CONVERTER
174            .body_to_result(resp_body, Opcode::PsaVerifyHash)
175            .is_err());
176    }
177
178    #[test]
179    fn op_from_mangled_req_body() {
180        let req_body =
181            RequestBody::from_bytes(vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]);
182
183        assert!(CONVERTER
184            .body_to_operation(req_body, Opcode::PsaVerifyHash)
185            .is_err());
186    }
187}