blob: c6f30dc9411659bfc23a73e3944daae035052a6b [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)]
David Brownc3898d62019-08-05 14:20:02 -060029#[derive(Copy, Clone, Debug, PartialEq, Eq)]
David Brown187dd882017-07-11 11:15:23 -060030#[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 Brownc3898d62019-08-05 14:20:02 -060077#[derive(Debug)]
David Brown187dd882017-07-11 11:15:23 -060078pub struct TlvGen {
David Brown43cda332017-09-01 09:53:23 -060079 flags: u32,
David Brown187dd882017-07-11 11:15:23 -060080 kinds: Vec<TlvKinds>,
David Brown7a81c4b2019-07-29 15:20:21 -060081 /// The total size of the payload.
David Brown187dd882017-07-11 11:15:23 -060082 size: u16,
David Brown7a81c4b2019-07-29 15:20:21 -060083 /// Extra bytes of the TLV that are protected.
84 protect_size: u16,
David Brown4243ab02017-07-11 12:24:23 -060085 payload: Vec<u8>,
David Brown7a81c4b2019-07-29 15:20:21 -060086 dependencies: Vec<Dependency>,
87}
88
David Brownc3898d62019-08-05 14:20:02 -060089#[derive(Debug)]
David Brown7a81c4b2019-07-29 15:20:21 -060090struct Dependency {
91 id: u8,
92 version: ImageVersion,
David Brown187dd882017-07-11 11:15:23 -060093}
94
Fabio Utzig1e48b912018-09-18 09:04:18 -030095pub const AES_SEC_KEY: &[u8; 16] = b"0123456789ABCDEF";
96
David Brown187dd882017-07-11 11:15:23 -060097impl TlvGen {
98 /// Construct a new tlv generator that will only contain a hash of the data.
David Brown7e701d82017-07-11 13:24:25 -060099 #[allow(dead_code)]
David Brown187dd882017-07-11 11:15:23 -0600100 pub fn new_hash_only() -> TlvGen {
101 TlvGen {
David Brown43cda332017-09-01 09:53:23 -0600102 flags: 0,
David Brown187dd882017-07-11 11:15:23 -0600103 kinds: vec![TlvKinds::SHA256],
104 size: 4 + 32,
David Brown7a81c4b2019-07-29 15:20:21 -0600105 protect_size: 0,
David Brown4243ab02017-07-11 12:24:23 -0600106 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600107 dependencies: vec![],
David Brown187dd882017-07-11 11:15:23 -0600108 }
109 }
110
David Brown7e701d82017-07-11 13:24:25 -0600111 #[allow(dead_code)]
112 pub fn new_rsa_pss() -> TlvGen {
113 TlvGen {
David Brown43cda332017-09-01 09:53:23 -0600114 flags: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200115 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048],
116 size: 4 + 32 + 4 + 32 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600117 protect_size: 0,
David Brown7e701d82017-07-11 13:24:25 -0600118 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600119 dependencies: vec![],
David Brown7e701d82017-07-11 13:24:25 -0600120 }
121 }
122
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200123 #[allow(dead_code)]
Fabio Utzig39297432019-05-08 18:51:10 -0300124 pub fn new_rsa3072_pss() -> TlvGen {
125 TlvGen {
126 flags: 0,
127 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA3072],
128 size: 4 + 32 + 4 + 32 + 4 + 384,
David Brown7a81c4b2019-07-29 15:20:21 -0600129 protect_size: 0,
Fabio Utzig39297432019-05-08 18:51:10 -0300130 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600131 dependencies: vec![],
Fabio Utzig39297432019-05-08 18:51:10 -0300132 }
133 }
134
135 #[allow(dead_code)]
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200136 pub fn new_ecdsa() -> TlvGen {
137 TlvGen {
138 flags: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200139 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256],
140 size: 4 + 32 + 4 + 32 + 4 + 72,
David Brown7a81c4b2019-07-29 15:20:21 -0600141 protect_size: 0,
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200142 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600143 dependencies: vec![],
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200144 }
145 }
146
Fabio Utzig1e48b912018-09-18 09:04:18 -0300147 #[allow(dead_code)]
Fabio Utzig97710282019-05-24 17:44:49 -0300148 pub fn new_ed25519() -> TlvGen {
149 TlvGen {
150 flags: 0,
151 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519],
152 size: 4 + 32 + 4 + 32 + 4 + 64,
David Brown7a81c4b2019-07-29 15:20:21 -0600153 protect_size: 0,
Fabio Utzig97710282019-05-24 17:44:49 -0300154 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600155 dependencies: vec![],
Fabio Utzig97710282019-05-24 17:44:49 -0300156 }
157 }
158
159 #[allow(dead_code)]
Fabio Utzig1e48b912018-09-18 09:04:18 -0300160 pub fn new_enc_rsa() -> TlvGen {
161 TlvGen {
162 flags: TlvFlags::ENCRYPTED as u32,
163 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
164 size: 4 + 32 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600165 protect_size: 0,
Fabio Utzig1e48b912018-09-18 09:04:18 -0300166 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600167 dependencies: vec![],
Fabio Utzig1e48b912018-09-18 09:04:18 -0300168 }
169 }
170
171 #[allow(dead_code)]
Fabio Utzig754438d2018-12-14 06:39:58 -0200172 pub fn new_sig_enc_rsa() -> TlvGen {
173 TlvGen {
174 flags: TlvFlags::ENCRYPTED as u32,
175 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048],
176 size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 256,
David Brown7a81c4b2019-07-29 15:20:21 -0600177 protect_size: 0,
Fabio Utzig754438d2018-12-14 06:39:58 -0200178 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600179 dependencies: vec![],
Fabio Utzig754438d2018-12-14 06:39:58 -0200180 }
181 }
182
183 #[allow(dead_code)]
Fabio Utzig1e48b912018-09-18 09:04:18 -0300184 pub fn new_enc_kw() -> TlvGen {
185 TlvGen {
186 flags: TlvFlags::ENCRYPTED as u32,
187 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW128],
188 size: 4 + 32 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600189 protect_size: 0,
Fabio Utzig1e48b912018-09-18 09:04:18 -0300190 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600191 dependencies: vec![],
Fabio Utzig1e48b912018-09-18 09:04:18 -0300192 }
193 }
194
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200195 #[allow(dead_code)]
196 pub fn new_rsa_kw() -> TlvGen {
197 TlvGen {
198 flags: TlvFlags::ENCRYPTED as u32,
199 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW128],
200 size: 4 + 32 + 4 + 32 + 4 + 256 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600201 protect_size: 0,
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200202 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600203 dependencies: vec![],
Fabio Utzig251ef1d2018-12-18 17:20:19 -0200204 }
205 }
206
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200207 #[allow(dead_code)]
208 pub fn new_ecdsa_kw() -> TlvGen {
209 TlvGen {
210 flags: TlvFlags::ENCRYPTED as u32,
211 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW128],
212 size: 4 + 32 + 4 + 32 + 4 + 72 + 4 + 24,
David Brown7a81c4b2019-07-29 15:20:21 -0600213 protect_size: 0,
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200214 payload: vec![],
David Brown7a81c4b2019-07-29 15:20:21 -0600215 dependencies: vec![],
Fabio Utzigb4d20c82018-12-27 16:08:39 -0200216 }
217 }
218
David Brown187dd882017-07-11 11:15:23 -0600219 /// Retrieve the size that the TLV will occupy. This can be called at any time.
220 pub fn get_size(&self) -> u16 {
David Brownf5b33d82017-09-01 10:58:27 -0600221 4 + self.size
David Brown187dd882017-07-11 11:15:23 -0600222 }
David Brown43643dd2019-01-11 15:43:28 -0700223}
224
225impl ManifestGen for TlvGen {
David Brownac46e262019-01-11 15:46:18 -0700226 fn get_magic(&self) -> u32 {
227 0x96f3b83d
228 }
229
David Brown43643dd2019-01-11 15:43:28 -0700230 /// Retrieve the header flags for this configuration. This can be called at any time.
231 fn get_flags(&self) -> u32 {
232 self.flags
233 }
David Brown187dd882017-07-11 11:15:23 -0600234
235 /// Add bytes to the covered hash.
David Brown43643dd2019-01-11 15:43:28 -0700236 fn add_bytes(&mut self, bytes: &[u8]) {
David Brown4243ab02017-07-11 12:24:23 -0600237 self.payload.extend_from_slice(bytes);
David Brown187dd882017-07-11 11:15:23 -0600238 }
239
David Brown7a81c4b2019-07-29 15:20:21 -0600240 fn protect_size(&self) -> u16 {
241 if self.protect_size == 0 {
242 0
243 } else {
244 // Include the protected size, as well as the TLV header.
245 4 + self.protect_size
246 }
247 }
248
249 fn add_dependency(&mut self, id: u8, version: &ImageVersion) {
250 let my_size = 4 + 4 + 8;
251 self.protect_size += my_size;
252 self.size += my_size;
253 self.dependencies.push(Dependency {
254 id: id,
255 version: version.clone(),
256 });
257 }
258
David Brown187dd882017-07-11 11:15:23 -0600259 /// Compute the TLV given the specified block of data.
David Brown43643dd2019-01-11 15:43:28 -0700260 fn make_tlv(self: Box<Self>) -> Vec<u8> {
David Brown187dd882017-07-11 11:15:23 -0600261 let mut result: Vec<u8> = vec![];
262
David Brownf5b33d82017-09-01 10:58:27 -0600263 let size = self.get_size();
264 result.push(0x07);
265 result.push(0x69);
David Brown91d68632019-07-29 14:32:13 -0600266 result.write_u16::<LittleEndian>(size).unwrap();
David Brownf5b33d82017-09-01 10:58:27 -0600267
David Brown7a81c4b2019-07-29 15:20:21 -0600268 for dep in &self.dependencies {
269 result.push(TlvKinds::DEPENDENCY as u8);
270 result.push(0);
271 result.push(12);
272 result.push(0);
273
274 // The dependency.
275 result.push(dep.id);
276 for _ in 0 .. 3 {
277 result.push(0);
278 }
279 result.push(dep.version.major);
280 result.push(dep.version.minor);
281 result.write_u16::<LittleEndian>(dep.version.revision).unwrap();
282 result.write_u32::<LittleEndian>(dep.version.build_num).unwrap();
283 }
284
285 // Ring does the signature itself, which means that it must be
286 // given a full, contiguous payload. Although this does help from
287 // a correct usage perspective, it is fairly stupid from an
288 // efficiency view. If this is shown to be a performance issue
289 // with the tests, the protected data could be appended to the
290 // payload, and then removed after the signature is done. For now,
291 // just make a signed payload.
292 let mut sig_payload = self.payload.clone();
293 if self.protect_size > 0 {
294 assert_eq!(self.protect_size as usize + 4, result.len());
295 sig_payload.extend_from_slice(&result);
296 }
297 let sig_payload = sig_payload;
298
David Brown187dd882017-07-11 11:15:23 -0600299 if self.kinds.contains(&TlvKinds::SHA256) {
David Brown7a81c4b2019-07-29 15:20:21 -0600300 let hash = digest::digest(&digest::SHA256, &sig_payload);
David Brown8054ce22017-07-11 12:12:09 -0600301 let hash = hash.as_ref();
David Brown187dd882017-07-11 11:15:23 -0600302
David Brown8054ce22017-07-11 12:12:09 -0600303 assert!(hash.len() == 32);
David Brown187dd882017-07-11 11:15:23 -0600304 result.push(TlvKinds::SHA256 as u8);
305 result.push(0);
306 result.push(32);
307 result.push(0);
David Brown8054ce22017-07-11 12:12:09 -0600308 result.extend_from_slice(hash);
David Brown187dd882017-07-11 11:15:23 -0600309 }
310
Fabio Utzig39297432019-05-08 18:51:10 -0300311 if self.kinds.contains(&TlvKinds::RSA2048) ||
312 self.kinds.contains(&TlvKinds::RSA3072) {
313
314 let is_rsa2048 = self.kinds.contains(&TlvKinds::RSA2048);
315
David Brown43cda332017-09-01 09:53:23 -0600316 // Output the hash of the public key.
Fabio Utzig39297432019-05-08 18:51:10 -0300317 let hash = if is_rsa2048 {
318 digest::digest(&digest::SHA256, RSA_PUB_KEY)
319 } else {
320 digest::digest(&digest::SHA256, RSA3072_PUB_KEY)
321 };
David Brown43cda332017-09-01 09:53:23 -0600322 let hash = hash.as_ref();
323
324 assert!(hash.len() == 32);
325 result.push(TlvKinds::KEYHASH as u8);
326 result.push(0);
327 result.push(32);
328 result.push(0);
329 result.extend_from_slice(hash);
330
David Brown7e701d82017-07-11 13:24:25 -0600331 // For now assume PSS.
Fabio Utzig39297432019-05-08 18:51:10 -0300332 let key_bytes = if is_rsa2048 {
333 pem::parse(include_bytes!("../../root-rsa-2048.pem").as_ref()).unwrap()
334 } else {
335 pem::parse(include_bytes!("../../root-rsa-3072.pem").as_ref()).unwrap()
336 };
David Brown7e701d82017-07-11 13:24:25 -0600337 assert_eq!(key_bytes.tag, "RSA PRIVATE KEY");
338 let key_bytes = untrusted::Input::from(&key_bytes.contents);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300339 let key_pair = RsaKeyPair::from_der(key_bytes).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600340 let rng = rand::SystemRandom::new();
Fabio Utzig05ab0142018-07-10 09:15:28 -0300341 let mut signature = vec![0; key_pair.public_modulus_len()];
Fabio Utzig39297432019-05-08 18:51:10 -0300342 if is_rsa2048 {
343 assert_eq!(signature.len(), 256);
344 } else {
345 assert_eq!(signature.len(), 384);
346 }
David Brown7a81c4b2019-07-29 15:20:21 -0600347 key_pair.sign(&RSA_PSS_SHA256, &rng, &sig_payload, &mut signature).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600348
Fabio Utzig39297432019-05-08 18:51:10 -0300349 if is_rsa2048 {
350 result.push(TlvKinds::RSA2048 as u8);
351 } else {
352 result.push(TlvKinds::RSA3072 as u8);
353 }
David Brown7e701d82017-07-11 13:24:25 -0600354 result.push(0);
David Brown91d68632019-07-29 14:32:13 -0600355 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
David Brown7e701d82017-07-11 13:24:25 -0600356 result.extend_from_slice(&signature);
357 }
358
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200359 if self.kinds.contains(&TlvKinds::ECDSA256) {
360 let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY);
361 let keyhash = keyhash.as_ref();
362
363 assert!(keyhash.len() == 32);
364 result.push(TlvKinds::KEYHASH as u8);
365 result.push(0);
366 result.push(32);
367 result.push(0);
368 result.extend_from_slice(keyhash);
369
Fabio Utzig05ab0142018-07-10 09:15:28 -0300370 let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap();
371 assert_eq!(key_bytes.tag, "PRIVATE KEY");
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200372
Fabio Utzig05ab0142018-07-10 09:15:28 -0300373 let key_bytes = untrusted::Input::from(&key_bytes.contents);
374 let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_ASN1_SIGNING,
375 key_bytes).unwrap();
376 let rng = rand::SystemRandom::new();
David Brown7a81c4b2019-07-29 15:20:21 -0600377 let payload = untrusted::Input::from(&sig_payload);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300378 let signature = key_pair.sign(&rng, payload).unwrap();
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200379
380 result.push(TlvKinds::ECDSA256 as u8);
381 result.push(0);
Fabio Utzig05ab0142018-07-10 09:15:28 -0300382
383 // signature must be padded...
384 let mut signature = signature.as_ref().to_vec();
385 while signature.len() < 72 {
386 signature.push(0);
387 signature[1] += 1;
388 }
389
David Brown91d68632019-07-29 14:32:13 -0600390 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
Fabio Utzig05ab0142018-07-10 09:15:28 -0300391 result.extend_from_slice(signature.as_ref());
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200392 }
393
Fabio Utzig97710282019-05-24 17:44:49 -0300394 if self.kinds.contains(&TlvKinds::ED25519) {
395 let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY);
396 let keyhash = keyhash.as_ref();
397
398 assert!(keyhash.len() == 32);
399 result.push(TlvKinds::KEYHASH as u8);
400 result.push(0);
401 result.push(32);
402 result.push(0);
403 result.extend_from_slice(keyhash);
404
David Brown7a81c4b2019-07-29 15:20:21 -0600405 let hash = digest::digest(&digest::SHA256, &sig_payload);
Fabio Utzig97710282019-05-24 17:44:49 -0300406 let hash = hash.as_ref();
407 assert!(hash.len() == 32);
408
409 let key_bytes = pem::parse(include_bytes!("../../root-ed25519.pem").as_ref()).unwrap();
410 assert_eq!(key_bytes.tag, "PRIVATE KEY");
411
412 let seed = untrusted::Input::from(&key_bytes.contents[16..48]);
413 let public = untrusted::Input::from(&ED25519_PUB_KEY[12..44]);
414 let key_pair = Ed25519KeyPair::from_seed_and_public_key(seed, public).unwrap();
415 let signature = key_pair.sign(&hash);
416
417 result.push(TlvKinds::ED25519 as u8);
418 result.push(0);
419
420 let signature = signature.as_ref().to_vec();
David Brown91d68632019-07-29 14:32:13 -0600421 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap();
Fabio Utzig97710282019-05-24 17:44:49 -0300422 result.extend_from_slice(signature.as_ref());
423 }
424
Fabio Utzig1e48b912018-09-18 09:04:18 -0300425 if self.kinds.contains(&TlvKinds::ENCRSA2048) {
426 let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem")
427 .as_ref()).unwrap();
428 assert_eq!(key_bytes.tag, "PUBLIC KEY");
429
430 let encbuf = match c::rsa_oaep_encrypt(&key_bytes.contents, AES_SEC_KEY) {
431 Ok(v) => v,
432 Err(_) => panic!("Failed to encrypt secret key"),
433 };
434
435 assert!(encbuf.len() == 256);
436 result.push(TlvKinds::ENCRSA2048 as u8);
437 result.push(0);
438 result.push(0);
439 result.push(1);
440 result.extend_from_slice(&encbuf);
441 }
442
443 if self.kinds.contains(&TlvKinds::ENCKW128) {
444 let key_bytes = base64::decode(
445 include_str!("../../enc-aes128kw.b64").trim()).unwrap();
446
447 let encbuf = match c::kw_encrypt(&key_bytes, AES_SEC_KEY) {
448 Ok(v) => v,
449 Err(_) => panic!("Failed to encrypt secret key"),
450 };
451
452 assert!(encbuf.len() == 24);
453 result.push(TlvKinds::ENCKW128 as u8);
454 result.push(0);
455 result.push(24);
456 result.push(0);
457 result.extend_from_slice(&encbuf);
458 }
459
David Brown187dd882017-07-11 11:15:23 -0600460 result
461 }
462}
David Brown43cda332017-09-01 09:53:23 -0600463
464include!("rsa_pub_key-rs.txt");
Fabio Utzig39297432019-05-08 18:51:10 -0300465include!("rsa3072_pub_key-rs.txt");
Fabio Utzig80fde2f2017-12-05 09:25:31 -0200466include!("ecdsa_pub_key-rs.txt");
Fabio Utzig97710282019-05-24 17:44:49 -0300467include!("ed25519_pub_key-rs.txt");