1 /*
2  * Copyright (c) 2017 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief 802.15.4 6LoWPAN authentication and encryption implementation
10  *
11  * All references to the spec refer to IEEE 802.15.4-2020.
12  */
13 
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(net_ieee802154_security, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
16 
17 #include "ieee802154_frame.h"
18 #include "ieee802154_security.h"
19 
20 #include <zephyr/crypto/crypto.h>
21 #include <zephyr/net/net_core.h>
22 
23 extern const uint8_t level_2_authtag_len[4];
24 
ieee802154_security_setup_session(struct ieee802154_security_ctx * sec_ctx,uint8_t level,uint8_t key_mode,uint8_t * key,uint8_t key_len)25 int ieee802154_security_setup_session(struct ieee802154_security_ctx *sec_ctx, uint8_t level,
26 				      uint8_t key_mode, uint8_t *key, uint8_t key_len)
27 {
28 	uint8_t authtag_len;
29 	int ret;
30 
31 	if (level > IEEE802154_SECURITY_LEVEL_ENC_MIC_128 ||
32 	    key_mode > IEEE802154_KEY_ID_MODE_SRC_8_INDEX) {
33 		return -EINVAL;
34 	}
35 
36 	/* TODO: supporting other key modes */
37 	if (level > IEEE802154_SECURITY_LEVEL_NONE &&
38 	    (key_len > IEEE802154_KEY_MAX_LEN || !key ||
39 	     key_mode != IEEE802154_KEY_ID_MODE_IMPLICIT)) {
40 		return -EINVAL;
41 	}
42 
43 	sec_ctx->level = level;
44 
45 	if (level == IEEE802154_SECURITY_LEVEL_NONE) {
46 		return 0;
47 	}
48 
49 
50 	if (level > IEEE802154_SECURITY_LEVEL_ENC) {
51 		authtag_len = level_2_authtag_len[level - 4];
52 	} else if (level < IEEE802154_SECURITY_LEVEL_ENC) {
53 		authtag_len = level_2_authtag_len[level];
54 	} else {
55 		/* Encryption-only security is no longer supported since IEEE 802.15.4-2020. */
56 		return -EINVAL;
57 	}
58 	sec_ctx->enc.mode_params.ccm_info.tag_len = authtag_len;
59 	sec_ctx->dec.mode_params.ccm_info.tag_len = authtag_len;
60 
61 	memcpy(sec_ctx->key, key, key_len);
62 	sec_ctx->key_len = key_len;
63 	sec_ctx->key_mode = key_mode;
64 
65 	sec_ctx->enc.key.bit_stream = sec_ctx->key;
66 	sec_ctx->enc.keylen = sec_ctx->key_len;
67 
68 	sec_ctx->dec.key.bit_stream = sec_ctx->key;
69 	sec_ctx->dec.keylen = sec_ctx->key_len;
70 
71 	ret = cipher_begin_session(sec_ctx->enc.device, &sec_ctx->enc, CRYPTO_CIPHER_ALGO_AES,
72 				   CRYPTO_CIPHER_MODE_CCM, CRYPTO_CIPHER_OP_ENCRYPT);
73 	if (ret) {
74 		NET_ERR("Could not setup encryption context");
75 
76 		return ret;
77 	}
78 
79 	ret = cipher_begin_session(sec_ctx->dec.device, &sec_ctx->dec, CRYPTO_CIPHER_ALGO_AES,
80 				   CRYPTO_CIPHER_MODE_CCM, CRYPTO_CIPHER_OP_DECRYPT);
81 	if (ret) {
82 		NET_ERR("Could not setup decryption context");
83 		cipher_free_session(sec_ctx->enc.device, &sec_ctx->enc);
84 
85 		return ret;
86 	}
87 
88 	return 0;
89 }
90 
ieee802154_security_teardown_session(struct ieee802154_security_ctx * sec_ctx)91 void ieee802154_security_teardown_session(struct ieee802154_security_ctx *sec_ctx)
92 {
93 	if (sec_ctx->level == IEEE802154_SECURITY_LEVEL_NONE) {
94 		return;
95 	}
96 
97 	cipher_free_session(sec_ctx->enc.device, &sec_ctx->enc);
98 	cipher_free_session(sec_ctx->dec.device, &sec_ctx->dec);
99 	sec_ctx->level = IEEE802154_SECURITY_LEVEL_NONE;
100 }
101 
prepare_cipher_aead_pkt(uint8_t * frame,uint8_t level,uint8_t ll_hdr_len,uint8_t payload_len,uint8_t authtag_len,struct cipher_aead_pkt * apkt,struct cipher_pkt * pkt)102 static void prepare_cipher_aead_pkt(uint8_t *frame, uint8_t level, uint8_t ll_hdr_len,
103 				    uint8_t payload_len, uint8_t authtag_len,
104 				    struct cipher_aead_pkt *apkt, struct cipher_pkt *pkt)
105 {
106 	bool is_authenticated;
107 	bool is_encrypted;
108 
109 	__ASSERT_NO_MSG(level != IEEE802154_SECURITY_LEVEL_ENC);
110 
111 	is_encrypted = level > IEEE802154_SECURITY_LEVEL_ENC;
112 	is_authenticated = level != IEEE802154_SECURITY_LEVEL_NONE;
113 
114 	/* See section 9.3.5.3 */
115 	pkt->in_buf = is_encrypted && payload_len ? frame + ll_hdr_len : NULL;
116 	pkt->in_len = is_encrypted ? payload_len : 0;
117 
118 	/* See section 9.3.5.4 */
119 	uint8_t out_buf_offset = is_encrypted ? ll_hdr_len : ll_hdr_len + payload_len;
120 	uint8_t auth_len = is_authenticated ? out_buf_offset : 0;
121 
122 	pkt->out_buf = frame + out_buf_offset;
123 	pkt->out_buf_max = (is_encrypted ? payload_len : 0) + authtag_len;
124 
125 	apkt->ad = is_authenticated ? frame : NULL;
126 	apkt->ad_len = auth_len;
127 	apkt->tag = is_authenticated ? frame + ll_hdr_len + payload_len : NULL;
128 	apkt->pkt = pkt;
129 }
130 
ieee802154_decrypt_auth(struct ieee802154_security_ctx * sec_ctx,uint8_t * frame,uint8_t ll_hdr_len,uint8_t payload_len,uint8_t authtag_len,uint8_t * src_ext_addr,uint32_t frame_counter)131 bool ieee802154_decrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *frame,
132 			     uint8_t ll_hdr_len, uint8_t payload_len, uint8_t authtag_len,
133 			     uint8_t *src_ext_addr, uint32_t frame_counter)
134 {
135 	struct cipher_aead_pkt apkt;
136 	struct cipher_pkt pkt;
137 	uint8_t nonce[13];
138 	uint8_t level;
139 	int ret;
140 
141 	if (!sec_ctx || sec_ctx->level == IEEE802154_SECURITY_LEVEL_NONE) {
142 		return true;
143 	}
144 
145 	level = sec_ctx->level;
146 
147 	/* See section 9.3.3.1 */
148 	memcpy(nonce, src_ext_addr, IEEE802154_EXT_ADDR_LENGTH);
149 	sys_put_be32(frame_counter, &nonce[8]);
150 	nonce[12] = level;
151 
152 	prepare_cipher_aead_pkt(frame, level, ll_hdr_len, payload_len, authtag_len, &apkt, &pkt);
153 
154 	ret = cipher_ccm_op(&sec_ctx->dec, &apkt, nonce);
155 	if (ret) {
156 		NET_ERR("Cannot decrypt/auth (%i): %p %u/%u - fc %u", ret, frame, ll_hdr_len,
157 			payload_len, frame_counter);
158 		return false;
159 	}
160 
161 	return true;
162 }
163 
ieee802154_encrypt_auth(struct ieee802154_security_ctx * sec_ctx,uint8_t * frame,uint8_t ll_hdr_len,uint8_t payload_len,uint8_t authtag_len,uint8_t * src_ext_addr)164 bool ieee802154_encrypt_auth(struct ieee802154_security_ctx *sec_ctx, uint8_t *frame,
165 			     uint8_t ll_hdr_len, uint8_t payload_len, uint8_t authtag_len,
166 			     uint8_t *src_ext_addr)
167 {
168 	struct cipher_aead_pkt apkt;
169 	struct cipher_pkt pkt;
170 	uint8_t nonce[13];
171 	uint8_t level;
172 	int ret;
173 
174 	if (!sec_ctx || sec_ctx->level == IEEE802154_SECURITY_LEVEL_NONE) {
175 		return true;
176 	}
177 
178 	level = sec_ctx->level;
179 
180 	if (level == IEEE802154_SECURITY_LEVEL_RESERVED) {
181 		NET_DBG("Encryption-only security is deprecated since IEEE 802.15.4-2015.");
182 		return false;
183 	}
184 
185 	if (sec_ctx->frame_counter == 0xffffffff) {
186 		NET_ERR("Max frame counter reached. Update key material to reset the counter.");
187 		return false;
188 	}
189 
190 	/* See section 9.3.3.1 */
191 	memcpy(nonce, src_ext_addr, IEEE802154_EXT_ADDR_LENGTH);
192 	sys_put_be32(sec_ctx->frame_counter, &nonce[8]);
193 	nonce[12] = level;
194 
195 	prepare_cipher_aead_pkt(frame, level, ll_hdr_len, payload_len, authtag_len, &apkt, &pkt);
196 
197 	ret = cipher_ccm_op(&sec_ctx->enc, &apkt, nonce);
198 	if (ret) {
199 		NET_ERR("Cannot encrypt/auth (%i): %p %u/%u - fc %u", ret, frame, ll_hdr_len,
200 			payload_len, sec_ctx->frame_counter);
201 		return false;
202 	}
203 
204 	sec_ctx->frame_counter++;
205 
206 	return true;
207 }
208 
ieee802154_security_init(struct ieee802154_security_ctx * sec_ctx)209 int ieee802154_security_init(struct ieee802154_security_ctx *sec_ctx)
210 {
211 	const struct device *dev;
212 
213 	(void)memset(&sec_ctx->enc, 0, sizeof(struct cipher_ctx));
214 	(void)memset(&sec_ctx->dec, 0, sizeof(struct cipher_ctx));
215 
216 	dev = device_get_binding(CONFIG_NET_L2_IEEE802154_SECURITY_CRYPTO_DEV_NAME);
217 	if (!dev) {
218 		return -ENODEV;
219 	}
220 
221 	sec_ctx->enc.flags = crypto_query_hwcaps(dev);
222 	sec_ctx->dec.flags = crypto_query_hwcaps(dev);
223 
224 	sec_ctx->enc.mode_params.ccm_info.nonce_len = 13U;
225 	sec_ctx->dec.mode_params.ccm_info.nonce_len = 13U;
226 
227 	sec_ctx->enc.device = dev;
228 	sec_ctx->dec.device = dev;
229 
230 	return 0;
231 }
232