LCOV - code coverage report
Current view: top level - spdk/lib/nvmf - auth.c (source / functions) Hit Total Coverage
Test: Combined Lines: 370 563 65.7 %
Date: 2024-11-20 12:56:55 Functions: 28 31 90.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 177 2269 7.8 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2024 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "spdk/nvme.h"
       6                 :            : #include "spdk/json.h"
       7                 :            : #include "spdk/log.h"
       8                 :            : #include "spdk/stdinc.h"
       9                 :            : #include "spdk/string.h"
      10                 :            : #include "spdk/thread.h"
      11                 :            : #include "spdk/util.h"
      12                 :            : #include "spdk_internal/nvme.h"
      13                 :            : 
      14                 :            : #include <openssl/rand.h>
      15                 :            : 
      16                 :            : #include "nvmf_internal.h"
      17                 :            : 
      18                 :            : #define NVMF_AUTH_DEFAULT_KATO_US       (120ull * 1000 * 1000)
      19                 :            : #define NVMF_AUTH_FAILURE1_DELAY_US     (100ull * 1000)
      20                 :            : #define NVMF_AUTH_DIGEST_MAX_SIZE       64
      21                 :            : #define NVMF_AUTH_DH_KEY_MAX_SIZE       1024
      22                 :            : 
      23                 :            : #define AUTH_ERRLOG(q, fmt, ...) \
      24                 :            :         SPDK_ERRLOG("[%s:%s:%u] " fmt, (q)->ctrlr->subsys->subnqn, (q)->ctrlr->hostnqn, \
      25                 :            :                     (q)->qid, ## __VA_ARGS__)
      26                 :            : #define AUTH_DEBUGLOG(q, fmt, ...) \
      27                 :            :         SPDK_DEBUGLOG(nvmf_auth, "[%s:%s:%u] " fmt, \
      28                 :            :                       (q)->ctrlr->subsys->subnqn, (q)->ctrlr->hostnqn, (q)->qid, ## __VA_ARGS__)
      29                 :            : #define AUTH_LOGDUMP(msg, buf, len) \
      30                 :            :         SPDK_LOGDUMP(nvmf_auth, msg, buf, len)
      31                 :            : 
      32                 :            : enum nvmf_qpair_auth_state {
      33                 :            :         NVMF_QPAIR_AUTH_NEGOTIATE,
      34                 :            :         NVMF_QPAIR_AUTH_CHALLENGE,
      35                 :            :         NVMF_QPAIR_AUTH_REPLY,
      36                 :            :         NVMF_QPAIR_AUTH_SUCCESS1,
      37                 :            :         NVMF_QPAIR_AUTH_SUCCESS2,
      38                 :            :         NVMF_QPAIR_AUTH_FAILURE1,
      39                 :            :         NVMF_QPAIR_AUTH_COMPLETED,
      40                 :            :         NVMF_QPAIR_AUTH_ERROR,
      41                 :            : };
      42                 :            : 
      43                 :            : struct spdk_nvmf_qpair_auth {
      44                 :            :         enum nvmf_qpair_auth_state      state;
      45                 :            :         struct spdk_poller              *poller;
      46                 :            :         int                             fail_reason;
      47                 :            :         uint16_t                        tid;
      48                 :            :         int                             digest;
      49                 :            :         int                             dhgroup;
      50                 :            :         uint8_t                         cval[NVMF_AUTH_DIGEST_MAX_SIZE];
      51                 :            :         uint32_t                        seqnum;
      52                 :            :         struct spdk_nvme_dhchap_dhkey   *dhkey;
      53                 :            :         bool                            cvalid;
      54                 :            : };
      55                 :            : 
      56                 :            : struct nvmf_auth_common_header {
      57                 :            :         uint8_t         auth_type;
      58                 :            :         uint8_t         auth_id;
      59                 :            :         uint8_t         reserved0[2];
      60                 :            :         uint16_t        t_id;
      61                 :            : };
      62                 :            : 
      63                 :            : static void
      64                 :       4692 : nvmf_auth_request_complete(struct spdk_nvmf_request *req, int sct, int sc, int dnr)
      65                 :            : {
      66   [ #  #  #  #  :       4692 :         struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl;
                   #  # ]
      67                 :            : 
      68   [ #  #  #  #  :       4692 :         response->status.sct = sct;
                   #  # ]
      69   [ #  #  #  #  :       4692 :         response->status.sc = sc;
                   #  # ]
      70   [ #  #  #  #  :       4692 :         response->status.dnr = dnr;
                   #  # ]
      71                 :            : 
      72                 :       4692 :         spdk_nvmf_request_complete(req);
      73                 :       4692 : }
      74                 :            : 
      75                 :            : static const char *
      76                 :       4984 : nvmf_auth_get_state_name(enum nvmf_qpair_auth_state state)
      77                 :            : {
      78                 :            :         static const char *state_names[] = {
      79                 :            :                 [NVMF_QPAIR_AUTH_NEGOTIATE] = "negotiate",
      80                 :            :                 [NVMF_QPAIR_AUTH_CHALLENGE] = "challenge",
      81                 :            :                 [NVMF_QPAIR_AUTH_REPLY] = "reply",
      82                 :            :                 [NVMF_QPAIR_AUTH_SUCCESS1] = "success1",
      83                 :            :                 [NVMF_QPAIR_AUTH_SUCCESS2] = "success2",
      84                 :            :                 [NVMF_QPAIR_AUTH_FAILURE1] = "failure1",
      85                 :            :                 [NVMF_QPAIR_AUTH_COMPLETED] = "completed",
      86                 :            :                 [NVMF_QPAIR_AUTH_ERROR] = "error",
      87                 :            :         };
      88                 :            : 
      89   [ #  #  #  #  :       4984 :         return state_names[state];
                   #  # ]
      90                 :            : }
      91                 :            : 
      92                 :            : static void
      93                 :       5688 : nvmf_auth_set_state(struct spdk_nvmf_qpair *qpair, enum nvmf_qpair_auth_state state)
      94                 :            : {
      95   [ #  #  #  # ]:       5688 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
      96                 :            : 
      97   [ +  +  #  #  :       5688 :         if (auth->state == state) {
                   #  # ]
      98                 :       1000 :                 return;
      99                 :            :         }
     100                 :            : 
     101   [ -  +  +  -  :       4688 :         AUTH_DEBUGLOG(qpair, "auth state: %s\n", nvmf_auth_get_state_name(state));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     102   [ #  #  #  # ]:       4688 :         auth->state = state;
     103                 :          0 : }
     104                 :            : 
     105                 :            : static void
     106                 :          0 : nvmf_auth_disconnect_qpair(struct spdk_nvmf_qpair *qpair)
     107                 :            : {
     108                 :          0 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_ERROR);
     109                 :          0 :         spdk_nvmf_qpair_disconnect(qpair);
     110                 :          0 : }
     111                 :            : 
     112                 :            : static void
     113                 :         32 : nvmf_auth_request_fail1(struct spdk_nvmf_request *req, int reason)
     114                 :            : {
     115   [ #  #  #  # ]:         32 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     116   [ #  #  #  # ]:         32 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     117                 :            : 
     118                 :         32 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_FAILURE1);
     119   [ #  #  #  # ]:         32 :         auth->fail_reason = reason;
     120                 :            : 
     121                 :            :         /* The command itself is completed successfully, but a subsequent AUTHENTICATION_RECV
     122                 :            :          * command will be completed with an AUTH_failure1 message
     123                 :            :          */
     124                 :         32 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     125                 :         32 : }
     126                 :            : 
     127                 :            : static bool
     128                 :       1292 : nvmf_auth_digest_allowed(struct spdk_nvmf_qpair *qpair, uint8_t digest)
     129                 :            : {
     130   [ #  #  #  #  :       1292 :         struct spdk_nvmf_tgt *tgt = qpair->group->tgt;
             #  #  #  # ]
     131                 :            : 
     132   [ -  +  #  #  :       1292 :         return tgt->dhchap_digests & SPDK_BIT(digest);
                   #  # ]
     133                 :            : }
     134                 :            : 
     135                 :            : static bool
     136                 :       1732 : nvmf_auth_dhgroup_allowed(struct spdk_nvmf_qpair *qpair, uint8_t dhgroup)
     137                 :            : {
     138   [ #  #  #  #  :       1732 :         struct spdk_nvmf_tgt *tgt = qpair->group->tgt;
             #  #  #  # ]
     139                 :            : 
     140   [ -  +  #  #  :       1732 :         return tgt->dhchap_dhgroups & SPDK_BIT(dhgroup);
                   #  # ]
     141                 :            : }
     142                 :            : 
     143                 :            : static void
     144                 :       1920 : nvmf_auth_qpair_cleanup(struct spdk_nvmf_qpair_auth *auth)
     145                 :            : {
     146         [ #  # ]:       1920 :         spdk_poller_unregister(&auth->poller);
     147         [ #  # ]:       1920 :         spdk_nvme_dhchap_dhkey_free(&auth->dhkey);
     148                 :       1920 : }
     149                 :            : 
     150                 :            : static int
     151                 :          0 : nvmf_auth_timeout_poller(void *ctx)
     152                 :            : {
     153                 :          0 :         struct spdk_nvmf_qpair *qpair = ctx;
     154   [ #  #  #  # ]:          0 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     155                 :            : 
     156   [ #  #  #  #  :          0 :         AUTH_ERRLOG(qpair, "authentication timed out\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     157         [ #  # ]:          0 :         spdk_poller_unregister(&auth->poller);
     158                 :            : 
     159   [ #  #  #  #  :          0 :         if (qpair->state == SPDK_NVMF_QPAIR_ENABLED) {
                   #  # ]
     160                 :            :                 /* Reauthentication timeout isn't considered to be a fatal failure */
     161                 :          0 :                 nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_COMPLETED);
     162                 :          0 :                 nvmf_auth_qpair_cleanup(auth);
     163                 :          0 :         } else {
     164                 :          0 :                 nvmf_auth_disconnect_qpair(qpair);
     165                 :            :         }
     166                 :            : 
     167                 :          0 :         return SPDK_POLLER_BUSY;
     168                 :            : }
     169                 :            : 
     170                 :            : static int
     171                 :       4660 : nvmf_auth_rearm_poller(struct spdk_nvmf_qpair *qpair)
     172                 :            : {
     173   [ #  #  #  # ]:       4660 :         struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
     174   [ #  #  #  # ]:       4660 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     175                 :            :         uint64_t timeout;
     176                 :            : 
     177   [ #  #  #  #  :       4660 :         timeout = ctrlr->feat.keep_alive_timer.bits.kato > 0 ?
          #  #  #  #  #  
                      # ]
     178   [ +  -  #  #  :       4660 :                   ctrlr->feat.keep_alive_timer.bits.kato * 1000 :
             #  #  #  # ]
     179                 :            :                   NVMF_AUTH_DEFAULT_KATO_US;
     180                 :            : 
     181         [ #  # ]:       4660 :         spdk_poller_unregister(&auth->poller);
     182   [ #  #  #  # ]:       4660 :         auth->poller = SPDK_POLLER_REGISTER(nvmf_auth_timeout_poller, qpair, timeout);
     183   [ -  +  #  #  :       4660 :         if (auth->poller == NULL) {
                   #  # ]
     184                 :          0 :                 return -ENOMEM;
     185                 :            :         }
     186                 :            : 
     187                 :       4660 :         return 0;
     188                 :          0 : }
     189                 :            : 
     190                 :            : static int
     191                 :       4692 : nvmf_auth_check_command(struct spdk_nvmf_request *req, uint8_t secp,
     192                 :            :                         uint8_t spsp0, uint8_t spsp1, uint32_t len)
     193                 :            : {
     194   [ #  #  #  # ]:       4692 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     195                 :            : 
     196         [ -  + ]:       4692 :         if (secp != SPDK_NVMF_AUTH_SECP_NVME) {
     197   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid secp=%u\n", secp);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     198                 :          0 :                 return -EINVAL;
     199                 :            :         }
     200   [ +  -  -  + ]:       4692 :         if (spsp0 != 1 || spsp1 != 1) {
     201   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid spsp0=%u, spsp1=%u\n", spsp0, spsp1);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     202                 :          0 :                 return -EINVAL;
     203                 :            :         }
     204   [ -  +  #  #  :       4692 :         if (len != req->length) {
                   #  # ]
     205   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid length: %"PRIu32" != %"PRIu32"\n", len, req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     206                 :          0 :                 return -EINVAL;
     207                 :            :         }
     208                 :            : 
     209                 :       4692 :         return 0;
     210                 :          0 : }
     211                 :            : 
     212                 :            : static void *
     213                 :       4692 : nvmf_auth_get_message(struct spdk_nvmf_request *req, size_t size)
     214                 :            : {
     215   [ +  -  +  -  :       4692 :         if (req->length > 0 && req->iovcnt == 1 && req->iov[0].iov_len >= size) {
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     216   [ #  #  #  #  :       4692 :                 return req->iov[0].iov_base;
          #  #  #  #  #  
                      # ]
     217                 :            :         }
     218                 :            : 
     219                 :          0 :         return NULL;
     220                 :          0 : }
     221                 :            : 
     222                 :            : static void
     223                 :        996 : nvmf_auth_negotiate_exec(struct spdk_nvmf_request *req, struct spdk_nvmf_auth_negotiate *msg)
     224                 :            : {
     225   [ #  #  #  # ]:        996 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     226   [ #  #  #  # ]:        996 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     227                 :        996 :         struct spdk_nvmf_auth_descriptor *desc = NULL;
     228                 :            :         /* These arrays are sorted from the strongest hash/dhgroup to the weakest, so the strongest
     229                 :            :          * hash/dhgroup pair supported by the host is always selected
     230                 :            :          */
     231                 :        996 :         enum spdk_nvmf_dhchap_hash digests[] = {
     232                 :            :                 SPDK_NVMF_DHCHAP_HASH_SHA512,
     233                 :            :                 SPDK_NVMF_DHCHAP_HASH_SHA384,
     234                 :            :                 SPDK_NVMF_DHCHAP_HASH_SHA256
     235                 :            :         };
     236                 :        996 :         enum spdk_nvmf_dhchap_dhgroup dhgroups[] = {
     237                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_8192,
     238                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_6144,
     239                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_4096,
     240                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_3072,
     241                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_2048,
     242                 :            :                 SPDK_NVMF_DHCHAP_DHGROUP_NULL,
     243                 :            :         };
     244                 :        996 :         int digest = -1, dhgroup = -1;
     245                 :            :         size_t i, j;
     246                 :            : 
     247   [ -  +  #  #  :        996 :         if (auth->state != NVMF_QPAIR_AUTH_NEGOTIATE) {
                   #  # ]
     248   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid state: %s\n", nvmf_auth_get_state_name(auth->state));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     249                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     250                 :          8 :                 return;
     251                 :            :         }
     252                 :            : 
     253   [ #  #  #  #  :        996 :         auth->tid = msg->t_id;
             #  #  #  # ]
     254   [ +  -  -  +  :        996 :         if (req->length < sizeof(*msg) || req->length != sizeof(*msg) + msg->napd * sizeof(*desc)) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     255   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length: %"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     256                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     257                 :          0 :                 return;
     258                 :            :         }
     259                 :            : 
     260   [ -  +  #  #  :        996 :         if (msg->sc_c != SPDK_NVMF_AUTH_SCC_DISABLED) {
                   #  # ]
     261   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "scc mismatch\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     262                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_SCC_MISMATCH);
     263                 :          0 :                 return;
     264                 :            :         }
     265                 :            : 
     266   [ +  -  #  #  :        996 :         for (i = 0; i < msg->napd; ++i) {
                   #  # ]
     267   [ +  -  #  #  :        996 :                 if (msg->descriptors[i].auth_id == SPDK_NVMF_AUTH_TYPE_DHCHAP) {
          #  #  #  #  #  
                      # ]
     268   [ #  #  #  # ]:        996 :                         desc = &msg->descriptors[i];
     269                 :        996 :                         break;
     270                 :            :                 }
     271                 :          0 :         }
     272         [ -  + ]:        996 :         if (desc == NULL) {
     273   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "no usable protocol found\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     274                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_PROTOCOL_UNUSABLE);
     275                 :          0 :                 return;
     276                 :            :         }
     277   [ +  -  #  #  :        996 :         if (desc->halen > SPDK_COUNTOF(desc->hash_id_list) ||
             #  #  #  # ]
     278   [ -  +  #  # ]:        996 :             desc->dhlen > SPDK_COUNTOF(desc->dhg_id_list)) {
     279   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid halen=%u, dhlen=%u\n", desc->halen, desc->dhlen);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     280                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     281                 :          0 :                 return;
     282                 :            :         }
     283                 :            : 
     284         [ +  + ]:       1296 :         for (i = 0; i < SPDK_COUNTOF(digests); ++i) {
     285   [ +  +  #  #  :       1292 :                 if (!nvmf_auth_digest_allowed(qpair, digests[i])) {
             #  #  #  # ]
     286                 :          4 :                         continue;
     287                 :            :                 }
     288   [ +  +  #  #  :       2992 :                 for (j = 0; j < desc->halen; ++j) {
                   #  # ]
     289   [ +  +  #  #  :       2696 :                         if (digests[i] == desc->hash_id_list[j]) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     290   [ -  +  +  -  :        992 :                                 AUTH_DEBUGLOG(qpair, "selected digest: %s\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     291                 :            :                                               spdk_nvme_dhchap_get_digest_name(digests[i]));
     292   [ #  #  #  #  :        992 :                                 digest = digests[i];
                   #  # ]
     293                 :        992 :                                 break;
     294                 :            :                         }
     295                 :          0 :                 }
     296         [ +  + ]:       1288 :                 if (digest >= 0) {
     297                 :        992 :                         break;
     298                 :            :                 }
     299                 :          0 :         }
     300         [ +  + ]:        996 :         if (digest < 0) {
     301   [ #  #  #  #  :          4 :                 AUTH_ERRLOG(qpair, "no usable digests found\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     302                 :          4 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_HASH_UNUSABLE);
     303                 :          4 :                 return;
     304                 :            :         }
     305                 :            : 
     306         [ +  + ]:       1736 :         for (i = 0; i < SPDK_COUNTOF(dhgroups); ++i) {
     307   [ +  +  #  #  :       1732 :                 if (!nvmf_auth_dhgroup_allowed(qpair, dhgroups[i])) {
             #  #  #  # ]
     308                 :         16 :                         continue;
     309                 :            :                 }
     310   [ +  +  #  #  :       5944 :                 for (j = 0; j < desc->dhlen; ++j) {
                   #  # ]
     311   [ +  +  #  #  :       5216 :                         if (dhgroups[i] == desc->dhg_id_list[j]) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     312   [ -  +  +  -  :        988 :                                 AUTH_DEBUGLOG(qpair, "selected dhgroup: %s\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     313                 :            :                                               spdk_nvme_dhchap_get_dhgroup_name(dhgroups[i]));
     314   [ #  #  #  #  :        988 :                                 dhgroup = dhgroups[i];
                   #  # ]
     315                 :        988 :                                 break;
     316                 :            :                         }
     317                 :          0 :                 }
     318         [ +  + ]:       1716 :                 if (dhgroup >= 0) {
     319                 :        988 :                         break;
     320                 :            :                 }
     321                 :          0 :         }
     322         [ +  + ]:        992 :         if (dhgroup < 0) {
     323   [ #  #  #  #  :          4 :                 AUTH_ERRLOG(qpair, "no usable dhgroups found\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     324                 :          4 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_DHGROUP_UNUSABLE);
     325                 :          4 :                 return;
     326                 :            :         }
     327                 :            : 
     328         [ -  + ]:        988 :         if (nvmf_auth_rearm_poller(qpair)) {
     329                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     330                 :            :                                            SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 1);
     331                 :          0 :                 nvmf_auth_disconnect_qpair(qpair);
     332                 :          0 :                 return;
     333                 :            :         }
     334                 :            : 
     335   [ #  #  #  # ]:        988 :         auth->digest = digest;
     336   [ #  #  #  # ]:        988 :         auth->dhgroup = dhgroup;
     337                 :        988 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_CHALLENGE);
     338                 :        988 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     339                 :          0 : }
     340                 :            : 
     341                 :            : static void
     342                 :        988 : nvmf_auth_reply_exec(struct spdk_nvmf_request *req, struct spdk_nvmf_dhchap_reply *msg)
     343                 :            : {
     344   [ #  #  #  # ]:        988 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     345   [ #  #  #  # ]:        988 :         struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
     346   [ #  #  #  # ]:        988 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     347                 :          0 :         uint8_t response[NVMF_AUTH_DIGEST_MAX_SIZE];
     348                 :          0 :         uint8_t dhsec[NVMF_AUTH_DH_KEY_MAX_SIZE];
     349                 :        988 :         struct spdk_key *key = NULL, *ckey = NULL;
     350                 :        988 :         size_t dhseclen = 0;
     351                 :            :         uint8_t hl;
     352                 :            :         int rc;
     353                 :            : 
     354   [ -  +  #  #  :        988 :         if (auth->state != NVMF_QPAIR_AUTH_REPLY) {
                   #  # ]
     355   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid state=%s\n", nvmf_auth_get_state_name(auth->state));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     356                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     357                 :          0 :                 goto out;
     358                 :            :         }
     359   [ -  +  #  #  :        988 :         if (req->length < sizeof(*msg)) {
                   #  # ]
     360   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length=%"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     361                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     362                 :          0 :                 goto out;
     363                 :            :         }
     364                 :            : 
     365   [ #  #  #  # ]:        988 :         hl = spdk_nvme_dhchap_get_digest_length(auth->digest);
     366   [ +  -  -  +  :        988 :         if (hl == 0 || msg->hl != hl) {
             #  #  #  # ]
     367   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "hash length mismatch: %u != %u\n", msg->hl, hl);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     368                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     369                 :          0 :                 goto out;
     370                 :            :         }
     371   [ -  +  #  #  :        988 :         if ((msg->dhvlen % 4) != 0) {
             #  #  #  # ]
     372   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "dhvlen=%u is not multiple of 4\n", msg->dhvlen);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     373                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     374                 :          0 :                 goto out;
     375                 :            :         }
     376   [ -  +  #  #  :        988 :         if (req->length != sizeof(*msg) + 2 * hl + msg->dhvlen) {
          #  #  #  #  #  
                #  #  # ]
     377   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length: %"PRIu32" != %zu\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     378                 :            :                             req->length, sizeof(*msg) + 2 * hl);
     379                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     380                 :          0 :                 goto out;
     381                 :            :         }
     382   [ -  +  #  #  :        988 :         if (msg->t_id != auth->tid) {
          #  #  #  #  #  
                      # ]
     383   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "transaction id mismatch: %u != %u\n", msg->t_id, auth->tid);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     384                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     385                 :          0 :                 goto out;
     386                 :            :         }
     387   [ +  +  -  +  :        988 :         if (msg->cvalid != 0 && msg->cvalid != 1) {
          #  #  #  #  #  
                #  #  # ]
     388   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "unexpected cvalid=%d\n", msg->cvalid);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     389                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     390                 :          0 :                 goto out;
     391                 :            :         }
     392   [ +  +  -  +  :        988 :         if (msg->cvalid && msg->seqnum == 0) {
          #  #  #  #  #  
                #  #  # ]
     393   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "unexpected seqnum=0 with cvalid=1\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     394                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     395                 :          0 :                 goto out;
     396                 :            :         }
     397                 :            : 
     398   [ #  #  #  #  :        988 :         key = nvmf_subsystem_get_dhchap_key(ctrlr->subsys, ctrlr->hostnqn, NVMF_AUTH_KEY_HOST);
                   #  # ]
     399         [ +  + ]:        988 :         if (key == NULL) {
     400   [ #  #  #  #  :          4 :                 AUTH_ERRLOG(qpair, "couldn't get DH-HMAC-CHAP key\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     401                 :          4 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     402                 :          4 :                 goto out;
     403                 :            :         }
     404                 :            : 
     405   [ +  +  #  #  :        984 :         if (auth->dhgroup != SPDK_NVMF_DHCHAP_DHGROUP_NULL) {
                   #  # ]
     406   [ -  +  +  -  :        936 :                 AUTH_LOGDUMP("host pubkey:", &msg->rval[2 * hl], msg->dhvlen);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     407                 :        936 :                 dhseclen = sizeof(dhsec);
     408   [ #  #  #  #  :        936 :                 rc = spdk_nvme_dhchap_dhkey_derive_secret(auth->dhkey, &msg->rval[2 * hl],
          #  #  #  #  #  
                      # ]
     409   [ #  #  #  # ]:        936 :                                 msg->dhvlen, dhsec, &dhseclen);
     410         [ -  + ]:        936 :                 if (rc != 0) {
     411   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "couldn't derive DH secret\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     412                 :          0 :                         nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     413                 :          0 :                         goto out;
     414                 :            :                 }
     415                 :            : 
     416   [ -  +  +  -  :        936 :                 AUTH_LOGDUMP("dh secret:", dhsec, dhseclen);
                   #  # ]
     417                 :          0 :         }
     418                 :            : 
     419   [ +  -  +  - ]:        984 :         assert(hl <= sizeof(response) && hl <= sizeof(auth->cval));
     420   [ #  #  #  # ]:       1968 :         rc = spdk_nvme_dhchap_calculate(key, (enum spdk_nvmf_dhchap_hash)auth->digest,
     421   [ #  #  #  #  :        984 :                                         "HostHost", auth->seqnum, auth->tid, 0,
             #  #  #  # ]
     422   [ #  #  #  #  :        984 :                                         ctrlr->hostnqn, ctrlr->subsys->subnqn,
             #  #  #  # ]
     423         [ #  # ]:        984 :                                         dhseclen > 0 ? dhsec : NULL, dhseclen,
     424         [ +  + ]:        984 :                                         auth->cval, response);
     425         [ -  + ]:        984 :         if (rc != 0) {
     426   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "failed to calculate challenge response: %s\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     427                 :            :                             spdk_strerror(-rc));
     428                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     429                 :          0 :                 goto out;
     430                 :            :         }
     431                 :            : 
     432   [ -  +  +  +  :        984 :         if (memcmp(msg->rval, response, hl) != 0) {
             #  #  #  # ]
     433   [ #  #  #  #  :         16 :                 AUTH_ERRLOG(qpair, "challenge response mismatch\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     434   [ -  +  +  -  :         16 :                 AUTH_LOGDUMP("response:", msg->rval, hl);
             #  #  #  # ]
     435   [ -  +  +  -  :         16 :                 AUTH_LOGDUMP("expected:", response, hl);
                   #  # ]
     436                 :         16 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     437                 :         16 :                 goto out;
     438                 :            :         }
     439                 :            : 
     440   [ +  +  #  #  :        968 :         if (msg->cvalid) {
                   #  # ]
     441   [ #  #  #  #  :        728 :                 ckey = nvmf_subsystem_get_dhchap_key(ctrlr->subsys, ctrlr->hostnqn,
                   #  # ]
     442                 :            :                                                      NVMF_AUTH_KEY_CTRLR);
     443         [ +  + ]:        728 :                 if (ckey == NULL) {
     444   [ #  #  #  #  :          4 :                         AUTH_ERRLOG(qpair, "missing DH-HMAC-CHAP ctrlr key\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     445                 :          4 :                         nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     446                 :          4 :                         goto out;
     447                 :            :                 }
     448   [ #  #  #  # ]:       1448 :                 rc = spdk_nvme_dhchap_calculate(ckey, (enum spdk_nvmf_dhchap_hash)auth->digest,
     449   [ #  #  #  #  :        724 :                                                 "Controller", msg->seqnum, auth->tid, 0,
             #  #  #  # ]
     450   [ #  #  #  #  :        724 :                                                 ctrlr->subsys->subnqn, ctrlr->hostnqn,
             #  #  #  # ]
     451         [ #  # ]:        724 :                                                 dhseclen > 0 ? dhsec : NULL, dhseclen,
     452   [ +  +  #  #  :        724 :                                                 &msg->rval[hl], auth->cval);
                   #  # ]
     453         [ -  + ]:        724 :                 if (rc != 0) {
     454   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "failed to calculate ctrlr challenge response: %s\n",
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     455                 :            :                                     spdk_strerror(-rc));
     456                 :          0 :                         nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_FAILED);
     457                 :          0 :                         goto out;
     458                 :            :                 }
     459   [ #  #  #  # ]:        724 :                 auth->cvalid = true;
     460                 :          0 :         }
     461                 :            : 
     462         [ -  + ]:        964 :         if (nvmf_auth_rearm_poller(qpair)) {
     463                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     464                 :            :                                            SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 1);
     465                 :          0 :                 nvmf_auth_disconnect_qpair(qpair);
     466                 :          0 :                 goto out;
     467                 :            :         }
     468                 :            : 
     469                 :        964 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_SUCCESS1);
     470                 :        964 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     471                 :        988 : out:
     472                 :        988 :         spdk_keyring_put_key(ckey);
     473                 :        988 :         spdk_keyring_put_key(key);
     474                 :        988 : }
     475                 :            : 
     476                 :            : static void
     477                 :        712 : nvmf_auth_success2_exec(struct spdk_nvmf_request *req, struct spdk_nvmf_dhchap_success2 *msg)
     478                 :            : {
     479   [ #  #  #  # ]:        712 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     480   [ #  #  #  # ]:        712 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     481                 :            : 
     482   [ -  +  #  #  :        712 :         if (auth->state != NVMF_QPAIR_AUTH_SUCCESS2) {
                   #  # ]
     483   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid state=%s\n", nvmf_auth_get_state_name(auth->state));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     484                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     485                 :          0 :                 return;
     486                 :            :         }
     487   [ -  +  #  #  :        712 :         if (req->length != sizeof(*msg)) {
                   #  # ]
     488   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length=%"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     489                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     490                 :          0 :                 return;
     491                 :            :         }
     492   [ -  +  #  #  :        712 :         if (msg->t_id != auth->tid) {
          #  #  #  #  #  
                      # ]
     493   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "transaction id mismatch: %u != %u\n", msg->t_id, auth->tid);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     494                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     495                 :          0 :                 return;
     496                 :            :         }
     497                 :            : 
     498   [ -  +  +  -  :        712 :         AUTH_DEBUGLOG(qpair, "controller authentication successful\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     499                 :        712 :         nvmf_qpair_set_state(qpair, SPDK_NVMF_QPAIR_ENABLED);
     500                 :        712 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_COMPLETED);
     501                 :        712 :         nvmf_auth_qpair_cleanup(auth);
     502                 :        712 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     503                 :          0 : }
     504                 :            : 
     505                 :            : static void
     506                 :         12 : nvmf_auth_failure2_exec(struct spdk_nvmf_request *req, struct spdk_nvmf_auth_failure *msg)
     507                 :            : {
     508   [ #  #  #  # ]:         12 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     509   [ #  #  #  # ]:         12 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     510                 :            : 
     511                 :            :         /* AUTH_failure2 is only expected when we're waiting for the success2 message */
     512   [ -  +  #  #  :         12 :         if (auth->state != NVMF_QPAIR_AUTH_SUCCESS2) {
                   #  # ]
     513   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid state=%s\n", nvmf_auth_get_state_name(auth->state));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     514                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     515                 :          0 :                 return;
     516                 :            :         }
     517   [ -  +  #  #  :         12 :         if (req->length != sizeof(*msg)) {
                   #  # ]
     518   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length=%"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     519                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     520                 :          0 :                 return;
     521                 :            :         }
     522   [ -  +  #  #  :         12 :         if (msg->t_id != auth->tid) {
          #  #  #  #  #  
                      # ]
     523   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "transaction id mismatch: %u != %u\n", msg->t_id, auth->tid);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     524                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     525                 :          0 :                 return;
     526                 :            :         }
     527                 :            : 
     528   [ #  #  #  #  :         12 :         AUTH_ERRLOG(qpair, "ctrlr authentication failed: rc=%d, rce=%d\n", msg->rc, msg->rce);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     529                 :         12 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_ERROR);
     530                 :         12 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     531                 :          0 : }
     532                 :            : 
     533                 :            : static void
     534                 :       2708 : nvmf_auth_send_exec(struct spdk_nvmf_request *req)
     535                 :            : {
     536   [ #  #  #  # ]:       2708 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     537   [ #  #  #  #  :       2708 :         struct spdk_nvmf_fabric_auth_send_cmd *cmd = &req->cmd->auth_send_cmd;
                   #  # ]
     538                 :            :         struct nvmf_auth_common_header *header;
     539                 :            :         int rc;
     540                 :            : 
     541   [ #  #  #  #  :       2708 :         rc = nvmf_auth_check_command(req, cmd->secp, cmd->spsp0, cmd->spsp1, cmd->tl);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     542         [ -  + ]:       2708 :         if (rc != 0) {
     543                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     544                 :            :                                            SPDK_NVME_SC_INVALID_FIELD, 1);
     545                 :          0 :                 return;
     546                 :            :         }
     547                 :            : 
     548                 :       2708 :         header = nvmf_auth_get_message(req, sizeof(*header));
     549         [ -  + ]:       2708 :         if (header == NULL) {
     550                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PAYLOAD);
     551                 :          0 :                 return;
     552                 :            :         }
     553                 :            : 
     554   [ +  +  -  #  :       2708 :         switch (header->auth_type) {
                #  #  # ]
     555                 :       1008 :         case SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE:
     556   [ +  +  -  #  :       1008 :                 switch (header->auth_id) {
                #  #  # ]
     557                 :        996 :                 case SPDK_NVMF_AUTH_ID_NEGOTIATE:
     558                 :        996 :                         nvmf_auth_negotiate_exec(req, (void *)header);
     559                 :        996 :                         break;
     560                 :         12 :                 case SPDK_NVMF_AUTH_ID_FAILURE2:
     561                 :         12 :                         nvmf_auth_failure2_exec(req, (void *)header);
     562                 :         12 :                         break;
     563                 :          0 :                 default:
     564   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "unexpected auth_id=%u\n", header->auth_id);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     565                 :          0 :                         nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     566                 :          0 :                         break;
     567                 :            :                 }
     568                 :       1008 :                 break;
     569                 :       1700 :         case SPDK_NVMF_AUTH_TYPE_DHCHAP:
     570   [ +  +  -  #  :       1700 :                 switch (header->auth_id) {
                #  #  # ]
     571                 :        988 :                 case SPDK_NVMF_AUTH_ID_DHCHAP_REPLY:
     572                 :        988 :                         nvmf_auth_reply_exec(req, (void *)header);
     573                 :        988 :                         break;
     574                 :        712 :                 case SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS2:
     575                 :        712 :                         nvmf_auth_success2_exec(req, (void *)header);
     576                 :        712 :                         break;
     577                 :          0 :                 default:
     578   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "unexpected auth_id=%u\n", header->auth_id);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     579                 :          0 :                         nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     580                 :          0 :                         break;
     581                 :            :                 }
     582                 :       1700 :                 break;
     583                 :          0 :         default:
     584   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "unexpected auth_type=%u\n", header->auth_type);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     585                 :          0 :                 nvmf_auth_request_fail1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     586                 :          0 :                 break;
     587                 :            :         }
     588                 :          0 : }
     589                 :            : 
     590                 :            : static void
     591                 :       1984 : nvmf_auth_recv_complete(struct spdk_nvmf_request *req, uint32_t length)
     592                 :            : {
     593   [ -  +  #  #  :       1984 :         assert(req->cmd->nvmf_cmd.fctype == SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     594   [ #  #  #  # ]:       1984 :         req->length = length;
     595                 :       1984 :         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_SUCCESS, 0);
     596                 :       1984 : }
     597                 :            : 
     598                 :            : static int
     599                 :          0 : nvmf_auth_recv_failure1_done(void *ctx)
     600                 :            : {
     601                 :          0 :         struct spdk_nvmf_qpair *qpair = ctx;
     602   [ #  #  #  # ]:          0 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     603                 :            : 
     604         [ #  # ]:          0 :         spdk_poller_unregister(&auth->poller);
     605                 :          0 :         nvmf_auth_disconnect_qpair(qpair);
     606                 :            : 
     607                 :          0 :         return SPDK_POLLER_BUSY;
     608                 :            : }
     609                 :            : 
     610                 :            : static void
     611                 :         32 : nvmf_auth_recv_failure1(struct spdk_nvmf_request *req, int fail_reason)
     612                 :            : {
     613   [ #  #  #  # ]:         32 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     614   [ #  #  #  # ]:         32 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     615                 :            :         struct spdk_nvmf_auth_failure *failure;
     616                 :            : 
     617                 :         32 :         failure = nvmf_auth_get_message(req, sizeof(*failure));
     618         [ -  + ]:         32 :         if (failure == NULL) {
     619                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     620                 :            :                                            SPDK_NVME_SC_INVALID_FIELD, 1);
     621                 :          0 :                 nvmf_auth_disconnect_qpair(qpair);
     622                 :          0 :                 return;
     623                 :            :         }
     624                 :            : 
     625   [ #  #  #  # ]:         32 :         failure->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
     626   [ #  #  #  # ]:         32 :         failure->auth_id = SPDK_NVMF_AUTH_ID_FAILURE1;
     627   [ #  #  #  #  :         32 :         failure->t_id = auth->tid;
             #  #  #  # ]
     628   [ #  #  #  # ]:         32 :         failure->rc = SPDK_NVMF_AUTH_FAILURE;
     629   [ #  #  #  # ]:         32 :         failure->rce = fail_reason;
     630                 :            : 
     631                 :         32 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_FAILURE1);
     632                 :         32 :         nvmf_auth_recv_complete(req, sizeof(*failure));
     633                 :            : 
     634         [ #  # ]:         32 :         spdk_poller_unregister(&auth->poller);
     635   [ #  #  #  # ]:         32 :         auth->poller = SPDK_POLLER_REGISTER(nvmf_auth_recv_failure1_done, qpair,
     636                 :            :                                             NVMF_AUTH_FAILURE1_DELAY_US);
     637                 :          0 : }
     638                 :            : 
     639                 :            : static int
     640                 :        988 : nvmf_auth_get_seqnum(struct spdk_nvmf_qpair *qpair)
     641                 :            : {
     642   [ #  #  #  #  :        988 :         struct spdk_nvmf_subsystem *subsys = qpair->ctrlr->subsys;
             #  #  #  # ]
     643   [ #  #  #  # ]:        988 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     644                 :            :         int rc;
     645                 :            : 
     646   [ -  +  #  # ]:        988 :         pthread_mutex_lock(&subsys->mutex);
     647   [ +  +  #  #  :        988 :         if (subsys->auth_seqnum == 0) {
                   #  # ]
     648         [ #  # ]:          8 :                 rc = RAND_bytes((void *)&subsys->auth_seqnum, sizeof(subsys->auth_seqnum));
     649         [ -  + ]:          8 :                 if (rc != 1) {
     650   [ #  #  #  # ]:          0 :                         pthread_mutex_unlock(&subsys->mutex);
     651                 :          0 :                         return -EIO;
     652                 :            :                 }
     653                 :          0 :         }
     654   [ -  +  #  # ]:        988 :         if (++subsys->auth_seqnum == 0) {
     655   [ #  #  #  # ]:          0 :                 subsys->auth_seqnum = 1;
     656                 :            : 
     657                 :          0 :         }
     658   [ #  #  #  #  :        988 :         auth->seqnum = subsys->auth_seqnum;
             #  #  #  # ]
     659   [ -  +  #  # ]:        988 :         pthread_mutex_unlock(&subsys->mutex);
     660                 :            : 
     661                 :        988 :         return 0;
     662                 :          0 : }
     663                 :            : 
     664                 :            : static int
     665                 :        988 : nvmf_auth_recv_challenge(struct spdk_nvmf_request *req)
     666                 :            : {
     667   [ #  #  #  # ]:        988 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     668   [ #  #  #  # ]:        988 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     669                 :            :         struct spdk_nvmf_dhchap_challenge *challenge;
     670                 :          0 :         uint8_t hl, dhv[NVMF_AUTH_DH_KEY_MAX_SIZE];
     671                 :        988 :         size_t dhvlen = 0;
     672                 :            :         int rc;
     673                 :            : 
     674   [ #  #  #  # ]:        988 :         hl = spdk_nvme_dhchap_get_digest_length(auth->digest);
     675   [ +  -  +  - ]:        988 :         assert(hl > 0 && hl <= sizeof(auth->cval));
     676                 :            : 
     677   [ +  +  #  #  :        988 :         if (auth->dhgroup != SPDK_NVMF_DHCHAP_DHGROUP_NULL) {
                   #  # ]
     678   [ #  #  #  #  :        940 :                 auth->dhkey = spdk_nvme_dhchap_generate_dhkey(auth->dhgroup);
             #  #  #  # ]
     679   [ -  +  #  #  :        940 :                 if (auth->dhkey == NULL) {
                   #  # ]
     680   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "failed to generate DH key\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     681                 :          0 :                         return SPDK_NVMF_AUTH_FAILED;
     682                 :            :                 }
     683                 :            : 
     684                 :        940 :                 dhvlen = sizeof(dhv);
     685   [ #  #  #  # ]:        940 :                 rc = spdk_nvme_dhchap_dhkey_get_pubkey(auth->dhkey, dhv, &dhvlen);
     686         [ -  + ]:        940 :                 if (rc != 0) {
     687   [ #  #  #  #  :          0 :                         AUTH_ERRLOG(qpair, "failed to get DH public key\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     688                 :          0 :                         return SPDK_NVMF_AUTH_FAILED;
     689                 :            :                 }
     690                 :            : 
     691   [ -  +  +  -  :        940 :                 AUTH_LOGDUMP("ctrlr pubkey:", dhv, dhvlen);
                   #  # ]
     692                 :          0 :         }
     693                 :            : 
     694                 :        988 :         challenge = nvmf_auth_get_message(req, sizeof(*challenge) + hl + dhvlen);
     695         [ -  + ]:        988 :         if (challenge == NULL) {
     696   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length: %"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     697                 :          0 :                 return SPDK_NVMF_AUTH_INCORRECT_PAYLOAD;
     698                 :            :         }
     699                 :        988 :         rc = nvmf_auth_get_seqnum(qpair);
     700         [ -  + ]:        988 :         if (rc != 0) {
     701                 :          0 :                 return SPDK_NVMF_AUTH_FAILED;
     702                 :            :         }
     703         [ #  # ]:        988 :         rc = RAND_bytes(auth->cval, hl);
     704         [ -  + ]:        988 :         if (rc != 1) {
     705                 :          0 :                 return SPDK_NVMF_AUTH_FAILED;
     706                 :            :         }
     707         [ -  + ]:        988 :         if (nvmf_auth_rearm_poller(qpair)) {
     708                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     709                 :            :                                            SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 1);
     710                 :          0 :                 nvmf_auth_disconnect_qpair(qpair);
     711                 :          0 :                 return 0;
     712                 :            :         }
     713                 :            : 
     714   [ -  +  -  +  :        988 :         memcpy(challenge->cval, auth->cval, hl);
             #  #  #  # ]
     715   [ -  +  -  +  :        988 :         memcpy(&challenge->cval[hl], dhv, dhvlen);
             #  #  #  # ]
     716   [ #  #  #  # ]:        988 :         challenge->auth_type = SPDK_NVMF_AUTH_TYPE_DHCHAP;
     717   [ #  #  #  # ]:        988 :         challenge->auth_id = SPDK_NVMF_AUTH_ID_DHCHAP_CHALLENGE;
     718   [ #  #  #  #  :        988 :         challenge->t_id = auth->tid;
             #  #  #  # ]
     719   [ #  #  #  # ]:        988 :         challenge->hl = hl;
     720   [ #  #  #  #  :        988 :         challenge->hash_id = (uint8_t)auth->digest;
             #  #  #  # ]
     721   [ #  #  #  #  :        988 :         challenge->dhg_id = (uint8_t)auth->dhgroup;
             #  #  #  # ]
     722   [ #  #  #  # ]:        988 :         challenge->dhvlen = dhvlen;
     723   [ #  #  #  #  :        988 :         challenge->seqnum = auth->seqnum;
             #  #  #  # ]
     724                 :            : 
     725                 :        988 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_REPLY);
     726                 :        988 :         nvmf_auth_recv_complete(req, sizeof(*challenge) + hl + dhvlen);
     727                 :            : 
     728                 :        988 :         return 0;
     729                 :          0 : }
     730                 :            : 
     731                 :            : static int
     732                 :        964 : nvmf_auth_recv_success1(struct spdk_nvmf_request *req)
     733                 :            : {
     734   [ #  #  #  # ]:        964 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     735   [ #  #  #  # ]:        964 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     736                 :            :         struct spdk_nvmf_dhchap_success1 *success;
     737                 :            :         uint8_t hl;
     738                 :            : 
     739   [ #  #  #  # ]:        964 :         hl = spdk_nvme_dhchap_get_digest_length(auth->digest);
     740   [ -  +  #  #  :        964 :         success = nvmf_auth_get_message(req, sizeof(*success) + auth->cvalid * hl);
                   #  # ]
     741         [ -  + ]:        964 :         if (success == NULL) {
     742   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "invalid message length: %"PRIu32"\n", req->length);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     743                 :          0 :                 return SPDK_NVMF_AUTH_INCORRECT_PAYLOAD;
     744                 :            :         }
     745                 :            : 
     746   [ -  +  +  -  :        964 :         AUTH_DEBUGLOG(qpair, "host authentication successful\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     747   [ #  #  #  # ]:        964 :         success->auth_type = SPDK_NVMF_AUTH_TYPE_DHCHAP;
     748   [ #  #  #  # ]:        964 :         success->auth_id = SPDK_NVMF_AUTH_ID_DHCHAP_SUCCESS1;
     749   [ #  #  #  #  :        964 :         success->t_id = auth->tid;
             #  #  #  # ]
     750                 :            :         /* Kernel initiator always expects hl to be set, regardless of rvalid */
     751   [ #  #  #  # ]:        964 :         success->hl = hl;
     752   [ #  #  #  # ]:        964 :         success->rvalid = 0;
     753                 :            : 
     754   [ -  +  +  +  :        964 :         if (!auth->cvalid) {
             #  #  #  # ]
     755                 :            :                 /* Host didn't request to authenticate us, we're done */
     756                 :        240 :                 nvmf_qpair_set_state(qpair, SPDK_NVMF_QPAIR_ENABLED);
     757                 :        240 :                 nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_COMPLETED);
     758                 :        240 :                 nvmf_auth_qpair_cleanup(auth);
     759                 :          0 :         } else {
     760         [ -  + ]:        724 :                 if (nvmf_auth_rearm_poller(qpair)) {
     761                 :          0 :                         nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     762                 :            :                                                    SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 1);
     763                 :          0 :                         nvmf_auth_disconnect_qpair(qpair);
     764                 :          0 :                         return 0;
     765                 :            :                 }
     766   [ -  +  +  -  :        724 :                 AUTH_DEBUGLOG(qpair, "cvalid=1, starting controller authentication\n");
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     767                 :        724 :                 nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_SUCCESS2);
     768   [ -  +  -  +  :        724 :                 memcpy(success->rval, auth->cval, hl);
             #  #  #  # ]
     769   [ #  #  #  # ]:        724 :                 success->rvalid = 1;
     770                 :            :         }
     771                 :            : 
     772   [ -  +  #  #  :        964 :         nvmf_auth_recv_complete(req, sizeof(*success) + auth->cvalid * hl);
                   #  # ]
     773                 :        964 :         return 0;
     774                 :          0 : }
     775                 :            : 
     776                 :            : static void
     777                 :       1984 : nvmf_auth_recv_exec(struct spdk_nvmf_request *req)
     778                 :            : {
     779   [ #  #  #  # ]:       1984 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     780   [ #  #  #  # ]:       1984 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     781   [ #  #  #  #  :       1984 :         struct spdk_nvmf_fabric_auth_recv_cmd *cmd = &req->cmd->auth_recv_cmd;
                   #  # ]
     782                 :            :         int rc;
     783                 :            : 
     784   [ #  #  #  #  :       1984 :         rc = nvmf_auth_check_command(req, cmd->secp, cmd->spsp0, cmd->spsp1, cmd->al);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     785         [ -  + ]:       1984 :         if (rc != 0) {
     786                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     787                 :            :                                            SPDK_NVME_SC_INVALID_FIELD, 1);
     788                 :          0 :                 return;
     789                 :            :         }
     790                 :            : 
     791   [ #  #  #  #  :       1984 :         spdk_iov_memset(req->iov, req->iovcnt, 0);
                   #  # ]
     792   [ +  +  +  -  :       1984 :         switch (auth->state) {
             #  #  #  # ]
     793                 :        988 :         case NVMF_QPAIR_AUTH_CHALLENGE:
     794                 :        988 :                 rc = nvmf_auth_recv_challenge(req);
     795         [ -  + ]:        988 :                 if (rc != 0) {
     796                 :          0 :                         nvmf_auth_recv_failure1(req, rc);
     797                 :          0 :                 }
     798                 :        988 :                 break;
     799                 :        964 :         case NVMF_QPAIR_AUTH_SUCCESS1:
     800                 :        964 :                 rc = nvmf_auth_recv_success1(req);
     801         [ -  + ]:        964 :                 if (rc != 0) {
     802                 :          0 :                         nvmf_auth_recv_failure1(req, rc);
     803                 :          0 :                 }
     804                 :        964 :                 break;
     805                 :         32 :         case NVMF_QPAIR_AUTH_FAILURE1:
     806   [ #  #  #  # ]:         32 :                 nvmf_auth_recv_failure1(req, auth->fail_reason);
     807                 :         32 :                 break;
     808                 :          0 :         default:
     809                 :          0 :                 nvmf_auth_recv_failure1(req, SPDK_NVMF_AUTH_INCORRECT_PROTOCOL_MESSAGE);
     810                 :          0 :                 break;
     811                 :            :         }
     812                 :          0 : }
     813                 :            : 
     814                 :            : static bool
     815                 :       4692 : nvmf_auth_check_state(struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req)
     816                 :            : {
     817   [ #  #  #  # ]:       4692 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     818                 :            :         int rc;
     819                 :            : 
     820   [ +  +  -  #  :       4692 :         switch (qpair->state) {
                #  #  # ]
     821                 :       4540 :         case SPDK_NVMF_QPAIR_AUTHENTICATING:
     822                 :       4540 :                 break;
     823                 :        152 :         case SPDK_NVMF_QPAIR_ENABLED:
     824   [ +  +  +  +  :        152 :                 if (auth == NULL || auth->state == NVMF_QPAIR_AUTH_COMPLETED) {
             #  #  #  # ]
     825                 :         32 :                         rc = nvmf_qpair_auth_init(qpair);
     826         [ -  + ]:         32 :                         if (rc != 0) {
     827                 :          0 :                                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     828                 :            :                                                            SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 0);
     829                 :          0 :                                 return false;
     830                 :            :                         }
     831                 :          0 :                 }
     832                 :        152 :                 break;
     833                 :          0 :         default:
     834                 :          0 :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     835                 :            :                                            SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR, 0);
     836                 :          0 :                 return false;
     837                 :            :         }
     838                 :            : 
     839                 :       4692 :         return true;
     840                 :          0 : }
     841                 :            : 
     842                 :            : int
     843                 :       4692 : nvmf_auth_request_exec(struct spdk_nvmf_request *req)
     844                 :            : {
     845   [ #  #  #  # ]:       4692 :         struct spdk_nvmf_qpair *qpair = req->qpair;
     846   [ #  #  #  # ]:       4692 :         union nvmf_h2c_msg *cmd = req->cmd;
     847                 :            : 
     848         [ -  + ]:       4692 :         if (!nvmf_auth_check_state(qpair, req)) {
     849                 :          0 :                 goto out;
     850                 :            :         }
     851                 :            : 
     852   [ -  +  #  #  :       4692 :         assert(cmd->nvmf_cmd.opcode == SPDK_NVME_OPC_FABRIC);
          #  #  #  #  #  
                      # ]
     853   [ +  +  -  #  :       4692 :         switch (cmd->nvmf_cmd.fctype) {
             #  #  #  #  
                      # ]
     854                 :       2708 :         case SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_SEND:
     855                 :       2708 :                 nvmf_auth_send_exec(req);
     856                 :       2708 :                 break;
     857                 :       1984 :         case SPDK_NVMF_FABRIC_COMMAND_AUTHENTICATION_RECV:
     858                 :       1984 :                 nvmf_auth_recv_exec(req);
     859                 :       1984 :                 break;
     860                 :          0 :         default:
     861         [ #  # ]:          0 :                 assert(0 && "invalid fctype");
     862                 :            :                 nvmf_auth_request_complete(req, SPDK_NVME_SCT_GENERIC,
     863                 :            :                                            SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, 0);
     864                 :            :                 break;
     865                 :          0 :         }
     866                 :       4692 : out:
     867                 :       4692 :         return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS;
     868                 :            : }
     869                 :            : 
     870                 :            : int
     871                 :        996 : nvmf_qpair_auth_init(struct spdk_nvmf_qpair *qpair)
     872                 :            : {
     873   [ #  #  #  # ]:        996 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     874                 :            :         int rc;
     875                 :            : 
     876         [ +  + ]:        996 :         if (auth == NULL) {
     877                 :        968 :                 auth = calloc(1, sizeof(*qpair->auth));
     878         [ -  + ]:        968 :                 if (auth == NULL) {
     879                 :          0 :                         return -ENOMEM;
     880                 :            :                 }
     881                 :          0 :         }
     882                 :            : 
     883   [ #  #  #  # ]:        996 :         auth->digest = -1;
     884   [ #  #  #  # ]:        996 :         qpair->auth = auth;
     885                 :        996 :         nvmf_auth_set_state(qpair, NVMF_QPAIR_AUTH_NEGOTIATE);
     886                 :            : 
     887                 :        996 :         rc = nvmf_auth_rearm_poller(qpair);
     888         [ -  + ]:        996 :         if (rc != 0) {
     889   [ #  #  #  #  :          0 :                 AUTH_ERRLOG(qpair, "failed to arm timeout poller: %s\n", spdk_strerror(-rc));
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     890                 :          0 :                 nvmf_qpair_auth_destroy(qpair);
     891                 :          0 :                 return rc;
     892                 :            :         }
     893                 :            : 
     894                 :        996 :         return 0;
     895                 :          0 : }
     896                 :            : 
     897                 :            : void
     898                 :      10160 : nvmf_qpair_auth_destroy(struct spdk_nvmf_qpair *qpair)
     899                 :            : {
     900   [ +  -  +  - ]:      10160 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     901                 :            : 
     902         [ +  + ]:      10160 :         if (auth != NULL) {
     903                 :        968 :                 nvmf_auth_qpair_cleanup(auth);
     904   [ #  #  #  # ]:        968 :                 free(qpair->auth);
     905   [ #  #  #  # ]:        968 :                 qpair->auth = NULL;
     906                 :          0 :         }
     907                 :      10160 : }
     908                 :            : 
     909                 :            : void
     910                 :        298 : nvmf_qpair_auth_dump(struct spdk_nvmf_qpair *qpair, struct spdk_json_write_ctx *w)
     911                 :            : {
     912   [ #  #  #  # ]:        298 :         struct spdk_nvmf_qpair_auth *auth = qpair->auth;
     913                 :            :         const char *digest, *dhgroup;
     914                 :            : 
     915         [ +  + ]:        298 :         if (auth == NULL) {
     916                 :          2 :                 return;
     917                 :            :         }
     918                 :            : 
     919                 :        296 :         spdk_json_write_named_object_begin(w, "auth");
     920   [ #  #  #  # ]:        296 :         spdk_json_write_named_string(w, "state", nvmf_auth_get_state_name(auth->state));
     921   [ #  #  #  # ]:        296 :         digest = spdk_nvme_dhchap_get_digest_name(auth->digest);
     922         [ +  - ]:        296 :         spdk_json_write_named_string(w, "digest", digest ? digest : "unknown");
     923   [ #  #  #  # ]:        296 :         dhgroup = spdk_nvme_dhchap_get_dhgroup_name(auth->dhgroup);
     924         [ +  - ]:        296 :         spdk_json_write_named_string(w, "dhgroup", dhgroup ? dhgroup : "unknown");
     925                 :        296 :         spdk_json_write_object_end(w);
     926                 :          0 : }
     927                 :            : 
     928                 :            : bool
     929                 :        356 : nvmf_auth_is_supported(void)
     930                 :            : {
     931                 :        356 :         return true;
     932                 :            : }
     933                 :        960 : SPDK_LOG_REGISTER_COMPONENT(nvmf_auth)

Generated by: LCOV version 1.15