1 // Copyright (c) 2017-2020 Linaro LTD 2 // Copyright (c) 2017-2020 JUUL Labs 3 // Copyright (c) 2021 Arm Limited 4 // 5 // SPDX-License-Identifier: Apache-2.0 6 7 //! TLV Support 8 //! 9 //! mcuboot images are followed immediately by a list of TLV items that contain integrity 10 //! information about the image. Their generation is made a little complicated because the size of 11 //! the TLV block is in the image header, which is included in the hash. Since some signatures can 12 //! vary in size, we just make them the largest size possible. 13 //! 14 //! Because of this header, we have to make two passes. The first pass will compute the size of 15 //! the TLV, and the second pass will build the data for the TLV. 16 17 use byteorder::{ 18 LittleEndian, WriteBytesExt, 19 }; 20 use crate::image::ImageVersion; 21 use log::info; 22 use ring::{digest, rand, agreement, hkdf, hmac}; 23 use ring::rand::SecureRandom; 24 use ring::signature::{ 25 RsaKeyPair, 26 RSA_PSS_SHA256, 27 EcdsaKeyPair, 28 ECDSA_P256_SHA256_ASN1_SIGNING, 29 Ed25519KeyPair, 30 }; 31 use aes_ctr::{ 32 Aes128Ctr, 33 Aes256Ctr, 34 stream_cipher::{ 35 generic_array::GenericArray, 36 NewStreamCipher, 37 SyncStreamCipher, 38 }, 39 }; 40 use mcuboot_sys::c; 41 use typenum::{U16, U32}; 42 43 #[repr(u16)] 44 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 45 #[allow(dead_code)] // TODO: For now 46 pub enum TlvKinds { 47 KEYHASH = 0x01, 48 SHA256 = 0x10, 49 RSA2048 = 0x20, 50 ECDSA224 = 0x21, 51 ECDSA256 = 0x22, 52 RSA3072 = 0x23, 53 ED25519 = 0x24, 54 ENCRSA2048 = 0x30, 55 ENCKW = 0x31, 56 ENCEC256 = 0x32, 57 ENCX25519 = 0x33, 58 DEPENDENCY = 0x40, 59 } 60 61 #[allow(dead_code, non_camel_case_types)] 62 pub enum TlvFlags { 63 PIC = 0x01, 64 NON_BOOTABLE = 0x02, 65 ENCRYPTED_AES128 = 0x04, 66 RAM_LOAD = 0x20, 67 ENCRYPTED_AES256 = 0x08, 68 } 69 70 /// A generator for manifests. The format of the manifest can be either a 71 /// traditional "TLV" or a SUIT-style manifest. 72 pub trait ManifestGen { 73 /// Retrieve the header magic value for this manifest type. get_magic(&self) -> u3274 fn get_magic(&self) -> u32; 75 76 /// Retrieve the flags value for this particular manifest type. get_flags(&self) -> u3277 fn get_flags(&self) -> u32; 78 79 /// Retrieve the number of bytes of this manifest that is "protected". 80 /// This field is stored in the outside image header instead of the 81 /// manifest header. protect_size(&self) -> u1682 fn protect_size(&self) -> u16; 83 84 /// Add a dependency on another image. add_dependency(&mut self, id: u8, version: &ImageVersion)85 fn add_dependency(&mut self, id: u8, version: &ImageVersion); 86 87 /// Add a sequence of bytes to the payload that the manifest is 88 /// protecting. add_bytes(&mut self, bytes: &[u8])89 fn add_bytes(&mut self, bytes: &[u8]); 90 91 /// Set an internal flag indicating that the next `make_tlv` should 92 /// corrupt the signature. corrupt_sig(&mut self)93 fn corrupt_sig(&mut self); 94 95 /// Construct the manifest for this payload. make_tlv(self: Box<Self>) -> Vec<u8>96 fn make_tlv(self: Box<Self>) -> Vec<u8>; 97 98 /// Generate a new encryption random key generate_enc_key(&mut self)99 fn generate_enc_key(&mut self); 100 101 /// Return the current encryption key get_enc_key(&self) -> Vec<u8>102 fn get_enc_key(&self) -> Vec<u8>; 103 } 104 105 #[derive(Debug, Default)] 106 pub struct TlvGen { 107 flags: u32, 108 kinds: Vec<TlvKinds>, 109 payload: Vec<u8>, 110 dependencies: Vec<Dependency>, 111 enc_key: Vec<u8>, 112 /// Should this signature be corrupted. 113 gen_corrupted: bool, 114 } 115 116 #[derive(Debug)] 117 struct Dependency { 118 id: u8, 119 version: ImageVersion, 120 } 121 122 impl TlvGen { 123 /// Construct a new tlv generator that will only contain a hash of the data. 124 #[allow(dead_code)] new_hash_only() -> TlvGen125 pub fn new_hash_only() -> TlvGen { 126 TlvGen { 127 kinds: vec![TlvKinds::SHA256], 128 ..Default::default() 129 } 130 } 131 132 #[allow(dead_code)] new_rsa_pss() -> TlvGen133 pub fn new_rsa_pss() -> TlvGen { 134 TlvGen { 135 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048], 136 ..Default::default() 137 } 138 } 139 140 #[allow(dead_code)] new_rsa3072_pss() -> TlvGen141 pub fn new_rsa3072_pss() -> TlvGen { 142 TlvGen { 143 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA3072], 144 ..Default::default() 145 } 146 } 147 148 #[allow(dead_code)] new_ecdsa() -> TlvGen149 pub fn new_ecdsa() -> TlvGen { 150 TlvGen { 151 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256], 152 ..Default::default() 153 } 154 } 155 156 #[allow(dead_code)] new_ed25519() -> TlvGen157 pub fn new_ed25519() -> TlvGen { 158 TlvGen { 159 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519], 160 ..Default::default() 161 } 162 } 163 164 #[allow(dead_code)] new_enc_rsa(aes_key_size: u32) -> TlvGen165 pub fn new_enc_rsa(aes_key_size: u32) -> TlvGen { 166 let flag = if aes_key_size == 256 { 167 TlvFlags::ENCRYPTED_AES256 as u32 168 } else { 169 TlvFlags::ENCRYPTED_AES128 as u32 170 }; 171 TlvGen { 172 flags: flag, 173 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048], 174 ..Default::default() 175 } 176 } 177 178 #[allow(dead_code)] new_sig_enc_rsa(aes_key_size: u32) -> TlvGen179 pub fn new_sig_enc_rsa(aes_key_size: u32) -> TlvGen { 180 let flag = if aes_key_size == 256 { 181 TlvFlags::ENCRYPTED_AES256 as u32 182 } else { 183 TlvFlags::ENCRYPTED_AES128 as u32 184 }; 185 TlvGen { 186 flags: flag, 187 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048], 188 ..Default::default() 189 } 190 } 191 192 #[allow(dead_code)] new_enc_kw(aes_key_size: u32) -> TlvGen193 pub fn new_enc_kw(aes_key_size: u32) -> TlvGen { 194 let flag = if aes_key_size == 256 { 195 TlvFlags::ENCRYPTED_AES256 as u32 196 } else { 197 TlvFlags::ENCRYPTED_AES128 as u32 198 }; 199 TlvGen { 200 flags: flag, 201 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW], 202 ..Default::default() 203 } 204 } 205 206 #[allow(dead_code)] new_rsa_kw(aes_key_size: u32) -> TlvGen207 pub fn new_rsa_kw(aes_key_size: u32) -> TlvGen { 208 let flag = if aes_key_size == 256 { 209 TlvFlags::ENCRYPTED_AES256 as u32 210 } else { 211 TlvFlags::ENCRYPTED_AES128 as u32 212 }; 213 TlvGen { 214 flags: flag, 215 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW], 216 ..Default::default() 217 } 218 } 219 220 #[allow(dead_code)] new_ecdsa_kw(aes_key_size: u32) -> TlvGen221 pub fn new_ecdsa_kw(aes_key_size: u32) -> TlvGen { 222 let flag = if aes_key_size == 256 { 223 TlvFlags::ENCRYPTED_AES256 as u32 224 } else { 225 TlvFlags::ENCRYPTED_AES128 as u32 226 }; 227 TlvGen { 228 flags: flag, 229 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCKW], 230 ..Default::default() 231 } 232 } 233 234 #[allow(dead_code)] new_ecies_p256(aes_key_size: u32) -> TlvGen235 pub fn new_ecies_p256(aes_key_size: u32) -> TlvGen { 236 let flag = if aes_key_size == 256 { 237 TlvFlags::ENCRYPTED_AES256 as u32 238 } else { 239 TlvFlags::ENCRYPTED_AES128 as u32 240 }; 241 TlvGen { 242 flags: flag, 243 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCEC256], 244 ..Default::default() 245 } 246 } 247 248 #[allow(dead_code)] new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen249 pub fn new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen { 250 let flag = if aes_key_size == 256 { 251 TlvFlags::ENCRYPTED_AES256 as u32 252 } else { 253 TlvFlags::ENCRYPTED_AES128 as u32 254 }; 255 TlvGen { 256 flags: flag, 257 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSA256, TlvKinds::ENCEC256], 258 ..Default::default() 259 } 260 } 261 262 #[allow(dead_code)] new_ecies_x25519(aes_key_size: u32) -> TlvGen263 pub fn new_ecies_x25519(aes_key_size: u32) -> TlvGen { 264 let flag = if aes_key_size == 256 { 265 TlvFlags::ENCRYPTED_AES256 as u32 266 } else { 267 TlvFlags::ENCRYPTED_AES128 as u32 268 }; 269 TlvGen { 270 flags: flag, 271 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCX25519], 272 ..Default::default() 273 } 274 } 275 276 #[allow(dead_code)] new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen277 pub fn new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen { 278 let flag = if aes_key_size == 256 { 279 TlvFlags::ENCRYPTED_AES256 as u32 280 } else { 281 TlvFlags::ENCRYPTED_AES128 as u32 282 }; 283 TlvGen { 284 flags: flag, 285 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519, TlvKinds::ENCX25519], 286 ..Default::default() 287 } 288 } 289 } 290 291 impl ManifestGen for TlvGen { get_magic(&self) -> u32292 fn get_magic(&self) -> u32 { 293 0x96f3b83d 294 } 295 296 /// Retrieve the header flags for this configuration. This can be called at any time. get_flags(&self) -> u32297 fn get_flags(&self) -> u32 { 298 self.flags 299 } 300 301 /// Add bytes to the covered hash. add_bytes(&mut self, bytes: &[u8])302 fn add_bytes(&mut self, bytes: &[u8]) { 303 self.payload.extend_from_slice(bytes); 304 } 305 protect_size(&self) -> u16306 fn protect_size(&self) -> u16 { 307 if self.dependencies.is_empty() { 308 0 309 } else { 310 // Include the header and space for each dependency. 311 4 + (self.dependencies.len() as u16) * (4 + 4 + 8) 312 } 313 } 314 add_dependency(&mut self, id: u8, version: &ImageVersion)315 fn add_dependency(&mut self, id: u8, version: &ImageVersion) { 316 self.dependencies.push(Dependency { 317 id, 318 version: version.clone(), 319 }); 320 } 321 corrupt_sig(&mut self)322 fn corrupt_sig(&mut self) { 323 self.gen_corrupted = true; 324 } 325 326 /// Compute the TLV given the specified block of data. make_tlv(self: Box<Self>) -> Vec<u8>327 fn make_tlv(self: Box<Self>) -> Vec<u8> { 328 let mut protected_tlv: Vec<u8> = vec![]; 329 330 if self.protect_size() > 0 { 331 protected_tlv.push(0x08); 332 protected_tlv.push(0x69); 333 let size = self.protect_size(); 334 protected_tlv.write_u16::<LittleEndian>(size).unwrap(); 335 for dep in &self.dependencies { 336 protected_tlv.write_u16::<LittleEndian>(TlvKinds::DEPENDENCY as u16).unwrap(); 337 protected_tlv.write_u16::<LittleEndian>(12).unwrap(); 338 339 // The dependency. 340 protected_tlv.push(dep.id); 341 protected_tlv.push(0); 342 protected_tlv.write_u16::<LittleEndian>(0).unwrap(); 343 protected_tlv.push(dep.version.major); 344 protected_tlv.push(dep.version.minor); 345 protected_tlv.write_u16::<LittleEndian>(dep.version.revision).unwrap(); 346 protected_tlv.write_u32::<LittleEndian>(dep.version.build_num).unwrap(); 347 } 348 349 assert_eq!(size, protected_tlv.len() as u16, "protected TLV length incorrect"); 350 } 351 352 // Ring does the signature itself, which means that it must be 353 // given a full, contiguous payload. Although this does help from 354 // a correct usage perspective, it is fairly stupid from an 355 // efficiency view. If this is shown to be a performance issue 356 // with the tests, the protected data could be appended to the 357 // payload, and then removed after the signature is done. For now, 358 // just make a signed payload. 359 let mut sig_payload = self.payload.clone(); 360 sig_payload.extend_from_slice(&protected_tlv); 361 362 let mut result: Vec<u8> = vec![]; 363 364 // add back signed payload 365 result.extend_from_slice(&protected_tlv); 366 367 // add non-protected payload 368 let npro_pos = result.len(); 369 result.push(0x07); 370 result.push(0x69); 371 // Placeholder for the size. 372 result.write_u16::<LittleEndian>(0).unwrap(); 373 374 if self.kinds.contains(&TlvKinds::SHA256) { 375 // If a signature is not requested, corrupt the hash we are 376 // generating. But, if there is a signature, output the 377 // correct hash. We want the hash test to pass so that the 378 // signature verification can be validated. 379 let mut corrupt_hash = self.gen_corrupted; 380 for k in &[TlvKinds::RSA2048, TlvKinds::RSA3072, 381 TlvKinds::ECDSA224, TlvKinds::ECDSA256, 382 TlvKinds::ED25519] 383 { 384 if self.kinds.contains(k) { 385 corrupt_hash = false; 386 break; 387 } 388 } 389 390 if corrupt_hash { 391 sig_payload[0] ^= 1; 392 } 393 394 let hash = digest::digest(&digest::SHA256, &sig_payload); 395 let hash = hash.as_ref(); 396 397 assert!(hash.len() == 32); 398 result.write_u16::<LittleEndian>(TlvKinds::SHA256 as u16).unwrap(); 399 result.write_u16::<LittleEndian>(32).unwrap(); 400 result.extend_from_slice(hash); 401 402 // Undo the corruption. 403 if corrupt_hash { 404 sig_payload[0] ^= 1; 405 } 406 407 } 408 409 if self.gen_corrupted { 410 // Corrupt what is signed by modifying the input to the 411 // signature code. 412 sig_payload[0] ^= 1; 413 } 414 415 if self.kinds.contains(&TlvKinds::RSA2048) || 416 self.kinds.contains(&TlvKinds::RSA3072) { 417 418 let is_rsa2048 = self.kinds.contains(&TlvKinds::RSA2048); 419 420 // Output the hash of the public key. 421 let hash = if is_rsa2048 { 422 digest::digest(&digest::SHA256, RSA_PUB_KEY) 423 } else { 424 digest::digest(&digest::SHA256, RSA3072_PUB_KEY) 425 }; 426 let hash = hash.as_ref(); 427 428 assert!(hash.len() == 32); 429 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 430 result.write_u16::<LittleEndian>(32).unwrap(); 431 result.extend_from_slice(hash); 432 433 // For now assume PSS. 434 let key_bytes = if is_rsa2048 { 435 pem::parse(include_bytes!("../../root-rsa-2048.pem").as_ref()).unwrap() 436 } else { 437 pem::parse(include_bytes!("../../root-rsa-3072.pem").as_ref()).unwrap() 438 }; 439 assert_eq!(key_bytes.tag, "RSA PRIVATE KEY"); 440 let key_pair = RsaKeyPair::from_der(&key_bytes.contents).unwrap(); 441 let rng = rand::SystemRandom::new(); 442 let mut signature = vec![0; key_pair.public_modulus_len()]; 443 if is_rsa2048 { 444 assert_eq!(signature.len(), 256); 445 } else { 446 assert_eq!(signature.len(), 384); 447 } 448 key_pair.sign(&RSA_PSS_SHA256, &rng, &sig_payload, &mut signature).unwrap(); 449 450 if is_rsa2048 { 451 result.write_u16::<LittleEndian>(TlvKinds::RSA2048 as u16).unwrap(); 452 } else { 453 result.write_u16::<LittleEndian>(TlvKinds::RSA3072 as u16).unwrap(); 454 } 455 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 456 result.extend_from_slice(&signature); 457 } 458 459 if self.kinds.contains(&TlvKinds::ECDSA256) { 460 let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); 461 let keyhash = keyhash.as_ref(); 462 463 assert!(keyhash.len() == 32); 464 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 465 result.write_u16::<LittleEndian>(32).unwrap(); 466 result.extend_from_slice(keyhash); 467 468 let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); 469 assert_eq!(key_bytes.tag, "PRIVATE KEY"); 470 471 let key_pair = EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_ASN1_SIGNING, 472 &key_bytes.contents).unwrap(); 473 let rng = rand::SystemRandom::new(); 474 let signature = key_pair.sign(&rng, &sig_payload).unwrap(); 475 476 result.write_u16::<LittleEndian>(TlvKinds::ECDSA256 as u16).unwrap(); 477 478 let signature = signature.as_ref().to_vec(); 479 480 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 481 result.extend_from_slice(signature.as_ref()); 482 } 483 484 if self.kinds.contains(&TlvKinds::ED25519) { 485 let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY); 486 let keyhash = keyhash.as_ref(); 487 488 assert!(keyhash.len() == 32); 489 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 490 result.write_u16::<LittleEndian>(32).unwrap(); 491 result.extend_from_slice(keyhash); 492 493 let hash = digest::digest(&digest::SHA256, &sig_payload); 494 let hash = hash.as_ref(); 495 assert!(hash.len() == 32); 496 497 let key_bytes = pem::parse(include_bytes!("../../root-ed25519.pem").as_ref()).unwrap(); 498 assert_eq!(key_bytes.tag, "PRIVATE KEY"); 499 500 let key_pair = Ed25519KeyPair::from_seed_and_public_key( 501 &key_bytes.contents[16..48], &ED25519_PUB_KEY[12..44]).unwrap(); 502 let signature = key_pair.sign(&hash); 503 504 result.write_u16::<LittleEndian>(TlvKinds::ED25519 as u16).unwrap(); 505 506 let signature = signature.as_ref().to_vec(); 507 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 508 result.extend_from_slice(signature.as_ref()); 509 } 510 511 if self.kinds.contains(&TlvKinds::ENCRSA2048) { 512 let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem") 513 .as_ref()).unwrap(); 514 assert_eq!(key_bytes.tag, "PUBLIC KEY"); 515 516 let cipherkey = self.get_enc_key(); 517 let cipherkey = cipherkey.as_slice(); 518 let encbuf = match c::rsa_oaep_encrypt(&key_bytes.contents, cipherkey) { 519 Ok(v) => v, 520 Err(_) => panic!("Failed to encrypt secret key"), 521 }; 522 523 assert!(encbuf.len() == 256); 524 result.write_u16::<LittleEndian>(TlvKinds::ENCRSA2048 as u16).unwrap(); 525 result.write_u16::<LittleEndian>(256).unwrap(); 526 result.extend_from_slice(&encbuf); 527 } 528 529 if self.kinds.contains(&TlvKinds::ENCKW) { 530 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 531 let aes256 = (self.get_flags() & flag) == flag; 532 let key_bytes = if aes256 { 533 base64::decode( 534 include_str!("../../enc-aes256kw.b64").trim()).unwrap() 535 } else { 536 base64::decode( 537 include_str!("../../enc-aes128kw.b64").trim()).unwrap() 538 }; 539 let cipherkey = self.get_enc_key(); 540 let cipherkey = cipherkey.as_slice(); 541 let keylen = if aes256 { 32 } else { 16 }; 542 let encbuf = match c::kw_encrypt(&key_bytes, cipherkey, keylen) { 543 Ok(v) => v, 544 Err(_) => panic!("Failed to encrypt secret key"), 545 }; 546 547 let size = if aes256 { 40 } else { 24 }; 548 assert!(encbuf.len() == size); 549 result.write_u16::<LittleEndian>(TlvKinds::ENCKW as u16).unwrap(); 550 result.write_u16::<LittleEndian>(size as u16).unwrap(); 551 result.extend_from_slice(&encbuf); 552 } 553 554 if self.kinds.contains(&TlvKinds::ENCEC256) || self.kinds.contains(&TlvKinds::ENCX25519) { 555 let key_bytes = if self.kinds.contains(&TlvKinds::ENCEC256) { 556 pem::parse(include_bytes!("../../enc-ec256-pub.pem").as_ref()).unwrap() 557 } else { 558 pem::parse(include_bytes!("../../enc-x25519-pub.pem").as_ref()).unwrap() 559 }; 560 assert_eq!(key_bytes.tag, "PUBLIC KEY"); 561 let rng = rand::SystemRandom::new(); 562 let alg = if self.kinds.contains(&TlvKinds::ENCEC256) { 563 &agreement::ECDH_P256 564 } else { 565 &agreement::X25519 566 }; 567 let pk = match agreement::EphemeralPrivateKey::generate(alg, &rng) { 568 Ok(v) => v, 569 Err(_) => panic!("Failed to generate ephemeral keypair"), 570 }; 571 572 let pubk = match pk.compute_public_key() { 573 Ok(pubk) => pubk, 574 Err(_) => panic!("Failed computing ephemeral public key"), 575 }; 576 577 let peer_pubk = if self.kinds.contains(&TlvKinds::ENCEC256) { 578 agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, &key_bytes.contents[26..]) 579 } else { 580 agreement::UnparsedPublicKey::new(&agreement::X25519, &key_bytes.contents[12..]) 581 }; 582 583 #[derive(Debug, PartialEq)] 584 struct OkmLen<T: core::fmt::Debug + PartialEq>(T); 585 586 impl hkdf::KeyType for OkmLen<usize> { 587 fn len(&self) -> usize { 588 self.0 589 } 590 } 591 592 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 593 let aes256 = (self.get_flags() & flag) == flag; 594 595 let derived_key = match agreement::agree_ephemeral( 596 pk, &peer_pubk, ring::error::Unspecified, |shared| { 597 let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &[]); 598 let prk = salt.extract(&shared); 599 let okm_len = if aes256 { 64 } else { 48 }; 600 let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(okm_len)) { 601 Ok(okm) => okm, 602 Err(_) => panic!("Failed building HKDF OKM"), 603 }; 604 let mut buf = if aes256 { vec![0u8; 64] } else { vec![0u8; 48] }; 605 match okm.fill(&mut buf) { 606 Ok(_) => Ok(buf), 607 Err(_) => panic!("Failed generating HKDF output"), 608 } 609 }, 610 ) { 611 Ok(v) => v, 612 Err(_) => panic!("Failed building HKDF"), 613 }; 614 615 let nonce = GenericArray::from_slice(&[0; 16]); 616 let mut cipherkey = self.get_enc_key(); 617 if aes256 { 618 let key: &GenericArray<u8, U32> = GenericArray::from_slice(&derived_key[..32]); 619 let mut cipher = Aes256Ctr::new(&key, &nonce); 620 cipher.apply_keystream(&mut cipherkey); 621 } else { 622 let key: &GenericArray<u8, U16> = GenericArray::from_slice(&derived_key[..16]); 623 let mut cipher = Aes128Ctr::new(&key, &nonce); 624 cipher.apply_keystream(&mut cipherkey); 625 } 626 627 let size = if aes256 { 32 } else { 16 }; 628 let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[size..]); 629 let tag = hmac::sign(&key, &cipherkey); 630 631 let mut buf = vec![]; 632 buf.append(&mut pubk.as_ref().to_vec()); 633 buf.append(&mut tag.as_ref().to_vec()); 634 buf.append(&mut cipherkey); 635 636 if self.kinds.contains(&TlvKinds::ENCEC256) { 637 let size = if aes256 { 129 } else { 113 }; 638 assert!(buf.len() == size); 639 result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap(); 640 result.write_u16::<LittleEndian>(size as u16).unwrap(); 641 } else { 642 let size = if aes256 { 96 } else { 80 }; 643 assert!(buf.len() == size); 644 result.write_u16::<LittleEndian>(TlvKinds::ENCX25519 as u16).unwrap(); 645 result.write_u16::<LittleEndian>(size as u16).unwrap(); 646 } 647 result.extend_from_slice(&buf); 648 } 649 650 // Patch the size back into the TLV header. 651 let size = (result.len() - npro_pos) as u16; 652 let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4]; 653 size_buf.write_u16::<LittleEndian>(size).unwrap(); 654 655 result 656 } 657 generate_enc_key(&mut self)658 fn generate_enc_key(&mut self) { 659 let rng = rand::SystemRandom::new(); 660 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 661 let aes256 = (self.get_flags() & flag) == flag; 662 let mut buf = if aes256 { 663 vec![0u8; 32] 664 } else { 665 vec![0u8; 16] 666 }; 667 if rng.fill(&mut buf).is_err() { 668 panic!("Error generating encrypted key"); 669 } 670 info!("New encryption key: {:02x?}", buf); 671 self.enc_key = buf; 672 } 673 get_enc_key(&self) -> Vec<u8>674 fn get_enc_key(&self) -> Vec<u8> { 675 if self.enc_key.len() != 32 && self.enc_key.len() != 16 { 676 panic!("No random key was generated"); 677 } 678 self.enc_key.clone() 679 } 680 } 681 682 include!("rsa_pub_key-rs.txt"); 683 include!("rsa3072_pub_key-rs.txt"); 684 include!("ecdsa_pub_key-rs.txt"); 685 include!("ed25519_pub_key-rs.txt"); 686