blob: 43dd2e252d81c9aeacde1ac4eaf10f4c72af9727 [file] [log] [blame]
David Brown187dd882017-07-11 11:15:23 -06001//! TLV Support
2//!
3//! mcuboot images are followed immediately by a list of TLV items that contain integrity
4//! information about the image. Their generation is made a little complicated because the size of
5//! the TLV block is in the image header, which is included in the hash. Since some signatures can
6//! vary in size, we just make them the largest size possible.
7//!
8//! Because of this header, we have to make two passes. The first pass will compute the size of
9//! the TLV, and the second pass will build the data for the TLV.
10
David Brown91d68632019-07-29 14:32:13 -060011use byteorder::{
12 LittleEndian, WriteBytesExt,
13};
David Brown7a81c4b2019-07-29 15:20:21 -060014use crate::image::ImageVersion;
David Brown7e701d82017-07-11 13:24:25 -060015use pem;
Fabio Utzig1e48b912018-09-18 09:04:18 -030016use base64;
Fabio Utzig05ab0142018-07-10 09:15:28 -030017use ring::{digest, rand};
18use ring::signature::{
19 RsaKeyPair,
20 RSA_PSS_SHA256,
21 EcdsaKeyPair,
22 ECDSA_P256_SHA256_ASN1_SIGNING,
Fabio Utzig97710282019-05-24 17:44:49 -030023 Ed25519KeyPair,
Fabio Utzig05ab0142018-07-10 09:15:28 -030024};
David Brown7e701d82017-07-11 13:24:25 -060025use untrusted;
Fabio Utzig80fde2f2017-12-05 09:25:31 -020026use mcuboot_sys::c;
David Brown187dd882017-07-11 11:15:23 -060027
David Brown187dd882017-07-11 11:15:23 -060028#[repr(u8)]
29#[derive(Copy, Clone, PartialEq, Eq)]
30#[allow(dead_code)] // TODO: For now
31pub enum TlvKinds {
David Brown43cda332017-09-01 09:53:23 -060032 KEYHASH = 0x01,
David Brown27648b82017-08-31 10:40:29 -060033 SHA256 = 0x10,
34 RSA2048 = 0x20,
35 ECDSA224 = 0x21,
36 ECDSA256 = 0x22,
Fabio Utzig39297432019-05-08 18:51:10 -030037 RSA3072 = 0x23,
Fabio Utzig97710282019-05-24 17:44:49 -030038 ED25519 = 0x24,
Fabio Utzig1e48b912018-09-18 09:04:18 -030039 ENCRSA2048 = 0x30,
40 ENCKW128 = 0x31,
David Brown7a81c4b2019-07-29 15:20:21 -060041 DEPENDENCY = 0x40,
Fabio Utzig1e48b912018-09-18 09:04:18 -030042}
43
44#[allow(dead_code, non_camel_case_types)]
45pub enum TlvFlags {
46 PIC = 0x01,
47 NON_BOOTABLE = 0x02,
48 ENCRYPTED = 0x04,
49 RAM_LOAD = 0x20,
David Brown187dd882017-07-11 11:15:23 -060050}
51
David Brown43643dd2019-01-11 15:43:28 -070052/// A generator for manifests. The format of the manifest can be either a
53/// traditional "TLV" or a SUIT-style manifest.
54pub trait ManifestGen {
David Brownac46e262019-01-11 15:46:18 -070055 /// Retrieve the header magic value for this manifest type.
56 fn get_magic(&self) -> u32;
57
David Brown43643dd2019-01-11 15:43:28 -070058 /// Retrieve the flags value for this particular manifest type.
59 fn get_flags(&self) -> u32;
60
David Brown7a81c4b2019-07-29 15:20:21 -060061 /// Retrieve the number of bytes of this manifest that is "protected".
62 /// This field is stored in the outside image header instead of the
63 /// manifest header.
64 fn protect_size(&self) -> u16;
65
66 /// Add a dependency on another image.
67 fn add_dependency(&mut self, id: u8, version: &ImageVersion);
68
David Brown43643dd2019-01-11 15:43:28 -070069 /// Add a sequence of bytes to the payload that the manifest is
70 /// protecting.
71 fn add_bytes(&mut self, bytes: &[u8]);
72
73 /// Construct the manifest for this payload.
74 fn make_tlv(self: Box<Self>) -> Vec<u8>;
75}
76
David Brown187dd882017-07-11 11:15:23 -060077pub struct TlvGen {
David Brown43cda332017-09-01 09:53:23 -060078 flags: u32,
David Brown187dd882017-07-11 11:15:23 -060079 kinds: Vec<TlvKinds>,
David Brown7a81c4b2019-07-29 15:20:21 -060080 /// The total size of the payload.
David Brown187dd882017-07-11 11:15:23 -060081 size: u16,
David Brown7a81c4b2019-07-29 15:20:21 -060082 /// Extra bytes of the TLV that are protected.
83 protect_size: u16,
David Brown4243ab02017-07-11 12:24:23 -060084 payload: Vec<u8>,
David Brown7a81c4b2019-07-29 15:20:21 -060085 dependencies: Vec<Dependency>,
86}
87
88struct Dependency {
89 id: u8,
90 version: ImageVersion,
David Brown187dd882017-07-11 11:15:23 -060091}
92
Fabio Utzig1e48b912018-09-18 09:04:18 -030093pub const AES_SEC_KEY: &[u8; 16] = b"0123456789ABCDEF";
94
David Brown187dd882017-07-11 11:15:23 -060095impl TlvGen {
96 /// Construct a new tlv generator that will only contain a hash of the data.
David Brown7e701d82017-07-11 13:24:25 -060097 #[allow(dead_code)]
David Brown187dd882017-07-11 11:15:23 -060098 pub fn new_hash_only() -> TlvGen {
99 TlvGen {
David Brown43cda332017-09-01 09:53:23 -0600100 flags: 0,
David Brown187dd882017-07-11 11:15:23 -0600101 kinds: vec![TlvKinds::SHA256],
102 size: 4 + 32,
David Brown7a81c4b2019-07-29 15:20:21 -0600103 protect_size: 0,
David Brown4243ab02017-07-11 12:24:23 -0600104 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600105 dependencies: vec![],
David Brown187dd882017-07-11 11:15:23 -0600106 }
107 }
108
David Brown7e701d82017-07-11 13:24:25 -0600109 #[allow(dead_code)]
110 pub fn new_rsa_pss() -> TlvGen {
111 TlvGen {
David Brown43cda332017-09-01 09:53:23 -0600112 flags: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200113 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048],
114 size: 4 + 32 + 4 + 32 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600115 protect_size: 0,
David Brown7e701d82017-07-11 13:24:25 -0600116 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600117 dependencies: vec![],
David Brown7e701d82017-07-11 13:24:25 -0600118 }
119 }
120
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200121 #[allow(dead_code)]
Fabio Utzig39297432019-05-08 18:51:10 -0300122 pub fn new_rsa3072_pss() -> TlvGen {
123 TlvGen {
124 flags: 0,
125 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA3072],
126 size: 4 + 32 + 4 + 32 + 4 + 384,
David Brown7a81c4b2019-07-29 15:20:21 -0600127 protect_size: 0,
Fabio Utzig39297432019-05-08 18:51:10 -0300128 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600129 dependencies: vec![],
Fabio Utzig39297432019-05-08 18:51:10 -0300130 }
131 }
132
133 #[allow(dead_code)]
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200134 pub fn new_ecdsa() -> TlvGen {
135 TlvGen {
136 flags: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200137 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256],
138 size: 4 + 32 + 4 + 32 + 4 + 72,
David Brown7a81c4b2019-07-29 15:20:21 -0600139 protect_size: 0,
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200140 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600141 dependencies: vec![],
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200142 }
143 }
144
Fabio Utzig1e48b912018-09-18 09:04:18 -0300145 #[allow(dead_code)]
Fabio Utzig97710282019-05-24 17:44:49 -0300146 pub fn new_ed25519() -> TlvGen {
147 TlvGen {
148 flags: 0,
149 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519],
150 size: 4 + 32 + 4 + 32 + 4 + 64,
David Brown7a81c4b2019-07-29 15:20:21 -0600151 protect_size: 0,
Fabio Utzig97710282019-05-24 17:44:49 -0300152 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600153 dependencies: vec![],
Fabio Utzig97710282019-05-24 17:44:49 -0300154 }
155 }
156
157 #[allow(dead_code)]
Fabio Utzig1e48b912018-09-18 09:04:18 -0300158 pub fn new_enc_rsa() -> TlvGen {
159 TlvGen {
160 flags: TlvFlags::ENCRYPTED as u32,
161 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
162 size: 4 + 32 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600163 protect_size: 0,
Fabio Utzig1e48b912018-09-18 09:04:18 -0300164 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600165 dependencies: vec![],
Fabio Utzig1e48b912018-09-18 09:04:18 -0300166 }
167 }
168
169 #[allow(dead_code)]
Fabio Utzig754438d2018-12-14 06:39:58 -0200170 pub fn new_sig_enc_rsa() -> TlvGen {
171 TlvGen {
172 flags: TlvFlags::ENCRYPTED as u32,
173 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048],
174 size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600175 protect_size: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200176 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600177 dependencies: vec![],
Fabio Utzig754438d2018-12-14 06:39:58 -0200178 }
179 }
180
181 #[allow(dead_code)]
Fabio Utzig1e48b912018-09-18 09:04:18 -0300182 pub fn new_enc_kw() -> TlvGen {
183 TlvGen {
184 flags: TlvFlags::ENCRYPTED as u32,
185 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW128],
186 size: 4 + 32 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600187 protect_size: 0,
Fabio Utzig1e48b912018-09-18 09:04:18 -0300188 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600189 dependencies: vec![],
Fabio Utzig1e48b912018-09-18 09:04:18 -0300190 }
191 }
192
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200193 #[allow(dead_code)]
194 pub fn new_rsa_kw() -> TlvGen {
195 TlvGen {
196 flags: TlvFlags::ENCRYPTED as u32,
197 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW128],
198 size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600199 protect_size: 0,
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200200 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600201 dependencies: vec![],
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200202 }
203 }
204
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200205 #[allow(dead_code)]
206 pub fn new_ecdsa_kw() -> TlvGen {
207 TlvGen {
208 flags: TlvFlags::ENCRYPTED as u32,
209 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW128],
210 size: 4 + 32 + 4 + 32 + 4 + 72 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600211 protect_size: 0,
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200212 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600213 dependencies: vec![],
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200214 }
215 }
216
David Brown187dd882017-07-11 11:15:23 -0600217 /// Retrieve the size that the TLV will occupy. This can be called at any time.
218 pub fn get_size(&self) -> u16 {
David Brownf5b33d82017-09-01 10:58:27 -0600219 4 + self.size
David Brown187dd882017-07-11 11:15:23 -0600220 }
David Brown43643dd2019-01-11 15:43:28 -0700221}
222
223impl ManifestGen for TlvGen {
David Brownac46e262019-01-11 15:46:18 -0700224 fn get_magic(&self) -> u32 {
225 0x96f3b83d
226 }
227
David Brown43643dd2019-01-11 15:43:28 -0700228 /// Retrieve the header flags for this configuration. This can be called at any time.
229 fn get_flags(&self) -> u32 {
230 self.flags
231 }
David Brown187dd882017-07-11 11:15:23 -0600232
233 /// Add bytes to the covered hash.
David Brown43643dd2019-01-11 15:43:28 -0700234 fn add_bytes(&mut self, bytes: &[u8]) {
David Brown4243ab02017-07-11 12:24:23 -0600235 self.payload.extend_from_slice(bytes);
David Brown187dd882017-07-11 11:15:23 -0600236 }
237
David Brown7a81c4b2019-07-29 15:20:21 -0600238 fn protect_size(&self) -> u16 {
239 if self.protect_size == 0 {
240 0
241 } else {
242 // Include the protected size, as well as the TLV header.
243 4 + self.protect_size
244 }
245 }
246
247 fn add_dependency(&mut self, id: u8, version: &ImageVersion) {
248 let my_size = 4 + 4 + 8;
249 self.protect_size += my_size;
250 self.size += my_size;
251 self.dependencies.push(Dependency {
252 id: id,
253 version: version.clone(),
254 });
255 }
256
David Brown187dd882017-07-11 11:15:23 -0600257 /// Compute the TLV given the specified block of data.
David Brown43643dd2019-01-11 15:43:28 -0700258 fn make_tlv(self: Box<Self>) -> Vec<u8> {
David Brown187dd882017-07-11 11:15:23 -0600259 let mut result: Vec<u8> = vec![];
260
David Brownf5b33d82017-09-01 10:58:27 -0600261 let size = self.get_size();
262 result.push(0x07);
263 result.push(0x69);
David Brown91d68632019-07-29 14:32:13 -0600264 result.write_u16::<LittleEndian>(size).unwrap();
David Brownf5b33d82017-09-01 10:58:27 -0600265
David Brown7a81c4b2019-07-29 15:20:21 -0600266 for dep in &self.dependencies {
267 result.push(TlvKinds::DEPENDENCY as u8);
268 result.push(0);
269 result.push(12);
270 result.push(0);
271
272 // The dependency.
273 result.push(dep.id);
274 for _ in 0 .. 3 {
275 result.push(0);
276 }
277 result.push(dep.version.major);
278 result.push(dep.version.minor);
279 result.write_u16::<LittleEndian>(dep.version.revision).unwrap();
280 result.write_u32::<LittleEndian>(dep.version.build_num).unwrap();
281 }
282
283 // Ring does the signature itself, which means that it must be
284 // given a full, contiguous payload. Although this does help from
285 // a correct usage perspective, it is fairly stupid from an
286 // efficiency view. If this is shown to be a performance issue
287 // with the tests, the protected data could be appended to the
288 // payload, and then removed after the signature is done. For now,
289 // just make a signed payload.
290 let mut sig_payload = self.payload.clone();
291 if self.protect_size > 0 {
292 assert_eq!(self.protect_size as usize + 4, result.len());
293 sig_payload.extend_from_slice(&result);
294 }
295 let sig_payload = sig_payload;
296
David Brown187dd882017-07-11 11:15:23 -0600297 if self.kinds.contains(&TlvKinds::SHA256) {
David Brown7a81c4b2019-07-29 15:20:21 -0600298 let hash = digest::digest(&digest::SHA256, &sig_payload);
David Brown8054ce22017-07-11 12:12:09 -0600299 let hash = hash.as_ref();
David Brown187dd882017-07-11 11:15:23 -0600300
David Brown8054ce22017-07-11 12:12:09 -0600301 assert!(hash.len() == 32);
David Brown187dd882017-07-11 11:15:23 -0600302 result.push(TlvKinds::SHA256 as u8);
303 result.push(0);
304 result.push(32);
305 result.push(0);
David Brown8054ce22017-07-11 12:12:09 -0600306 result.extend_from_slice(hash);
David Brown187dd882017-07-11 11:15:23 -0600307 }
308
Fabio Utzig39297432019-05-08 18:51:10 -0300309 if self.kinds.contains(&TlvKinds::RSA2048) ||
310 self.kinds.contains(&TlvKinds::RSA3072) {
311
312 let is_rsa2048 = self.kinds.contains(&TlvKinds::RSA2048);
313
David Brown43cda332017-09-01 09:53:23 -0600314 // Output the hash of the public key.
Fabio Utzig39297432019-05-08 18:51:10 -0300315 let hash = if is_rsa2048 {
316 digest::digest(&digest::SHA256, RSA_PUB_KEY)
317 } else {
318 digest::digest(&digest::SHA256, RSA3072_PUB_KEY)
319 };
David Brown43cda332017-09-01 09:53:23 -0600320 let hash = hash.as_ref();
321
322 assert!(hash.len() == 32);
323 result.push(TlvKinds::KEYHASH as u8);
324 result.push(0);
325 result.push(32);
326 result.push(0);
327 result.extend_from_slice(hash);
328
David Brown7e701d82017-07-11 13:24:25 -0600329 // For now assume PSS.
Fabio Utzig39297432019-05-08 18:51:10 -0300330 let key_bytes = if is_rsa2048 {
331 pem::parse(include_bytes!("../../root-rsa-2048.pem").as_ref()).unwrap()
332 } else {
333 pem::parse(include_bytes!("../../root-rsa-3072.pem").as_ref()).unwrap()
334 };
David Brown7e701d82017-07-11 13:24:25 -0600335 assert_eq!(key_bytes.tag, "RSA PRIVATE KEY");
336 let key_bytes = untrusted::Input::from(&key_bytes.contents);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300337 let key_pair = RsaKeyPair::from_der(key_bytes).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600338 let rng = rand::SystemRandom::new();
Fabio Utzig05ab0142018-07-10 09:15:28 -0300339 let mut signature = vec![0; key_pair.public_modulus_len()];
Fabio Utzig39297432019-05-08 18:51:10 -0300340 if is_rsa2048 {
341 assert_eq!(signature.len(), 256);
342 } else {
343 assert_eq!(signature.len(), 384);
344 }
David Brown7a81c4b2019-07-29 15:20:21 -0600345 key_pair.sign(&RSA_PSS_SHA256, &rng, &sig_payload, &mut signature).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600346
Fabio Utzig39297432019-05-08 18:51:10 -0300347 if is_rsa2048 {
348 result.push(TlvKinds::RSA2048 as u8);
349 } else {
350 result.push(TlvKinds::RSA3072 as u8);
351 }
David Brown7e701d82017-07-11 13:24:25 -0600352 result.push(0);
David Brown91d68632019-07-29 14:32:13 -0600353 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600354 result.extend_from_slice(&signature);
355 }
356
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200357 if self.kinds.contains(&TlvKinds::ECDSA256) {
358 let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY);
359 let keyhash = keyhash.as_ref();
360
361 assert!(keyhash.len() == 32);
362 result.push(TlvKinds::KEYHASH as u8);
363 result.push(0);
364 result.push(32);
365 result.push(0);
366 result.extend_from_slice(keyhash);
367
Fabio Utzig05ab0142018-07-10 09:15:28 -0300368 let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap();
369 assert_eq!(key_bytes.tag, "PRIVATE KEY");
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200370
Fabio Utzig05ab0142018-07-10 09:15:28 -0300371 let key_bytes = untrusted::Input::from(&key_bytes.contents);
372 let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_ASN1_SIGNING,
373 key_bytes).unwrap();
374 let rng = rand::SystemRandom::new();
David Brown7a81c4b2019-07-29 15:20:21 -0600375 let payload = untrusted::Input::from(&sig_payload);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300376 let signature = key_pair.sign(&rng, payload).unwrap();
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200377
378 result.push(TlvKinds::ECDSA256 as u8);
379 result.push(0);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300380
381 // signature must be padded...
382 let mut signature = signature.as_ref().to_vec();
383 while signature.len() < 72 {
384 signature.push(0);
385 signature[1] += 1;
386 }
387
David Brown91d68632019-07-29 14:32:13 -0600388 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
Fabio Utzig05ab0142018-07-10 09:15:28 -0300389 result.extend_from_slice(signature.as_ref());
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200390 }
391
Fabio Utzig97710282019-05-24 17:44:49 -0300392 if self.kinds.contains(&TlvKinds::ED25519) {
393 let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY);
394 let keyhash = keyhash.as_ref();
395
396 assert!(keyhash.len() == 32);
397 result.push(TlvKinds::KEYHASH as u8);
398 result.push(0);
399 result.push(32);
400 result.push(0);
401 result.extend_from_slice(keyhash);
402
David Brown7a81c4b2019-07-29 15:20:21 -0600403 let hash = digest::digest(&digest::SHA256, &sig_payload);
Fabio Utzig97710282019-05-24 17:44:49 -0300404 let hash = hash.as_ref();
405 assert!(hash.len() == 32);
406
407 let key_bytes = pem::parse(include_bytes!("../../root-ed25519.pem").as_ref()).unwrap();
408 assert_eq!(key_bytes.tag, "PRIVATE KEY");
409
410 let seed = untrusted::Input::from(&key_bytes.contents[16..48]);
411 let public = untrusted::Input::from(&ED25519_PUB_KEY[12..44]);
412 let key_pair = Ed25519KeyPair::from_seed_and_public_key(seed, public).unwrap();
413 let signature = key_pair.sign(&hash);
414
415 result.push(TlvKinds::ED25519 as u8);
416 result.push(0);
417
418 let signature = signature.as_ref().to_vec();
David Brown91d68632019-07-29 14:32:13 -0600419 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
Fabio Utzig97710282019-05-24 17:44:49 -0300420 result.extend_from_slice(signature.as_ref());
421 }
422
Fabio Utzig1e48b912018-09-18 09:04:18 -0300423 if self.kinds.contains(&TlvKinds::ENCRSA2048) {
424 let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem")
425 .as_ref()).unwrap();
426 assert_eq!(key_bytes.tag, "PUBLIC KEY");
427
428 let encbuf = match c::rsa_oaep_encrypt(&key_bytes.contents, AES_SEC_KEY) {
429 Ok(v) => v,
430 Err(_) => panic!("Failed to encrypt secret key"),
431 };
432
433 assert!(encbuf.len() == 256);
434 result.push(TlvKinds::ENCRSA2048 as u8);
435 result.push(0);
436 result.push(0);
437 result.push(1);
438 result.extend_from_slice(&encbuf);
439 }
440
441 if self.kinds.contains(&TlvKinds::ENCKW128) {
442 let key_bytes = base64::decode(
443 include_str!("../../enc-aes128kw.b64").trim()).unwrap();
444
445 let encbuf = match c::kw_encrypt(&key_bytes, AES_SEC_KEY) {
446 Ok(v) => v,
447 Err(_) => panic!("Failed to encrypt secret key"),
448 };
449
450 assert!(encbuf.len() == 24);
451 result.push(TlvKinds::ENCKW128 as u8);
452 result.push(0);
453 result.push(24);
454 result.push(0);
455 result.extend_from_slice(&encbuf);
456 }
457
David Brown187dd882017-07-11 11:15:23 -0600458 result
459 }
460}
David Brown43cda332017-09-01 09:53:23 -0600461
462include!("rsa_pub_key-rs.txt");
Fabio Utzig39297432019-05-08 18:51:10 -0300463include!("rsa3072_pub_key-rs.txt");
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200464include!("ecdsa_pub_key-rs.txt");
Fabio Utzig97710282019-05-24 17:44:49 -0300465include!("ed25519_pub_key-rs.txt");