]> git.proxmox.com Git - cargo.git/blobdiff - vendor/openssl/src/bn.rs
New upstream version 0.63.1
[cargo.git] / vendor / openssl / src / bn.rs
index 6738ee177ccb696eacba3623dbc0313331378560..5de7f7cb38fa67f71684d081acf4f1687bfc7bb6 100644 (file)
@@ -33,15 +33,18 @@ use std::{fmt, ptr};
 use crate::asn1::Asn1Integer;
 use crate::error::ErrorStack;
 use crate::string::OpensslString;
-use crate::{cvt, cvt_n, cvt_p};
+use crate::{cvt, cvt_n, cvt_p, LenType};
+use openssl_macros::corresponds;
 
 cfg_if! {
-    if #[cfg(ossl110)] {
+    if #[cfg(any(ossl110, libressl350))] {
         use ffi::{
             BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
             BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
             BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
         };
+    } else if #[cfg(boringssl)] {
+        use ffi::BN_is_negative;
     } else {
         use ffi::{
             get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
@@ -98,16 +101,23 @@ foreign_type_and_impl_send_sync! {
 
 impl BigNumContext {
     /// Returns a new `BigNumContext`.
-    ///
-    /// See OpenSSL documentation at [`BN_CTX_new`].
-    ///
-    /// [`BN_CTX_new`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_CTX_new.html
+    #[corresponds(BN_CTX_new)]
     pub fn new() -> Result<BigNumContext, ErrorStack> {
         unsafe {
             ffi::init();
             cvt_p(ffi::BN_CTX_new()).map(BigNumContext)
         }
     }
+
+    /// Returns a new secure `BigNumContext`.
+    #[corresponds(BN_CTX_secure_new)]
+    #[cfg(ossl110)]
+    pub fn new_secure() -> Result<BigNumContext, ErrorStack> {
+        unsafe {
+            ffi::init();
+            cvt_p(ffi::BN_CTX_secure_new()).map(BigNumContext)
+        }
+    }
 }
 
 foreign_type_and_impl_send_sync! {
@@ -148,46 +158,31 @@ impl BigNumRef {
     /// Erases the memory used by this `BigNum`, resetting its value to 0.
     ///
     /// This can be used to destroy sensitive data such as keys when they are no longer needed.
-    ///
-    /// OpenSSL documentation at [`BN_clear`]
-    ///
-    /// [`BN_clear`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear.html
+    #[corresponds(BN_clear)]
     pub fn clear(&mut self) {
         unsafe { ffi::BN_clear(self.as_ptr()) }
     }
 
     /// Adds a `u32` to `self`.
-    ///
-    /// OpenSSL documentation at [`BN_add_word`]
-    ///
-    /// [`BN_add_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_add_word.html
+    #[corresponds(BN_add_word)]
     pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
     }
 
     /// Subtracts a `u32` from `self`.
-    ///
-    /// OpenSSL documentation at [`BN_sub_word`]
-    ///
-    /// [`BN_sub_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sub_word.html
+    #[corresponds(BN_sub_word)]
     pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
     }
 
     /// Multiplies a `u32` by `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mul_word`]
-    ///
-    /// [`BN_mul_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mul_word.html
+    #[corresponds(BN_mul_word)]
     pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
     }
 
     /// Divides `self` by a `u32`, returning the remainder.
-    ///
-    /// OpenSSL documentation at [`BN_div_word`]
-    ///
-    /// [`BN_div_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div_word.html
+    #[corresponds(BN_div_word)]
     #[allow(clippy::useless_conversion)]
     pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
         unsafe {
@@ -201,10 +196,7 @@ impl BigNumRef {
     }
 
     /// Returns the result of `self` modulo `w`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_word`]
-    ///
-    /// [`BN_mod_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_word.html
+    #[corresponds(BN_mod_word)]
     #[allow(clippy::useless_conversion)]
     pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
         unsafe {
@@ -219,19 +211,13 @@ impl BigNumRef {
 
     /// Places a cryptographically-secure pseudo-random nonnegative
     /// number less than `self` in `rnd`.
-    ///
-    /// OpenSSL documentation at [`BN_rand_range`]
-    ///
-    /// [`BN_rand_range`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand_range.html
+    #[corresponds(BN_rand_range)]
     pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
     }
 
     /// The cryptographically weak counterpart to `rand_in_range`.
-    ///
-    /// OpenSSL documentation at [`BN_pseudo_rand_range`]
-    ///
-    /// [`BN_pseudo_rand_range`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_pseudo_rand_range.html
+    #[corresponds(BN_pseudo_rand_range)]
     pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
     }
@@ -239,10 +225,7 @@ impl BigNumRef {
     /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
     ///
     /// When setting a bit outside of `self`, it is expanded.
-    ///
-    /// OpenSSL documentation at [`BN_set_bit`]
-    ///
-    /// [`BN_set_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_bit.html
+    #[corresponds(BN_set_bit)]
     #[allow(clippy::useless_conversion)]
     pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
@@ -251,20 +234,14 @@ impl BigNumRef {
     /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
     ///
     /// When clearing a bit outside of `self`, an error is returned.
-    ///
-    /// OpenSSL documentation at [`BN_clear_bit`]
-    ///
-    /// [`BN_clear_bit`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_clear_bit.html
+    #[corresponds(BN_clear_bit)]
     #[allow(clippy::useless_conversion)]
     pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
     }
 
     /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise.
-    ///
-    /// OpenSSL documentation at [`BN_is_bit_set`]
-    ///
-    /// [`BN_is_bit_set`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_bit_set.html
+    #[corresponds(BN_is_bit_set)]
     #[allow(clippy::useless_conversion)]
     pub fn is_bit_set(&self, n: i32) -> bool {
         unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
@@ -273,94 +250,69 @@ impl BigNumRef {
     /// Truncates `self` to the lowest `n` bits.
     ///
     /// An error occurs if `self` is already shorter than `n` bits.
-    ///
-    /// OpenSSL documentation at [`BN_mask_bits`]
-    ///
-    /// [`BN_mask_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mask_bits.html
+    #[corresponds(BN_mask_bits)]
     #[allow(clippy::useless_conversion)]
     pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
     }
 
     /// Places `a << 1` in `self`.  Equivalent to `self * 2`.
-    ///
-    /// OpenSSL documentation at [`BN_lshift1`]
-    ///
-    /// [`BN_lshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift1.html
+    #[corresponds(BN_lshift1)]
     pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
     }
 
     /// Places `a >> 1` in `self`. Equivalent to `self / 2`.
-    ///
-    /// OpenSSL documentation at [`BN_rshift1`]
-    ///
-    /// [`BN_rshift1`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift1.html
+    #[corresponds(BN_rshift1)]
     pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
     }
 
     /// Places `a + b` in `self`.  [`core::ops::Add`] is also implemented for `BigNumRef`.
     ///
-    /// OpenSSL documentation at [`BN_add`]
-    ///
     /// [`core::ops::Add`]: struct.BigNumRef.html#method.add
-    /// [`BN_add`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_add.html
+    #[corresponds(BN_add)]
     pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
     }
 
     /// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`.
     ///
-    /// OpenSSL documentation at [`BN_sub`]
-    ///
     /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub
-    /// [`BN_sub`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sub.html
+    #[corresponds(BN_sub)]
     pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
     }
 
     /// Places `a << n` in `self`.  Equivalent to `a * 2 ^ n`.
-    ///
-    /// OpenSSL documentation at [`BN_lshift`]
-    ///
-    /// [`BN_lshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_lshift.html
+    #[corresponds(BN_lshift)]
     #[allow(clippy::useless_conversion)]
     pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
     }
 
     /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`.
-    ///
-    /// OpenSSL documentation at [`BN_rshift`]
-    ///
-    /// [`BN_rshift`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rshift.html
+    #[corresponds(BN_rshift)]
     #[allow(clippy::useless_conversion)]
     pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
     }
 
     /// Creates a new BigNum with the same value.
-    ///
-    /// OpenSSL documentation at [`BN_dup`]
-    ///
-    /// [`BN_dup`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dup.html
+    #[corresponds(BN_dup)]
     pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
         unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
     }
 
     /// Sets the sign of `self`.  Pass true to set `self` to a negative.  False sets
     /// `self` positive.
+    #[corresponds(BN_set_negative)]
     pub fn set_negative(&mut self, negative: bool) {
         unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
     }
 
     /// Compare the absolute values of `self` and `oth`.
     ///
-    /// OpenSSL documentation at [`BN_ucmp`]
-    ///
-    /// [`BN_ucmp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_ucmp.html
-    ///
     /// # Examples
     ///
     /// ```
