1//! High level interface to certain symmetric ciphers. 2//! 3//! # Examples 4//! 5//! Encrypt data in AES128 CBC mode 6//! 7//! ``` 8//! use openssl::symm::{encrypt, Cipher}; 9//! 10//! let cipher = Cipher::aes_128_cbc(); 11//! let data = b"Some Crypto Text"; 12//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; 13//! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; 14//! let ciphertext = encrypt( 15//! cipher, 16//! key, 17//! Some(iv), 18//! data).unwrap(); 19//! 20//! assert_eq!( 21//! b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\ 22//! \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1", 23//! &ciphertext[..]); 24//! ``` 25//! 26//! Encrypting an asymmetric key with a symmetric cipher 27//! 28//! ``` 29//! use openssl::rsa::{Padding, Rsa}; 30//! use openssl::symm::Cipher; 31//! 32//! // Generate keypair and encrypt private key: 33//! let keypair = Rsa::generate(2048).unwrap(); 34//! let cipher = Cipher::aes_256_cbc(); 35//! let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap(); 36//! let privkey_pem = keypair.private_key_to_pem_passphrase(cipher, b"Rust").unwrap(); 37//! // pubkey_pem and privkey_pem could be written to file here. 38//! 39//! // Load private and public key from string: 40//! let pubkey = Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); 41//! let privkey = Rsa::private_key_from_pem_passphrase(&privkey_pem, b"Rust").unwrap(); 42//! 43//! // Use the asymmetric keys to encrypt and decrypt a short message: 44//! let msg = b"Foo bar"; 45//! let mut encrypted = vec![0; pubkey.size() as usize]; 46//! let mut decrypted = vec![0; privkey.size() as usize]; 47//! let len = pubkey.public_encrypt(msg, &mut encrypted, Padding::PKCS1).unwrap(); 48//! assert!(len > msg.len()); 49//! let len = privkey.private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1).unwrap(); 50//! let output_string = String::from_utf8(decrypted[..len].to_vec()).unwrap(); 51//! assert_eq!("Foo bar", output_string); 52//! println!("Decrypted: '{}'", output_string); 53//! ``` 54use crate::cipher::CipherRef; 55use crate::cipher_ctx::{CipherCtx, CipherCtxRef}; 56use crate::error::ErrorStack; 57use crate::nid::Nid; 58use cfg_if::cfg_if; 59use foreign_types::ForeignTypeRef; 60 61#[derive(Copy, Clone)] 62pub enum Mode { 63 Encrypt, 64 Decrypt, 65} 66 67/// Represents a particular cipher algorithm. 68/// 69/// See OpenSSL doc at [`EVP_EncryptInit`] for more information on each algorithms. 70/// 71/// [`EVP_EncryptInit`]: https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html 72#[derive(Copy, Clone, PartialEq, Eq)] 73pub struct Cipher(*const ffi::EVP_CIPHER); 74 75impl Cipher { 76 /// Looks up the cipher for a certain nid. 77 /// 78 /// This corresponds to [`EVP_get_cipherbynid`] 79 /// 80 /// [`EVP_get_cipherbynid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_get_cipherbyname.html 81 pub fn from_nid(nid: Nid) -> Option<Cipher> { 82 let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) }; 83 if ptr.is_null() { 84 None 85 } else { 86 Some(Cipher(ptr)) 87 } 88 } 89 90 /// Returns the cipher's Nid. 91 /// 92 /// This corresponds to [`EVP_CIPHER_nid`] 93 /// 94 /// [`EVP_CIPHER_nid`]: https://www.openssl.org/docs/manmaster/crypto/EVP_CIPHER_nid.html 95 pub fn nid(&self) -> Nid { 96 let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) }; 97 Nid::from_raw(nid) 98 } 99 100 pub fn aes_128_ecb() -> Cipher { 101 unsafe { Cipher(ffi::EVP_aes_128_ecb()) } 102 } 103 104 pub fn aes_128_cbc() -> Cipher { 105 unsafe { Cipher(ffi::EVP_aes_128_cbc()) } 106 } 107 108 #[cfg(not(boringssl))] 109 pub fn aes_128_xts() -> Cipher { 110 unsafe { Cipher(ffi::EVP_aes_128_xts()) } 111 } 112 113 pub fn aes_128_ctr() -> Cipher { 114 unsafe { Cipher(ffi::EVP_aes_128_ctr()) } 115 } 116 117 #[cfg(not(boringssl))] 118 pub fn aes_128_cfb1() -> Cipher { 119 unsafe { Cipher(ffi::EVP_aes_128_cfb1()) } 120 } 121 122 pub fn aes_128_cfb128() -> Cipher { 123 unsafe { Cipher(ffi::EVP_aes_128_cfb128()) } 124 } 125 126 #[cfg(not(boringssl))] 127 pub fn aes_128_cfb8() -> Cipher { 128 unsafe { Cipher(ffi::EVP_aes_128_cfb8()) } 129 } 130 131 pub fn aes_128_gcm() -> Cipher { 132 unsafe { Cipher(ffi::EVP_aes_128_gcm()) } 133 } 134 135 #[cfg(not(boringssl))] 136 pub fn aes_128_ccm() -> Cipher { 137 unsafe { Cipher(ffi::EVP_aes_128_ccm()) } 138 } 139 140 pub fn aes_128_ofb() -> Cipher { 141 unsafe { Cipher(ffi::EVP_aes_128_ofb()) } 142 } 143 144 /// Requires OpenSSL 1.1.0 or newer. 145 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 146 pub fn aes_128_ocb() -> Cipher { 147 unsafe { Cipher(ffi::EVP_aes_128_ocb()) } 148 } 149 150 pub fn aes_192_ecb() -> Cipher { 151 unsafe { Cipher(ffi::EVP_aes_192_ecb()) } 152 } 153 154 pub fn aes_192_cbc() -> Cipher { 155 unsafe { Cipher(ffi::EVP_aes_192_cbc()) } 156 } 157 158 pub fn aes_192_ctr() -> Cipher { 159 unsafe { Cipher(ffi::EVP_aes_192_ctr()) } 160 } 161 162 #[cfg(not(boringssl))] 163 pub fn aes_192_cfb1() -> Cipher { 164 unsafe { Cipher(ffi::EVP_aes_192_cfb1()) } 165 } 166 167 pub fn aes_192_cfb128() -> Cipher { 168 unsafe { Cipher(ffi::EVP_aes_192_cfb128()) } 169 } 170 171 #[cfg(not(boringssl))] 172 pub fn aes_192_cfb8() -> Cipher { 173 unsafe { Cipher(ffi::EVP_aes_192_cfb8()) } 174 } 175 176 pub fn aes_192_gcm() -> Cipher { 177 unsafe { Cipher(ffi::EVP_aes_192_gcm()) } 178 } 179 180 #[cfg(not(boringssl))] 181 pub fn aes_192_ccm() -> Cipher { 182 unsafe { Cipher(ffi::EVP_aes_192_ccm()) } 183 } 184 185 pub fn aes_192_ofb() -> Cipher { 186 unsafe { Cipher(ffi::EVP_aes_192_ofb()) } 187 } 188 189 /// Requires OpenSSL 1.1.0 or newer. 190 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 191 pub fn aes_192_ocb() -> Cipher { 192 unsafe { Cipher(ffi::EVP_aes_192_ocb()) } 193 } 194 195 pub fn aes_256_ecb() -> Cipher { 196 unsafe { Cipher(ffi::EVP_aes_256_ecb()) } 197 } 198 199 pub fn aes_256_cbc() -> Cipher { 200 unsafe { Cipher(ffi::EVP_aes_256_cbc()) } 201 } 202 203 #[cfg(not(boringssl))] 204 pub fn aes_256_xts() -> Cipher { 205 unsafe { Cipher(ffi::EVP_aes_256_xts()) } 206 } 207 208 pub fn aes_256_ctr() -> Cipher { 209 unsafe { Cipher(ffi::EVP_aes_256_ctr()) } 210 } 211 212 #[cfg(not(boringssl))] 213 pub fn aes_256_cfb1() -> Cipher { 214 unsafe { Cipher(ffi::EVP_aes_256_cfb1()) } 215 } 216 217 pub fn aes_256_cfb128() -> Cipher { 218 unsafe { Cipher(ffi::EVP_aes_256_cfb128()) } 219 } 220 221 #[cfg(not(boringssl))] 222 pub fn aes_256_cfb8() -> Cipher { 223 unsafe { Cipher(ffi::EVP_aes_256_cfb8()) } 224 } 225 226 pub fn aes_256_gcm() -> Cipher { 227 unsafe { Cipher(ffi::EVP_aes_256_gcm()) } 228 } 229 230 #[cfg(not(boringssl))] 231 pub fn aes_256_ccm() -> Cipher { 232 unsafe { Cipher(ffi::EVP_aes_256_ccm()) } 233 } 234 235 pub fn aes_256_ofb() -> Cipher { 236 unsafe { Cipher(ffi::EVP_aes_256_ofb()) } 237 } 238 239 /// Requires OpenSSL 1.1.0 or newer. 240 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 241 pub fn aes_256_ocb() -> Cipher { 242 unsafe { Cipher(ffi::EVP_aes_256_ocb()) } 243 } 244 245 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] 246 pub fn bf_cbc() -> Cipher { 247 unsafe { Cipher(ffi::EVP_bf_cbc()) } 248 } 249 250 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] 251 pub fn bf_ecb() -> Cipher { 252 unsafe { Cipher(ffi::EVP_bf_ecb()) } 253 } 254 255 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))] 256 pub fn bf_cfb64() -> Cipher { 257 unsafe { Cipher(ffi::EVP_bf_cfb64()) } 258 } 259 260 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))] 261 pub fn bf_ofb() -> Cipher { 262 unsafe { Cipher(ffi::EVP_bf_ofb()) } 263 } 264 265 pub fn des_cbc() -> Cipher { 266 unsafe { Cipher(ffi::EVP_des_cbc()) } 267 } 268 269 pub fn des_ecb() -> Cipher { 270 unsafe { Cipher(ffi::EVP_des_ecb()) } 271 } 272 273 pub fn des_ede3() -> Cipher { 274 unsafe { Cipher(ffi::EVP_des_ede3()) } 275 } 276 277 pub fn des_ede3_cbc() -> Cipher { 278 unsafe { Cipher(ffi::EVP_des_ede3_cbc()) } 279 } 280 281 #[cfg(not(boringssl))] 282 pub fn des_ede3_cfb64() -> Cipher { 283 unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) } 284 } 285 286 #[cfg(not(osslconf = "OPENSSL_NO_RC4"))] 287 pub fn rc4() -> Cipher { 288 unsafe { Cipher(ffi::EVP_rc4()) } 289 } 290 291 /// Requires OpenSSL 1.1.0 or newer. 292 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] 293 pub fn chacha20() -> Cipher { 294 unsafe { Cipher(ffi::EVP_chacha20()) } 295 } 296 297 /// Requires OpenSSL 1.1.0 or newer. 298 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] 299 pub fn chacha20_poly1305() -> Cipher { 300 unsafe { Cipher(ffi::EVP_chacha20_poly1305()) } 301 } 302 303 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] 304 pub fn seed_cbc() -> Cipher { 305 unsafe { Cipher(ffi::EVP_seed_cbc()) } 306 } 307 308 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] 309 pub fn seed_cfb128() -> Cipher { 310 unsafe { Cipher(ffi::EVP_seed_cfb128()) } 311 } 312 313 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] 314 pub fn seed_ecb() -> Cipher { 315 unsafe { Cipher(ffi::EVP_seed_ecb()) } 316 } 317 318 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] 319 pub fn seed_ofb() -> Cipher { 320 unsafe { Cipher(ffi::EVP_seed_ofb()) } 321 } 322 323 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 324 pub fn sm4_ecb() -> Cipher { 325 unsafe { Cipher(ffi::EVP_sm4_ecb()) } 326 } 327 328 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 329 pub fn sm4_cbc() -> Cipher { 330 unsafe { Cipher(ffi::EVP_sm4_cbc()) } 331 } 332 333 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 334 pub fn sm4_ctr() -> Cipher { 335 unsafe { Cipher(ffi::EVP_sm4_ctr()) } 336 } 337 338 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 339 pub fn sm4_cfb128() -> Cipher { 340 unsafe { Cipher(ffi::EVP_sm4_cfb128()) } 341 } 342 343 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 344 pub fn sm4_ofb() -> Cipher { 345 unsafe { Cipher(ffi::EVP_sm4_ofb()) } 346 } 347 348 /// Creates a `Cipher` from a raw pointer to its OpenSSL type. 349 /// 350 /// # Safety 351 /// 352 /// The caller must ensure the pointer is valid for the `'static` lifetime. 353 pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher { 354 Cipher(ptr) 355 } 356 357 #[allow(clippy::trivially_copy_pass_by_ref)] 358 pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER { 359 self.0 360 } 361 362 /// Returns the length of keys used with this cipher. 363 #[allow(clippy::trivially_copy_pass_by_ref)] 364 pub fn key_len(&self) -> usize { 365 unsafe { EVP_CIPHER_key_length(self.0) as usize } 366 } 367 368 /// Returns the length of the IV used with this cipher, or `None` if the 369 /// cipher does not use an IV. 370 #[allow(clippy::trivially_copy_pass_by_ref)] 371 pub fn iv_len(&self) -> Option<usize> { 372 unsafe { 373 let len = EVP_CIPHER_iv_length(self.0) as usize; 374 if len == 0 { 375 None 376 } else { 377 Some(len) 378 } 379 } 380 } 381 382 /// Returns the block size of the cipher. 383 /// 384 /// # Note 385 /// 386 /// Stream ciphers such as RC4 have a block size of 1. 387 #[allow(clippy::trivially_copy_pass_by_ref)] 388 pub fn block_size(&self) -> usize { 389 unsafe { EVP_CIPHER_block_size(self.0) as usize } 390 } 391 392 /// Determines whether the cipher is using CCM mode 393 #[cfg(not(boringssl))] 394 fn is_ccm(self) -> bool { 395 // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected 396 self == Cipher::aes_128_ccm() || self == Cipher::aes_256_ccm() 397 } 398 399 #[cfg(boringssl)] 400 fn is_ccm(self) -> bool { 401 false 402 } 403 404 /// Determines whether the cipher is using OCB mode 405 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 406 fn is_ocb(self) -> bool { 407 self == Cipher::aes_128_ocb() 408 || self == Cipher::aes_192_ocb() 409 || self == Cipher::aes_256_ocb() 410 } 411 412 #[cfg(any(not(ossl110), osslconf = "OPENSSL_NO_OCB"))] 413 const fn is_ocb(self) -> bool { 414 false 415 } 416} 417 418unsafe impl Sync for Cipher {} 419unsafe impl Send for Cipher {} 420 421/// Represents a symmetric cipher context. 422/// 423/// Padding is enabled by default. 424/// 425/// # Examples 426/// 427/// Encrypt some plaintext in chunks, then decrypt the ciphertext back into plaintext, in AES 128 428/// CBC mode. 429/// 430/// ``` 431/// use openssl::symm::{Cipher, Mode, Crypter}; 432/// 433/// let plaintexts: [&[u8]; 2] = [b"Some Stream of", b" Crypto Text"]; 434/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; 435/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; 436/// let data_len = plaintexts.iter().fold(0, |sum, x| sum + x.len()); 437/// 438/// // Create a cipher context for encryption. 439/// let mut encrypter = Crypter::new( 440/// Cipher::aes_128_cbc(), 441/// Mode::Encrypt, 442/// key, 443/// Some(iv)).unwrap(); 444/// 445/// let block_size = Cipher::aes_128_cbc().block_size(); 446/// let mut ciphertext = vec![0; data_len + block_size]; 447/// 448/// // Encrypt 2 chunks of plaintexts successively. 449/// let mut count = encrypter.update(plaintexts[0], &mut ciphertext).unwrap(); 450/// count += encrypter.update(plaintexts[1], &mut ciphertext[count..]).unwrap(); 451/// count += encrypter.finalize(&mut ciphertext[count..]).unwrap(); 452/// ciphertext.truncate(count); 453/// 454/// assert_eq!( 455/// b"\x0F\x21\x83\x7E\xB2\x88\x04\xAF\xD9\xCC\xE2\x03\x49\xB4\x88\xF6\xC4\x61\x0E\x32\x1C\xF9\ 456/// \x0D\x66\xB1\xE6\x2C\x77\x76\x18\x8D\x99", 457/// &ciphertext[..] 458/// ); 459/// 460/// 461/// // Let's pretend we don't know the plaintext, and now decrypt the ciphertext. 462/// let data_len = ciphertext.len(); 463/// let ciphertexts = [&ciphertext[..9], &ciphertext[9..]]; 464/// 465/// // Create a cipher context for decryption. 466/// let mut decrypter = Crypter::new( 467/// Cipher::aes_128_cbc(), 468/// Mode::Decrypt, 469/// key, 470/// Some(iv)).unwrap(); 471/// let mut plaintext = vec![0; data_len + block_size]; 472/// 473/// // Decrypt 2 chunks of ciphertexts successively. 474/// let mut count = decrypter.update(ciphertexts[0], &mut plaintext).unwrap(); 475/// count += decrypter.update(ciphertexts[1], &mut plaintext[count..]).unwrap(); 476/// count += decrypter.finalize(&mut plaintext[count..]).unwrap(); 477/// plaintext.truncate(count); 478/// 479/// assert_eq!(b"Some Stream of Crypto Text", &plaintext[..]); 480/// ``` 481pub struct Crypter { 482 ctx: CipherCtx, 483} 484 485impl Crypter { 486 /// Creates a new `Crypter`. The initialisation vector, `iv`, is not necessary for certain 487 /// types of `Cipher`. 488 /// 489 /// # Panics 490 /// 491 /// Panics if an IV is required by the cipher but not provided. Also make sure that the key 492 /// and IV size are appropriate for your cipher. 493 pub fn new( 494 t: Cipher, 495 mode: Mode, 496 key: &[u8], 497 iv: Option<&[u8]>, 498 ) -> Result<Crypter, ErrorStack> { 499 let mut ctx = CipherCtx::new()?; 500 501 let f = match mode { 502 Mode::Encrypt => CipherCtxRef::encrypt_init, 503 Mode::Decrypt => CipherCtxRef::decrypt_init, 504 }; 505 506 f( 507 &mut ctx, 508 Some(unsafe { CipherRef::from_ptr(t.as_ptr() as *mut _) }), 509 None, 510 None, 511 )?; 512 513 ctx.set_key_length(key.len())?; 514 515 if let (Some(iv), Some(iv_len)) = (iv, t.iv_len()) { 516 if iv.len() != iv_len { 517 ctx.set_iv_length(iv.len())?; 518 } 519 } 520 521 f(&mut ctx, None, Some(key), iv)?; 522 523 Ok(Crypter { ctx }) 524 } 525 526 /// Enables or disables padding. 527 /// 528 /// If padding is disabled, total amount of data encrypted/decrypted must 529 /// be a multiple of the cipher's block size. 530 pub fn pad(&mut self, padding: bool) { 531 self.ctx.set_padding(padding) 532 } 533 534 /// Sets the tag used to authenticate ciphertext in AEAD ciphers such as AES GCM. 535 /// 536 /// When decrypting cipher text using an AEAD cipher, this must be called before `finalize`. 537 pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> { 538 self.ctx.set_tag(tag) 539 } 540 541 /// Sets the length of the authentication tag to generate in AES CCM. 542 /// 543 /// When encrypting with AES CCM, the tag length needs to be explicitly set in order 544 /// to use a value different than the default 12 bytes. 545 pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> { 546 self.ctx.set_tag_length(tag_len) 547 } 548 549 /// Feeds total plaintext length to the cipher. 550 /// 551 /// The total plaintext or ciphertext length MUST be passed to the cipher when it operates in 552 /// CCM mode. 553 pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> { 554 self.ctx.set_data_len(data_len) 555 } 556 557 /// Feeds Additional Authenticated Data (AAD) through the cipher. 558 /// 559 /// This can only be used with AEAD ciphers such as AES GCM. Data fed in is not encrypted, but 560 /// is factored into the authentication tag. It must be called before the first call to 561 /// `update`. 562 pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> { 563 self.ctx.cipher_update(input, None)?; 564 Ok(()) 565 } 566 567 /// Feeds data from `input` through the cipher, writing encrypted/decrypted 568 /// bytes into `output`. 569 /// 570 /// The number of bytes written to `output` is returned. Note that this may 571 /// not be equal to the length of `input`. 572 /// 573 /// # Panics 574 /// 575 /// Panics for stream ciphers if `output.len() < input.len()`. 576 /// 577 /// Panics for block ciphers if `output.len() < input.len() + block_size`, 578 /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). 579 /// 580 /// Panics if `output.len() > c_int::max_value()`. 581 pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> { 582 self.ctx.cipher_update(input, Some(output)) 583 } 584 585 /// Finishes the encryption/decryption process, writing any remaining data 586 /// to `output`. 587 /// 588 /// The number of bytes written to `output` is returned. 589 /// 590 /// `update` should not be called after this method. 591 /// 592 /// # Panics 593 /// 594 /// Panics for block ciphers if `output.len() < block_size`, 595 /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). 596 pub fn finalize(&mut self, output: &mut [u8]) -> Result<usize, ErrorStack> { 597 self.ctx.cipher_final(output) 598 } 599 600 /// Retrieves the authentication tag used to authenticate ciphertext in AEAD ciphers such 601 /// as AES GCM. 602 /// 603 /// When encrypting data with an AEAD cipher, this must be called after `finalize`. 604 /// 605 /// The size of the buffer indicates the required size of the tag. While some ciphers support a 606 /// range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 607 /// bytes, for example. 608 pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { 609 self.ctx.tag(tag) 610 } 611} 612 613/// Encrypts data in one go, and returns the encrypted data. 614/// 615/// Data is encrypted using the specified cipher type `t` in encrypt mode with the specified `key` 616/// and initialization vector `iv`. Padding is enabled. 617/// 618/// This is a convenient interface to `Crypter` to encrypt all data in one go. To encrypt a stream 619/// of data incrementally , use `Crypter` instead. 620/// 621/// # Examples 622/// 623/// Encrypt data in AES128 CBC mode 624/// 625/// ``` 626/// use openssl::symm::{encrypt, Cipher}; 627/// 628/// let cipher = Cipher::aes_128_cbc(); 629/// let data = b"Some Crypto Text"; 630/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; 631/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; 632/// let ciphertext = encrypt( 633/// cipher, 634/// key, 635/// Some(iv), 636/// data).unwrap(); 637/// 638/// assert_eq!( 639/// b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\ 640/// \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1", 641/// &ciphertext[..]); 642/// ``` 643pub fn encrypt( 644 t: Cipher, 645 key: &[u8], 646 iv: Option<&[u8]>, 647 data: &[u8], 648) -> Result<Vec<u8>, ErrorStack> { 649 cipher(t, Mode::Encrypt, key, iv, data) 650} 651 652/// Decrypts data in one go, and returns the decrypted data. 653/// 654/// Data is decrypted using the specified cipher type `t` in decrypt mode with the specified `key` 655/// and initialization vector `iv`. Padding is enabled. 656/// 657/// This is a convenient interface to `Crypter` to decrypt all data in one go. To decrypt a stream 658/// of data incrementally , use `Crypter` instead. 659/// 660/// # Examples 661/// 662/// Decrypt data in AES128 CBC mode 663/// 664/// ``` 665/// use openssl::symm::{decrypt, Cipher}; 666/// 667/// let cipher = Cipher::aes_128_cbc(); 668/// let data = b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\ 669/// \x87\x4D\xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1"; 670/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; 671/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; 672/// let ciphertext = decrypt( 673/// cipher, 674/// key, 675/// Some(iv), 676/// data).unwrap(); 677/// 678/// assert_eq!( 679/// b"Some Crypto Text", 680/// &ciphertext[..]); 681/// ``` 682pub fn decrypt( 683 t: Cipher, 684 key: &[u8], 685 iv: Option<&[u8]>, 686 data: &[u8], 687) -> Result<Vec<u8>, ErrorStack> { 688 cipher(t, Mode::Decrypt, key, iv, data) 689} 690 691fn cipher( 692 t: Cipher, 693 mode: Mode, 694 key: &[u8], 695 iv: Option<&[u8]>, 696 data: &[u8], 697) -> Result<Vec<u8>, ErrorStack> { 698 let mut c = Crypter::new(t, mode, key, iv)?; 699 let mut out = vec![0; data.len() + t.block_size()]; 700 let count = c.update(data, &mut out)?; 701 let rest = c.finalize(&mut out[count..])?; 702 out.truncate(count + rest); 703 Ok(out) 704} 705 706/// Like `encrypt`, but for AEAD ciphers such as AES GCM. 707/// 708/// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag 709/// will be copied into the `tag` field. 710/// 711/// The size of the `tag` buffer indicates the required size of the tag. While some ciphers support 712/// a range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 bytes, 713/// for example. 714pub fn encrypt_aead( 715 t: Cipher, 716 key: &[u8], 717 iv: Option<&[u8]>, 718 aad: &[u8], 719 data: &[u8], 720 tag: &mut [u8], 721) -> Result<Vec<u8>, ErrorStack> { 722 let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?; 723 let mut out = vec![0; data.len() + t.block_size()]; 724 725 let is_ccm = t.is_ccm(); 726 if is_ccm || t.is_ocb() { 727 c.set_tag_len(tag.len())?; 728 if is_ccm { 729 c.set_data_len(data.len())?; 730 } 731 } 732 733 c.aad_update(aad)?; 734 let count = c.update(data, &mut out)?; 735 let rest = c.finalize(&mut out[count..])?; 736 c.get_tag(tag)?; 737 out.truncate(count + rest); 738 Ok(out) 739} 740 741/// Like `decrypt`, but for AEAD ciphers such as AES GCM. 742/// 743/// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag 744/// should be provided in the `tag` field. 745pub fn decrypt_aead( 746 t: Cipher, 747 key: &[u8], 748 iv: Option<&[u8]>, 749 aad: &[u8], 750 data: &[u8], 751 tag: &[u8], 752) -> Result<Vec<u8>, ErrorStack> { 753 let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?; 754 let mut out = vec![0; data.len() + t.block_size()]; 755 756 let is_ccm = t.is_ccm(); 757 if is_ccm || t.is_ocb() { 758 c.set_tag(tag)?; 759 if is_ccm { 760 c.set_data_len(data.len())?; 761 } 762 } 763 764 c.aad_update(aad)?; 765 let count = c.update(data, &mut out)?; 766 767 let rest = if t.is_ccm() { 768 0 769 } else { 770 c.set_tag(tag)?; 771 c.finalize(&mut out[count..])? 772 }; 773 774 out.truncate(count + rest); 775 Ok(out) 776} 777 778cfg_if! { 779 if #[cfg(any(boringssl, ossl110, libressl273))] { 780 use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; 781 } else { 782 use crate::LenType; 783 784 #[allow(bad_style)] 785 pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType { 786 (*ptr).iv_len 787 } 788 789 #[allow(bad_style)] 790 pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType { 791 (*ptr).block_size 792 } 793 794 #[allow(bad_style)] 795 pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> LenType { 796 (*ptr).key_len 797 } 798 } 799} 800 801#[cfg(test)] 802mod tests { 803 use super::*; 804 use hex::{self, FromHex}; 805 806 #[test] 807 fn test_stream_cipher_output() { 808 let key = [0u8; 16]; 809 let iv = [0u8; 16]; 810 let mut c = super::Crypter::new( 811 super::Cipher::aes_128_ctr(), 812 super::Mode::Encrypt, 813 &key, 814 Some(&iv), 815 ) 816 .unwrap(); 817 818 assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15); 819 assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1); 820 assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0); 821 } 822 823 // Test vectors from FIPS-197: 824 // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf 825 #[test] 826 fn test_aes_256_ecb() { 827 let k0 = [ 828 0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8, 829 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8, 830 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8, 831 ]; 832 let p0 = [ 833 0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8, 834 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8, 835 ]; 836 let c0 = [ 837 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8, 838 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8, 839 ]; 840 let mut c = super::Crypter::new( 841 super::Cipher::aes_256_ecb(), 842 super::Mode::Encrypt, 843 &k0, 844 None, 845 ) 846 .unwrap(); 847 c.pad(false); 848 let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()]; 849 let count = c.update(&p0, &mut r0).unwrap(); 850 let rest = c.finalize(&mut r0[count..]).unwrap(); 851 r0.truncate(count + rest); 852 assert_eq!(hex::encode(&r0), hex::encode(c0)); 853 854 let mut c = super::Crypter::new( 855 super::Cipher::aes_256_ecb(), 856 super::Mode::Decrypt, 857 &k0, 858 None, 859 ) 860 .unwrap(); 861 c.pad(false); 862 let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()]; 863 let count = c.update(&r0, &mut p1).unwrap(); 864 let rest = c.finalize(&mut p1[count..]).unwrap(); 865 p1.truncate(count + rest); 866 assert_eq!(hex::encode(p1), hex::encode(p0)); 867 } 868 869 #[test] 870 fn test_aes_256_cbc_decrypt() { 871 let iv = [ 872 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8, 873 107_u8, 208_u8, 14_u8, 236_u8, 60_u8, 874 ]; 875 let data = [ 876 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8, 877 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8, 878 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8, 879 ]; 880 let ciphered_data = [ 881 0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8, 882 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8, 883 ]; 884 let mut cr = super::Crypter::new( 885 super::Cipher::aes_256_cbc(), 886 super::Mode::Decrypt, 887 &data, 888 Some(&iv), 889 ) 890 .unwrap(); 891 cr.pad(false); 892 let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()]; 893 let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap(); 894 let rest = cr.finalize(&mut unciphered_data[count..]).unwrap(); 895 unciphered_data.truncate(count + rest); 896 897 let expected_unciphered_data = b"I love turtles.\x01"; 898 899 assert_eq!(&unciphered_data, expected_unciphered_data); 900 } 901 902 fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) { 903 let pt = Vec::from_hex(pt).unwrap(); 904 let ct = Vec::from_hex(ct).unwrap(); 905 let key = Vec::from_hex(key).unwrap(); 906 let iv = Vec::from_hex(iv).unwrap(); 907 908 let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap(); 909 let expected = pt; 910 911 if computed != expected { 912 println!("Computed: {}", hex::encode(&computed)); 913 println!("Expected: {}", hex::encode(&expected)); 914 if computed.len() != expected.len() { 915 println!( 916 "Lengths differ: {} in computed vs {} expected", 917 computed.len(), 918 expected.len() 919 ); 920 } 921 panic!("test failure"); 922 } 923 } 924 925 #[cfg(not(boringssl))] 926 fn cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) { 927 let pt = Vec::from_hex(pt).unwrap(); 928 let ct = Vec::from_hex(ct).unwrap(); 929 let key = Vec::from_hex(key).unwrap(); 930 let iv = Vec::from_hex(iv).unwrap(); 931 932 let computed = { 933 let mut c = Crypter::new(ciphertype, Mode::Decrypt, &key, Some(&iv)).unwrap(); 934 c.pad(false); 935 let mut out = vec![0; ct.len() + ciphertype.block_size()]; 936 let count = c.update(&ct, &mut out).unwrap(); 937 let rest = c.finalize(&mut out[count..]).unwrap(); 938 out.truncate(count + rest); 939 out 940 }; 941 let expected = pt; 942 943 if computed != expected { 944 println!("Computed: {}", hex::encode(&computed)); 945 println!("Expected: {}", hex::encode(&expected)); 946 if computed.len() != expected.len() { 947 println!( 948 "Lengths differ: {} in computed vs {} expected", 949 computed.len(), 950 expected.len() 951 ); 952 } 953 panic!("test failure"); 954 } 955 } 956 957 #[test] 958 fn test_rc4() { 959 #[cfg(ossl300)] 960 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 961 962 let pt = "0000000000000000000000000000000000000000000000000000000000000000000000000000"; 963 let ct = "A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; 964 let key = "97CD440324DA5FD1F7955C1C13B6B466"; 965 let iv = ""; 966 967 cipher_test(super::Cipher::rc4(), pt, ct, key, iv); 968 } 969 970 #[test] 971 #[cfg(not(boringssl))] 972 fn test_aes256_xts() { 973 // Test case 174 from 974 // http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip 975 let pt = "77f4ef63d734ebd028508da66c22cdebdd52ecd6ee2ab0a50bc8ad0cfd692ca5fcd4e6dedc45df7f\ 976 6503f462611dc542"; 977 let ct = "ce7d905a7776ac72f240d22aafed5e4eb7566cdc7211220e970da634ce015f131a5ecb8d400bc9e8\ 978 4f0b81d8725dbbc7"; 979 let key = "b6bfef891f83b5ff073f2231267be51eb084b791fa19a154399c0684c8b2dfcb37de77d28bbda3b\ 980 4180026ad640b74243b3133e7b9fae629403f6733423dae28"; 981 let iv = "db200efb7eaaa737dbdf40babb68953f"; 982 983 cipher_test(super::Cipher::aes_256_xts(), pt, ct, key, iv); 984 } 985 986 #[test] 987 fn test_aes128_ctr() { 988 let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\ 989 E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"; 990 let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\ 991 5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE"; 992 let key = "2B7E151628AED2A6ABF7158809CF4F3C"; 993 let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"; 994 995 cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv); 996 } 997 998 #[test] 999 #[cfg(not(boringssl))] 1000 fn test_aes128_cfb1() { 1001 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1002 1003 let pt = "6bc1"; 1004 let ct = "68b3"; 1005 let key = "2b7e151628aed2a6abf7158809cf4f3c"; 1006 let iv = "000102030405060708090a0b0c0d0e0f"; 1007 1008 cipher_test(super::Cipher::aes_128_cfb1(), pt, ct, key, iv); 1009 } 1010 1011 #[test] 1012 #[cfg(not(boringssl))] 1013 fn test_aes128_cfb128() { 1014 let pt = "6bc1bee22e409f96e93d7e117393172a"; 1015 let ct = "3b3fd92eb72dad20333449f8e83cfb4a"; 1016 let key = "2b7e151628aed2a6abf7158809cf4f3c"; 1017 let iv = "000102030405060708090a0b0c0d0e0f"; 1018 1019 cipher_test(super::Cipher::aes_128_cfb128(), pt, ct, key, iv); 1020 } 1021 1022 #[test] 1023 #[cfg(not(boringssl))] 1024 fn test_aes128_cfb8() { 1025 let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; 1026 let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9"; 1027 let key = "2b7e151628aed2a6abf7158809cf4f3c"; 1028 let iv = "000102030405060708090a0b0c0d0e0f"; 1029 1030 cipher_test(super::Cipher::aes_128_cfb8(), pt, ct, key, iv); 1031 } 1032 1033 #[test] 1034 fn test_aes128_ofb() { 1035 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1036 1037 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; 1038 let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"; 1039 let key = "2b7e151628aed2a6abf7158809cf4f3c"; 1040 let iv = "000102030405060708090a0b0c0d0e0f"; 1041 1042 cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv); 1043 } 1044 1045 #[test] 1046 fn test_aes192_ctr() { 1047 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1048 1049 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; 1050 let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050"; 1051 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; 1052 let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; 1053 1054 cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv); 1055 } 1056 1057 #[test] 1058 #[cfg(not(boringssl))] 1059 fn test_aes192_cfb1() { 1060 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1061 1062 let pt = "6bc1"; 1063 let ct = "9359"; 1064 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; 1065 let iv = "000102030405060708090a0b0c0d0e0f"; 1066 1067 cipher_test(super::Cipher::aes_192_cfb1(), pt, ct, key, iv); 1068 } 1069 1070 #[test] 1071 #[cfg(not(boringssl))] 1072 fn test_aes192_cfb128() { 1073 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1074 1075 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; 1076 let ct = "cdc80d6fddf18cab34c25909c99a417467ce7f7f81173621961a2b70171d3d7a2e1e8a1dd59b88b1c8e60fed1efac4c9c05f9f9ca9834fa042ae8fba584b09ff"; 1077 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; 1078 let iv = "000102030405060708090a0b0c0d0e0f"; 1079 1080 cipher_test(super::Cipher::aes_192_cfb128(), pt, ct, key, iv); 1081 } 1082 1083 #[test] 1084 #[cfg(not(boringssl))] 1085 fn test_aes192_cfb8() { 1086 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1087 1088 let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; 1089 let ct = "cda2521ef0a905ca44cd057cbf0d47a0678a"; 1090 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; 1091 let iv = "000102030405060708090a0b0c0d0e0f"; 1092 1093 cipher_test(super::Cipher::aes_192_cfb8(), pt, ct, key, iv); 1094 } 1095 1096 #[test] 1097 fn test_aes192_ofb() { 1098 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1099 1100 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; 1101 let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a"; 1102 let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; 1103 let iv = "000102030405060708090a0b0c0d0e0f"; 1104 1105 cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv); 1106 } 1107 1108 #[test] 1109 #[cfg(not(boringssl))] 1110 fn test_aes256_cfb1() { 1111 let pt = "6bc1"; 1112 let ct = "9029"; 1113 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 1114 let iv = "000102030405060708090a0b0c0d0e0f"; 1115 1116 cipher_test(super::Cipher::aes_256_cfb1(), pt, ct, key, iv); 1117 } 1118 1119 #[test] 1120 #[cfg(not(boringssl))] 1121 fn test_aes256_cfb128() { 1122 let pt = "6bc1bee22e409f96e93d7e117393172a"; 1123 let ct = "dc7e84bfda79164b7ecd8486985d3860"; 1124 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 1125 let iv = "000102030405060708090a0b0c0d0e0f"; 1126 1127 cipher_test(super::Cipher::aes_256_cfb128(), pt, ct, key, iv); 1128 } 1129 1130 #[test] 1131 #[cfg(not(boringssl))] 1132 fn test_aes256_cfb8() { 1133 let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; 1134 let ct = "dc1f1a8520a64db55fcc8ac554844e889700"; 1135 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 1136 let iv = "000102030405060708090a0b0c0d0e0f"; 1137 1138 cipher_test(super::Cipher::aes_256_cfb8(), pt, ct, key, iv); 1139 } 1140 1141 #[test] 1142 fn test_aes256_ofb() { 1143 // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 1144 1145 let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; 1146 let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484"; 1147 let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 1148 let iv = "000102030405060708090a0b0c0d0e0f"; 1149 1150 cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv); 1151 } 1152 1153 #[test] 1154 #[cfg_attr(ossl300, ignore)] 1155 #[cfg(not(boringssl))] 1156 fn test_bf_cbc() { 1157 #[cfg(ossl300)] 1158 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1159 1160 // https://www.schneier.com/code/vectors.txt 1161 1162 let pt = "37363534333231204E6F77206973207468652074696D6520666F722000000000"; 1163 let ct = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"; 1164 let key = "0123456789ABCDEFF0E1D2C3B4A59687"; 1165 let iv = "FEDCBA9876543210"; 1166 1167 cipher_test_nopad(super::Cipher::bf_cbc(), pt, ct, key, iv); 1168 } 1169 1170 #[test] 1171 #[cfg_attr(ossl300, ignore)] 1172 #[cfg(not(boringssl))] 1173 fn test_bf_ecb() { 1174 #[cfg(ossl300)] 1175 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1176 1177 let pt = "5CD54CA83DEF57DA"; 1178 let ct = "B1B8CC0B250F09A0"; 1179 let key = "0131D9619DC1376E"; 1180 let iv = "0000000000000000"; 1181 1182 cipher_test_nopad(super::Cipher::bf_ecb(), pt, ct, key, iv); 1183 } 1184 1185 #[test] 1186 #[cfg_attr(ossl300, ignore)] 1187 #[cfg(not(boringssl))] 1188 fn test_bf_cfb64() { 1189 #[cfg(ossl300)] 1190 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1191 1192 let pt = "37363534333231204E6F77206973207468652074696D6520666F722000"; 1193 let ct = "E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"; 1194 let key = "0123456789ABCDEFF0E1D2C3B4A59687"; 1195 let iv = "FEDCBA9876543210"; 1196 1197 cipher_test_nopad(super::Cipher::bf_cfb64(), pt, ct, key, iv); 1198 } 1199 1200 #[test] 1201 #[cfg_attr(ossl300, ignore)] 1202 #[cfg(not(boringssl))] 1203 fn test_bf_ofb() { 1204 #[cfg(ossl300)] 1205 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1206 1207 let pt = "37363534333231204E6F77206973207468652074696D6520666F722000"; 1208 let ct = "E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"; 1209 let key = "0123456789ABCDEFF0E1D2C3B4A59687"; 1210 let iv = "FEDCBA9876543210"; 1211 1212 cipher_test_nopad(super::Cipher::bf_ofb(), pt, ct, key, iv); 1213 } 1214 1215 #[test] 1216 fn test_des_cbc() { 1217 #[cfg(ossl300)] 1218 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1219 1220 let pt = "54686973206973206120746573742e"; 1221 let ct = "6f2867cfefda048a4046ef7e556c7132"; 1222 let key = "7cb66337f3d3c0fe"; 1223 let iv = "0001020304050607"; 1224 1225 cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv); 1226 } 1227 1228 #[test] 1229 fn test_des_ecb() { 1230 #[cfg(ossl300)] 1231 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1232 1233 let pt = "54686973206973206120746573742e"; 1234 let ct = "0050ab8aecec758843fe157b4dde938c"; 1235 let key = "7cb66337f3d3c0fe"; 1236 let iv = "0001020304050607"; 1237 1238 cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv); 1239 } 1240 1241 #[test] 1242 fn test_des_ede3() { 1243 let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd"; 1244 let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd"; 1245 let key = "010203040506070801020304050607080102030405060708"; 1246 let iv = "5cc118306dc702e4"; 1247 1248 cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv); 1249 } 1250 1251 #[test] 1252 fn test_des_ede3_cbc() { 1253 let pt = "54686973206973206120746573742e"; 1254 let ct = "6f2867cfefda048a4046ef7e556c7132"; 1255 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; 1256 let iv = "0001020304050607"; 1257 1258 cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv); 1259 } 1260 1261 #[test] 1262 #[cfg(not(boringssl))] 1263 fn test_des_ede3_cfb64() { 1264 let pt = "2b1773784b5889dc788477367daa98ad"; 1265 let ct = "6f2867cfefda048a4046ef7e556c7132"; 1266 let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; 1267 let iv = "0001020304050607"; 1268 1269 cipher_test(super::Cipher::des_ede3_cfb64(), pt, ct, key, iv); 1270 } 1271 1272 #[test] 1273 fn test_aes128_gcm() { 1274 let key = "23dc8d23d95b6fd1251741a64f7d4f41"; 1275 let iv = "f416f48ad44d9efa1179e167"; 1276 let pt = "6cb9b71dd0ccd42cdf87e8e396fc581fd8e0d700e360f590593b748e105390de"; 1277 let aad = "45074844c97d515c65bbe37c210a5a4b08c21c588efe5c5f73c4d9c17d34dacddc0bb6a8a53f7bf477b9780c1c2a928660df87016b2873fe876b2b887fb5886bfd63216b7eaecc046372a82c047eb043f0b063226ee52a12c69b"; 1278 let ct = "8ad20486778e87387efb3f2574e509951c0626816722018129e578b2787969d3"; 1279 let tag = "91e1bc09"; 1280 1281 // this tag is smaller than you'd normally want, but I pulled this test from the part of 1282 // the NIST test vectors that cover 4 byte tags. 1283 let mut actual_tag = [0; 4]; 1284 let out = encrypt_aead( 1285 Cipher::aes_128_gcm(), 1286 &Vec::from_hex(key).unwrap(), 1287 Some(&Vec::from_hex(iv).unwrap()), 1288 &Vec::from_hex(aad).unwrap(), 1289 &Vec::from_hex(pt).unwrap(), 1290 &mut actual_tag, 1291 ) 1292 .unwrap(); 1293 assert_eq!(ct, hex::encode(out)); 1294 assert_eq!(tag, hex::encode(actual_tag)); 1295 1296 let out = decrypt_aead( 1297 Cipher::aes_128_gcm(), 1298 &Vec::from_hex(key).unwrap(), 1299 Some(&Vec::from_hex(iv).unwrap()), 1300 &Vec::from_hex(aad).unwrap(), 1301 &Vec::from_hex(ct).unwrap(), 1302 &Vec::from_hex(tag).unwrap(), 1303 ) 1304 .unwrap(); 1305 assert_eq!(pt, hex::encode(out)); 1306 } 1307 1308 #[test] 1309 #[cfg(not(boringssl))] 1310 fn test_aes128_ccm() { 1311 let key = "3ee186594f110fb788a8bf8aa8be5d4a"; 1312 let nonce = "44f705d52acf27b7f17196aa9b"; 1313 let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57"; 1314 1315 let pt = "d71864877f2578db092daba2d6a1f9f4698a9c356c7830a1"; 1316 let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0"; 1317 let tag = "d6965f5aa6e31302a9cc2b36"; 1318 1319 let mut actual_tag = [0; 12]; 1320 let out = encrypt_aead( 1321 Cipher::aes_128_ccm(), 1322 &Vec::from_hex(key).unwrap(), 1323 Some(&Vec::from_hex(nonce).unwrap()), 1324 &Vec::from_hex(aad).unwrap(), 1325 &Vec::from_hex(pt).unwrap(), 1326 &mut actual_tag, 1327 ) 1328 .unwrap(); 1329 1330 assert_eq!(ct, hex::encode(out)); 1331 assert_eq!(tag, hex::encode(actual_tag)); 1332 1333 let out = decrypt_aead( 1334 Cipher::aes_128_ccm(), 1335 &Vec::from_hex(key).unwrap(), 1336 Some(&Vec::from_hex(nonce).unwrap()), 1337 &Vec::from_hex(aad).unwrap(), 1338 &Vec::from_hex(ct).unwrap(), 1339 &Vec::from_hex(tag).unwrap(), 1340 ) 1341 .unwrap(); 1342 assert_eq!(pt, hex::encode(out)); 1343 } 1344 1345 #[test] 1346 #[cfg(not(boringssl))] 1347 fn test_aes128_ccm_verify_fail() { 1348 let key = "3ee186594f110fb788a8bf8aa8be5d4a"; 1349 let nonce = "44f705d52acf27b7f17196aa9b"; 1350 let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57"; 1351 1352 let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0"; 1353 let tag = "00005f5aa6e31302a9cc2b36"; 1354 1355 let out = decrypt_aead( 1356 Cipher::aes_128_ccm(), 1357 &Vec::from_hex(key).unwrap(), 1358 Some(&Vec::from_hex(nonce).unwrap()), 1359 &Vec::from_hex(aad).unwrap(), 1360 &Vec::from_hex(ct).unwrap(), 1361 &Vec::from_hex(tag).unwrap(), 1362 ); 1363 assert!(out.is_err()); 1364 } 1365 1366 #[test] 1367 #[cfg(not(boringssl))] 1368 fn test_aes256_ccm() { 1369 let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; 1370 let nonce = "dde2a362ce81b2b6913abc3095"; 1371 let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695"; 1372 1373 let pt = "7ebef26bf4ecf6f0ebb2eb860edbf900f27b75b4a6340fdb"; 1374 let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd"; 1375 let tag = "2927a053c9244d3217a7ad05"; 1376 1377 let mut actual_tag = [0; 12]; 1378 let out = encrypt_aead( 1379 Cipher::aes_256_ccm(), 1380 &Vec::from_hex(key).unwrap(), 1381 Some(&Vec::from_hex(nonce).unwrap()), 1382 &Vec::from_hex(aad).unwrap(), 1383 &Vec::from_hex(pt).unwrap(), 1384 &mut actual_tag, 1385 ) 1386 .unwrap(); 1387 1388 assert_eq!(ct, hex::encode(out)); 1389 assert_eq!(tag, hex::encode(actual_tag)); 1390 1391 let out = decrypt_aead( 1392 Cipher::aes_256_ccm(), 1393 &Vec::from_hex(key).unwrap(), 1394 Some(&Vec::from_hex(nonce).unwrap()), 1395 &Vec::from_hex(aad).unwrap(), 1396 &Vec::from_hex(ct).unwrap(), 1397 &Vec::from_hex(tag).unwrap(), 1398 ) 1399 .unwrap(); 1400 assert_eq!(pt, hex::encode(out)); 1401 } 1402 1403 #[test] 1404 #[cfg(not(boringssl))] 1405 fn test_aes256_ccm_verify_fail() { 1406 let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; 1407 let nonce = "dde2a362ce81b2b6913abc3095"; 1408 let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695"; 1409 1410 let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd"; 1411 let tag = "0000a053c9244d3217a7ad05"; 1412 1413 let out = decrypt_aead( 1414 Cipher::aes_256_ccm(), 1415 &Vec::from_hex(key).unwrap(), 1416 Some(&Vec::from_hex(nonce).unwrap()), 1417 &Vec::from_hex(aad).unwrap(), 1418 &Vec::from_hex(ct).unwrap(), 1419 &Vec::from_hex(tag).unwrap(), 1420 ); 1421 assert!(out.is_err()); 1422 } 1423 1424 #[test] 1425 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 1426 fn test_aes_128_ocb() { 1427 let key = "000102030405060708090a0b0c0d0e0f"; 1428 let aad = "0001020304050607"; 1429 let tag = "16dc76a46d47e1ead537209e8a96d14e"; 1430 let iv = "000102030405060708090a0b"; 1431 let pt = "0001020304050607"; 1432 let ct = "92b657130a74b85a"; 1433 1434 let mut actual_tag = [0; 16]; 1435 let out = encrypt_aead( 1436 Cipher::aes_128_ocb(), 1437 &Vec::from_hex(key).unwrap(), 1438 Some(&Vec::from_hex(iv).unwrap()), 1439 &Vec::from_hex(aad).unwrap(), 1440 &Vec::from_hex(pt).unwrap(), 1441 &mut actual_tag, 1442 ) 1443 .unwrap(); 1444 1445 assert_eq!(ct, hex::encode(out)); 1446 assert_eq!(tag, hex::encode(actual_tag)); 1447 1448 let out = decrypt_aead( 1449 Cipher::aes_128_ocb(), 1450 &Vec::from_hex(key).unwrap(), 1451 Some(&Vec::from_hex(iv).unwrap()), 1452 &Vec::from_hex(aad).unwrap(), 1453 &Vec::from_hex(ct).unwrap(), 1454 &Vec::from_hex(tag).unwrap(), 1455 ) 1456 .unwrap(); 1457 assert_eq!(pt, hex::encode(out)); 1458 } 1459 1460 #[test] 1461 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] 1462 fn test_aes_128_ocb_fail() { 1463 let key = "000102030405060708090a0b0c0d0e0f"; 1464 let aad = "0001020304050607"; 1465 let tag = "16dc76a46d47e1ead537209e8a96d14e"; 1466 let iv = "000000000405060708090a0b"; 1467 let ct = "92b657130a74b85a"; 1468 1469 let out = decrypt_aead( 1470 Cipher::aes_128_ocb(), 1471 &Vec::from_hex(key).unwrap(), 1472 Some(&Vec::from_hex(iv).unwrap()), 1473 &Vec::from_hex(aad).unwrap(), 1474 &Vec::from_hex(ct).unwrap(), 1475 &Vec::from_hex(tag).unwrap(), 1476 ); 1477 assert!(out.is_err()); 1478 } 1479 1480 #[test] 1481 #[cfg(ossl110)] 1482 fn test_chacha20() { 1483 let key = "0000000000000000000000000000000000000000000000000000000000000000"; 1484 let iv = "00000000000000000000000000000000"; 1485 let pt = 1486 "000000000000000000000000000000000000000000000000000000000000000000000000000000000\ 1487 00000000000000000000000000000000000000000000000"; 1488 let ct = 1489 "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7\ 1490 724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586"; 1491 1492 cipher_test(Cipher::chacha20(), pt, ct, key, iv); 1493 } 1494 1495 #[test] 1496 #[cfg(ossl110)] 1497 fn test_chacha20_poly1305() { 1498 let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"; 1499 let iv = "070000004041424344454647"; 1500 let aad = "50515253c0c1c2c3c4c5c6c7"; 1501 let pt = 1502 "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393\ 1503 a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f722074\ 1504 6865206675747572652c2073756e73637265656e20776f756c642062652069742e"; 1505 let ct = 1506 "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca967128\ 1507 2fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fa\ 1508 b324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116"; 1509 let tag = "1ae10b594f09e26a7e902ecbd0600691"; 1510 1511 let mut actual_tag = [0; 16]; 1512 let out = encrypt_aead( 1513 Cipher::chacha20_poly1305(), 1514 &Vec::from_hex(key).unwrap(), 1515 Some(&Vec::from_hex(iv).unwrap()), 1516 &Vec::from_hex(aad).unwrap(), 1517 &Vec::from_hex(pt).unwrap(), 1518 &mut actual_tag, 1519 ) 1520 .unwrap(); 1521 assert_eq!(ct, hex::encode(out)); 1522 assert_eq!(tag, hex::encode(actual_tag)); 1523 1524 let out = decrypt_aead( 1525 Cipher::chacha20_poly1305(), 1526 &Vec::from_hex(key).unwrap(), 1527 Some(&Vec::from_hex(iv).unwrap()), 1528 &Vec::from_hex(aad).unwrap(), 1529 &Vec::from_hex(ct).unwrap(), 1530 &Vec::from_hex(tag).unwrap(), 1531 ) 1532 .unwrap(); 1533 assert_eq!(pt, hex::encode(out)); 1534 } 1535 1536 #[test] 1537 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] 1538 fn test_seed_cbc() { 1539 #[cfg(ossl300)] 1540 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1541 1542 let pt = "5363686f6b6f6c6164656e6b756368656e0a"; 1543 let ct = "c2edf0fb2eb11bf7b2f39417a8528896d34b24b6fd79e5923b116dfcd2aba5a4"; 1544 let key = "41414141414141414141414141414141"; 1545 let iv = "41414141414141414141414141414141"; 1546 1547 cipher_test(super::Cipher::seed_cbc(), pt, ct, key, iv); 1548 } 1549 1550 #[test] 1551 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] 1552 fn test_seed_cfb128() { 1553 #[cfg(ossl300)] 1554 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1555 1556 let pt = "5363686f6b6f6c6164656e6b756368656e0a"; 1557 let ct = "71d4d25fc1750cb7789259e7f34061939a41"; 1558 let key = "41414141414141414141414141414141"; 1559 let iv = "41414141414141414141414141414141"; 1560 1561 cipher_test(super::Cipher::seed_cfb128(), pt, ct, key, iv); 1562 } 1563 1564 #[test] 1565 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] 1566 fn test_seed_ecb() { 1567 #[cfg(ossl300)] 1568 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1569 1570 let pt = "5363686f6b6f6c6164656e6b756368656e0a"; 1571 let ct = "0263a9cd498cf0edb0ef72a3231761d00ce601f7d08ad19ad74f0815f2c77f7e"; 1572 let key = "41414141414141414141414141414141"; 1573 let iv = "41414141414141414141414141414141"; 1574 1575 cipher_test(super::Cipher::seed_ecb(), pt, ct, key, iv); 1576 } 1577 1578 #[test] 1579 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] 1580 fn test_seed_ofb() { 1581 #[cfg(ossl300)] 1582 let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 1583 1584 let pt = "5363686f6b6f6c6164656e6b756368656e0a"; 1585 let ct = "71d4d25fc1750cb7789259e7f34061930afd"; 1586 let key = "41414141414141414141414141414141"; 1587 let iv = "41414141414141414141414141414141"; 1588 1589 cipher_test(super::Cipher::seed_ofb(), pt, ct, key, iv); 1590 } 1591 1592 // GB/T 32907-2016 1593 // http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7803DE42D3BC5E80B0C3E5D8E873D56A 1594 #[test] 1595 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] 1596 fn test_sm4_ecb() { 1597 use std::mem; 1598 1599 let key = vec![ 1600 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 1601 0x32, 0x10, 1602 ]; 1603 let pt = vec![ 1604 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 1605 0x32, 0x10, 1606 ]; 1607 let ct = vec![ 1608 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 1609 0x42, 0x46, 1610 ]; 1611 let ct1 = vec![ 1612 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 1613 0x3f, 0x66, 1614 ]; 1615 1616 let block_size = Cipher::sm4_ecb().block_size(); 1617 let mut c = Crypter::new(Cipher::sm4_ecb(), Mode::Encrypt, &key, None).unwrap(); 1618 c.pad(false); 1619 1620 // 1 round 1621 let mut r = vec![0; pt.len() + Cipher::sm4_ecb().block_size()]; 1622 let count = c.update(&pt, &mut r).unwrap(); 1623 assert_eq!(ct, &r[..count]); 1624 1625 // 1000000 rounds 1626 let mut r1 = vec![0; pt.len() + Cipher::sm4_ecb().block_size()]; 1627 for _ in 0..999999 { 1628 c.update(&r[..block_size], &mut r1).unwrap(); 1629 mem::swap(&mut r, &mut r1); 1630 } 1631 assert_eq!(ct1, &r[..count]); 1632 } 1633} 1634