/src/spdm-rs/spdmlib/src/message/psk_finish.rs
Line | Count | Source |
1 | | // Copyright (c) 2020 Intel Corporation |
2 | | // |
3 | | // SPDX-License-Identifier: Apache-2.0 or MIT |
4 | | |
5 | | use super::SpdmVersion; |
6 | | use crate::common::opaque::SpdmOpaqueStruct; |
7 | | use crate::common::spdm_codec::SpdmCodec; |
8 | | use crate::error::SPDM_STATUS_BUFFER_FULL; |
9 | | use crate::protocol::SpdmDigestStruct; |
10 | | use crate::{common, error::SpdmStatus}; |
11 | | use codec::{Codec, Reader, Writer}; |
12 | | |
13 | | #[derive(Debug, Clone, Default)] |
14 | | pub struct SpdmPskFinishRequestPayload { |
15 | | pub verify_data: SpdmDigestStruct, |
16 | | pub opaque: SpdmOpaqueStruct, // Spdm 1.4 |
17 | | } |
18 | | |
19 | | impl SpdmCodec for SpdmPskFinishRequestPayload { |
20 | 0 | fn spdm_encode( |
21 | 0 | &self, |
22 | 0 | context: &mut common::SpdmContext, |
23 | 0 | bytes: &mut Writer, |
24 | 0 | ) -> Result<usize, SpdmStatus> { |
25 | 0 | let mut cnt = 0usize; |
26 | 0 | cnt += 0u8.encode(bytes).map_err(|_| SPDM_STATUS_BUFFER_FULL)?; // param1 |
27 | 0 | cnt += 0u8.encode(bytes).map_err(|_| SPDM_STATUS_BUFFER_FULL)?; // param2 |
28 | 0 | if context.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion14 { |
29 | 0 | cnt += self.opaque.spdm_encode(context, bytes)?; |
30 | 0 | } |
31 | 0 | cnt += self.verify_data.spdm_encode(context, bytes)?; |
32 | 0 | Ok(cnt) |
33 | 0 | } |
34 | | |
35 | 0 | fn spdm_read( |
36 | 0 | context: &mut common::SpdmContext, |
37 | 0 | r: &mut Reader, |
38 | 0 | ) -> Option<SpdmPskFinishRequestPayload> { |
39 | 0 | u8::read(r)?; // param1 |
40 | 0 | u8::read(r)?; // param2 |
41 | 0 | let mut opaque = SpdmOpaqueStruct::default(); |
42 | 0 | if context.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion14 { |
43 | 0 | opaque = SpdmOpaqueStruct::spdm_read(context, r)?; |
44 | 0 | } |
45 | 0 | let verify_data = SpdmDigestStruct::spdm_read(context, r)?; |
46 | | |
47 | 0 | Some(SpdmPskFinishRequestPayload { |
48 | 0 | verify_data, |
49 | 0 | opaque, |
50 | 0 | }) |
51 | 0 | } |
52 | | } |
53 | | |
54 | | #[derive(Debug, Clone, Default)] |
55 | | pub struct SpdmPskFinishResponsePayload { |
56 | | pub opaque: SpdmOpaqueStruct, // Spdm 1.4 |
57 | | } |
58 | | |
59 | | impl SpdmCodec for SpdmPskFinishResponsePayload { |
60 | 0 | fn spdm_encode( |
61 | 0 | &self, |
62 | 0 | context: &mut common::SpdmContext, |
63 | 0 | bytes: &mut Writer, |
64 | 0 | ) -> Result<usize, SpdmStatus> { |
65 | 0 | let mut cnt = 0usize; |
66 | 0 | cnt += 0u8.encode(bytes).map_err(|_| SPDM_STATUS_BUFFER_FULL)?; // param1 |
67 | 0 | cnt += 0u8.encode(bytes).map_err(|_| SPDM_STATUS_BUFFER_FULL)?; // param2 |
68 | 0 | if context.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion14 { |
69 | 0 | cnt += self.opaque.spdm_encode(context, bytes)?; |
70 | 0 | } |
71 | 0 | Ok(cnt) |
72 | 0 | } |
73 | | |
74 | 0 | fn spdm_read( |
75 | 0 | context: &mut common::SpdmContext, |
76 | 0 | r: &mut Reader, |
77 | 0 | ) -> Option<SpdmPskFinishResponsePayload> { |
78 | 0 | u8::read(r)?; // param1 |
79 | 0 | u8::read(r)?; // param2 |
80 | 0 | let mut opaque = SpdmOpaqueStruct::default(); |
81 | 0 | if context.negotiate_info.spdm_version_sel >= SpdmVersion::SpdmVersion14 { |
82 | 0 | opaque = SpdmOpaqueStruct::spdm_read(context, r)?; |
83 | 0 | } |
84 | | |
85 | 0 | Some(SpdmPskFinishResponsePayload { opaque }) |
86 | 0 | } |
87 | | } |
88 | | |
89 | | #[cfg(test)] |
90 | | #[path = "mod_test.common.inc.rs"] |
91 | | mod testlib; |
92 | | |
93 | | #[cfg(test)] |
94 | | mod tests { |
95 | | use super::*; |
96 | | use crate::common::{SpdmConfigInfo, SpdmContext, SpdmProvisionInfo, MAX_SPDM_OPAQUE_SIZE}; |
97 | | use crate::protocol::*; |
98 | | use testlib::{create_spdm_context, DeviceIO, TransportEncap}; |
99 | | extern crate alloc; |
100 | | use alloc::boxed::Box; |
101 | | |
102 | | #[test] |
103 | | fn test_case0_spdm_psk_finish_request_payload() { |
104 | | let u8_slice = &mut [0u8; 2 + SPDM_MAX_HASH_SIZE]; |
105 | | let mut writer = Writer::init(u8_slice); |
106 | | let value = SpdmPskFinishRequestPayload { |
107 | | verify_data: SpdmDigestStruct { |
108 | | data_size: SPDM_MAX_HASH_SIZE as u16, |
109 | | data: Box::new([100u8; SPDM_MAX_HASH_SIZE]), |
110 | | }, |
111 | | opaque: SpdmOpaqueStruct { |
112 | | data_size: MAX_SPDM_OPAQUE_SIZE as u16, |
113 | | data: [100u8; MAX_SPDM_OPAQUE_SIZE], |
114 | | }, |
115 | | }; |
116 | | |
117 | | create_spdm_context!(context); |
118 | | |
119 | | context.negotiate_info.base_hash_sel = SpdmBaseHashAlgo::TPM_ALG_SHA_512; |
120 | | |
121 | | assert!(value.spdm_encode(&mut context, &mut writer).is_ok()); |
122 | | let mut reader = Reader::init(u8_slice); |
123 | | assert_eq!(2 + SPDM_MAX_HASH_SIZE, reader.left()); |
124 | | let psk_finish_request = |
125 | | SpdmPskFinishRequestPayload::spdm_read(&mut context, &mut reader).unwrap(); |
126 | | |
127 | | assert_eq!( |
128 | | psk_finish_request.verify_data.data_size, |
129 | | SHA512_DIGEST_SIZE as u16 |
130 | | ); |
131 | | for i in 0..SHA512_DIGEST_SIZE { |
132 | | assert_eq!(psk_finish_request.verify_data.data[i], 100u8); |
133 | | } |
134 | | assert_eq!(0, reader.left()); |
135 | | } |
136 | | #[test] |
137 | | fn test_case0_spdm_psk_finish_response_payload() { |
138 | | let u8_slice = &mut [0u8; 2]; |
139 | | let mut writer = Writer::init(u8_slice); |
140 | | let value = SpdmPskFinishResponsePayload { |
141 | | opaque: SpdmOpaqueStruct { |
142 | | data_size: MAX_SPDM_OPAQUE_SIZE as u16, |
143 | | data: [100u8; MAX_SPDM_OPAQUE_SIZE], |
144 | | }, |
145 | | }; |
146 | | |
147 | | create_spdm_context!(context); |
148 | | |
149 | | assert!(value.spdm_encode(&mut context, &mut writer).is_ok()); |
150 | | let mut reader = Reader::init(u8_slice); |
151 | | SpdmPskFinishResponsePayload::spdm_read(&mut context, &mut reader); |
152 | | } |
153 | | } |