cxgb4/chcr: Save tx keys and handle HW response
[linux-2.6-block.git] / drivers / crypto / chelsio / chcr_ktls.c
CommitLineData
34aba2c4
RM
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (C) 2020 Chelsio Communications. All rights reserved. */
3
4#ifdef CONFIG_CHELSIO_TLS_DEVICE
5#include "chcr_ktls.h"
6
8a30923e
RM
7static int chcr_init_tcb_fields(struct chcr_ktls_info *tx_info);
8/*
9 * chcr_ktls_save_keys: calculate and save crypto keys.
10 * @tx_info - driver specific tls info.
11 * @crypto_info - tls crypto information.
12 * @direction - TX/RX direction.
13 * return - SUCCESS/FAILURE.
14 */
15static int chcr_ktls_save_keys(struct chcr_ktls_info *tx_info,
16 struct tls_crypto_info *crypto_info,
17 enum tls_offload_ctx_dir direction)
18{
19 int ck_size, key_ctx_size, mac_key_size, keylen, ghash_size, ret;
20 unsigned char ghash_h[TLS_CIPHER_AES_GCM_256_TAG_SIZE];
21 struct tls12_crypto_info_aes_gcm_128 *info_128_gcm;
22 struct ktls_key_ctx *kctx = &tx_info->key_ctx;
23 struct crypto_cipher *cipher;
24 unsigned char *key, *salt;
25
26 switch (crypto_info->cipher_type) {
27 case TLS_CIPHER_AES_GCM_128:
28 info_128_gcm =
29 (struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
30 keylen = TLS_CIPHER_AES_GCM_128_KEY_SIZE;
31 ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_128;
32 tx_info->salt_size = TLS_CIPHER_AES_GCM_128_SALT_SIZE;
33 mac_key_size = CHCR_KEYCTX_MAC_KEY_SIZE_128;
34 tx_info->iv_size = TLS_CIPHER_AES_GCM_128_IV_SIZE;
35 tx_info->iv = be64_to_cpu(*(__be64 *)info_128_gcm->iv);
36
37 ghash_size = TLS_CIPHER_AES_GCM_128_TAG_SIZE;
38 key = info_128_gcm->key;
39 salt = info_128_gcm->salt;
40 tx_info->record_no = *(u64 *)info_128_gcm->rec_seq;
41
42 break;
43
44 default:
45 pr_err("GCM: cipher type 0x%x not supported\n",
46 crypto_info->cipher_type);
47 ret = -EINVAL;
48 goto out;
49 }
50
51 key_ctx_size = CHCR_KTLS_KEY_CTX_LEN +
52 roundup(keylen, 16) + ghash_size;
53 /* Calculate the H = CIPH(K, 0 repeated 16 times).
54 * It will go in key context
55 */
56 cipher = crypto_alloc_cipher("aes", 0, 0);
57 if (IS_ERR(cipher)) {
58 ret = -ENOMEM;
59 goto out;
60 }
61
62 ret = crypto_cipher_setkey(cipher, key, keylen);
63 if (ret)
64 goto out1;
65
66 memset(ghash_h, 0, ghash_size);
67 crypto_cipher_encrypt_one(cipher, ghash_h, ghash_h);
68
69 /* fill the Key context */
70 if (direction == TLS_OFFLOAD_CTX_DIR_TX) {
71 kctx->ctx_hdr = FILL_KEY_CTX_HDR(ck_size,
72 mac_key_size,
73 key_ctx_size >> 4);
74 } else {
75 ret = -EINVAL;
76 goto out1;
77 }
78
79 memcpy(kctx->salt, salt, tx_info->salt_size);
80 memcpy(kctx->key, key, keylen);
81 memcpy(kctx->key + keylen, ghash_h, ghash_size);
82 tx_info->key_ctx_len = key_ctx_size;
83
84out1:
85 crypto_free_cipher(cipher);
86out:
87 return ret;
88}
89
90static int chcr_ktls_update_connection_state(struct chcr_ktls_info *tx_info,
91 int new_state)
92{
93 unsigned long flags;
94
95 /* This function can be called from both rx (interrupt context) and tx
96 * queue contexts.
97 */
98 spin_lock_irqsave(&tx_info->lock, flags);
99 switch (tx_info->connection_state) {
100 case KTLS_CONN_CLOSED:
101 tx_info->connection_state = new_state;
102 break;
103
104 case KTLS_CONN_ACT_OPEN_REQ:
105 /* only go forward if state is greater than current state. */
106 if (new_state <= tx_info->connection_state)
107 break;
108 /* update to the next state and also initialize TCB */
109 tx_info->connection_state = new_state;
110 /* FALLTHRU */
111 case KTLS_CONN_ACT_OPEN_RPL:
112 /* if we are stuck in this state, means tcb init might not
113 * received by HW, try sending it again.
114 */
115 if (!chcr_init_tcb_fields(tx_info))
116 tx_info->connection_state = KTLS_CONN_SET_TCB_REQ;
117 break;
118
119 case KTLS_CONN_SET_TCB_REQ:
120 /* only go forward if state is greater than current state. */
121 if (new_state <= tx_info->connection_state)
122 break;
123 /* update to the next state and check if l2t_state is valid */
124 tx_info->connection_state = new_state;
125 /* FALLTHRU */
126 case KTLS_CONN_SET_TCB_RPL:
127 /* Check if l2t state is valid, then move to ready state. */
128 if (cxgb4_check_l2t_valid(tx_info->l2te))
129 tx_info->connection_state = KTLS_CONN_TX_READY;
130 break;
131
132 case KTLS_CONN_TX_READY:
133 /* nothing to be done here */
134 break;
135
136 default:
137 pr_err("unknown KTLS connection state\n");
138 break;
139 }
140 spin_unlock_irqrestore(&tx_info->lock, flags);
141
142 return tx_info->connection_state;
143}
34aba2c4
RM
144/*
145 * chcr_ktls_act_open_req: creates TCB entry for ipv4 connection.
146 * @sk - tcp socket.
147 * @tx_info - driver specific tls info.
148 * @atid - connection active tid.
149 * return - send success/failure.
150 */
151static int chcr_ktls_act_open_req(struct sock *sk,
152 struct chcr_ktls_info *tx_info,
153 int atid)
154{
155 struct inet_sock *inet = inet_sk(sk);
156 struct cpl_t6_act_open_req *cpl6;
157 struct cpl_act_open_req *cpl;
158 struct sk_buff *skb;
159 unsigned int len;
160 int qid_atid;
161 u64 options;
162
163 len = sizeof(*cpl6);
164 skb = alloc_skb(len, GFP_KERNEL);
165 if (unlikely(!skb))
166 return -ENOMEM;
167 /* mark it a control pkt */
168 set_wr_txq(skb, CPL_PRIORITY_CONTROL, tx_info->port_id);
169
170 cpl6 = __skb_put_zero(skb, len);
171 cpl = (struct cpl_act_open_req *)cpl6;
172 INIT_TP_WR(cpl6, 0);
173 qid_atid = TID_QID_V(tx_info->rx_qid) |
174 TID_TID_V(atid);
175 OPCODE_TID(cpl) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, qid_atid));
176 cpl->local_port = inet->inet_sport;
177 cpl->peer_port = inet->inet_dport;
178 cpl->local_ip = inet->inet_rcv_saddr;
179 cpl->peer_ip = inet->inet_daddr;
180
181 /* fill first 64 bit option field. */
182 options = TCAM_BYPASS_F | ULP_MODE_V(ULP_MODE_NONE) | NON_OFFLOAD_F |
183 SMAC_SEL_V(tx_info->smt_idx) | TX_CHAN_V(tx_info->tx_chan);
184 cpl->opt0 = cpu_to_be64(options);
185
186 /* next 64 bit option field. */
187 options =
188 TX_QUEUE_V(tx_info->adap->params.tp.tx_modq[tx_info->tx_chan]);
189 cpl->opt2 = htonl(options);
190
191 return cxgb4_l2t_send(tx_info->netdev, skb, tx_info->l2te);
192}
193
194/*
195 * chcr_setup_connection: create a TCB entry so that TP will form tcp packets.
196 * @sk - tcp socket.
197 * @tx_info - driver specific tls info.
198 * return: NET_TX_OK/NET_XMIT_DROP
199 */
200static int chcr_setup_connection(struct sock *sk,
201 struct chcr_ktls_info *tx_info)
202{
203 struct tid_info *t = &tx_info->adap->tids;
204 int atid, ret = 0;
205
206 atid = cxgb4_alloc_atid(t, tx_info);
207 if (atid == -1)
208 return -EINVAL;
209
210 tx_info->atid = atid;
211 tx_info->ip_family = sk->sk_family;
212
213 if (sk->sk_family == AF_INET ||
214 (sk->sk_family == AF_INET6 && !sk->sk_ipv6only &&
215 ipv6_addr_type(&sk->sk_v6_daddr) == IPV6_ADDR_MAPPED)) {
216 tx_info->ip_family = AF_INET;
217 ret = chcr_ktls_act_open_req(sk, tx_info, atid);
218 } else {
219 tx_info->ip_family = AF_INET6;
220 ret = -EOPNOTSUPP;
221 }
222
223 /* if return type is NET_XMIT_CN, msg will be sent but delayed, mark ret
224 * success, if any other return type clear atid and return that failure.
225 */
226 if (ret) {
227 if (ret == NET_XMIT_CN)
228 ret = 0;
229 else
230 cxgb4_free_atid(t, atid);
8a30923e 231 goto out;
34aba2c4
RM
232 }
233
8a30923e
RM
234 /* update the connection state */
235 chcr_ktls_update_connection_state(tx_info, KTLS_CONN_ACT_OPEN_REQ);
236out:
34aba2c4
RM
237 return ret;
238}
239
240/*
241 * chcr_set_tcb_field: update tcb fields.
242 * @tx_info - driver specific tls info.
243 * @word - TCB word.
244 * @mask - TCB word related mask.
245 * @val - TCB word related value.
246 * @no_reply - set 1 if not looking for TP response.
247 */
248static int chcr_set_tcb_field(struct chcr_ktls_info *tx_info, u16 word,
249 u64 mask, u64 val, int no_reply)
250{
251 struct cpl_set_tcb_field *req;
252 struct sk_buff *skb;
253
254 skb = alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_ATOMIC);
255 if (!skb)
256 return -ENOMEM;
257
258 req = (struct cpl_set_tcb_field *)__skb_put_zero(skb, sizeof(*req));
259 INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, tx_info->tid);
260 req->reply_ctrl = htons(QUEUENO_V(tx_info->rx_qid) |
261 NO_REPLY_V(no_reply));
262 req->word_cookie = htons(TCB_WORD_V(word));
263 req->mask = cpu_to_be64(mask);
264 req->val = cpu_to_be64(val);
265
266 set_wr_txq(skb, CPL_PRIORITY_CONTROL, tx_info->port_id);
267 return cxgb4_ofld_send(tx_info->netdev, skb);
268}
269
270/*
271 * chcr_ktls_mark_tcb_close: mark tcb state to CLOSE
272 * @tx_info - driver specific tls info.
273 * return: NET_TX_OK/NET_XMIT_DROP.
274 */
275static int chcr_ktls_mark_tcb_close(struct chcr_ktls_info *tx_info)
276{
277 return chcr_set_tcb_field(tx_info, TCB_T_STATE_W,
278 TCB_T_STATE_V(TCB_T_STATE_M),
279 CHCR_TCB_STATE_CLOSED, 1);
280}
281
282/*
283 * chcr_ktls_dev_del: call back for tls_dev_del.
284 * Remove the tid and l2t entry and close the connection.
285 * it per connection basis.
286 * @netdev - net device.
287 * @tls_cts - tls context.
288 * @direction - TX/RX crypto direction
289 */
290static void chcr_ktls_dev_del(struct net_device *netdev,
291 struct tls_context *tls_ctx,
292 enum tls_offload_ctx_dir direction)
293{
294 struct chcr_ktls_ofld_ctx_tx *tx_ctx =
295 chcr_get_ktls_tx_context(tls_ctx);
296 struct chcr_ktls_info *tx_info = tx_ctx->chcr_info;
297
298 if (!tx_info)
299 return;
300
301 spin_lock(&tx_info->lock);
302 tx_info->connection_state = KTLS_CONN_CLOSED;
303 spin_unlock(&tx_info->lock);
304
305 if (tx_info->l2te)
306 cxgb4_l2t_release(tx_info->l2te);
307
308 if (tx_info->tid != -1) {
309 /* clear tcb state and then release tid */
310 chcr_ktls_mark_tcb_close(tx_info);
311 cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
312 tx_info->tid, tx_info->ip_family);
313 }
314 kvfree(tx_info);
315 tx_ctx->chcr_info = NULL;
316}
317
318/*
319 * chcr_ktls_dev_add: call back for tls_dev_add.
320 * Create a tcb entry for TP. Also add l2t entry for the connection. And
321 * generate keys & save those keys locally.
322 * @netdev - net device.
323 * @tls_cts - tls context.
324 * @direction - TX/RX crypto direction
325 * return: SUCCESS/FAILURE.
326 */
327static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
328 enum tls_offload_ctx_dir direction,
329 struct tls_crypto_info *crypto_info,
330 u32 start_offload_tcp_sn)
331{
332 struct tls_context *tls_ctx = tls_get_ctx(sk);
333 struct chcr_ktls_ofld_ctx_tx *tx_ctx;
334 struct chcr_ktls_info *tx_info;
335 struct dst_entry *dst;
336 struct adapter *adap;
337 struct port_info *pi;
338 struct neighbour *n;
339 u8 daaddr[16];
340 int ret = -1;
341
342 tx_ctx = chcr_get_ktls_tx_context(tls_ctx);
343
344 pi = netdev_priv(netdev);
345 adap = pi->adapter;
346 if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
347 pr_err("not expecting for RX direction\n");
348 ret = -EINVAL;
349 goto out;
350 }
351 if (tx_ctx->chcr_info) {
352 ret = -EINVAL;
353 goto out;
354 }
355
356 tx_info = kvzalloc(sizeof(*tx_info), GFP_KERNEL);
357 if (!tx_info) {
358 ret = -ENOMEM;
359 goto out;
360 }
361
362 spin_lock_init(&tx_info->lock);
363
364 /* clear connection state */
365 spin_lock(&tx_info->lock);
366 tx_info->connection_state = KTLS_CONN_CLOSED;
367 spin_unlock(&tx_info->lock);
368
369 tx_info->sk = sk;
370 /* initialize tid and atid to -1, 0 is a also a valid id. */
371 tx_info->tid = -1;
372 tx_info->atid = -1;
373
374 tx_info->adap = adap;
375 tx_info->netdev = netdev;
376 tx_info->tx_chan = pi->tx_chan;
377 tx_info->smt_idx = pi->smt_idx;
378 tx_info->port_id = pi->port_id;
379
380 tx_info->rx_qid = chcr_get_first_rx_qid(adap);
381 if (unlikely(tx_info->rx_qid < 0))
382 goto out2;
383
384 tx_info->prev_seq = start_offload_tcp_sn;
385 tx_info->tcp_start_seq_number = start_offload_tcp_sn;
386
8a30923e
RM
387 /* save crypto keys */
388 ret = chcr_ktls_save_keys(tx_info, crypto_info, direction);
389 if (ret < 0)
390 goto out2;
391
34aba2c4
RM
392 /* get peer ip */
393 if (sk->sk_family == AF_INET ||
394 (sk->sk_family == AF_INET6 && !sk->sk_ipv6only &&
395 ipv6_addr_type(&sk->sk_v6_daddr) == IPV6_ADDR_MAPPED)) {
396 memcpy(daaddr, &sk->sk_daddr, 4);
397 } else {
398 goto out2;
399 }
400
401 /* get the l2t index */
402 dst = sk_dst_get(sk);
403 if (!dst) {
404 pr_err("DST entry not found\n");
405 goto out2;
406 }
407 n = dst_neigh_lookup(dst, daaddr);
408 if (!n || !n->dev) {
409 pr_err("neighbour not found\n");
410 dst_release(dst);
411 goto out2;
412 }
413 tx_info->l2te = cxgb4_l2t_get(adap->l2t, n, n->dev, 0);
414
415 neigh_release(n);
416 dst_release(dst);
417
418 if (!tx_info->l2te) {
419 pr_err("l2t entry not found\n");
420 goto out2;
421 }
422
423 tx_ctx->chcr_info = tx_info;
424
425 /* create a filter and call cxgb4_l2t_send to send the packet out, which
426 * will take care of updating l2t entry in hw if not already done.
427 */
428 ret = chcr_setup_connection(sk, tx_info);
429 if (ret)
430 goto out2;
431
432 return 0;
433out2:
434 kvfree(tx_info);
435out:
436 return ret;
437}
438
439static const struct tlsdev_ops chcr_ktls_ops = {
440 .tls_dev_add = chcr_ktls_dev_add,
441 .tls_dev_del = chcr_ktls_dev_del,
442};
443
444/*
445 * chcr_enable_ktls: add NETIF_F_HW_TLS_TX flag in all the ports.
446 */
447void chcr_enable_ktls(struct adapter *adap)
448{
449 struct net_device *netdev;
450 int i;
451
452 for_each_port(adap, i) {
453 netdev = adap->port[i];
454 netdev->features |= NETIF_F_HW_TLS_TX;
455 netdev->hw_features |= NETIF_F_HW_TLS_TX;
456 netdev->tlsdev_ops = &chcr_ktls_ops;
457 }
458}
459
460/*
461 * chcr_disable_ktls: remove NETIF_F_HW_TLS_TX flag from all the ports.
462 */
463void chcr_disable_ktls(struct adapter *adap)
464{
465 struct net_device *netdev;
466 int i;
467
468 for_each_port(adap, i) {
469 netdev = adap->port[i];
470 netdev->features &= ~NETIF_F_HW_TLS_TX;
471 netdev->hw_features &= ~NETIF_F_HW_TLS_TX;
472 netdev->tlsdev_ops = NULL;
473 }
474}
8a30923e
RM
475
476/*
477 * chcr_init_tcb_fields: Initialize tcb fields to handle TCP seq number
478 * handling.
479 * @tx_info - driver specific tls info.
480 * return: NET_TX_OK/NET_XMIT_DROP
481 */
482static int chcr_init_tcb_fields(struct chcr_ktls_info *tx_info)
483{
484 int ret = 0;
485
486 /* set tcb in offload and bypass */
487 ret =
488 chcr_set_tcb_field(tx_info, TCB_T_FLAGS_W,
489 TCB_T_FLAGS_V(TF_CORE_BYPASS_F | TF_NON_OFFLOAD_F),
490 TCB_T_FLAGS_V(TF_CORE_BYPASS_F), 1);
491 if (ret)
492 return ret;
493 /* reset snd_una and snd_next fields in tcb */
494 ret = chcr_set_tcb_field(tx_info, TCB_SND_UNA_RAW_W,
495 TCB_SND_NXT_RAW_V(TCB_SND_NXT_RAW_M) |
496 TCB_SND_UNA_RAW_V(TCB_SND_UNA_RAW_M),
497 0, 1);
498 if (ret)
499 return ret;
500
501 /* reset send max */
502 ret = chcr_set_tcb_field(tx_info, TCB_SND_MAX_RAW_W,
503 TCB_SND_MAX_RAW_V(TCB_SND_MAX_RAW_M),
504 0, 1);
505 if (ret)
506 return ret;
507
508 /* update l2t index and request for tp reply to confirm tcb is
509 * initialised to handle tx traffic.
510 */
511 ret = chcr_set_tcb_field(tx_info, TCB_L2T_IX_W,
512 TCB_L2T_IX_V(TCB_L2T_IX_M),
513 TCB_L2T_IX_V(tx_info->l2te->idx), 0);
514 return ret;
515}
516
517/*
518 * chcr_ktls_cpl_act_open_rpl: connection reply received from TP.
519 */
520int chcr_ktls_cpl_act_open_rpl(struct adapter *adap, unsigned char *input)
521{
522 const struct cpl_act_open_rpl *p = (void *)input;
523 struct chcr_ktls_info *tx_info = NULL;
524 unsigned int atid, tid, status;
525 struct tid_info *t;
526
527 tid = GET_TID(p);
528 status = AOPEN_STATUS_G(ntohl(p->atid_status));
529 atid = TID_TID_G(AOPEN_ATID_G(ntohl(p->atid_status)));
530
531 t = &adap->tids;
532 tx_info = lookup_atid(t, atid);
533
534 if (!tx_info || tx_info->atid != atid) {
535 pr_err("tx_info or atid is not correct\n");
536 return -1;
537 }
538
539 if (!status) {
540 tx_info->tid = tid;
541 cxgb4_insert_tid(t, tx_info, tx_info->tid, tx_info->ip_family);
542
543 cxgb4_free_atid(t, atid);
544 tx_info->atid = -1;
545 /* update the connection state */
546 chcr_ktls_update_connection_state(tx_info,
547 KTLS_CONN_ACT_OPEN_RPL);
548 }
549 return 0;
550}
551
552/*
553 * chcr_ktls_cpl_set_tcb_rpl: TCB reply received from TP.
554 */
555int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input)
556{
557 const struct cpl_set_tcb_rpl *p = (void *)input;
558 struct chcr_ktls_info *tx_info = NULL;
559 struct tid_info *t;
560 u32 tid, status;
561
562 tid = GET_TID(p);
563 status = p->status;
564
565 t = &adap->tids;
566 tx_info = lookup_tid(t, tid);
567 if (!tx_info || tx_info->tid != tid) {
568 pr_err("tx_info or atid is not correct\n");
569 return -1;
570 }
571 /* update the connection state */
572 chcr_ktls_update_connection_state(tx_info, KTLS_CONN_SET_TCB_RPL);
573 return 0;
574}
34aba2c4 575#endif /* CONFIG_CHELSIO_TLS_DEVICE */