LCOV - code coverage report
Current view: top level - utils - s2n_safety.h (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 15 15 100.0 %
Date: 2025-08-15 07:28:39 Functions: 19 25 76.0 %
Branches: 45 92 48.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License").
       5                 :            :  * You may not use this file except in compliance with the License.
       6                 :            :  * A copy of the License is located at
       7                 :            :  *
       8                 :            :  *  http://aws.amazon.com/apache2.0
       9                 :            :  *
      10                 :            :  * or in the "license" file accompanying this file. This file is distributed
      11                 :            :  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
      12                 :            :  * express or implied. See the License for the specific language governing
      13                 :            :  * permissions and limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #pragma once
      17                 :            : 
      18                 :            : #include <stdbool.h>
      19                 :            : #include <stdint.h>
      20                 :            : #include <stdlib.h>
      21                 :            : #include <string.h>
      22                 :            : 
      23                 :            : #include "error/s2n_errno.h"
      24                 :            : #include "utils/s2n_ensure.h"
      25                 :            : #include "utils/s2n_result.h"
      26                 :            : #include "utils/s2n_safety_macros.h"
      27                 :            : 
      28                 :            : /**
      29                 :            :  * The goal of s2n_safety is to provide helpers to perform common
      30                 :            :  * checks, which help with code readability.
      31                 :            :  */
      32                 :            : 
      33                 :            : /**
      34                 :            :  * Marks a case of a switch statement as able to fall through to the next case
      35                 :            :  */
      36                 :            : #if defined(S2N_FALL_THROUGH_SUPPORTED)
      37                 :            :     #define FALL_THROUGH __attribute__((fallthrough))
      38                 :            : #else
      39                 :            :     #define FALL_THROUGH ((void) 0)
      40                 :            : #endif
      41                 :            : 
      42                 :            : int s2n_in_unit_test_set(bool is_unit);
      43                 :            : int s2n_in_integ_test_set(bool is_integ);
      44                 :            : bool s2n_in_unit_test();
      45                 :            : bool s2n_in_test();
      46                 :            : 
      47                 :            : /* Returns true if a and b are equal, in constant time */
      48                 :            : bool s2n_constant_time_equals(const uint8_t* a, const uint8_t* b, const uint32_t len);
      49                 :            : 
      50                 :            : /* Copy src to dst, or don't copy it, in constant time */
      51                 :            : int s2n_constant_time_copy_or_dont(uint8_t* dst, const uint8_t* src, uint32_t len, uint8_t dont);
      52                 :            : 
      53                 :            : /* If src contains valid PKCS#1 v1.5 padding of exactly expectlen bytes, decode
      54                 :            :  * it into dst, otherwise leave dst alone, in constant time.
      55                 :            :  * Always returns zero. */
      56                 :            : int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t* dst, const uint8_t* src, uint32_t srclen, uint32_t expectlen);
      57                 :            : 
      58                 :            : /**
      59                 :            :  * Runs _thecleanup function on _thealloc once _thealloc went out of scope
      60                 :            :  */
      61                 :            : #define DEFER_CLEANUP(_thealloc, _thecleanup) \
      62                 :    1817848 :     __attribute__((cleanup(_thecleanup))) _thealloc
      63                 :            : /**
      64                 :            :  * Often we want to free memory on an error, but not on a success.
      65                 :            :  * We do this by declaring a variable with DEFER_CLEANUP, then zeroing
      66                 :            :  * that variable after success to prevent DEFER_CLEANUP from accessing
      67                 :            :  * and freeing any memory it allocated.
      68                 :            :  *
      69                 :            :  * This pattern is not intuitive, so a named macro makes it more readable.
      70                 :            :  */
      71                 :     793140 : #define ZERO_TO_DISABLE_DEFER_CLEANUP(_thealloc) memset(&_thealloc, 0, sizeof(_thealloc))
      72                 :            : 
      73                 :            : /* We want to apply blinding whenever `action` fails.
      74                 :            :  * Unfortunately, because functions in S2N do not have a consistent return type, determining failure is difficult.
      75                 :            :  * Instead, let's rely on the consistent error handling behavior of returning from a method early on error
      76                 :            :  * and apply blinding if our tracking variable goes out of scope early.
      77                 :            :  */
      78                 :            : S2N_CLEANUP_RESULT s2n_connection_apply_error_blinding(struct s2n_connection** conn);
      79                 :            : #define WITH_ERROR_BLINDING(conn, action)                                                                 \
      80                 :     662689 :     do {                                                                                                  \
      81                 :     662689 :         DEFER_CLEANUP(struct s2n_connection* _conn_to_blind = conn, s2n_connection_apply_error_blinding); \
      82                 :    2141532 :         action;                                                                                           \
      83                 :     662689 :         /* The `if` here is to avoid a redundantInitialization warning from cppcheck */                   \
      84                 :     662689 :         if (_conn_to_blind) {                                                                             \
      85                 :     661560 :             _conn_to_blind = NULL;                                                                        \
      86                 :     661560 :         }                                                                                                 \
      87                 :     661560 :     } while (0)
      88                 :            : 
      89                 :            : /* Creates cleanup function for pointers from function func which accepts a pointer.
      90                 :            :  * This is useful for DEFER_CLEANUP as it passes &_thealloc into _thecleanup function,
      91                 :            :  * so if _thealloc is a pointer _thecleanup will receive a pointer to a pointer.*/
      92                 :            : #define DEFINE_POINTER_CLEANUP_FUNC(type, func) \
      93                 :            :     static inline void func##_pointer(type* p)  \
      94                 :      99143 :     {                                           \
      95 [ +  - ][ +  - ]:      99143 :         if (p && *p)                            \
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
         [ #  # ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  + ]
      96                 :      99143 :             func(*p);                           \
      97                 :      99143 :     }                                           \
      98                 :            :     struct __useless_struct_to_allow_trailing_semicolon__
      99                 :            : 
     100                 :            : /* This method works for ARRAYS, not for POINTERS.
     101                 :            :  * Calling sizeof on an array declared in the current function correctly returns
     102                 :            :  * the total size of the array. But once the array is passed to another function,
     103                 :            :  * it behaves like a pointer. Calling sizeof on a pointer only returns the size
     104                 :            :  * of the pointer address itself (so usually 8).
     105                 :            :  * Newer compilers (gcc >= 8.1, clang >= 8.0) will warn if the argument is a pointer.
     106                 :            :  */
     107                 :      93031 : #define s2n_array_len(array) (sizeof(array) / sizeof(array[0]))
     108                 :            : 
     109                 :            : int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out);
     110                 :            : 
     111                 :            : /**
     112                 :            :  * Rounds "initial" up to a multiple of "alignment", and stores the result in "out".
     113                 :            :  * Raises an error if overflow would occur.
     114                 :            :  * NOT CONSTANT TIME.
     115                 :            :  */
     116                 :            : int s2n_align_to(uint32_t initial, uint32_t alignment, uint32_t* out);
     117                 :            : int s2n_add_overflow(uint32_t a, uint32_t b, uint32_t* out);
     118                 :            : int s2n_sub_overflow(uint32_t a, uint32_t b, uint32_t* out);
     119                 :            : #define S2N_ADD_IS_OVERFLOW_SAFE(a, b, max) (((max) >= (a)) && ((max) - (a) >= (b)))

Generated by: LCOV version 1.14