@@ -371,20 +323,19 @@ impl BigNumRef {
     ///
     /// assert_eq!(s.ucmp(&o), Ordering::Equal);
     /// ```
+    #[corresponds(BN_ucmp)]
     pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
         unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
     }
 
     /// Returns `true` if `self` is negative.
+    #[corresponds(BN_is_negative)]
     pub fn is_negative(&self) -> bool {
         unsafe { BN_is_negative(self.as_ptr()) == 1 }
     }
 
     /// Returns the number of significant bits in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_num_bits`]
-    ///
-    /// [`BN_num_bits`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_num_bits.html
+    #[corresponds(BN_num_bits)]
     pub fn num_bits(&self) -> i32 {
         unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
     }
@@ -417,10 +368,8 @@ impl BigNumRef {
     /// }
     /// ```
     ///
-    /// OpenSSL documentation at [`BN_rand`]
-    ///
     /// [`constants`]: index.html#constants
-    /// [`BN_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_rand.html
+    #[corresponds(BN_rand)]
     #[allow(clippy::useless_conversion)]
     pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
         unsafe {
@@ -435,10 +384,7 @@ impl BigNumRef {
     }
 
     /// The cryptographically weak counterpart to `rand`.  Not suitable for key generation.
-    ///
-    /// OpenSSL documentation at [`BN_psuedo_rand`]
-    ///
-    /// [`BN_psuedo_rand`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_pseudo_rand.html
+    #[corresponds(BN_pseudo_rand)]
     #[allow(clippy::useless_conversion)]
     pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
         unsafe {
@@ -475,10 +421,7 @@ impl BigNumRef {
     ///    Ok((big))
     /// }
     /// ```
-    ///
-    /// OpenSSL documentation at [`BN_generate_prime_ex`]
-    ///
-    /// [`BN_generate_prime_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_generate_prime_ex.html
+    #[corresponds(BN_generate_prime_ex)]
     pub fn generate_prime(
         &mut self,
         bits: i32,
@@ -502,10 +445,8 @@ impl BigNumRef {
     /// Places the result of `a * b` in `self`.
     /// [`core::ops::Mul`] is also implemented for `BigNumRef`.
     ///
-    /// OpenSSL documentation at [`BN_mul`]
-    ///
     /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul
-    /// [`BN_mul`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mul.html
+    #[corresponds(BN_mul)]
     pub fn checked_mul(
         &mut self,
         a: &BigNumRef,
@@ -526,10 +467,8 @@ impl BigNumRef {
     /// Places the result of `a / b` in `self`. The remainder is discarded.
     /// [`core::ops::Div`] is also implemented for `BigNumRef`.
     ///
-    /// OpenSSL documentation at [`BN_div`]
-    ///
     /// [`core::ops::Div`]: struct.BigNumRef.html#method.div
-    /// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html
+    #[corresponds(BN_div)]
     pub fn checked_div(
         &mut self,
         a: &BigNumRef,
@@ -549,10 +488,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `a % b` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_div`]
-    ///
-    /// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html
+    #[corresponds(BN_div)]
     pub fn checked_rem(
         &mut self,
         a: &BigNumRef,
@@ -572,10 +508,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `a / b` in `self` and `a % b` in `rem`.
-    ///
-    /// OpenSSL documentation at [`BN_div`]
-    ///
-    /// [`BN_div`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_div.html
+    #[corresponds(BN_div)]
     pub fn div_rem(
         &mut self,
         rem: &mut BigNumRef,
@@ -596,20 +529,14 @@ impl BigNumRef {
     }
 
     /// Places the result of `a²` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_sqr`]
-    ///
-    /// [`BN_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_sqr.html
+    #[corresponds(BN_sqr)]
     pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
         unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
     }
 
     /// Places the result of `a mod m` in `self`.  As opposed to `div_rem`
     /// the result is non-negative.
-    ///
-    /// OpenSSL documentation at [`BN_nnmod`]
-    ///
-    /// [`BN_nnmod`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_nnmod.html
+    #[corresponds(BN_nnmod)]
     pub fn nnmod(
         &mut self,
         a: &BigNumRef,
@@ -628,10 +555,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `(a + b) mod m` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_add`]
-    ///
-    /// [`BN_mod_add`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_add.html
+    #[corresponds(BN_mod_add)]
     pub fn mod_add(
         &mut self,
         a: &BigNumRef,
@@ -652,10 +576,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `(a - b) mod m` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_sub`]
-    ///
-    /// [`BN_mod_sub`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sub.html
+    #[corresponds(BN_mod_sub)]
     pub fn mod_sub(
         &mut self,
         a: &BigNumRef,
@@ -676,10 +597,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `(a * b) mod m` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_mul`]
-    ///
-    /// [`BN_mod_mul`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_mul.html
+    #[corresponds(BN_mod_mul)]
     pub fn mod_mul(
         &mut self,
         a: &BigNumRef,
@@ -700,10 +618,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `a² mod m` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_sqr`]
-    ///
-    /// [`BN_mod_sqr`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_sqr.html
+    #[corresponds(BN_mod_sqr)]
     pub fn mod_sqr(
         &mut self,
         a: &BigNumRef,
@@ -722,10 +637,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `a^p` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_exp`]
-    ///
-    /// [`BN_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_exp.html
+    #[corresponds(BN_exp)]
     pub fn exp(
         &mut self,
         a: &BigNumRef,
@@ -744,10 +656,7 @@ impl BigNumRef {
     }
 
     /// Places the result of `a^p mod m` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_mod_exp`]
-    ///
-    /// [`BN_mod_exp`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_mod_exp.html
+    #[corresponds(BN_mod_exp)]
     pub fn mod_exp(
         &mut self,
         a: &BigNumRef,
@@ -768,6 +677,7 @@ impl BigNumRef {
     }
 
     /// Places the inverse of `a` modulo `n` in `self`.
+    #[corresponds(BN_mod_inverse)]
     pub fn mod_inverse(
         &mut self,
         a: &BigNumRef,
@@ -786,10 +696,7 @@ impl BigNumRef {
     }
 
     /// Places the greatest common denominator of `a` and `b` in `self`.
-    ///
-    /// OpenSSL documentation at [`BN_gcd`]
-    ///
-    /// [`BN_gcd`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_gcd.html
+    #[corresponds(BN_gcd)]
     pub fn gcd(
         &mut self,
         a: &BigNumRef,
@@ -811,13 +718,10 @@ impl BigNumRef {
     ///
     /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
     ///
-    /// OpenSSL documentation at [`BN_is_prime_ex`]
-    ///
-    /// [`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_prime_ex.html
-    ///
     /// # Return Value
     ///
     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
+    #[corresponds(BN_is_prime_ex)]
     #[allow(clippy::useless_conversion)]
     pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
         unsafe {
@@ -837,13 +741,10 @@ impl BigNumRef {
     /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
     /// iterations.
     ///
-    /// OpenSSL documentation at [`BN_is_prime_fasttest_ex`]
-    ///
-    /// [`BN_is_prime_fasttest_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_is_prime_fasttest_ex.html
-    ///
     /// # Return Value
     ///
     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
+    #[corresponds(BN_is_prime_fasttest_ex)]
     #[allow(clippy::useless_conversion)]
     pub fn is_prime_fasttest(
         &self,
@@ -875,6 +776,7 @@ impl BigNumRef {
     /// let s_vec = s.to_vec();
     /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
     /// ```
+    #[corresponds(BN_bn2bin)]
     pub fn to_vec(&self) -> Vec<u8> {
         let size = self.num_bytes() as usize;
         let mut v = Vec::with_capacity(size);
@@ -885,6 +787,38 @@ impl BigNumRef {
         v
     }
 
+    /// Returns a big-endian byte vector representation of the absolute value of `self` padded
+    /// to `pad_to` bytes.
+    ///
+    /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
+    ///
+    /// `self` can be recreated by using `from_slice`.
+    ///
+    /// ```
+    /// # use openssl::bn::BigNum;
+    /// let bn = BigNum::from_u32(0x4543).unwrap();
+    ///
+    /// let bn_vec = bn.to_vec_padded(4).unwrap();
+    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
+    ///
+    /// let r = bn.to_vec_padded(1);
+    /// assert!(r.is_err());
+    ///
+    /// let bn = -BigNum::from_u32(0x4543).unwrap();
+    /// let bn_vec = bn.to_vec_padded(4).unwrap();
+    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
+    /// ```
+    #[corresponds(BN_bn2binpad)]
+    #[cfg(ossl110)]
+    pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
+        let mut v = Vec::with_capacity(pad_to as usize);
+        unsafe {
+            cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
+            v.set_len(pad_to as usize);
+        }
+        Ok(v)
+    }
+
     /// Returns a decimal string representation of `self`.
     ///
     /// ```
@@ -893,6 +827,7 @@ impl BigNumRef {
     ///
     /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
     /// ```
+    #[corresponds(BN_bn2dec)]
     pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
         unsafe {
             let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
@@ -906,8 +841,9 @@ impl BigNumRef {
     /// # use openssl::bn::BigNum;
     /// let s = -BigNum::from_u32(0x99ff).unwrap();
     ///
-    /// assert_eq!(&**s.to_hex_str().unwrap(), "-99FF");
+    /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
     /// ```
+    #[corresponds(BN_bn2hex)]
     pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
         unsafe {
             let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
@@ -916,16 +852,45 @@ impl BigNumRef {
     }
 
     /// Returns an `Asn1Integer` containing the value of `self`.
+    #[corresponds(BN_to_ASN1_INTEGER)]
     pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
         unsafe {
             cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
                 .map(|p| Asn1Integer::from_ptr(p))
         }
     }
+
+    /// Force constant time computation on this value.
+    #[corresponds(BN_set_flags)]
+    #[cfg(ossl110)]
+    pub fn set_const_time(&mut self) {
+        unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
+    }
+
+    /// Returns true if `self` is in const time mode.
+    #[corresponds(BN_get_flags)]
+    #[cfg(ossl110)]
+    pub fn is_const_time(&self) -> bool {
+        unsafe {
+            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
+            ret == ffi::BN_FLG_CONSTTIME
+        }
+    }
+
+    /// Returns true if `self` was created with [`BigNum::new_secure`].
+    #[corresponds(BN_get_flags)]
+    #[cfg(ossl110)]
+    pub fn is_secure(&self) -> bool {
+        unsafe {
+            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
+            ret == ffi::BN_FLG_SECURE
+        }
+    }
 }
 
 impl BigNum {
     /// Creates a new `BigNum` with the value 0.
+    #[corresponds(BN_new)]
     pub fn new() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -934,11 +899,19 @@ impl BigNum {
         }
     }
 
+    /// Returns a new secure `BigNum`.
+    #[corresponds(BN_secure_new)]
+    #[cfg(ossl110)]
+    pub fn new_secure() -> Result<BigNum, ErrorStack> {
+        unsafe {
+            ffi::init();
+            let v = cvt_p(ffi::BN_secure_new())?;
+            Ok(BigNum::from_ptr(v))
+        }
+    }
+
     /// Creates a new `BigNum` with the given value.
-    ///
-    /// OpenSSL documentation at [`BN_set_word`]
-    ///
-    /// [`BN_set_word`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_set_word.html
+    #[corresponds(BN_set_word)]
     pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
         BigNum::new().and_then(|v| unsafe {
             cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
@@ -946,10 +919,7 @@ impl BigNum {
     }
 
     /// Creates a `BigNum` from a decimal string.
-    ///
-    /// OpenSSL documentation at [`BN_dec2bn`]
-    ///
-    /// [`BN_dec2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_dec2bn.html
+    #[corresponds(BN_dec2bn)]
     pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -961,10 +931,7 @@ impl BigNum {
     }
 
     /// Creates a `BigNum` from a hexadecimal string.
-    ///
-    /// OpenSSL documentation at [`BN_hex2bn`]
-    ///
-    /// [`BN_hex2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_hex2bn.html
+    #[corresponds(BN_hex2bn)]
     pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -979,10 +946,9 @@ impl BigNum {
     /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc2409_prime_768`]
-    ///
     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
-    /// [`BN_get_rfc2409_prime_768`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc2409_prime_768.html
+    #[corresponds(BN_get_rfc2409_prime_768)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -994,10 +960,9 @@ impl BigNum {
     /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc2409_prime_1024`]
-    ///
     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
-    /// [`BN_get_rfc2409_prime_1024`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc2409_prime_1024.html
+    #[corresponds(BN_get_rfc2409_prime_1024)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1009,10 +974,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_1536`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
-    /// [`BN_get_rfc3526_prime_1536`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_1536.html
+    #[corresponds(BN_get_rfc3526_prime_1536)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1024,10 +988,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_2048`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
-    /// [`BN_get_rfc3526_prime_2048`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_2048.html
+    #[corresponds(BN_get_rfc3526_prime_2048)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1039,10 +1002,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_3072`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
-    /// [`BN_get_rfc3526_prime_3072`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_3072.html
+    #[corresponds(BN_get_rfc3526_prime_3072)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1054,10 +1016,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_4096`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
-    /// [`BN_get_rfc3526_prime_4096`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_4096.html
+    #[corresponds(BN_get_rfc3526_prime_4096)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1069,10 +1030,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 6144`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 17.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_6144`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
-    /// [`BN_get_rfc3526_prime_6144`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_6144.html
+    #[corresponds(BN_get_rfc3526_prime_6114)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1084,10 +1044,9 @@ impl BigNum {
     /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
     ///
-    /// OpenSSL documentation at [`BN_get_rfc3526_prime_8192`]
-    ///
     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
-    /// [`BN_get_rfc3526_prime_8192`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_get_rfc3526_prime_8192.html
+    #[corresponds(BN_get_rfc3526_prime_8192)]
+    #[cfg(not(boringssl))]
     pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
@@ -1107,13 +1066,15 @@ impl BigNum {
     ///
     /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
     /// ```
+    #[corresponds(BN_bin2bn)]
     pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
         unsafe {
             ffi::init();
             assert!(n.len() <= c_int::max_value() as usize);
+
             cvt_p(ffi::BN_bin2bn(
                 n.as_ptr(),
-                n.len() as c_int,
+                n.len() as LenType,
                 ptr::null_mut(),
             ))
             .map(|p| BigNum::from_ptr(p))
@@ -1428,4 +1389,38 @@ mod tests {
         assert!(p.is_prime(100, &mut ctx).unwrap());
         assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
     }
+
+    #[cfg(ossl110)]
+    #[test]
+    fn test_secure_bn_ctx() {
+        let mut cxt = BigNumContext::new_secure().unwrap();
+        let a = BigNum::from_u32(8).unwrap();
+        let b = BigNum::from_u32(3).unwrap();
+
+        let mut remainder = BigNum::new().unwrap();
+        remainder.nnmod(&a, &b, &mut cxt).unwrap();
+
+        assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
+    }
+
+    #[cfg(ossl110)]
+    #[test]
+    fn test_secure_bn() {
+        let a = BigNum::new().unwrap();
+        assert!(!a.is_secure());
+
+        let b = BigNum::new_secure().unwrap();
+        assert!(b.is_secure())
+    }
+
+    #[cfg(ossl110)]
+    #[test]
+    fn test_const_time_bn() {
+        let a = BigNum::new().unwrap();
+        assert!(!a.is_const_time());
+
+        let mut b = BigNum::new().unwrap();
+        b.set_const_time();
+        assert!(b.is_const_time())
+    }
 }