LCOV - code coverage report
Current view: top level - tls - s2n_async_offload.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 47 47 100.0 %
Date: 2026-10-06 07:26:09 Functions: 5 5 100.0 %
Branches: 38 88 43.2 %

           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                 :            : #include "tls/s2n_async_offload.h"
      16                 :            : 
      17                 :            : #include "api/s2n.h"
      18                 :            : #include "crypto/s2n_hash.h"
      19                 :            : #include "crypto/s2n_signature.h"
      20                 :            : #include "error/s2n_errno.h"
      21                 :            : #include "tls/s2n_connection.h"
      22                 :            : #include "tls/s2n_handshake.h"
      23                 :            : #include "utils/s2n_blob.h"
      24                 :            : #include "utils/s2n_mem.h"
      25                 :            : #include "utils/s2n_result.h"
      26                 :            : #include "utils/s2n_safety.h"
      27                 :            : 
      28                 :            : S2N_RESULT s2n_async_offload_cb_invoke(struct s2n_connection *conn, struct s2n_async_offload_op *op)
      29                 :         13 : {
      30 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(conn);
      31 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(conn->config);
      32 [ #  # ][ -  + ]:         13 :     RESULT_ENSURE_REF(conn->config->async_offload_cb);
      33                 :            : 
      34 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(op);
      35 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(op->perform);
      36 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE_REF(op->op_data_free);
      37 [ -  + ][ #  # ]:         13 :     RESULT_ENSURE(op->async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
      38                 :            : 
      39                 :         13 :     op->async_state = S2N_ASYNC_INVOKED;
      40 [ +  + ][ +  - ]:         13 :     RESULT_ENSURE(conn->config->async_offload_cb(conn, op, conn->config->async_offload_ctx) == S2N_SUCCESS,
      41                 :         11 :             S2N_ERR_CANCELLED);
      42                 :            : 
      43                 :            :     /*
      44                 :            :      * If the callback already completed the operation, continue.
      45                 :            :      * Otherwise, we need to block s2n_negotiate and wait for the operation to complete.
      46                 :            :      */
      47         [ +  + ]:         11 :     if (op->async_state == S2N_ASYNC_COMPLETE) {
      48                 :          4 :         return S2N_RESULT_OK;
      49                 :          4 :     }
      50         [ +  - ]:          7 :     RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
      51                 :          7 : }
      52                 :            : 
      53                 :            : int s2n_async_offload_op_perform(struct s2n_async_offload_op *op)
      54                 :         22 : {
      55 [ +  + ][ +  - ]:         22 :     POSIX_ENSURE_REF(op);
      56 [ +  + ][ +  - ]:         21 :     POSIX_ENSURE(op->async_state == S2N_ASYNC_INVOKED, S2N_ERR_INVALID_STATE);
      57 [ -  + ][ #  # ]:         14 :     POSIX_ENSURE(op->type != 0, S2N_ERR_INVALID_STATE);
      58                 :            : 
      59 [ -  + ][ #  # ]:         14 :     POSIX_ENSURE_REF(op->conn);
      60 [ #  # ][ -  + ]:         14 :     POSIX_ENSURE_REF(op->perform);
      61                 :            : 
      62         [ +  + ]:         14 :     POSIX_GUARD_RESULT(op->perform(op));
      63                 :         13 :     op->async_state = S2N_ASYNC_COMPLETE;
      64                 :         13 :     return S2N_SUCCESS;
      65                 :         14 : }
      66                 :            : 
      67                 :            : /**
      68                 :            :  * Unconditionally releases the op's resources, regardless of async_state.
      69                 :            :  *
      70                 :            :  * This is the connection teardown path (s2n_connection_free / s2n_connection_wipe).
      71                 :            :  * It MUST always fully free the op, even if a failed s2n_async_offload_op_perform()
      72                 :            :  * left the op in S2N_ASYNC_INVOKED; otherwise the remainder of teardown is skipped
      73                 :            :  * and the connection leaks.
      74                 :            :  */
      75                 :            : S2N_RESULT s2n_async_offload_op_free(struct s2n_async_offload_op *op)
      76                 :    3549534 : {
      77 [ -  + ][ #  # ]:    3549534 :     RESULT_ENSURE_REF(op);
      78         [ +  + ]:    3549534 :     if (op->op_data_free == NULL) {
      79                 :    3549520 :         return S2N_RESULT_OK;
      80                 :    3549520 :     }
      81                 :            : 
      82         [ -  + ]:         14 :     RESULT_GUARD(op->op_data_free(op));
      83 [ -  + ][ #  # ]:         14 :     RESULT_CHECKED_MEMSET(op, 0, sizeof(struct s2n_async_offload_op));
                 [ +  - ]
      84                 :         14 :     return S2N_RESULT_OK;
      85                 :         14 : }
      86                 :            : 
      87                 :            : /**
      88                 :            :  * MUST be called at the end of each handshake state handler that may invoke async_offload_cb
      89                 :            :  * to clean up the op object for its next use.
      90                 :            :  *
      91                 :            :  * Unlike s2n_async_offload_op_free(), this is the handshake-path cleanup and refuses
      92                 :            :  * to free an op that is still in flight (S2N_ASYNC_INVOKED): s2n still holds
      93                 :            :  * references to its data, so wiping mid-negotiation would be a logic error.
      94                 :            :  */
      95                 :            : S2N_RESULT s2n_async_offload_op_reset(struct s2n_async_offload_op *op)
      96                 :       3508 : {
      97 [ #  # ][ -  + ]:       3508 :     RESULT_ENSURE_REF(op);
      98                 :            :     /* Sync case without the callback: async_offload_cb not invoked in the current state */
      99         [ +  + ]:       3508 :     if (op->async_state == S2N_ASYNC_NOT_INVOKED) {
     100                 :       3497 :         return S2N_RESULT_OK;
     101                 :       3497 :     }
     102                 :            : 
     103 [ #  # ][ -  + ]:         11 :     RESULT_ENSURE(op->async_state == S2N_ASYNC_COMPLETE, S2N_ERR_INVALID_STATE);
     104         [ -  + ]:         11 :     RESULT_GUARD(s2n_async_offload_op_free(op));
     105                 :         11 :     return S2N_RESULT_OK;
     106                 :         11 : }
     107                 :            : 
     108                 :            : bool s2n_async_offload_op_is_in_allow_list(struct s2n_config *config, s2n_async_offload_op_type op_type)
     109                 :       3529 : {
     110 [ +  - ][ +  + ]:       3529 :     return config && (config->async_offload_allow_list & op_type);
     111                 :       3529 : }

Generated by: LCOV version 1.14