| 714 | /// response, use the js_enc_key. |
| 715 | #[cfg(feature = "crypto")] |
| 716 | pub fn encrypt_join_accept_payload(&mut self, key: &AES128Key) -> Result<()> { |
| 717 | use aes::cipher::KeyInit; |
| 718 | |
| 719 | if self.mic.is_none() { |
| 720 | return Err(anyhow!("mic must be set first")); |
| 721 | } |
| 722 | |
| 723 | if let Payload::JoinAccept(pl) = &self.payload { |
| 724 | let mut pt = pl.to_vec()?; |
| 725 | pt.extend_from_slice(&self.mic.unwrap()); |
| 726 | |
| 727 | if pt.len() % 16 != 0 { |
| 728 | return Err(anyhow!("plaintext must be a multiple of 16 bytes")); |
| 729 | } |
| 730 | |
| 731 | let key_bytes = key.to_bytes(); |
| 732 | let key = Array::from(key_bytes); |
| 733 | let cipher = Aes128::new(&key); |
| 734 | |
| 735 | let mut ct = Vec::new(); |
| 736 | |
| 737 | for i in 0..(pt.len() / 16) { |
| 738 | let index = i * 16; |
| 739 | |
| 740 | let mut block = Block::try_from(&pt[index..index + 16])?; |
| 741 | cipher.decrypt_block(&mut block); |
| 742 | ct.extend_from_slice(block.as_slice()); |
| 743 | } |
| 744 | |
| 745 | self.payload = Payload::Raw(ct[0..ct.len() - 4].to_vec()); |
| 746 | let mut mic: [u8; 4] = [0; 4]; |
| 747 | mic.clone_from_slice(&ct[ct.len() - 4..]); |
| 748 | self.mic = Some(mic); |
| 749 | return Ok(()); |
| 750 | } |
| 751 | |
| 752 | Err(anyhow!("payload must be of type JoinAcceptPayload")) |
| 753 | } |
| 754 | |
| 755 | /// Decrypt the join-accept payload with the given key. |
| 756 | /// Note that the decryption must be performed before validating the MIC, since the MIC is part |