1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * fs/hmdfs/comm/crypto.c
4 *
5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
6 */
7
8 #include "crypto.h"
9
10 #include <crypto/aead.h>
11 #include <crypto/hash.h>
12 #include <linux/tcp.h>
13 #include <net/inet_connection_sock.h>
14 #include <net/tcp_states.h>
15 #include <net/tls.h>
16
17 #include "hmdfs.h"
18
tls_crypto_set_key(struct connection * conn_impl,int tx)19 static void tls_crypto_set_key(struct connection *conn_impl, int tx)
20 {
21 int rc = 0;
22 struct tcp_handle *tcp = conn_impl->connect_handle;
23 struct tls_context *ctx = tls_get_ctx(tcp->sock->sk);
24 struct cipher_context *cctx = NULL;
25 struct tls_sw_context_tx *sw_ctx_tx = NULL;
26 struct tls_sw_context_rx *sw_ctx_rx = NULL;
27 struct crypto_aead **aead = NULL;
28 struct tls12_crypto_info_aes_gcm_128 *crypto_info = NULL;
29
30 if (tx) {
31 crypto_info = &conn_impl->send_crypto_info;
32 cctx = &ctx->tx;
33 sw_ctx_tx = tls_sw_ctx_tx(ctx);
34 aead = &sw_ctx_tx->aead_send;
35 } else {
36 crypto_info = &conn_impl->recv_crypto_info;
37 cctx = &ctx->rx;
38 sw_ctx_rx = tls_sw_ctx_rx(ctx);
39 aead = &sw_ctx_rx->aead_recv;
40 }
41
42 memcpy(cctx->iv, crypto_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
43 memcpy(cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, crypto_info->iv,
44 TLS_CIPHER_AES_GCM_128_IV_SIZE);
45 memcpy(cctx->rec_seq, crypto_info->rec_seq,
46 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
47 rc = crypto_aead_setkey(*aead, crypto_info->key,
48 TLS_CIPHER_AES_GCM_128_KEY_SIZE);
49 if (rc)
50 hmdfs_err("crypto set key error");
51 }
52
tls_crypto_info_init(struct connection * conn_impl)53 int tls_crypto_info_init(struct connection *conn_impl)
54 {
55 int ret = 0;
56 u8 key_meterial[HMDFS_KEY_SIZE];
57 struct tcp_handle *tcp =
58 (struct tcp_handle *)(conn_impl->connect_handle);
59 if (conn_impl->node->version < DFS_2_0 || !tcp)
60 return -EINVAL;
61 // send
62 update_key(conn_impl->send_key, key_meterial, HKDF_TYPE_IV);
63 ret = tcp->sock->ops->setsockopt(tcp->sock, SOL_TCP, TCP_ULP,
64 KERNEL_SOCKPTR("tls"), sizeof("tls"));
65 if (ret)
66 hmdfs_err("set tls error %d", ret);
67 tcp->connect->send_crypto_info.info.version = TLS_1_2_VERSION;
68 tcp->connect->send_crypto_info.info.cipher_type =
69 TLS_CIPHER_AES_GCM_128;
70
71 memcpy(tcp->connect->send_crypto_info.key, tcp->connect->send_key,
72 TLS_CIPHER_AES_GCM_128_KEY_SIZE);
73 memcpy(tcp->connect->send_crypto_info.iv,
74 key_meterial + CRYPTO_IV_OFFSET, TLS_CIPHER_AES_GCM_128_IV_SIZE);
75 memcpy(tcp->connect->send_crypto_info.salt,
76 key_meterial + CRYPTO_SALT_OFFSET,
77 TLS_CIPHER_AES_GCM_128_SALT_SIZE);
78 memcpy(tcp->connect->send_crypto_info.rec_seq,
79 key_meterial + CRYPTO_SEQ_OFFSET,
80 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
81
82 ret = tcp->sock->ops->setsockopt(tcp->sock, SOL_TLS, TLS_TX,
83 KERNEL_SOCKPTR(&(tcp->connect->send_crypto_info)),
84 sizeof(tcp->connect->send_crypto_info));
85 if (ret)
86 hmdfs_err("set tls send_crypto_info error %d", ret);
87
88 // recv
89 update_key(tcp->connect->recv_key, key_meterial, HKDF_TYPE_IV);
90 tcp->connect->recv_crypto_info.info.version = TLS_1_2_VERSION;
91 tcp->connect->recv_crypto_info.info.cipher_type =
92 TLS_CIPHER_AES_GCM_128;
93
94 memcpy(tcp->connect->recv_crypto_info.key, tcp->connect->recv_key,
95 TLS_CIPHER_AES_GCM_128_KEY_SIZE);
96 memcpy(tcp->connect->recv_crypto_info.iv,
97 key_meterial + CRYPTO_IV_OFFSET, TLS_CIPHER_AES_GCM_128_IV_SIZE);
98 memcpy(tcp->connect->recv_crypto_info.salt,
99 key_meterial + CRYPTO_SALT_OFFSET,
100 TLS_CIPHER_AES_GCM_128_SALT_SIZE);
101 memcpy(tcp->connect->recv_crypto_info.rec_seq,
102 key_meterial + CRYPTO_SEQ_OFFSET,
103 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
104 memset(key_meterial, 0, HMDFS_KEY_SIZE);
105
106 ret = tcp->sock->ops->setsockopt(tcp->sock, SOL_TLS, TLS_RX,
107 KERNEL_SOCKPTR(&(tcp->connect->recv_crypto_info)),
108 sizeof(tcp->connect->recv_crypto_info));
109 if (ret)
110 hmdfs_err("set tls recv_crypto_info error %d", ret);
111 return ret;
112 }
113
tls_set_tx(struct tcp_handle * tcp)114 static int tls_set_tx(struct tcp_handle *tcp)
115 {
116 int ret = 0;
117 u8 new_key[HMDFS_KEY_SIZE];
118 u8 key_meterial[HMDFS_KEY_SIZE];
119
120 ret = update_key(tcp->connect->send_key, new_key, HKDF_TYPE_REKEY);
121 if (ret < 0)
122 return ret;
123 memcpy(tcp->connect->send_key, new_key, HMDFS_KEY_SIZE);
124 ret = update_key(tcp->connect->send_key, key_meterial, HKDF_TYPE_IV);
125 if (ret < 0)
126 return ret;
127
128 memcpy(tcp->connect->send_crypto_info.key, tcp->connect->send_key,
129 TLS_CIPHER_AES_GCM_128_KEY_SIZE);
130 memcpy(tcp->connect->send_crypto_info.iv,
131 key_meterial + CRYPTO_IV_OFFSET, TLS_CIPHER_AES_GCM_128_IV_SIZE);
132 memcpy(tcp->connect->send_crypto_info.salt,
133 key_meterial + CRYPTO_SALT_OFFSET,
134 TLS_CIPHER_AES_GCM_128_SALT_SIZE);
135 memcpy(tcp->connect->send_crypto_info.rec_seq,
136 key_meterial + CRYPTO_SEQ_OFFSET,
137 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
138 memset(new_key, 0, HMDFS_KEY_SIZE);
139 memset(key_meterial, 0, HMDFS_KEY_SIZE);
140
141 tls_crypto_set_key(tcp->connect, 1);
142 return 0;
143 }
144
tls_set_rx(struct tcp_handle * tcp)145 static int tls_set_rx(struct tcp_handle *tcp)
146 {
147 int ret = 0;
148 u8 new_key[HMDFS_KEY_SIZE];
149 u8 key_meterial[HMDFS_KEY_SIZE];
150
151 ret = update_key(tcp->connect->recv_key, new_key, HKDF_TYPE_REKEY);
152 if (ret < 0)
153 return ret;
154 memcpy(tcp->connect->recv_key, new_key, HMDFS_KEY_SIZE);
155 ret = update_key(tcp->connect->recv_key, key_meterial, HKDF_TYPE_IV);
156 if (ret < 0)
157 return ret;
158
159 memcpy(tcp->connect->recv_crypto_info.key, tcp->connect->recv_key,
160 TLS_CIPHER_AES_GCM_128_KEY_SIZE);
161 memcpy(tcp->connect->recv_crypto_info.iv,
162 key_meterial + CRYPTO_IV_OFFSET, TLS_CIPHER_AES_GCM_128_IV_SIZE);
163 memcpy(tcp->connect->recv_crypto_info.salt,
164 key_meterial + CRYPTO_SALT_OFFSET,
165 TLS_CIPHER_AES_GCM_128_SALT_SIZE);
166 memcpy(tcp->connect->recv_crypto_info.rec_seq,
167 key_meterial + CRYPTO_SEQ_OFFSET,
168 TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
169 memset(new_key, 0, HMDFS_KEY_SIZE);
170 memset(key_meterial, 0, HMDFS_KEY_SIZE);
171 tls_crypto_set_key(tcp->connect, 0);
172 return 0;
173 }
174
set_crypto_info(struct connection * conn_impl,int set_type)175 int set_crypto_info(struct connection *conn_impl, int set_type)
176 {
177 int ret = 0;
178 __u8 version = conn_impl->node->version;
179 struct tcp_handle *tcp =
180 (struct tcp_handle *)(conn_impl->connect_handle);
181 if (version < DFS_2_0 || !tcp)
182 return -EINVAL;
183
184 if (set_type == SET_CRYPTO_SEND) {
185 ret = tls_set_tx(tcp);
186 if (ret) {
187 hmdfs_err("tls set tx fail");
188 return ret;
189 }
190 }
191 if (set_type == SET_CRYPTO_RECV) {
192 ret = tls_set_rx(tcp);
193 if (ret) {
194 hmdfs_err("tls set rx fail");
195 return ret;
196 }
197 }
198 hmdfs_info("KTLS setting success");
199 return ret;
200 }
201
hmac_sha256(u8 * key,u8 key_len,char * info,u8 info_len,u8 * output)202 static int hmac_sha256(u8 *key, u8 key_len, char *info, u8 info_len, u8 *output)
203 {
204 struct crypto_shash *tfm = NULL;
205 struct shash_desc *shash = NULL;
206 int ret = 0;
207
208 if (!key)
209 return -EINVAL;
210
211 tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
212 if (IS_ERR(tfm)) {
213 hmdfs_err("crypto_alloc_ahash failed: err %ld", PTR_ERR(tfm));
214 return PTR_ERR(tfm);
215 }
216
217 ret = crypto_shash_setkey(tfm, key, key_len);
218 if (ret) {
219 hmdfs_err("crypto_ahash_setkey failed: err %d", ret);
220 goto failed;
221 }
222
223 shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
224 GFP_KERNEL);
225 if (!shash) {
226 ret = -ENOMEM;
227 goto failed;
228 }
229
230 shash->tfm = tfm;
231
232 ret = crypto_shash_digest(shash, info, info_len, output);
233
234 kfree(shash);
235
236 failed:
237 crypto_free_shash(tfm);
238 return ret;
239 }
240
241 static const char *const g_key_lable[] = { "ktls key initiator",
242 "ktls key accepter",
243 "ktls key update", "ktls iv&salt" };
244 static const int g_key_lable_len[] = { 18, 17, 15, 12 };
245
update_key(__u8 * old_key,__u8 * new_key,int type)246 int update_key(__u8 *old_key, __u8 *new_key, int type)
247 {
248 int ret = 0;
249 char lable[MAX_LABLE_SIZE];
250 u8 lable_size;
251
252 lable_size = g_key_lable_len[type] + sizeof(u16) + sizeof(char);
253 *((u16 *)lable) = HMDFS_KEY_SIZE;
254 memcpy(lable + sizeof(u16), g_key_lable[type], g_key_lable_len[type]);
255 *(lable + sizeof(u16) + g_key_lable_len[type]) = 0x01;
256 ret = hmac_sha256(old_key, HMDFS_KEY_SIZE, lable, lable_size, new_key);
257 if (ret < 0)
258 hmdfs_err("hmac sha256 error");
259 return ret;
260 }
261