1 // Copyright (c) 2017-2021 Linaro LTD 2 // Copyright (c) 2017-2020 JUUL Labs 3 // Copyright (c) 2021-2023 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 cipher::FromBlockCipher; 21 use crate::caps::Caps; 22 use crate::image::ImageVersion; 23 use log::info; 24 use ring::{digest, rand, agreement, hkdf, hmac}; 25 use ring::rand::SecureRandom; 26 use ring::signature::{ 27 RsaKeyPair, 28 RSA_PSS_SHA256, 29 EcdsaKeyPair, 30 ECDSA_P256_SHA256_ASN1_SIGNING, 31 Ed25519KeyPair, 32 ECDSA_P384_SHA384_ASN1_SIGNING, 33 }; 34 use aes::{ 35 Aes128, 36 Aes128Ctr, 37 Aes256, 38 Aes256Ctr, 39 NewBlockCipher 40 }; 41 use cipher::{ 42 generic_array::GenericArray, 43 StreamCipher, 44 }; 45 use mcuboot_sys::c; 46 use typenum::{U16, U32}; 47 48 #[repr(u16)] 49 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 50 #[allow(dead_code)] // TODO: For now 51 pub enum TlvKinds { 52 KEYHASH = 0x01, 53 SHA256 = 0x10, 54 SHA384 = 0x11, 55 RSA2048 = 0x20, 56 ECDSASIG = 0x22, 57 RSA3072 = 0x23, 58 ED25519 = 0x24, 59 ENCRSA2048 = 0x30, 60 ENCKW = 0x31, 61 ENCEC256 = 0x32, 62 ENCX25519 = 0x33, 63 DEPENDENCY = 0x40, 64 SECCNT = 0x50, 65 } 66 67 #[allow(dead_code, non_camel_case_types)] 68 pub enum TlvFlags { 69 PIC = 0x01, 70 NON_BOOTABLE = 0x02, 71 ENCRYPTED_AES128 = 0x04, 72 ENCRYPTED_AES256 = 0x08, 73 RAM_LOAD = 0x20, 74 } 75 76 /// A generator for manifests. The format of the manifest can be either a 77 /// traditional "TLV" or a SUIT-style manifest. 78 pub trait ManifestGen { 79 /// Retrieve the header magic value for this manifest type. get_magic(&self) -> u3280 fn get_magic(&self) -> u32; 81 82 /// Retrieve the flags value for this particular manifest type. get_flags(&self) -> u3283 fn get_flags(&self) -> u32; 84 85 /// Retrieve the number of bytes of this manifest that is "protected". 86 /// This field is stored in the outside image header instead of the 87 /// manifest header. protect_size(&self) -> u1688 fn protect_size(&self) -> u16; 89 90 /// Add a dependency on another image. add_dependency(&mut self, id: u8, version: &ImageVersion)91 fn add_dependency(&mut self, id: u8, version: &ImageVersion); 92 93 /// Add a sequence of bytes to the payload that the manifest is 94 /// protecting. add_bytes(&mut self, bytes: &[u8])95 fn add_bytes(&mut self, bytes: &[u8]); 96 97 /// Set an internal flag indicating that the next `make_tlv` should 98 /// corrupt the signature. corrupt_sig(&mut self)99 fn corrupt_sig(&mut self); 100 101 /// Estimate the size of the TLV. This can be called before the payload is added (but after 102 /// other information is added). Some of the signature algorithms can generate variable sized 103 /// data, and therefore, this can slightly overestimate the size. estimate_size(&self) -> usize104 fn estimate_size(&self) -> usize; 105 106 /// Construct the manifest for this payload. make_tlv(self: Box<Self>) -> Vec<u8>107 fn make_tlv(self: Box<Self>) -> Vec<u8>; 108 109 /// Generate a new encryption random key generate_enc_key(&mut self)110 fn generate_enc_key(&mut self); 111 112 /// Return the current encryption key get_enc_key(&self) -> Vec<u8>113 fn get_enc_key(&self) -> Vec<u8>; 114 115 /// Set the security counter to the specified value. set_security_counter(&mut self, security_cnt: Option<u32>)116 fn set_security_counter(&mut self, security_cnt: Option<u32>); 117 118 /// Sets the ignore_ram_load_flag so that can be validated when it is missing, 119 /// it will not load successfully. set_ignore_ram_load_flag(&mut self)120 fn set_ignore_ram_load_flag(&mut self); 121 } 122 123 #[derive(Debug, Default)] 124 pub struct TlvGen { 125 flags: u32, 126 kinds: Vec<TlvKinds>, 127 payload: Vec<u8>, 128 dependencies: Vec<Dependency>, 129 enc_key: Vec<u8>, 130 /// Should this signature be corrupted. 131 gen_corrupted: bool, 132 security_cnt: Option<u32>, 133 /// Ignore RAM_LOAD flag 134 ignore_ram_load_flag: bool, 135 } 136 137 #[derive(Debug)] 138 struct Dependency { 139 id: u8, 140 version: ImageVersion, 141 } 142 143 impl TlvGen { 144 /// Construct a new tlv generator that will only contain a hash of the data. 145 #[allow(dead_code)] new_hash_only() -> TlvGen146 pub fn new_hash_only() -> TlvGen { 147 TlvGen { 148 kinds: vec![TlvKinds::SHA256], 149 ..Default::default() 150 } 151 } 152 153 #[allow(dead_code)] new_rsa_pss() -> TlvGen154 pub fn new_rsa_pss() -> TlvGen { 155 TlvGen { 156 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048], 157 ..Default::default() 158 } 159 } 160 161 #[allow(dead_code)] new_rsa3072_pss() -> TlvGen162 pub fn new_rsa3072_pss() -> TlvGen { 163 TlvGen { 164 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA3072], 165 ..Default::default() 166 } 167 } 168 169 #[allow(dead_code)] new_ecdsa() -> TlvGen170 pub fn new_ecdsa() -> TlvGen { 171 let hash_kind = if cfg!(feature = "sig-p384") { 172 TlvKinds::SHA384 173 } else { 174 TlvKinds::SHA256 175 }; 176 TlvGen { 177 kinds: vec![hash_kind, TlvKinds::ECDSASIG], 178 ..Default::default() 179 } 180 } 181 182 #[allow(dead_code)] new_ed25519() -> TlvGen183 pub fn new_ed25519() -> TlvGen { 184 TlvGen { 185 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519], 186 ..Default::default() 187 } 188 } 189 190 #[allow(dead_code)] new_enc_rsa(aes_key_size: u32) -> TlvGen191 pub fn new_enc_rsa(aes_key_size: u32) -> TlvGen { 192 let flag = if aes_key_size == 256 { 193 TlvFlags::ENCRYPTED_AES256 as u32 194 } else { 195 TlvFlags::ENCRYPTED_AES128 as u32 196 }; 197 TlvGen { 198 flags: flag, 199 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048], 200 ..Default::default() 201 } 202 } 203 204 #[allow(dead_code)] new_sig_enc_rsa(aes_key_size: u32) -> TlvGen205 pub fn new_sig_enc_rsa(aes_key_size: u32) -> TlvGen { 206 let flag = if aes_key_size == 256 { 207 TlvFlags::ENCRYPTED_AES256 as u32 208 } else { 209 TlvFlags::ENCRYPTED_AES128 as u32 210 }; 211 TlvGen { 212 flags: flag, 213 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCRSA2048], 214 ..Default::default() 215 } 216 } 217 218 #[allow(dead_code)] new_enc_kw(aes_key_size: u32) -> TlvGen219 pub fn new_enc_kw(aes_key_size: u32) -> TlvGen { 220 let flag = if aes_key_size == 256 { 221 TlvFlags::ENCRYPTED_AES256 as u32 222 } else { 223 TlvFlags::ENCRYPTED_AES128 as u32 224 }; 225 TlvGen { 226 flags: flag, 227 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW], 228 ..Default::default() 229 } 230 } 231 232 #[allow(dead_code)] new_rsa_kw(aes_key_size: u32) -> TlvGen233 pub fn new_rsa_kw(aes_key_size: u32) -> TlvGen { 234 let flag = if aes_key_size == 256 { 235 TlvFlags::ENCRYPTED_AES256 as u32 236 } else { 237 TlvFlags::ENCRYPTED_AES128 as u32 238 }; 239 TlvGen { 240 flags: flag, 241 kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048, TlvKinds::ENCKW], 242 ..Default::default() 243 } 244 } 245 246 #[allow(dead_code)] new_ecdsa_kw(aes_key_size: u32) -> TlvGen247 pub fn new_ecdsa_kw(aes_key_size: u32) -> TlvGen { 248 let flag = if aes_key_size == 256 { 249 TlvFlags::ENCRYPTED_AES256 as u32 250 } else { 251 TlvFlags::ENCRYPTED_AES128 as u32 252 }; 253 TlvGen { 254 flags: flag, 255 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSASIG, TlvKinds::ENCKW], 256 ..Default::default() 257 } 258 } 259 260 #[allow(dead_code)] new_ecies_p256(aes_key_size: u32) -> TlvGen261 pub fn new_ecies_p256(aes_key_size: u32) -> TlvGen { 262 let flag = if aes_key_size == 256 { 263 TlvFlags::ENCRYPTED_AES256 as u32 264 } else { 265 TlvFlags::ENCRYPTED_AES128 as u32 266 }; 267 TlvGen { 268 flags: flag, 269 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCEC256], 270 ..Default::default() 271 } 272 } 273 274 #[allow(dead_code)] new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen275 pub fn new_ecdsa_ecies_p256(aes_key_size: u32) -> TlvGen { 276 let flag = if aes_key_size == 256 { 277 TlvFlags::ENCRYPTED_AES256 as u32 278 } else { 279 TlvFlags::ENCRYPTED_AES128 as u32 280 }; 281 TlvGen { 282 flags: flag, 283 kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSASIG, TlvKinds::ENCEC256], 284 ..Default::default() 285 } 286 } 287 288 #[allow(dead_code)] new_ecies_x25519(aes_key_size: u32) -> TlvGen289 pub fn new_ecies_x25519(aes_key_size: u32) -> TlvGen { 290 let flag = if aes_key_size == 256 { 291 TlvFlags::ENCRYPTED_AES256 as u32 292 } else { 293 TlvFlags::ENCRYPTED_AES128 as u32 294 }; 295 TlvGen { 296 flags: flag, 297 kinds: vec![TlvKinds::SHA256, TlvKinds::ENCX25519], 298 ..Default::default() 299 } 300 } 301 302 #[allow(dead_code)] new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen303 pub fn new_ed25519_ecies_x25519(aes_key_size: u32) -> TlvGen { 304 let flag = if aes_key_size == 256 { 305 TlvFlags::ENCRYPTED_AES256 as u32 306 } else { 307 TlvFlags::ENCRYPTED_AES128 as u32 308 }; 309 TlvGen { 310 flags: flag, 311 kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519, TlvKinds::ENCX25519], 312 ..Default::default() 313 } 314 } 315 316 #[allow(dead_code)] new_sec_cnt() -> TlvGen317 pub fn new_sec_cnt() -> TlvGen { 318 TlvGen { 319 kinds: vec![TlvKinds::SHA256, TlvKinds::SECCNT], 320 ..Default::default() 321 } 322 } 323 324 } 325 326 impl ManifestGen for TlvGen { get_magic(&self) -> u32327 fn get_magic(&self) -> u32 { 328 0x96f3b83d 329 } 330 331 /// Retrieve the header flags for this configuration. This can be called at any time. get_flags(&self) -> u32332 fn get_flags(&self) -> u32 { 333 // For the RamLoad case, add in the flag for this feature. 334 if Caps::RamLoad.present() && !self.ignore_ram_load_flag { 335 self.flags | (TlvFlags::RAM_LOAD as u32) 336 } else { 337 self.flags 338 } 339 } 340 341 /// Add bytes to the covered hash. add_bytes(&mut self, bytes: &[u8])342 fn add_bytes(&mut self, bytes: &[u8]) { 343 self.payload.extend_from_slice(bytes); 344 } 345 protect_size(&self) -> u16346 fn protect_size(&self) -> u16 { 347 let mut size = 0; 348 if !self.dependencies.is_empty() || (Caps::HwRollbackProtection.present() && self.security_cnt.is_some()) { 349 // include the TLV area header. 350 size += 4; 351 // add space for each dependency. 352 size += (self.dependencies.len() as u16) * (4 + std::mem::size_of::<Dependency>() as u16); 353 if Caps::HwRollbackProtection.present() && self.security_cnt.is_some() { 354 size += 4 + 4; 355 } 356 } 357 size 358 } 359 add_dependency(&mut self, id: u8, version: &ImageVersion)360 fn add_dependency(&mut self, id: u8, version: &ImageVersion) { 361 self.dependencies.push(Dependency { 362 id, 363 version: version.clone(), 364 }); 365 } 366 corrupt_sig(&mut self)367 fn corrupt_sig(&mut self) { 368 self.gen_corrupted = true; 369 } 370 estimate_size(&self) -> usize371 fn estimate_size(&self) -> usize { 372 // Begin the estimate with the 4 byte header. 373 let mut estimate = 4; 374 // A very poor estimate. 375 376 // Estimate the size of the image hash. 377 if self.kinds.contains(&TlvKinds::SHA256) { 378 estimate += 4 + 32; 379 } else if self.kinds.contains(&TlvKinds::SHA384) { 380 estimate += 4 + 48; 381 } 382 383 // Add an estimate in for each of the signature algorithms. 384 if self.kinds.contains(&TlvKinds::RSA2048) { 385 estimate += 4 + 32; // keyhash 386 estimate += 4 + 256; // RSA2048 387 } 388 if self.kinds.contains(&TlvKinds::RSA3072) { 389 estimate += 4 + 32; // keyhash 390 estimate += 4 + 384; // RSA3072 391 } 392 if self.kinds.contains(&TlvKinds::ED25519) { 393 estimate += 4 + 32; // keyhash 394 estimate += 4 + 64; // ED25519 signature. 395 } 396 if self.kinds.contains(&TlvKinds::ECDSASIG) { 397 // ECDSA signatures are encoded as ASN.1 with the x and y values 398 // stored as signed integers. As such, the size can vary by 2 bytes, 399 // if for example the 256-bit value has the high bit, it takes an 400 // extra 0 byte to avoid it being seen as a negative number. 401 if self.kinds.contains(&TlvKinds::SHA384) { 402 estimate += 4 + 48; // SHA384 403 estimate += 4 + 104; // ECDSA384 (varies) 404 } else { 405 estimate += 4 + 32; // SHA256 406 estimate += 4 + 72; // ECDSA256 (varies) 407 } 408 } 409 410 // Estimate encryption. 411 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 412 let aes256 = (self.get_flags() & flag) == flag; 413 414 if self.kinds.contains(&TlvKinds::ENCRSA2048) { 415 estimate += 4 + 256; 416 } 417 if self.kinds.contains(&TlvKinds::ENCKW) { 418 estimate += 4 + if aes256 { 40 } else { 24 }; 419 } 420 if self.kinds.contains(&TlvKinds::ENCEC256) { 421 estimate += 4 + if aes256 { 129 } else { 113 }; 422 } 423 if self.kinds.contains(&TlvKinds::ENCX25519) { 424 estimate += 4 + if aes256 { 96 } else { 80 }; 425 } 426 427 // Gather the size of the protected TLV area. 428 estimate += self.protect_size() as usize; 429 430 estimate 431 } 432 433 /// Compute the TLV given the specified block of data. make_tlv(self: Box<Self>) -> Vec<u8>434 fn make_tlv(self: Box<Self>) -> Vec<u8> { 435 let size_estimate = self.estimate_size(); 436 437 let mut protected_tlv: Vec<u8> = vec![]; 438 439 if self.protect_size() > 0 { 440 protected_tlv.push(0x08); 441 protected_tlv.push(0x69); 442 let size = self.protect_size(); 443 protected_tlv.write_u16::<LittleEndian>(size).unwrap(); 444 for dep in &self.dependencies { 445 protected_tlv.write_u16::<LittleEndian>(TlvKinds::DEPENDENCY as u16).unwrap(); 446 protected_tlv.write_u16::<LittleEndian>(12).unwrap(); 447 448 // The dependency. 449 protected_tlv.push(dep.id); 450 protected_tlv.push(0); 451 protected_tlv.write_u16::<LittleEndian>(0).unwrap(); 452 protected_tlv.push(dep.version.major); 453 protected_tlv.push(dep.version.minor); 454 protected_tlv.write_u16::<LittleEndian>(dep.version.revision).unwrap(); 455 protected_tlv.write_u32::<LittleEndian>(dep.version.build_num).unwrap(); 456 } 457 458 // Security counter has to be at the protected TLV area also 459 if Caps::HwRollbackProtection.present() && self.security_cnt.is_some() { 460 protected_tlv.write_u16::<LittleEndian>(TlvKinds::SECCNT as u16).unwrap(); 461 protected_tlv.write_u16::<LittleEndian>(std::mem::size_of::<u32>() as u16).unwrap(); 462 protected_tlv.write_u32::<LittleEndian>(self.security_cnt.unwrap() as u32).unwrap(); 463 } 464 465 assert_eq!(size, protected_tlv.len() as u16, "protected TLV length incorrect"); 466 } 467 468 // Ring does the signature itself, which means that it must be 469 // given a full, contiguous payload. Although this does help from 470 // a correct usage perspective, it is fairly stupid from an 471 // efficiency view. If this is shown to be a performance issue 472 // with the tests, the protected data could be appended to the 473 // payload, and then removed after the signature is done. For now, 474 // just make a signed payload. 475 let mut sig_payload = self.payload.clone(); 476 sig_payload.extend_from_slice(&protected_tlv); 477 478 let mut result: Vec<u8> = vec![]; 479 480 // add back signed payload 481 result.extend_from_slice(&protected_tlv); 482 483 // add non-protected payload 484 let npro_pos = result.len(); 485 result.push(0x07); 486 result.push(0x69); 487 // Placeholder for the size. 488 result.write_u16::<LittleEndian>(0).unwrap(); 489 490 if self.kinds.iter().any(|v| v == &TlvKinds::SHA256 || v == &TlvKinds::SHA384) { 491 // If a signature is not requested, corrupt the hash we are 492 // generating. But, if there is a signature, output the 493 // correct hash. We want the hash test to pass so that the 494 // signature verification can be validated. 495 let mut corrupt_hash = self.gen_corrupted; 496 for k in &[TlvKinds::RSA2048, TlvKinds::RSA3072, 497 TlvKinds::ED25519, TlvKinds::ECDSASIG] 498 { 499 if self.kinds.contains(k) { 500 corrupt_hash = false; 501 break; 502 } 503 } 504 505 if corrupt_hash { 506 sig_payload[0] ^= 1; 507 } 508 let (hash,hash_size,tlv_kind) = if self.kinds.contains(&TlvKinds::SHA256) 509 { 510 let hash = digest::digest(&digest::SHA256, &sig_payload); 511 (hash,32,TlvKinds::SHA256) 512 } 513 else { 514 let hash = digest::digest(&digest::SHA384, &sig_payload); 515 (hash,48,TlvKinds::SHA384) 516 }; 517 let hash = hash.as_ref(); 518 519 assert!(hash.len() == hash_size); 520 result.write_u16::<LittleEndian>(tlv_kind as u16).unwrap(); 521 result.write_u16::<LittleEndian>(hash_size as u16).unwrap(); 522 result.extend_from_slice(hash); 523 524 // Undo the corruption. 525 if corrupt_hash { 526 sig_payload[0] ^= 1; 527 } 528 529 } 530 531 if self.gen_corrupted { 532 // Corrupt what is signed by modifying the input to the 533 // signature code. 534 sig_payload[0] ^= 1; 535 } 536 537 if self.kinds.contains(&TlvKinds::RSA2048) || 538 self.kinds.contains(&TlvKinds::RSA3072) { 539 540 let is_rsa2048 = self.kinds.contains(&TlvKinds::RSA2048); 541 542 // Output the hash of the public key. 543 let hash = if is_rsa2048 { 544 digest::digest(&digest::SHA256, RSA_PUB_KEY) 545 } else { 546 digest::digest(&digest::SHA256, RSA3072_PUB_KEY) 547 }; 548 let hash = hash.as_ref(); 549 550 assert!(hash.len() == 32); 551 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 552 result.write_u16::<LittleEndian>(32).unwrap(); 553 result.extend_from_slice(hash); 554 555 // For now assume PSS. 556 let key_bytes = if is_rsa2048 { 557 pem::parse(include_bytes!("../../root-rsa-2048.pem").as_ref()).unwrap() 558 } else { 559 pem::parse(include_bytes!("../../root-rsa-3072.pem").as_ref()).unwrap() 560 }; 561 assert_eq!(key_bytes.tag, "RSA PRIVATE KEY"); 562 let key_pair = RsaKeyPair::from_der(&key_bytes.contents).unwrap(); 563 let rng = rand::SystemRandom::new(); 564 let mut signature = vec![0; key_pair.public_modulus_len()]; 565 if is_rsa2048 { 566 assert_eq!(signature.len(), 256); 567 } else { 568 assert_eq!(signature.len(), 384); 569 } 570 key_pair.sign(&RSA_PSS_SHA256, &rng, &sig_payload, &mut signature).unwrap(); 571 572 if is_rsa2048 { 573 result.write_u16::<LittleEndian>(TlvKinds::RSA2048 as u16).unwrap(); 574 } else { 575 result.write_u16::<LittleEndian>(TlvKinds::RSA3072 as u16).unwrap(); 576 } 577 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 578 result.extend_from_slice(&signature); 579 } 580 581 if self.kinds.contains(&TlvKinds::ECDSASIG) { 582 let rng = rand::SystemRandom::new(); 583 let (signature, keyhash, keyhash_size) = if self.kinds.contains(&TlvKinds::SHA384) { 584 let keyhash = digest::digest(&digest::SHA384, ECDSAP384_PUB_KEY); 585 let key_bytes = pem::parse(include_bytes!("../../root-ec-p384-pkcs8.pem").as_ref()).unwrap(); 586 let sign_algo = &ECDSA_P384_SHA384_ASN1_SIGNING; 587 let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); 588 (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 48) 589 } else { 590 let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); 591 let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); 592 let sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; 593 let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); 594 (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 32) 595 }; 596 597 // Write public key 598 let keyhash_slice = keyhash.as_ref(); 599 assert!(keyhash_slice.len() == keyhash_size); 600 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 601 result.write_u16::<LittleEndian>(keyhash_size as u16).unwrap(); 602 result.extend_from_slice(keyhash_slice); 603 604 // Write signature 605 result.write_u16::<LittleEndian>(TlvKinds::ECDSASIG as u16).unwrap(); 606 let signature = signature.as_ref().to_vec(); 607 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 608 result.extend_from_slice(&signature); 609 } 610 611 if self.kinds.contains(&TlvKinds::ED25519) { 612 let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY); 613 let keyhash = keyhash.as_ref(); 614 615 assert!(keyhash.len() == 32); 616 result.write_u16::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap(); 617 result.write_u16::<LittleEndian>(32).unwrap(); 618 result.extend_from_slice(keyhash); 619 620 let hash = digest::digest(&digest::SHA256, &sig_payload); 621 let hash = hash.as_ref(); 622 assert!(hash.len() == 32); 623 624 let key_bytes = pem::parse(include_bytes!("../../root-ed25519.pem").as_ref()).unwrap(); 625 assert_eq!(key_bytes.tag, "PRIVATE KEY"); 626 627 let key_pair = Ed25519KeyPair::from_seed_and_public_key( 628 &key_bytes.contents[16..48], &ED25519_PUB_KEY[12..44]).unwrap(); 629 let signature = key_pair.sign(&hash); 630 631 result.write_u16::<LittleEndian>(TlvKinds::ED25519 as u16).unwrap(); 632 633 let signature = signature.as_ref().to_vec(); 634 result.write_u16::<LittleEndian>(signature.len() as u16).unwrap(); 635 result.extend_from_slice(signature.as_ref()); 636 } 637 638 if self.kinds.contains(&TlvKinds::ENCRSA2048) { 639 let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem") 640 .as_ref()).unwrap(); 641 assert_eq!(key_bytes.tag, "PUBLIC KEY"); 642 643 let cipherkey = self.get_enc_key(); 644 let cipherkey = cipherkey.as_slice(); 645 let encbuf = match c::rsa_oaep_encrypt(&key_bytes.contents, cipherkey) { 646 Ok(v) => v, 647 Err(_) => panic!("Failed to encrypt secret key"), 648 }; 649 650 assert!(encbuf.len() == 256); 651 result.write_u16::<LittleEndian>(TlvKinds::ENCRSA2048 as u16).unwrap(); 652 result.write_u16::<LittleEndian>(256).unwrap(); 653 result.extend_from_slice(&encbuf); 654 } 655 656 if self.kinds.contains(&TlvKinds::ENCKW) { 657 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 658 let aes256 = (self.get_flags() & flag) == flag; 659 let key_bytes = if aes256 { 660 base64::decode( 661 include_str!("../../enc-aes256kw.b64").trim()).unwrap() 662 } else { 663 base64::decode( 664 include_str!("../../enc-aes128kw.b64").trim()).unwrap() 665 }; 666 let cipherkey = self.get_enc_key(); 667 let cipherkey = cipherkey.as_slice(); 668 let keylen = if aes256 { 32 } else { 16 }; 669 let encbuf = match c::kw_encrypt(&key_bytes, cipherkey, keylen) { 670 Ok(v) => v, 671 Err(_) => panic!("Failed to encrypt secret key"), 672 }; 673 674 let size = if aes256 { 40 } else { 24 }; 675 assert!(encbuf.len() == size); 676 result.write_u16::<LittleEndian>(TlvKinds::ENCKW as u16).unwrap(); 677 result.write_u16::<LittleEndian>(size as u16).unwrap(); 678 result.extend_from_slice(&encbuf); 679 } 680 681 if self.kinds.contains(&TlvKinds::ENCEC256) || self.kinds.contains(&TlvKinds::ENCX25519) { 682 let key_bytes = if self.kinds.contains(&TlvKinds::ENCEC256) { 683 pem::parse(include_bytes!("../../enc-ec256-pub.pem").as_ref()).unwrap() 684 } else { 685 pem::parse(include_bytes!("../../enc-x25519-pub.pem").as_ref()).unwrap() 686 }; 687 assert_eq!(key_bytes.tag, "PUBLIC KEY"); 688 let rng = rand::SystemRandom::new(); 689 let alg = if self.kinds.contains(&TlvKinds::ENCEC256) { 690 &agreement::ECDH_P256 691 } else { 692 &agreement::X25519 693 }; 694 let pk = match agreement::EphemeralPrivateKey::generate(alg, &rng) { 695 Ok(v) => v, 696 Err(_) => panic!("Failed to generate ephemeral keypair"), 697 }; 698 699 let pubk = match pk.compute_public_key() { 700 Ok(pubk) => pubk, 701 Err(_) => panic!("Failed computing ephemeral public key"), 702 }; 703 704 let peer_pubk = if self.kinds.contains(&TlvKinds::ENCEC256) { 705 agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, &key_bytes.contents[26..]) 706 } else { 707 agreement::UnparsedPublicKey::new(&agreement::X25519, &key_bytes.contents[12..]) 708 }; 709 710 #[derive(Debug, PartialEq)] 711 struct OkmLen<T: core::fmt::Debug + PartialEq>(T); 712 713 impl hkdf::KeyType for OkmLen<usize> { 714 fn len(&self) -> usize { 715 self.0 716 } 717 } 718 719 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 720 let aes256 = (self.get_flags() & flag) == flag; 721 722 let derived_key = match agreement::agree_ephemeral( 723 pk, &peer_pubk, ring::error::Unspecified, |shared| { 724 let salt = hkdf::Salt::new(hkdf::HKDF_SHA256, &[]); 725 let prk = salt.extract(&shared); 726 let okm_len = if aes256 { 64 } else { 48 }; 727 let okm = match prk.expand(&[b"MCUBoot_ECIES_v1"], OkmLen(okm_len)) { 728 Ok(okm) => okm, 729 Err(_) => panic!("Failed building HKDF OKM"), 730 }; 731 let mut buf = if aes256 { vec![0u8; 64] } else { vec![0u8; 48] }; 732 match okm.fill(&mut buf) { 733 Ok(_) => Ok(buf), 734 Err(_) => panic!("Failed generating HKDF output"), 735 } 736 }, 737 ) { 738 Ok(v) => v, 739 Err(_) => panic!("Failed building HKDF"), 740 }; 741 742 let nonce = GenericArray::from_slice(&[0; 16]); 743 let mut cipherkey = self.get_enc_key(); 744 if aes256 { 745 let key: &GenericArray<u8, U32> = GenericArray::from_slice(&derived_key[..32]); 746 let block = Aes256::new(&key); 747 let mut cipher = Aes256Ctr::from_block_cipher(block, &nonce); 748 cipher.apply_keystream(&mut cipherkey); 749 } else { 750 let key: &GenericArray<u8, U16> = GenericArray::from_slice(&derived_key[..16]); 751 let block = Aes128::new(&key); 752 let mut cipher = Aes128Ctr::from_block_cipher(block, &nonce); 753 cipher.apply_keystream(&mut cipherkey); 754 } 755 756 let size = if aes256 { 32 } else { 16 }; 757 let key = hmac::Key::new(hmac::HMAC_SHA256, &derived_key[size..]); 758 let tag = hmac::sign(&key, &cipherkey); 759 760 let mut buf = vec![]; 761 buf.append(&mut pubk.as_ref().to_vec()); 762 buf.append(&mut tag.as_ref().to_vec()); 763 buf.append(&mut cipherkey); 764 765 if self.kinds.contains(&TlvKinds::ENCEC256) { 766 let size = if aes256 { 129 } else { 113 }; 767 assert!(buf.len() == size); 768 result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap(); 769 result.write_u16::<LittleEndian>(size as u16).unwrap(); 770 } else { 771 let size = if aes256 { 96 } else { 80 }; 772 assert!(buf.len() == size); 773 result.write_u16::<LittleEndian>(TlvKinds::ENCX25519 as u16).unwrap(); 774 result.write_u16::<LittleEndian>(size as u16).unwrap(); 775 } 776 result.extend_from_slice(&buf); 777 } 778 779 // Patch the size back into the TLV header. 780 let size = (result.len() - npro_pos) as u16; 781 let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4]; 782 size_buf.write_u16::<LittleEndian>(size).unwrap(); 783 784 // ECDSA is stored as an ASN.1 integer. For a 128-bit value, this maximally results in 33 785 // bytes of storage for each of the two values. If the high bit is zero, it will take 32 786 // bytes, if the top 8 bits are zero, it will take 31 bits, and so on. The smaller size 787 // will occur with decreasing likelihood. We'll allow this to get a bit smaller, hopefully 788 // allowing the tests to pass with false failures rare. For this case, we'll handle up to 789 // the top 16 bits of both numbers being all zeros (1 in 2^32). 790 if !Caps::has_ecdsa() { 791 if size_estimate != result.len() { 792 panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len()); 793 } 794 } else { 795 if size_estimate < result.len() || size_estimate > result.len() + 6 { 796 panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len()); 797 } 798 } 799 if size_estimate != result.len() { 800 log::warn!("Size off: {} actual {}", size_estimate, result.len()); 801 } 802 803 result 804 } 805 generate_enc_key(&mut self)806 fn generate_enc_key(&mut self) { 807 let rng = rand::SystemRandom::new(); 808 let flag = TlvFlags::ENCRYPTED_AES256 as u32; 809 let aes256 = (self.get_flags() & flag) == flag; 810 let mut buf = if aes256 { 811 vec![0u8; 32] 812 } else { 813 vec![0u8; 16] 814 }; 815 if rng.fill(&mut buf).is_err() { 816 panic!("Error generating encrypted key"); 817 } 818 info!("New encryption key: {:02x?}", buf); 819 self.enc_key = buf; 820 } 821 get_enc_key(&self) -> Vec<u8>822 fn get_enc_key(&self) -> Vec<u8> { 823 if self.enc_key.len() != 32 && self.enc_key.len() != 16 { 824 panic!("No random key was generated"); 825 } 826 self.enc_key.clone() 827 } 828 set_security_counter(&mut self, security_cnt: Option<u32>)829 fn set_security_counter(&mut self, security_cnt: Option<u32>) { 830 self.security_cnt = security_cnt; 831 } 832 set_ignore_ram_load_flag(&mut self)833 fn set_ignore_ram_load_flag(&mut self) { 834 self.ignore_ram_load_flag = true; 835 } 836 } 837 838 include!("rsa_pub_key-rs.txt"); 839 include!("rsa3072_pub_key-rs.txt"); 840 include!("ecdsa_pub_key-rs.txt"); 841 include!("ed25519_pub_key-rs.txt"); 842