[PATCH 13/17] nvme-tcp: reset after recovery for secure concatenation
Sagi Grimberg
sagi at grimberg.me
Sun Apr 21 08:09:27 PDT 2024
On 21/04/2024 17:37, Hannes Reinecke wrote:
> On 4/21/24 13:22, Sagi Grimberg wrote:
>>
>>
>> On 09/04/2024 1:10, Hannes Reinecke wrote:
>>> On 4/8/24 23:23, Sagi Grimberg wrote:
>>>>
>>>>
>>>> On 08/04/2024 9:25, Hannes Reinecke wrote:
>>>>> On 4/7/24 23:49, Sagi Grimberg wrote:
>>>>>>
>>>>>>
>>>>>> On 18/03/2024 17:03, Hannes Reinecke wrote:
>>>>>>> From: Hannes Reinecke <hare at suse.de>
>>>>>>>
>>>>>>> With TP8018 a new key will be generated from the DH-HMAC-CHAP
>>>>>>> protocol after reset or recovery, but we need to start over
>>>>>>> to establish a new TLS connection with the new keys.
>>>>>>>
>>>>>>> Signed-off-by: Hannes Reinecke <hare at suse.de>
>>>>>>> ---
>>>>>>> drivers/nvme/host/tcp.c | 20 ++++++++++++++++++++
>>>>>>> 1 file changed, 20 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
>>>>>>> index 94152ded123a..3811ee9cd040 100644
>>>>>>> --- a/drivers/nvme/host/tcp.c
>>>>>>> +++ b/drivers/nvme/host/tcp.c
>>>>>>> @@ -2219,6 +2219,22 @@ static void
>>>>>>> nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl)
>>>>>>> }
>>>>>>> }
>>>>>>> +static bool nvme_tcp_reset_for_secure_concat(struct nvme_ctrl
>>>>>>> *ctrl)
>>>>>>> +{
>>>>>>> + if (!ctrl->opts->concat)
>>>>>>> + return false;
>>>>>>> + /*
>>>>>>> + * If a key has been generated and TLS has not been enabled
>>>>>>> + * reset the queue to start TLS handshake.
>>>>>>> + */
>>>>>>> + if (ctrl->opts->tls_key && !ctrl->tls_key) {
>>>>>>> + dev_info(ctrl->device, "Reset to enable TLS with
>>>>>>> generated PSK\n");
>>>>>>> + nvme_reset_ctrl(ctrl);
>>>>>>> + return true;
>>>>>>> + }
>>>>>>> + return false;
>>>>>>> +}
>>>>>>> +
>>>>>>> static void nvme_tcp_revoke_generated_tls_key(struct nvme_ctrl
>>>>>>> *ctrl)
>>>>>>> {
>>>>>>> if (!ctrl->opts->concat)
>>>>>>> @@ -2321,6 +2337,9 @@ static void
>>>>>>> nvme_tcp_reconnect_ctrl_work(struct work_struct *work)
>>>>>>> if (nvme_tcp_setup_ctrl(ctrl, false))
>>>>>>> goto requeue;
>>>>>>> + if (nvme_tcp_reset_for_secure_concat(ctrl))
>>>>>>> + return;
>>>>>>> +
>>>>>>> dev_info(ctrl->device, "Successfully reconnected (%d
>>>>>>> attempt)\n",
>>>>>>> ctrl->nr_reconnects);
>>>>>>> @@ -2396,6 +2415,7 @@ static void nvme_reset_ctrl_work(struct
>>>>>>> work_struct *work)
>>>>>>> if (nvme_tcp_setup_ctrl(ctrl, false))
>>>>>>> goto out_fail;
>>>>>>> + nvme_tcp_reset_for_secure_concat(ctrl);
>>>>>>
>>>>>> This is really strange. I'd imagine that this would be needed
>>>>>> only if the derived psk expired no?
>>>>>
>>>>> You are absolutely correct. But once you reset the connection the
>>>>> derived PSK of the previous connection _is_ expired as DH-HMAC-CHAP
>>>>> generated a new one.
>>>>>
>>>>> Remember: for secure concatenation we _always_ have a two-step
>>>>> connection setup. The initial connection runs for DH-HMAC-CHAP
>>>>> to generate the PSK, and then a connection reset to start over
>>>>> with TLS and the generated PSK.
>>>>> So upon reset we have to invalidate the generated PSK, reset the
>>>>> connection to run DH-HMAC-CHAP, and reset _again_ to start over
>>>>> with the new PSK.
>>>>
>>>> So what is the point of setting the derived psk with a timeout?
>>>>
>>>> Seems rather silly doing that _every_ reset/reconnect... But ok...
>>>
>>> Mandated by TP8018. Generated TLS PSK should be renewed after a
>>> certain time. Makes sense in general, but still a pain.
>>
>> I understand that psk can expire, I don't understand why we need to
>> reset every
>> single time. What if I'm doing the loop: while true; do nvme reset
>> /dev/nvme0; done?
>>
>> Will it do 2 resets every time?
>
> For secure concatenation: yes.
>
> Secure concatenation consists on running DH-HMAC-CHAP, generate a TLS
> PSK from the generated credentials, and then start TLS with the
> generated TLS PSK. This is run for every connection attempt, so each
> connection attempt gets a new TLS PSK; after the connection is reset
> the old PSK _cannot_ be reused, and we need to clear them up via
> some sort of garbage collection. By adding an expiration time to the
> key we achieve exactly this.
> And that is why we need to reset twice; we need to run the DH-HMAC-CHAP
> protocol _after_ recovery, and use the generated keys to establish a
> TLS connection. And as the TLS connection is established before the
> initial connect is sent we need to reset the connection after the
> DH-HMAC-CHAP protocol is run (as this is run _after_ the connect
> command).
Got it.
More information about the Linux-nvme
mailing list