mundane/boringssl/
mod.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! The BoringSSL API.
6//!
7//! This module provides a safe access to the BoringSSL API.
8//!
9//! It accomplishes this using the following structure:
10//! - The internal `raw` module provides nearly-raw access to the BoringSSL API.
11//!   For each function in the BoringSSL API, it exposes an equivalent Rust
12//!   function which performs error checking. Functions which return pointers
13//!   return `Result<NonNull<T>, BoringError>`, functions which return status
14//!   codes return `Result<(), BoringError>`, etc. This API makes it less likely
15//!   to accidentally forget to check for null pointers or error status codes.
16//! - The internal `wrapper` module provides types which wrap C objects and
17//!   handle many of the details of their lifecycles. These include
18//!   `CStackWrapper`, which handles initializing and destructing
19//!   stack-allocated C objects; `CHeapWrapper`, which is analogous to Rust's
20//!   `Box` or `Rc`, and handles allocation, reference counting, and freeing;
21//!   and `CRef`, which is analogous to a Rust reference.
22//! - This module builds on top of the `raw` and `wrapper` modules to provide a
23//!   safe API. This allows us to `#![forbid(unsafe_code)]` in the rest of the
24//!   crate, which in turn means that this is the only module whose memory
25//!   safety needs to be manually verified.
26//!
27//! # Usage
28//!
29//! Each type, `T`, from the BoringSSL API is exposed as either a
30//! `CStackWrapper<T>`, a `CHeapWrapper<T>`, or a `CRef<T>`. Each function from
31//! the BoringSSL API which operates on a particular type is exposed as a method
32//! on the wrapped version of that type. For example, the BoringSSL `CBS_len`
33//! function operates on a `CBS`; we provide the `cbs_len` method on the
34//! `CStackWrapper<CBS>` type. While BoringSSL functions that operate on a
35//! particular type take the form `TYPE_method`, the Rust equivalents are all
36//! lower-case - `type_method`.
37//!
38//! Some functions which do not make sense as methods are exposed as bare
39//! functions. For example, the BoringSSL `ECDSA_sign` function is exposed as a
40//! bare function as `ecdsa_sign`.
41//!
42//! Types which can be constructed without arguments implement `Default`. Types
43//! which require arguments to be constructed provide associated functions which
44//! take those arguments and return a new instance of that type. For example,
45//! the `CHeapWrapper<EC_KEY>::ec_key_parse_private_key` function parses a
46//! private key from an input stream and returns a new `CHeapWrapper<EC_KEY>`.
47//!
48//! # API Guidelines
49//!
50//! This module is meant to be as close as possible to a direct set of FFI
51//! bindings while still providing a safe API. While memory safety is handled
52//! internally, and certain error conditions which could affect memory safety
53//! are checked internally (and cause the process to abort if they fail), most
54//! errors are returned from the API, as they are considered business logic,
55//! which is outside the scope of this module.
56
57// NOTES on safety requirements of the BoringSSL API:
58// - Though it may not be explicitly documented, calling methods on uinitialized
59//   values is UB. Remember, this is C! Always initialize (usually via XXX_init
60//   or a similarly-named function) before calling any methods or functions.
61// - Any BoringSSL documentation that says "x property must hold" means that, if
62//   that property doesn't hold, it may cause UB - you are not guaranteed that
63//   it will be detected and an error will be returned.
64// - If a pointer parameter is const, the function does NOT take ownership of
65//   the object and does NOT retain a reference to the object (in Rust
66//   terminology, the object need only live as long as the function call). If
67//   the pointer parameter is not const, it MAY take ownership or hold a
68//   reference depending on the documentation. Generally, ownership is only
69//   taken if explicitly documented, but documentation bugs may exist, so be
70//   careful.
71
72#[macro_use]
73mod abort;
74#[macro_use]
75mod wrapper;
76mod raw;
77
78// C types
79pub use bssl_sys::{
80    BIGNUM, CBB, CBS, EC_GROUP, EC_KEY, EVP_MD, EVP_PKEY, HMAC_CTX, MD5_CTX, RC4_KEY, RSA, RSA_F4,
81    SHA256_CTX, SHA512_CTX, SHA_CTX,
82};
83// C constants
84pub use bssl_sys::{
85    NID_X9_62_prime256v1, NID_md5, NID_secp384r1, NID_secp521r1, NID_sha1, NID_sha256, NID_sha384,
86    NID_sha512, ED25519_PRIVATE_KEY_LEN, ED25519_PUBLIC_KEY_LEN, ED25519_SIGNATURE_LEN,
87    MD5_DIGEST_LENGTH, SHA256_DIGEST_LENGTH, SHA384_DIGEST_LENGTH, SHA512_DIGEST_LENGTH,
88    SHA_DIGEST_LENGTH,
89};
90// wrapper types
91pub use boringssl::wrapper::{CHeapWrapper, CRef, CStackWrapper};
92
93use std::convert::TryInto;
94use std::ffi::CStr;
95use std::fmt::{self, Debug, Display, Formatter};
96use std::mem::MaybeUninit;
97use std::num::NonZeroUsize;
98use std::os::raw::{c_char, c_int, c_uint, c_void};
99use std::{cmp, ptr, slice};
100
101use boringssl::abort::UnwrapAbort;
102use boringssl::raw::{
103    BN_set_u64, CBB_data, CBB_init, CBB_len, CBS_init, CBS_len, CRYPTO_memcmp, ECDSA_sign,
104    ECDSA_size, ECDSA_verify, EC_GROUP_get_curve_name, EC_GROUP_new_by_curve_name,
105    EC_KEY_generate_key, EC_KEY_get0_group, EC_KEY_marshal_private_key, EC_KEY_parse_private_key,
106    EC_KEY_set_group, EC_curve_nid2nist, ED25519_keypair, ED25519_keypair_from_seed, ED25519_sign,
107    ED25519_verify, ERR_print_errors_cb, EVP_PBE_scrypt, EVP_PKEY_assign_EC_KEY,
108    EVP_PKEY_assign_RSA, EVP_PKEY_get1_EC_KEY, EVP_PKEY_get1_RSA, EVP_marshal_public_key,
109    EVP_parse_public_key, HMAC_CTX_copy, HMAC_CTX_init, HMAC_Final, HMAC_Init_ex, HMAC_Update,
110    HMAC_size, RAND_bytes, RC4_set_key, RSA_bits, RSA_generate_key_ex, RSA_marshal_private_key,
111    RSA_parse_private_key, RSA_sign_pss_mgf1, RSA_size, RSA_verify_pss_mgf1, SHA384_Init, RC4,
112};
113#[cfg(feature = "rsa-pkcs1v15")]
114use boringssl::raw::{RSA_sign, RSA_verify};
115
116impl CStackWrapper<BIGNUM> {
117    /// The `BN_set_u64` function.
118    #[must_use]
119    pub fn bn_set_u64(&mut self, value: u64) -> Result<(), BoringError> {
120        unsafe { BN_set_u64(self.as_mut(), value) }
121    }
122}
123
124impl CStackWrapper<CBB> {
125    /// Creates a new `CBB` and initializes it with `CBB_init`.
126    ///
127    /// `cbb_new` can only fail due to OOM.
128    #[must_use]
129    pub fn cbb_new(initial_capacity: usize) -> Result<CStackWrapper<CBB>, BoringError> {
130        unsafe {
131            let mut cbb = MaybeUninit::uninit();
132            CBB_init(cbb.as_mut_ptr(), initial_capacity)?;
133            Ok(CStackWrapper::new(cbb.assume_init()))
134        }
135    }
136
137    /// Invokes a callback on the contents of a `CBB`.
138    ///
139    /// `cbb_with_data` accepts a callback, and invokes that callback, passing a
140    /// slice of the current contents of this `CBB`.
141    #[must_use]
142    pub fn cbb_with_data<O, F: Fn(&[u8]) -> O>(&self, with_data: F) -> O {
143        unsafe {
144            // NOTE: The return value of CBB_data is only valid until the next
145            // operation on the CBB. This method is safe because the slice
146            // reference cannot outlive this function body, and thus cannot live
147            // beyond another method call that could invalidate the buffer.
148            let len = CBB_len(self.as_const());
149            if len == 0 {
150                // If len is 0, then CBB_data could technically return a null
151                // pointer. Constructing a slice from a null pointer is likely
152                // invalid, so we do this instead.
153                with_data(&[])
154            } else {
155                // Since the length is non-zero, CBB_data should not return a
156                // null pointer.
157                let ptr = CBB_data(self.as_const()).unwrap_abort();
158                // TODO(joshlf): Can with_data use this to smuggle out the
159                // reference, outliving the lifetime of self?
160                with_data(slice::from_raw_parts(ptr.as_ptr(), len))
161            }
162        }
163    }
164}
165
166impl CStackWrapper<CBS> {
167    /// The `CBS_len` function.
168    #[must_use]
169    pub fn cbs_len(&self) -> usize {
170        unsafe { CBS_len(self.as_const()) }
171    }
172
173    /// Invokes a callback on a temporary `CBS`.
174    ///
175    /// `cbs_with_temp_buffer` constructs a `CBS` from the provided byte slice,
176    /// and invokes a callback on the `CBS`. The `CBS` is destructed before
177    /// `cbs_with_temp_buffer` returns.
178    // TODO(joshlf): Holdover until we figure out how to put lifetimes in CStackWrappers.
179    #[must_use]
180    pub fn cbs_with_temp_buffer<O, F: Fn(&mut CStackWrapper<CBS>) -> O>(
181        bytes: &[u8],
182        with_cbs: F,
183    ) -> O {
184        unsafe {
185            let mut cbs = MaybeUninit::uninit();
186            CBS_init(cbs.as_mut_ptr(), bytes.as_ptr(), bytes.len());
187            let mut cbs = CStackWrapper::new(cbs.assume_init());
188            with_cbs(&mut cbs)
189        }
190    }
191}
192
193impl CRef<'static, EC_GROUP> {
194    /// The `EC_GROUP_new_by_curve_name` function.
195    #[must_use]
196    pub fn ec_group_new_by_curve_name(nid: c_int) -> Result<CRef<'static, EC_GROUP>, BoringError> {
197        unsafe { Ok(CRef::new(EC_GROUP_new_by_curve_name(nid)?)) }
198    }
199}
200
201impl<'a> CRef<'a, EC_GROUP> {
202    /// The `EC_GROUP_get_curve_name` function.
203    #[must_use]
204    pub fn ec_group_get_curve_name(&self) -> c_int {
205        unsafe { EC_GROUP_get_curve_name(self.as_const()) }
206    }
207}
208
209/// The `EC_curve_nid2nist` function.
210#[must_use]
211pub fn ec_curve_nid2nist(nid: c_int) -> Result<&'static CStr, BoringError> {
212    unsafe { Ok(CStr::from_ptr(EC_curve_nid2nist(nid)?.as_ptr())) }
213}
214
215impl CHeapWrapper<EC_KEY> {
216    /// The `EC_KEY_generate_key` function.
217    #[must_use]
218    pub fn ec_key_generate_key(&mut self) -> Result<(), BoringError> {
219        unsafe { EC_KEY_generate_key(self.as_mut()) }
220    }
221
222    /// The `EC_KEY_parse_private_key` function.
223    ///
224    /// If `group` is `None`, then the group pointer argument to
225    /// `EC_KEY_parse_private_key` will be NULL.
226    #[must_use]
227    pub fn ec_key_parse_private_key(
228        cbs: &mut CStackWrapper<CBS>,
229        group: Option<CRef<'static, EC_GROUP>>,
230    ) -> Result<CHeapWrapper<EC_KEY>, BoringError> {
231        unsafe {
232            Ok(CHeapWrapper::new_from(EC_KEY_parse_private_key(
233                cbs.as_mut(),
234                group.map(|g| g.as_const()).unwrap_or(ptr::null()),
235            )?))
236        }
237    }
238
239    /// The `EC_KEY_get0_group` function.
240    #[must_use]
241    #[allow(clippy::needless_lifetimes)] // to be more explicit
242    pub fn ec_key_get0_group<'a>(&'a self) -> Result<CRef<'a, EC_GROUP>, BoringError> {
243        // get0 doesn't increment the refcount; the lifetimes ensure that the
244        // returned CRef can't outlive self
245        unsafe { Ok(CRef::new(EC_KEY_get0_group(self.as_const())?)) }
246    }
247
248    /// The `EC_KEY_set_group` function.
249    #[must_use]
250    pub fn ec_key_set_group(&mut self, group: &CRef<'static, EC_GROUP>) -> Result<(), BoringError> {
251        unsafe { EC_KEY_set_group(self.as_mut(), group.as_const()) }
252    }
253
254    /// The `EC_KEY_marshal_private_key` function.
255    #[must_use]
256    pub fn ec_key_marshal_private_key(
257        &self,
258        cbb: &mut CStackWrapper<CBB>,
259    ) -> Result<(), BoringError> {
260        unsafe { EC_KEY_marshal_private_key(cbb.as_mut(), self.as_const(), 0) }
261    }
262}
263
264/// The `ECDSA_sign` function.
265///
266/// `ecdsa_sign` returns the number of bytes written to `sig`.
267///
268/// # Aborts
269///
270/// `ecdsa_sign` aborts if `sig` is shorter than the minimum required signature
271/// size given by `ecdsa_size`, or if `key` doesn't have a group set.
272#[must_use]
273pub fn ecdsa_sign(
274    digest: &[u8],
275    sig: &mut [u8],
276    key: &CHeapWrapper<EC_KEY>,
277) -> Result<usize, BoringError> {
278    unsafe {
279        // If we call ECDSA_sign with sig.len() < min_size, it will invoke UB.
280        // ECDSA_size fails if the key doesn't have a group set.
281        let min_size = ecdsa_size(key).unwrap_abort();
282        assert_abort!(sig.len() >= min_size.get());
283
284        let mut sig_len: c_uint = 0;
285        ECDSA_sign(
286            0,
287            digest.as_ptr(),
288            digest.len(),
289            sig.as_mut_ptr(),
290            &mut sig_len,
291            key.as_const(),
292        )?;
293        // ECDSA_sign guarantees that it only needs ECDSA_size bytes for the
294        // signature.
295        let sig_len = sig_len.try_into().unwrap_abort();
296        assert_abort!(sig_len <= min_size.get());
297        Ok(sig_len)
298    }
299}
300
301/// The `ECDSA_verify` function.
302#[must_use]
303pub fn ecdsa_verify(digest: &[u8], sig: &[u8], key: &CHeapWrapper<EC_KEY>) -> bool {
304    unsafe {
305        ECDSA_verify(0, digest.as_ptr(), digest.len(), sig.as_ptr(), sig.len(), key.as_const())
306    }
307}
308
309/// The `ECDSA_size` function.
310#[must_use]
311pub fn ecdsa_size(key: &CHeapWrapper<EC_KEY>) -> Result<NonZeroUsize, BoringError> {
312    unsafe { ECDSA_size(key.as_const()) }
313}
314
315/// The `ED25519_keypair` function.
316#[must_use]
317pub fn ed25519_keypair() -> [u8; ED25519_PRIVATE_KEY_LEN as usize] {
318    let mut public_unused = [0u8; ED25519_PUBLIC_KEY_LEN as usize];
319    let mut private = [0u8; ED25519_PRIVATE_KEY_LEN as usize];
320    unsafe {
321        ED25519_keypair((&mut public_unused[..]).as_mut_ptr(), (&mut private[..]).as_mut_ptr())
322    };
323    private
324}
325
326/// The `ED25519_sign` function.
327#[must_use]
328pub fn ed25519_sign(message: &[u8], private_key: &[u8; 64]) -> Result<[u8; 64], BoringError> {
329    let mut sig = [0u8; 64];
330    unsafe { ED25519_sign(&mut sig, message.as_ptr(), message.len(), private_key)? };
331    Ok(sig)
332}
333
334/// The `ED25519_keypair_from_seed` function.
335#[must_use]
336pub fn ed25519_keypair_from_seed(seed: &[u8; 32]) -> ([u8; 32], [u8; 64]) {
337    let mut public = [0u8; 32];
338    let mut private = [0u8; 64];
339    unsafe {
340        ED25519_keypair_from_seed(
341            (&mut public[..]).as_mut_ptr(),
342            (&mut private[..]).as_mut_ptr(),
343            (&seed[..]).as_ptr(),
344        )
345    };
346    (public, private)
347}
348
349/// The `ED25519_verify` function.
350#[must_use]
351pub fn ed25519_verify(message: &[u8], signature: &[u8; 64], public_key: &[u8; 32]) -> bool {
352    unsafe { ED25519_verify(message.as_ptr(), message.len(), signature, public_key) }
353}
354
355impl CHeapWrapper<EVP_PKEY> {
356    /// The `EVP_parse_public_key` function.
357    #[must_use]
358    pub fn evp_parse_public_key(
359        cbs: &mut CStackWrapper<CBS>,
360    ) -> Result<CHeapWrapper<EVP_PKEY>, BoringError> {
361        unsafe { Ok(CHeapWrapper::new_from(EVP_parse_public_key(cbs.as_mut())?)) }
362    }
363
364    /// The `EVP_marshal_public_key` function.
365    #[must_use]
366    pub fn evp_marshal_public_key(&self, cbb: &mut CStackWrapper<CBB>) -> Result<(), BoringError> {
367        unsafe { EVP_marshal_public_key(cbb.as_mut(), self.as_const()) }
368    }
369
370    /// The `EVP_PKEY_assign_EC_KEY` function.
371    pub fn evp_pkey_assign_ec_key(&mut self, ec_key: CHeapWrapper<EC_KEY>) {
372        unsafe {
373            // NOTE: It's very important that we use 'into_mut' here so that
374            // ec_key's refcount is not decremented. That's because
375            // EVP_PKEY_assign_EC_KEY doesn't increment the refcount of its
376            // argument.
377            let key = ec_key.into_mut();
378            // EVP_PKEY_assign_EC_KEY only fails if key is NULL.
379            EVP_PKEY_assign_EC_KEY(self.as_mut(), key).unwrap_abort()
380        }
381    }
382
383    /// The `EVP_PKEY_assign_RSA` function.
384    pub fn evp_pkey_assign_rsa(&mut self, rsa: CHeapWrapper<RSA>) {
385        unsafe {
386            // NOTE: It's very important that we use 'into_mut' here so that
387            // rsa's refcount is not decremented. That's because
388            // EVP_PKEY_assign_RSA doesn't increment the refcount of its
389            // argument.
390            let key = rsa.into_mut();
391            // EVP_PKEY_assign_RSA only fails if key is NULL.
392            EVP_PKEY_assign_RSA(self.as_mut(), key).unwrap_abort()
393        }
394    }
395
396    /// The `EVP_PKEY_get1_EC_KEY` function.
397    #[must_use]
398    pub fn evp_pkey_get1_ec_key(&mut self) -> Result<CHeapWrapper<EC_KEY>, BoringError> {
399        // NOTE: It's important that we use get1 here, as it increments the
400        // refcount of the EC_KEY before returning a pointer to it.
401        unsafe { Ok(CHeapWrapper::new_from(EVP_PKEY_get1_EC_KEY(self.as_mut())?)) }
402    }
403
404    /// The `EVP_PKEY_get1_RSA` function.
405    #[must_use]
406    pub fn evp_pkey_get1_rsa(&mut self) -> Result<CHeapWrapper<RSA>, BoringError> {
407        // NOTE: It's important that we use get1 here, as it increments the
408        // refcount of the RSA key before returning a pointer to it.
409        unsafe { Ok(CHeapWrapper::new_from(EVP_PKEY_get1_RSA(self.as_mut())?)) }
410    }
411}
412
413/// The `EVP_PBE_scrypt` function.
414#[allow(non_snake_case)]
415#[must_use]
416pub fn evp_pbe_scrypt(
417    password: &[u8],
418    salt: &[u8],
419    N: u64,
420    r: u64,
421    p: u64,
422    max_mem: usize,
423    out_key: &mut [u8],
424) -> Result<(), BoringError> {
425    unsafe {
426        EVP_PBE_scrypt(
427            password.as_ptr() as *const c_char,
428            password.len(),
429            salt.as_ptr(),
430            salt.len(),
431            N,
432            r,
433            p,
434            max_mem,
435            out_key.as_mut_ptr(),
436            out_key.len(),
437        )
438    }
439}
440
441/// The `PKCS5_PBKDF2_HMAC` function.
442#[cfg(feature = "kdf")]
443#[must_use]
444pub fn pkcs5_pbkdf2_hmac(
445    password: &[u8],
446    salt: &[u8],
447    iterations: c_uint,
448    digest: &CRef<'static, EVP_MD>,
449    out_key: &mut [u8],
450) -> Result<(), BoringError> {
451    unsafe {
452        raw::PKCS5_PBKDF2_HMAC(
453            password.as_ptr() as *const c_char,
454            password.len(),
455            salt.as_ptr(),
456            salt.len(),
457            iterations,
458            digest.as_const(),
459            out_key.len(),
460            out_key.as_mut_ptr(),
461        )
462    }
463}
464
465impl CStackWrapper<SHA512_CTX> {
466    /// Initializes a new `CStackWrapper<SHA512_CTX>` as a SHA-384 hash.
467    ///
468    /// The BoringSSL `SHA512_CTX` is used for both the SHA-512 and SHA-384 hash
469    /// functions. The implementation of `Default` for
470    /// `CStackWrapper<SHA512_CTX>` produces a context initialized for a SHA-512
471    /// hash. In order to produce a context for a SHA-384 hash, use this
472    /// constructor instead.
473    #[must_use]
474    pub fn sha384_new() -> CStackWrapper<SHA512_CTX> {
475        unsafe {
476            let mut ctx = MaybeUninit::uninit();
477            SHA384_Init(ctx.as_mut_ptr());
478            CStackWrapper::new(ctx.assume_init())
479        }
480    }
481}
482
483macro_rules! impl_evp_digest {
484    (#[$doc:meta] $name:ident, $raw_name:ident) => {
485        #[$doc]
486        #[must_use]
487        pub fn $name() -> CRef<'static, EVP_MD> {
488            unsafe { CRef::new(::boringssl::raw::$raw_name()) }
489        }
490    };
491}
492
493impl CRef<'static, EVP_MD> {
494    impl_evp_digest!(
495        /// The `EVP_md5` function.
496        evp_md5,
497        EVP_md5
498    );
499    impl_evp_digest!(
500        /// The `EVP_sha1` function.
501        evp_sha1,
502        EVP_sha1
503    );
504    impl_evp_digest!(
505        /// The `EVP_sha256` function.
506        evp_sha256,
507        EVP_sha256
508    );
509    impl_evp_digest!(
510        /// The `EVP_sha384` function.
511        evp_sha384,
512        EVP_sha384
513    );
514    impl_evp_digest!(
515        /// The `EVP_sha512` function.
516        evp_sha512,
517        EVP_sha512
518    );
519}
520
521impl CStackWrapper<HMAC_CTX> {
522    /// Initializes a new `HMAC_CTX`.
523    ///
524    /// `hmac_ctx_new` initializes a new `HMAC_CTX` using `HMAC_CTX_init` and
525    /// then further initializes it with `HMAC_CTX_Init_ex`. It can only fail
526    /// due to OOM.
527    #[must_use]
528    pub fn hmac_ctx_new(
529        key: &[u8],
530        md: &CRef<'static, EVP_MD>,
531    ) -> Result<CStackWrapper<HMAC_CTX>, BoringError> {
532        unsafe {
533            let mut ctx = MaybeUninit::uninit();
534            HMAC_CTX_init(ctx.as_mut_ptr());
535            HMAC_Init_ex(
536                ctx.as_mut_ptr(),
537                key.as_ptr() as *const c_void,
538                key.len(),
539                md.as_const(),
540            )?;
541            Ok(CStackWrapper::new(ctx.assume_init()))
542        }
543    }
544
545    /// The `HMAC_Update` function.
546    pub fn hmac_update(&mut self, data: &[u8]) {
547        unsafe { HMAC_Update(self.as_mut(), data.as_ptr(), data.len()) }
548    }
549
550    // NOTE(joshlf): We require exactly the right length (as opposed to just
551    // long enough) so that we don't have to have hmac_final return a length.
552
553    /// The `HMAC_Final` function.
554    ///
555    /// # Aborts
556    ///
557    /// `hmac_final` aborts if `out` is not exactly the right length (as defined
558    /// by `HMAC_size`).
559    pub fn hmac_final(&mut self, out: &mut [u8]) {
560        unsafe {
561            let hmac_size = HMAC_size(self.as_const());
562            assert_abort_eq!(out.len(), hmac_size);
563            let mut hmac_final_size: u32 = 0;
564            // HMAC_Final is documented to fail on allocation failure, but an
565            // internal comment states that it's infallible. In either case, we
566            // want to panic. Normally, for allocation failure, we'd put the
567            // unwrap higher in the stack, but since this is supposed to be
568            // infallible anyway, we put it here.
569            //
570            // TODO(joshlf): Remove this comment once HMAC_Final is documented
571            // as being infallible.
572            HMAC_Final(self.as_mut(), out.as_mut_ptr(), &mut hmac_final_size).unwrap_abort();
573            // `HMAC_Final` guarantees that it will set its out argument to the
574            // same value returned by `HMAC_size`. If the conversion from `u32`
575            // to `usize` fails, that means that a) we are on a 16-bit platform
576            // and b) that `HMAC_Final` failed to uphold its contract.
577            assert_abort_eq!(
578                hmac_size,
579                hmac_final_size
580                    .try_into()
581                    .expect("`HMAC_Final` returned size out of range of `usize`")
582            );
583            assert_abort_eq!(out.len(), hmac_size);
584        }
585    }
586
587    /// The `HMAC_CTX_copy` function.
588    pub fn hmac_ctx_copy(&self) -> Result<Self, BoringError> {
589        unsafe {
590            let mut ctx = MaybeUninit::uninit();
591            HMAC_CTX_copy(ctx.as_mut_ptr(), self.as_const())?;
592            Ok(CStackWrapper::new(ctx.assume_init()))
593        }
594    }
595}
596
597impl CStackWrapper<RC4_KEY> {
598    /// The `RC4_set_key` function.
599    ///
600    /// # Aborts
601    ///
602    /// `RC4_set_key` encodes the key length with `u32`, which may differ from
603    /// the target platform's word size (`usize`). This function aborts if the
604    /// length of the `key` slice exceeds `u32::MAX`.
605    pub fn rc4_set_key(key: &[u8]) -> Self {
606        let mut rc4 = RC4_KEY { x: 0, y: 0, data: [0; 256] };
607        unsafe {
608            // `RC4_set_key` reads `key` and writes into `rc4`. It does not take
609            // ownership of `key` and `key` need not live as long as `rc4`.
610            RC4_set_key(&mut rc4, key.len().try_into().unwrap_abort(), key.as_ptr());
611            CStackWrapper::new(rc4)
612        }
613    }
614
615    /// The `RC4` function.
616    pub fn rc4(&mut self, input: &[u8], output: &mut [u8]) {
617        let len = cmp::min(input.len(), output.len());
618        let input = &input[..len];
619        let output = &mut output[..len];
620        unsafe {
621            RC4(self.as_mut(), len, input.as_ptr(), output.as_mut_ptr());
622        }
623    }
624}
625
626impl CHeapWrapper<RSA> {
627    /// The `RSA_bits` function.
628    #[must_use]
629    pub fn rsa_bits(&self) -> c_uint {
630        // RSA_bits does not mutate its argument but, for
631        // backwards-compatibility reasons, continues to take a normal
632        // (non-const) pointer.
633        unsafe { RSA_bits(self.as_const() as *mut _) }
634    }
635
636    /// The `RSA_generate_key_ex` function.
637    #[must_use]
638    pub fn rsa_generate_key_ex(
639        &mut self,
640        bits: c_int,
641        e: &CRef<'_, BIGNUM>,
642    ) -> Result<(), BoringError> {
643        unsafe {
644            // NOTE: It's very important that we use 'into_mut' here so that e's
645            // refcount is not decremented. That's because RSA_generate_key_ex
646            // takes ownership of e, and thus doesn't increment its refcount.
647            RSA_generate_key_ex(self.as_mut(), bits, e.as_const(), ptr::null_mut())
648        }
649    }
650
651    /// The `RSA_marshal_private_key` function.
652    #[must_use]
653    pub fn rsa_marshal_private_key(&self, cbb: &mut CStackWrapper<CBB>) -> Result<(), BoringError> {
654        unsafe { RSA_marshal_private_key(cbb.as_mut(), self.as_const()) }
655    }
656
657    /// The `RSA_parse_private_key` function.
658    #[must_use]
659    pub fn rsa_parse_private_key(
660        cbs: &mut CStackWrapper<CBS>,
661    ) -> Result<CHeapWrapper<RSA>, BoringError> {
662        unsafe { Ok(CHeapWrapper::new_from(RSA_parse_private_key(cbs.as_mut())?)) }
663    }
664
665    /// The `RSA_size` function.
666    #[must_use]
667    pub fn rsa_size(&self) -> Result<NonZeroUsize, BoringError> {
668        unsafe { RSA_size(self.as_const()) }
669    }
670}
671
672/// The `RSA_sign` function.
673///
674/// # Aborts
675///
676/// `rsa_sign` aborts if `sig` is shorter than the minimum required signature
677/// size given by `rsa_size`.
678#[cfg(feature = "rsa-pkcs1v15")]
679pub fn rsa_sign(
680    hash_nid: c_int,
681    digest: &[u8],
682    sig: &mut [u8],
683    key: &CHeapWrapper<RSA>,
684) -> Result<usize, BoringError> {
685    unsafe {
686        // If we call RSA_sign with sig.len() < min_size, it will invoke UB.
687        let min_size = key.rsa_size().unwrap_abort();
688        assert_abort!(sig.len() >= min_size.get());
689
690        let mut sig_len: c_uint = 0;
691        RSA_sign(
692            hash_nid,
693            digest.as_ptr(),
694            digest.len().try_into().unwrap_abort(),
695            sig.as_mut_ptr(),
696            &mut sig_len,
697            // RSA_sign does not mutate its argument but, for
698            // backwards-compatibility reasons, continues to take a normal
699            // (non-const) pointer.
700            key.as_const() as *mut _,
701        )?;
702
703        // RSA_sign guarantees that it only needs RSA_size bytes for the
704        // signature.
705        let sig_len = sig_len.try_into().unwrap_abort();
706        assert_abort!(sig_len <= min_size.get());
707        Ok(sig_len)
708    }
709}
710
711/// The `rsa_sign_pss_mgf1` function.
712#[must_use]
713pub fn rsa_sign_pss_mgf1(
714    key: &CHeapWrapper<RSA>,
715    sig: &mut [u8],
716    digest: &[u8],
717    md: &CRef<'static, EVP_MD>,
718    mgf1_md: Option<&CRef<'static, EVP_MD>>,
719    salt_len: c_int,
720) -> Result<usize, BoringError> {
721    unsafe {
722        let mut sig_len: usize = 0;
723        RSA_sign_pss_mgf1(
724            // RSA_sign_pss_mgf1 does not mutate its argument but, for
725            // backwards-compatibility reasons, continues to take a normal
726            // (non-const) pointer.
727            key.as_const() as *mut _,
728            &mut sig_len,
729            sig.as_mut_ptr(),
730            sig.len(),
731            digest.as_ptr(),
732            digest.len(),
733            md.as_const(),
734            mgf1_md.map(CRef::as_const).unwrap_or(ptr::null()),
735            salt_len,
736        )?;
737
738        // RSA_sign_pss_mgf1 guarantees that it only needs RSA_size bytes for
739        // the signature.
740        let rsa_size = key.rsa_size().unwrap_abort();
741        let sig_len = sig_len;
742        assert_abort!(sig_len <= rsa_size.get());
743        Ok(sig_len)
744    }
745}
746
747/// The `RSA_verify` function.
748#[must_use]
749#[cfg(feature = "rsa-pkcs1v15")]
750pub fn rsa_verify(hash_nid: c_int, digest: &[u8], sig: &[u8], key: &CHeapWrapper<RSA>) -> bool {
751    unsafe {
752        RSA_verify(
753            hash_nid,
754            digest.as_ptr(),
755            digest.len(),
756            sig.as_ptr(),
757            sig.len(),
758            // RSA_verify does not mutate its argument but, for
759            // backwards-compatibility reasons, continues to take a normal
760            // (non-const) pointer.
761            key.as_const() as *mut _,
762        )
763    }
764}
765
766/// The `RSA_verify_pss_mgf1` function.
767#[must_use]
768pub fn rsa_verify_pss_mgf1(
769    key: &CHeapWrapper<RSA>,
770    digest: &[u8],
771    md: &CRef<'static, EVP_MD>,
772    mgf1_md: Option<&CRef<'static, EVP_MD>>,
773    salt_len: c_int,
774    sig: &[u8],
775) -> bool {
776    unsafe {
777        RSA_verify_pss_mgf1(
778            // RSA_verify_pss_mgf1 does not mutate its argument but, for
779            // backwards-compatibility reasons, continues to take a normal
780            // (non-const) pointer.
781            key.as_const() as *mut _,
782            digest.as_ptr(),
783            digest.len(),
784            md.as_const(),
785            mgf1_md.map(CRef::as_const).unwrap_or(ptr::null()),
786            salt_len,
787            sig.as_ptr(),
788            sig.len(),
789        )
790    }
791}
792
793/// Implements `CStackWrapper` for a hash context type.
794///
795/// The caller provides doc comments, a public method name, and a private
796/// function name (from the `raw` module) for an update function and a final
797/// function (e.g., `SHA256_Update` and `SHA256_Final`). Note that, as multiple
798/// impl blocks are allowed for a particular type, the same context type may be
799/// used multiple times. This is useful because both SHA-384 and SHA-512 use the
800/// `SHA512_CTX` context type.
801macro_rules! impl_hash {
802    ($ctx:ident, $digest_len:ident, #[$update_doc:meta] $update:ident, $update_raw:ident, #[$final_doc:meta] $final:ident, $final_raw:ident) => {
803        impl CStackWrapper<$ctx> {
804            #[$update_doc]
805            pub fn $update(&mut self, data: &[u8]) {
806                unsafe {
807                    ::boringssl::raw::$update_raw(
808                        self.as_mut(),
809                        data.as_ptr() as *const c_void,
810                        data.len(),
811                    )
812                }
813            }
814
815            #[$final_doc]
816            #[must_use]
817            pub fn $final(
818                &mut self,
819            ) -> [u8; ::bssl_sys::$digest_len as usize] {
820                unsafe {
821                    let mut md = MaybeUninit::<[u8; ::bssl_sys::$digest_len as usize]>::uninit();
822                    // SHA1_Final promises to return 1. SHA256_Final,
823                    // SHA384_Final, and SHA512_Final all document that they
824                    // only fail due to programmer error. The only input to the
825                    // function which could cause this is the context. I suspect
826                    // that the error condition is that XXX_Final is called
827                    // twice without resetting, but I'm not sure. Until we
828                    // figure it out, let's err on the side of caution and abort
829                    // here.
830                    //
831                    // TODO(joshlf): Figure out how XXX_Final can fail.
832                    ::boringssl::raw::$final_raw(md.as_mut_ptr() as _, self.as_mut()).unwrap_abort();
833                    md.assume_init()
834                }
835            }
836        }
837    };
838    (@doc_string $s:expr) => (#[doc="The `"] #[doc=$s] #[doc="` function."]);
839}
840
841/// Implements `Clone` for a `CStackWrapper<T>`.
842///
843/// Unsound for types without no-op `CDestruct` impls, or which
844/// capture `!Sync` shared state.
845macro_rules! impl_clone {
846    ($ty: ty) => {
847        impl Clone for CStackWrapper<$ty> {
848            fn clone(&self) -> Self {
849                unsafe { CStackWrapper::new(*self.as_const()) }
850            }
851        }
852    };
853}
854
855impl_hash!(
856    MD5_CTX,
857    MD5_DIGEST_LENGTH,
858    /// The `MD5_Update` function.
859    md5_update,
860    MD5_Update,
861    /// The `MD5_Final` function.
862    md5_final,
863    MD5_Final
864);
865impl_clone!(MD5_CTX);
866impl_hash!(
867    SHA_CTX,
868    SHA_DIGEST_LENGTH,
869    /// The `SHA1_Update` function.
870    sha1_update,
871    SHA1_Update,
872    /// The `SHA1_Final` function.
873    sha1_final,
874    SHA1_Final
875);
876impl_clone!(SHA_CTX);
877impl_hash!(
878    SHA256_CTX,
879    SHA256_DIGEST_LENGTH,
880    /// The `SHA256_Update` function.
881    sha256_update,
882    SHA256_Update,
883    /// The `SHA256_Final` function.
884    sha256_final,
885    SHA256_Final
886);
887impl_clone!(SHA256_CTX);
888impl_hash!(
889    SHA512_CTX,
890    SHA384_DIGEST_LENGTH,
891    /// The `SHA384_Update` function.
892    sha384_update,
893    SHA384_Update,
894    /// The `SHA384_Final` function.
895    sha384_final,
896    SHA384_Final
897);
898impl_hash!(
899    SHA512_CTX,
900    SHA512_DIGEST_LENGTH,
901    /// The `SHA512_Update` function.
902    sha512_update,
903    SHA512_Update,
904    /// The `SHA512_Final` function.
905    sha512_final,
906    SHA512_Final
907);
908impl_clone!(SHA512_CTX);
909
910/// The `CRYPTO_memcmp` function.
911///
912/// `crypto_memcmp` first verifies that `a.len() == b.len()` before calling
913/// `CRYPTO_memcmp`.
914#[must_use]
915pub fn crypto_memcmp(a: &[u8], b: &[u8]) -> bool {
916    if a.len() != b.len() {
917        return false;
918    }
919    unsafe { CRYPTO_memcmp(a.as_ptr() as *const c_void, b.as_ptr() as *const c_void, a.len()) == 0 }
920}
921
922/// The `RAND_bytes` function.
923pub fn rand_bytes(buf: &mut [u8]) {
924    unsafe { RAND_bytes(buf.as_mut_ptr(), buf.len()) }
925}
926
927/// An error generated by BoringSSL.
928///
929/// The `Debug` impl prints a stack trace. Each element of the trace corresponds
930/// to a function within BoringSSL which voluntarily pushed itself onto the
931/// stack. In this sense, it is not the same as a normal stack trace. Each
932/// element of the trace is of the form `[thread id]:error:[error code]:[library
933/// name]:OPENSSL_internal:[reason string]:[file]:[line number]:[optional string
934/// data]`.
935///
936/// The `Display` impl prints the first element of the stack trace.
937///
938/// Some BoringSSL functions do not record any error in the error stack. Errors
939/// generated from such functions are printed as `error calling <function name>`
940/// for both `Debug` and `Display` impls.
941pub struct BoringError {
942    stack_trace: Vec<String>,
943}
944
945impl BoringError {
946    /// Consumes the error stack.
947    ///
948    /// `f` is the name of the function that failed. If the error stack is empty
949    /// (some BoringSSL functions do not push errors onto the stack when
950    /// returning errors), the returned `BoringError` will simply note that the
951    /// named function failed; both the `Debug` and `Display` implementations
952    /// will return `error calling f`, where `f` is the value of the `f`
953    /// argument.
954    #[must_use]
955    fn consume_stack(f: &str) -> BoringError {
956        let stack_trace = {
957            let trace = get_error_stack_trace();
958            if trace.is_empty() {
959                vec![format!("error calling {}", f)]
960            } else {
961                trace
962            }
963        };
964        BoringError { stack_trace }
965    }
966
967    /// The number of frames in the stack trace.
968    ///
969    /// Guaranteed to be at least 1.
970    #[must_use]
971    pub fn stack_depth(&self) -> usize {
972        self.stack_trace.len()
973    }
974}
975
976fn get_error_stack_trace() -> Vec<String> {
977    // Credit to agl@google.com for this implementation.
978
979    unsafe extern "C" fn error_callback(s: *const c_char, s_len: usize, ctx: *mut c_void) -> c_int {
980        let stack_trace = ctx as *mut Vec<String>;
981        let s = ::std::slice::from_raw_parts(s as *const u8, s_len - 1);
982        (*stack_trace).push(String::from_utf8_lossy(s).to_string());
983        1
984    }
985
986    let mut stack_trace = Vec::new();
987    unsafe { ERR_print_errors_cb(Some(error_callback), &mut stack_trace as *mut _ as *mut c_void) };
988    stack_trace
989}
990
991impl Display for BoringError {
992    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
993        write!(f, "{}", self.stack_trace[0])
994    }
995}
996
997impl Debug for BoringError {
998    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
999        for elem in &self.stack_trace {
1000            writeln!(f, "{}", elem)?;
1001        }
1002        Ok(())
1003    }
1004}
1005
1006#[cfg(test)]
1007mod tests {
1008    use super::*;
1009    use util::should_fail;
1010
1011    #[test]
1012    fn test_boring_error() {
1013        let _ = CStackWrapper::cbs_with_temp_buffer(&[], |cbs| {
1014            should_fail(
1015                CHeapWrapper::evp_parse_public_key(cbs),
1016                "boringssl::EVP_parse_public_key",
1017                "public key routines:OPENSSL_internal:DECODE_ERROR",
1018            );
1019        });
1020    }
1021}