1#![cfg_attr(not(test), no_std)]
22
23#[cfg(all(target_os = "none", feature = "sftp"))]
28pub use sftpserver::run_ota_server;
29#[cfg(all(target_os = "none", feature = "sftp"))]
33mod handler;
34#[cfg(all(target_os = "none", feature = "sftp"))]
36mod sftpserver;
37
38pub mod tlv;
42
43pub use tlv::OtaHeader;
47
48#[cfg(test)]
49mod ota_tlv_tests {
50
51 use crate::OtaHeader;
52 use crate::tlv::*;
53 use sunset::sshwire;
54
55 #[test]
56 fn test_ota_tlv_round_trip() {
57 let variants = [
58 Tlv::FirmwareBlob { size: 1024 },
59 Tlv::Sha256Checksum {
60 checksum: [
61 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
62 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
63 ],
64 },
65 Tlv::OtaType {
66 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
67 },
68 ];
69 for variant in &variants {
70 let mut buffer = [0u8; MAX_TLV_SIZE as usize];
71 let used = sshwire::write_ssh(&mut buffer, variant).expect("Failed to create SSH sink");
72
73 let (decoded, _) =
75 sshwire::read_ssh::<Tlv>(&buffer[..used], None).expect("Failed to decode TLV");
76 match (variant, decoded) {
77 (Tlv::FirmwareBlob { size: s1 }, Tlv::FirmwareBlob { size: s2 }) => {
78 assert_eq!(s1, &s2);
79 }
80 (Tlv::Sha256Checksum { checksum: c1 }, Tlv::Sha256Checksum { checksum: c2 }) => {
81 assert_eq!(c1, &c2);
82 }
83 (Tlv::OtaType { ota_type: o1 }, Tlv::OtaType { ota_type: o2 }) => {
84 assert_eq!(o1, &o2);
85 }
86 _ => panic!("Decoded variant does not match original"),
87 }
88 }
89 }
90
91 #[test]
92 fn deserializing_full_header() {
93 let mut buffer = [0u8; 512];
94 let mut offset = 0;
95
96 let ota_type_tlv = Tlv::OtaType {
97 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
98 };
99 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_type_tlv)
100 .expect("Failed to write OTA Type TLV");
101
102 let ota_checksum = Tlv::Sha256Checksum {
103 checksum: [
104 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
105 24, 25, 26, 27, 28, 29, 30, 31, 32,
106 ],
107 };
108
109 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_checksum)
110 .expect("Failed to write SHA256 Checksum TLV");
111
112 let firmware_blob_tlv = Tlv::FirmwareBlob { size: 2048 };
113 offset += sshwire::write_ssh(&mut buffer[offset..], &firmware_blob_tlv)
114 .expect("Failed to write Firmware Blob TLV");
115
116 let (header, _) =
117 OtaHeader::deserialize(&buffer[..offset]).expect("Failed to deserialize header");
118
119 assert_eq!(header.ota_type, Some(OTA_TYPE_VALUE_SSH_STAMP));
120 assert_eq!(header.firmware_blob_size, Some(2048));
121 assert_eq!(
122 header.sha256_checksum,
123 Some([
124 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
125 24, 25, 26, 27, 28, 29, 30, 31, 32,
126 ])
127 );
128 }
129
130 #[test]
131 fn tlvs_after_firmware_blob_are_ignored() {
132 let mut buffer = [0u8; 512];
133 let mut offset = 0;
134
135 let ota_type_tlv = Tlv::OtaType {
136 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
137 };
138 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_type_tlv)
139 .expect("Failed to write OTA Type TLV");
140
141 let firmware_blob_tlv = Tlv::FirmwareBlob { size: 2048 };
142 offset += sshwire::write_ssh(&mut buffer[offset..], &firmware_blob_tlv)
143 .expect("Failed to write Firmware Blob TLV");
144
145 let ota_checksum = Tlv::Sha256Checksum {
147 checksum: [
148 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
149 24, 25, 26, 27, 28, 29, 30, 31, 32,
150 ],
151 };
152 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_checksum)
153 .expect("Failed to write SHA256 Checksum TLV");
154
155 let (header, _) =
156 OtaHeader::deserialize(&buffer[..offset]).expect("Failed to deserialize header");
157
158 assert_eq!(header.ota_type, Some(OTA_TYPE_VALUE_SSH_STAMP));
159 assert_eq!(header.firmware_blob_size, Some(2048));
160 assert_eq!(header.sha256_checksum, None);
161 }
162
163 #[test]
164 fn ota_type_must_be_first_tlv() {
165 let mut buffer = [0u8; 512];
166 let mut offset = 0;
167
168 let ota_checksum = Tlv::Sha256Checksum {
169 checksum: [
170 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
171 24, 25, 26, 27, 28, 29, 30, 31, 32,
172 ],
173 };
174
175 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_checksum)
176 .expect("Failed to write SHA256 Checksum TLV");
177
178 let ota_type = Tlv::OtaType {
179 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
180 };
181 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_type)
182 .expect("Failed to write OTA Type TLV");
183
184 let firmware_blob_tlv = Tlv::FirmwareBlob { size: 2048 };
185 offset += sshwire::write_ssh(&mut buffer[offset..], &firmware_blob_tlv)
186 .expect("Failed to write Firmware Blob TLV");
187
188 assert!(OtaHeader::deserialize(&buffer[..offset]).is_err());
189 }
190
191 #[test]
192 fn deserializing_header_missing_firmware_blob() {
193 let mut buffer = [0u8; 512];
194 let mut offset = 0;
195
196 let ota_type_tlv = Tlv::OtaType {
197 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
198 };
199 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_type_tlv)
200 .expect("Failed to write OTA Type TLV");
201
202 let ota_checksum = Tlv::Sha256Checksum {
203 checksum: [
204 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
205 24, 25, 26, 27, 28, 29, 30, 31, 32,
206 ],
207 };
208
209 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_checksum)
210 .expect("Failed to write SHA256 Checksum TLV");
211
212 let (header, _) =
213 OtaHeader::deserialize(&buffer[..offset]).expect("Failed to deserialize header");
214
215 assert_eq!(header.ota_type, Some(OTA_TYPE_VALUE_SSH_STAMP));
216 assert_eq!(header.firmware_blob_size, None);
217 assert_eq!(
218 header.sha256_checksum,
219 Some([
220 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
221 24, 25, 26, 27, 28, 29, 30, 31, 32,
222 ])
223 );
224 }
225
226 #[test]
227 fn skipping_unknown_tlv() {
228 let mut buffer = [0u8; 512];
229 let mut offset = 0;
230
231 let ota_type_tlv = Tlv::OtaType {
232 ota_type: OTA_TYPE_VALUE_SSH_STAMP,
233 };
234 offset += sshwire::write_ssh(&mut buffer[offset..], &ota_type_tlv)
235 .expect("Failed to write OTA Type TLV");
236
237 let unknown_type: OtaTlvType = 99;
239 let unknown_type_len: OtaTlvLen = 4;
240 let unknown_value: [u8; 4] = [10, 20, 30, 40];
241
242 offset += sshwire::write_ssh(&mut buffer[offset..], &unknown_type)
243 .expect("Failed to write unknown TLV type");
244 offset += sshwire::write_ssh(&mut buffer[offset..], &unknown_type_len)
245 .expect("Failed to write unknown TLV length");
246 offset += sshwire::write_ssh(&mut buffer[offset..], &unknown_value)
247 .expect("Failed to write unknown TLV value");
248
249 let firmware_blob_tlv = Tlv::FirmwareBlob { size: 2048 };
250 let used = sshwire::write_ssh(&mut buffer[offset..], &firmware_blob_tlv)
251 .expect("Failed to write Firmware Blob TLV");
252 offset += used;
253
254 let (header, _) =
255 OtaHeader::deserialize(&buffer[..offset]).expect("Failed to deserialize header");
256
257 assert_eq!(header.ota_type, Some(OTA_TYPE_VALUE_SSH_STAMP));
258 assert_eq!(header.firmware_blob_size, Some(2048));
259 assert_eq!(header.sha256_checksum, None);
260 }
261
262 }