1 //! Symmetric ciphers. 2 3 #[cfg(ossl300)] 4 use crate::cvt_p; 5 #[cfg(ossl300)] 6 use crate::error::ErrorStack; 7 #[cfg(ossl300)] 8 use crate::lib_ctx::LibCtxRef; 9 use crate::nid::Nid; 10 use cfg_if::cfg_if; 11 use foreign_types::{ForeignTypeRef, Opaque}; 12 use openssl_macros::corresponds; 13 #[cfg(ossl300)] 14 use std::ffi::CString; 15 #[cfg(ossl300)] 16 use std::ptr; 17 18 cfg_if! { 19 if #[cfg(any(boringssl, ossl110, libressl273))] { 20 use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; 21 } else { 22 use libc::c_int; 23 24 #[allow(bad_style)] 25 pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int { 26 (*ptr).iv_len 27 } 28 29 #[allow(bad_style)] 30 pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int { 31 (*ptr).block_size 32 } 33 34 #[allow(bad_style)] 35 pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int { 36 (*ptr).key_len 37 } 38 } 39 } 40 41 cfg_if! { 42 if #[cfg(ossl300)] { 43 use foreign_types::ForeignType; 44 use std::ops::{Deref, DerefMut}; 45 46 type Inner = *mut ffi::EVP_CIPHER; 47 48 impl Drop for Cipher { 49 #[inline] 50 fn drop(&mut self) { 51 unsafe { 52 ffi::EVP_CIPHER_free(self.as_ptr()); 53 } 54 } 55 } 56 57 impl ForeignType for Cipher { 58 type CType = ffi::EVP_CIPHER; 59 type Ref = CipherRef; 60 61 #[inline] 62 unsafe fn from_ptr(ptr: *mut Self::CType) -> Self { 63 Cipher(ptr) 64 } 65 66 #[inline] 67 fn as_ptr(&self) -> *mut Self::CType { 68 self.0 69 } 70 } 71 72 impl Deref for Cipher { 73 type Target = CipherRef; 74 75 #[inline] 76 fn deref(&self) -> &Self::Target { 77 unsafe { 78 CipherRef::from_ptr(self.as_ptr()) 79 } 80 } 81 } 82 83 impl DerefMut for Cipher { 84 #[inline] 85 fn deref_mut(&mut self) -> &mut Self::Target { 86 unsafe { 87 CipherRef::from_ptr_mut(self.as_ptr()) 88 } 89 } 90 } 91 } else { 92 enum Inner {} 93 } 94 } 95 96 /// A symmetric cipher. 97 pub struct Cipher(Inner); 98 99 unsafe impl Sync for Cipher {} 100 unsafe impl Send for Cipher {} 101 102 impl Cipher { 103 /// Looks up the cipher for a certain nid. 104 #[corresponds(EVP_get_cipherbynid)] from_nid(nid: Nid) -> Option<&'static CipherRef>105 pub fn from_nid(nid: Nid) -> Option<&'static CipherRef> { 106 unsafe { 107 let ptr = ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())); 108 if ptr.is_null() { 109 None 110 } else { 111 Some(CipherRef::from_ptr(ptr as *mut _)) 112 } 113 } 114 } 115 116 /// Fetches a cipher object corresponding to the specified algorithm name and properties. 117 /// 118 /// Requires OpenSSL 3.0.0 or newer. 119 #[corresponds(EVP_CIPHER_fetch)] 120 #[cfg(ossl300)] fetch( ctx: Option<&LibCtxRef>, algorithm: &str, properties: Option<&str>, ) -> Result<Self, ErrorStack>121 pub fn fetch( 122 ctx: Option<&LibCtxRef>, 123 algorithm: &str, 124 properties: Option<&str>, 125 ) -> Result<Self, ErrorStack> { 126 let algorithm = CString::new(algorithm).unwrap(); 127 let properties = properties.map(|s| CString::new(s).unwrap()); 128 129 unsafe { 130 let ptr = cvt_p(ffi::EVP_CIPHER_fetch( 131 ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), 132 algorithm.as_ptr(), 133 properties.map_or(ptr::null_mut(), |s| s.as_ptr()), 134 ))?; 135 136 Ok(Cipher::from_ptr(ptr)) 137 } 138 } 139 aes_128_ecb() -> &'static CipherRef140 pub fn aes_128_ecb() -> &'static CipherRef { 141 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) } 142 } 143 aes_128_cbc() -> &'static CipherRef144 pub fn aes_128_cbc() -> &'static CipherRef { 145 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) } 146 } 147 148 #[cfg(not(boringssl))] aes_128_xts() -> &'static CipherRef149 pub fn aes_128_xts() -> &'static CipherRef { 150 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) } 151 } 152 153 #[cfg(not(boringssl))] aes_128_ctr() -> &'static CipherRef154 pub fn aes_128_ctr() -> &'static CipherRef { 155 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) } 156 } 157 158 #[cfg(not(boringssl))] aes_128_cfb1() -> &'static CipherRef159 pub fn aes_128_cfb1() -> &'static CipherRef { 160 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) } 161 } 162 163 #[cfg(not(boringssl))] aes_128_cfb128() -> &'static CipherRef164 pub fn aes_128_cfb128() -> &'static CipherRef { 165 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) } 166 } 167 168 #[cfg(not(boringssl))] aes_128_cfb8() -> &'static CipherRef169 pub fn aes_128_cfb8() -> &'static CipherRef { 170 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) } 171 } 172 173 #[cfg(not(boringssl))] aes_128_gcm() -> &'static CipherRef174 pub fn aes_128_gcm() -> &'static CipherRef { 175 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) } 176 } 177 178 #[cfg(not(boringssl))] aes_128_ccm() -> &'static CipherRef179 pub fn aes_128_ccm() -> &'static CipherRef { 180 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) } 181 } 182 183 #[cfg(not(boringssl))] aes_128_ofb() -> &'static CipherRef184 pub fn aes_128_ofb() -> &'static CipherRef { 185 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) } 186 } 187 188 /// Requires OpenSSL 1.1.0 or newer. 189 #[cfg(ossl110)] aes_128_ocb() -> &'static CipherRef190 pub fn aes_128_ocb() -> &'static CipherRef { 191 unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) } 192 } 193 aes_192_ecb() -> &'static CipherRef194 pub fn aes_192_ecb() -> &'static CipherRef { 195 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) } 196 } 197 aes_192_cbc() -> &'static CipherRef198 pub fn aes_192_cbc() -> &'static CipherRef { 199 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) } 200 } 201 aes_192_ctr() -> &'static CipherRef202 pub fn aes_192_ctr() -> &'static CipherRef { 203 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) } 204 } 205 206 #[cfg(not(boringssl))] aes_192_cfb1() -> &'static CipherRef207 pub fn aes_192_cfb1() -> &'static CipherRef { 208 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) } 209 } 210 aes_192_cfb128() -> &'static CipherRef211 pub fn aes_192_cfb128() -> &'static CipherRef { 212 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) } 213 } 214 215 #[cfg(not(boringssl))] aes_192_cfb8() -> &'static CipherRef216 pub fn aes_192_cfb8() -> &'static CipherRef { 217 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) } 218 } 219 aes_192_gcm() -> &'static CipherRef220 pub fn aes_192_gcm() -> &'static CipherRef { 221 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) } 222 } 223 224 #[cfg(not(boringssl))] aes_192_ccm() -> &'static CipherRef225 pub fn aes_192_ccm() -> &'static CipherRef { 226 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) } 227 } 228 aes_192_ofb() -> &'static CipherRef229 pub fn aes_192_ofb() -> &'static CipherRef { 230 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) } 231 } 232 233 /// Requires OpenSSL 1.1.0 or newer. 234 #[cfg(ossl110)] aes_192_ocb() -> &'static CipherRef235 pub fn aes_192_ocb() -> &'static CipherRef { 236 unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) } 237 } 238 aes_256_ecb() -> &'static CipherRef239 pub fn aes_256_ecb() -> &'static CipherRef { 240 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) } 241 } 242 aes_256_cbc() -> &'static CipherRef243 pub fn aes_256_cbc() -> &'static CipherRef { 244 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) } 245 } 246 aes_256_ctr() -> &'static CipherRef247 pub fn aes_256_ctr() -> &'static CipherRef { 248 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) } 249 } 250 251 #[cfg(not(boringssl))] aes_256_cfb1() -> &'static CipherRef252 pub fn aes_256_cfb1() -> &'static CipherRef { 253 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) } 254 } 255 aes_256_cfb128() -> &'static CipherRef256 pub fn aes_256_cfb128() -> &'static CipherRef { 257 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) } 258 } 259 260 #[cfg(not(boringssl))] aes_256_cfb8() -> &'static CipherRef261 pub fn aes_256_cfb8() -> &'static CipherRef { 262 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) } 263 } 264 aes_256_gcm() -> &'static CipherRef265 pub fn aes_256_gcm() -> &'static CipherRef { 266 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) } 267 } 268 269 #[cfg(not(boringssl))] aes_256_ccm() -> &'static CipherRef270 pub fn aes_256_ccm() -> &'static CipherRef { 271 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) } 272 } 273 aes_256_ofb() -> &'static CipherRef274 pub fn aes_256_ofb() -> &'static CipherRef { 275 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) } 276 } 277 278 /// Requires OpenSSL 1.1.0 or newer. 279 #[cfg(ossl110)] aes_256_ocb() -> &'static CipherRef280 pub fn aes_256_ocb() -> &'static CipherRef { 281 unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) } 282 } 283 284 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] bf_cbc() -> &'static CipherRef285 pub fn bf_cbc() -> &'static CipherRef { 286 unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) } 287 } 288 289 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] bf_ecb() -> &'static CipherRef290 pub fn bf_ecb() -> &'static CipherRef { 291 unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) } 292 } 293 294 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] 295 #[cfg(not(boringssl))] bf_cfb64() -> &'static CipherRef296 pub fn bf_cfb64() -> &'static CipherRef { 297 unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) } 298 } 299 300 #[cfg(not(osslconf = "OPENSSL_NO_BF"))] 301 #[cfg(not(boringssl))] bf_ofb() -> &'static CipherRef302 pub fn bf_ofb() -> &'static CipherRef { 303 unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) } 304 } 305 des_cbc() -> &'static CipherRef306 pub fn des_cbc() -> &'static CipherRef { 307 unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) } 308 } 309 des_ecb() -> &'static CipherRef310 pub fn des_ecb() -> &'static CipherRef { 311 unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) } 312 } 313 des_ede3() -> &'static CipherRef314 pub fn des_ede3() -> &'static CipherRef { 315 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) } 316 } 317 des_ede3_cbc() -> &'static CipherRef318 pub fn des_ede3_cbc() -> &'static CipherRef { 319 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) } 320 } 321 322 #[cfg(not(boringssl))] des_ede3_cfb64() -> &'static CipherRef323 pub fn des_ede3_cfb64() -> &'static CipherRef { 324 unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) } 325 } 326 rc4() -> &'static CipherRef327 pub fn rc4() -> &'static CipherRef { 328 unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) } 329 } 330 331 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia128_cfb128() -> &'static CipherRef332 pub fn camellia128_cfb128() -> &'static CipherRef { 333 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) } 334 } 335 336 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia128_ecb() -> &'static CipherRef337 pub fn camellia128_ecb() -> &'static CipherRef { 338 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) } 339 } 340 341 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia192_cfb128() -> &'static CipherRef342 pub fn camellia192_cfb128() -> &'static CipherRef { 343 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) } 344 } 345 346 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia192_ecb() -> &'static CipherRef347 pub fn camellia192_ecb() -> &'static CipherRef { 348 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) } 349 } 350 351 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia256_cfb128() -> &'static CipherRef352 pub fn camellia256_cfb128() -> &'static CipherRef { 353 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) } 354 } 355 356 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAMELLIA")))] camellia256_ecb() -> &'static CipherRef357 pub fn camellia256_ecb() -> &'static CipherRef { 358 unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) } 359 } 360 361 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))] cast5_cfb64() -> &'static CipherRef362 pub fn cast5_cfb64() -> &'static CipherRef { 363 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) } 364 } 365 366 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_CAST")))] cast5_ecb() -> &'static CipherRef367 pub fn cast5_ecb() -> &'static CipherRef { 368 unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) } 369 } 370 371 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))] idea_cfb64() -> &'static CipherRef372 pub fn idea_cfb64() -> &'static CipherRef { 373 unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) } 374 } 375 376 #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_IDEA")))] idea_ecb() -> &'static CipherRef377 pub fn idea_ecb() -> &'static CipherRef { 378 unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) } 379 } 380 381 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] chacha20() -> &'static CipherRef382 pub fn chacha20() -> &'static CipherRef { 383 unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) } 384 } 385 386 #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] chacha20_poly1305() -> &'static CipherRef387 pub fn chacha20_poly1305() -> &'static CipherRef { 388 unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) } 389 } 390 391 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] 392 #[cfg(not(boringssl))] seed_cbc() -> &'static CipherRef393 pub fn seed_cbc() -> &'static CipherRef { 394 unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) } 395 } 396 397 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] 398 #[cfg(not(boringssl))] seed_cfb128() -> &'static CipherRef399 pub fn seed_cfb128() -> &'static CipherRef { 400 unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) } 401 } 402 403 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] 404 #[cfg(not(boringssl))] seed_ecb() -> &'static CipherRef405 pub fn seed_ecb() -> &'static CipherRef { 406 unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) } 407 } 408 409 #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] 410 #[cfg(not(boringssl))] seed_ofb() -> &'static CipherRef411 pub fn seed_ofb() -> &'static CipherRef { 412 unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) } 413 } 414 415 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] sm4_ecb() -> &'static CipherRef416 pub fn sm4_ecb() -> &'static CipherRef { 417 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) } 418 } 419 420 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] sm4_cbc() -> &'static CipherRef421 pub fn sm4_cbc() -> &'static CipherRef { 422 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) } 423 } 424 425 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] sm4_ctr() -> &'static CipherRef426 pub fn sm4_ctr() -> &'static CipherRef { 427 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) } 428 } 429 430 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] sm4_cfb128() -> &'static CipherRef431 pub fn sm4_cfb128() -> &'static CipherRef { 432 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) } 433 } 434 435 #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] sm4_ofb() -> &'static CipherRef436 pub fn sm4_ofb() -> &'static CipherRef { 437 unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) } 438 } 439 } 440 441 /// A reference to a [`Cipher`]. 442 pub struct CipherRef(Opaque); 443 444 impl ForeignTypeRef for CipherRef { 445 type CType = ffi::EVP_CIPHER; 446 } 447 448 unsafe impl Sync for CipherRef {} 449 unsafe impl Send for CipherRef {} 450 451 impl CipherRef { 452 /// Returns the cipher's Nid. 453 #[corresponds(EVP_CIPHER_nid)] nid(&self) -> Nid454 pub fn nid(&self) -> Nid { 455 let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) }; 456 Nid::from_raw(nid) 457 } 458 459 /// Returns the length of keys used with this cipher. 460 #[corresponds(EVP_CIPHER_key_length)] key_length(&self) -> usize461 pub fn key_length(&self) -> usize { 462 unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize } 463 } 464 465 /// Returns the length of the IV used with this cipher. 466 /// 467 /// # Note 468 /// 469 /// Ciphers that do not use an IV have an IV length of 0. 470 #[corresponds(EVP_CIPHER_iv_length)] iv_length(&self) -> usize471 pub fn iv_length(&self) -> usize { 472 unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize } 473 } 474 475 /// Returns the block size of the cipher. 476 /// 477 /// # Note 478 /// 479 /// Stream ciphers have a block size of 1. 480 #[corresponds(EVP_CIPHER_block_size)] block_size(&self) -> usize481 pub fn block_size(&self) -> usize { 482 unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize } 483 } 484 } 485