1 /*
2    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3    file at the top-level directory of this distribution.
4 
5    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8    option. This file may not be copied, modified, or distributed
9    except according to those terms.
10 */
11 
12 #include "edhoc.h"
13 
14 #include "edhoc/c_x.h"
15 #include "edhoc/th.h"
16 
17 #include "common/crypto_wrapper.h"
18 #include "common/oscore_edhoc_error.h"
19 #include "common/memcpy_s.h"
20 #include "common/print_util.h"
21 
22 #include "cbor/edhoc_encode_data_2.h"
23 #include "cbor/edhoc_encode_th2.h"
24 #include "cbor/edhoc_encode_th3.h"
25 #include "cbor/edhoc_encode_th4.h"
26 
27 /**
28  * @brief   Setups a data structure used as input for th2, namely CBOR sequence
29  *          (H(message_1), G_Y, C_R)
30  * @param   msg1 pointer to a message 1
31  * @param   msg1_len length of message 1
32  * @param   c_i Pointer to the conception identifier of the initiator
33  * @param   g_y Pointer to the public DH parameter
34  * @param   c_r Pointer to the conception identifier of the responder
35  * @param   th2_input ouput buffer for the data structure
36  * @param   th2_input_len length of th2_input
37  */
th2_input_encode(uint8_t * hash_msg1,uint32_t hash_msg1_len,uint8_t * g_y,uint32_t g_y_len,struct c_x * c_r,uint8_t * th2_input,uint32_t * th2_input_len)38 static inline enum err th2_input_encode(uint8_t *hash_msg1,
39 					uint32_t hash_msg1_len, uint8_t *g_y,
40 					uint32_t g_y_len, struct c_x *c_r,
41 					uint8_t *th2_input,
42 					uint32_t *th2_input_len)
43 {
44 	size_t payload_len_out;
45 	struct th2 th2;
46 
47 	/*Encode hash_msg1*/
48 	th2._th2_hash_msg1.value = hash_msg1;
49 	th2._th2_hash_msg1.len = hash_msg1_len;
50 
51 	/*Encode G_Y*/
52 	th2._th2_G_Y.value = g_y;
53 	th2._th2_G_Y.len = g_y_len;
54 
55 	/*Encode C_R as int or byte*/
56 	if (c_r->type == INT) {
57 		th2._th2_C_R_choice = _th2_C_R_int;
58 		th2._th2_C_R_int = c_r->mem.c_x_int;
59 	} else {
60 		th2._th2_C_R_choice = _th2_C_R_bstr;
61 		th2._th2_C_R_bstr.value = c_r->mem.c_x_bstr.ptr;
62 		th2._th2_C_R_bstr.len = c_r->mem.c_x_bstr.len;
63 	}
64 	TRY_EXPECT(cbor_encode_th2(th2_input, *th2_input_len, &th2,
65 				   &payload_len_out),
66 		   true);
67 
68 	/* Get the the total th2 length */
69 	*th2_input_len = (uint32_t) payload_len_out;
70 
71 	PRINT_ARRAY("Input to calculate TH_2 (CBOR Sequence)", th2_input,
72 		    *th2_input_len);
73 	return ok;
74 }
75 
76 /**
77  * @brief   Setups a data structure used as input for th3
78  * @param   th2 pointer to a th2
79  * @param   th2_len length of th2
80  * @param   ciphertext_2
81  * @param   ciphertext_2_len  length of ciphertext_2_len
82  * @param   data_3
83  * @param   data_3_len  length of data_3_len
84  * @param   th3_input ouput buffer for the data structure
85  * @param   th3_input_len length of th3_input
86  */
th3_input_encode(uint8_t * th2,uint32_t th2_len,uint8_t * ciphertext_2,uint32_t ciphertext_2_len,uint8_t * th3_input,uint32_t * th3_input_len)87 static inline enum err th3_input_encode(uint8_t *th2, uint32_t th2_len,
88 					uint8_t *ciphertext_2,
89 					uint32_t ciphertext_2_len,
90 					uint8_t *th3_input,
91 					uint32_t *th3_input_len)
92 {
93 	struct th3 th3;
94 
95 	/*Encode th2*/
96 	th3._th3_th_2.value = th2;
97 	th3._th3_th_2.len = th2_len;
98 
99 	/*Encode ciphertext_2*/
100 	th3._th3_CIPHERTEXT_2.value = ciphertext_2;
101 	th3._th3_CIPHERTEXT_2.len = ciphertext_2_len;
102 
103 	size_t payload_len_out;
104 	TRY_EXPECT(cbor_encode_th3(th3_input, *th3_input_len, &th3,
105 				   &payload_len_out),
106 		   true);
107 	*th3_input_len = (uint32_t) payload_len_out;
108 
109 	PRINT_ARRAY("Input to calculate TH_3 (CBOR Sequence)", th3_input,
110 		    *th3_input_len);
111 	return ok;
112 }
113 
114 /**
115  * @brief   Setups a data structure used as input for th4
116  * @param   th3 pointer to a th3
117  * @param   th3_len length of th3
118  * @param   ciphertext_3
119  * @param   ciphertext_3_len  length of ciphertext_3_len
120  * @param   th4_input ouput buffer for the data structure
121  * @param   th4_input_len length of th4_input
122  */
th4_input_encode(uint8_t * th3,uint32_t th3_len,uint8_t * ciphertext_3,uint32_t ciphertext_3_len,uint8_t * th4_input,uint32_t * th4_input_len)123 static inline enum err th4_input_encode(uint8_t *th3, uint32_t th3_len,
124 					uint8_t *ciphertext_3,
125 					uint32_t ciphertext_3_len,
126 					uint8_t *th4_input,
127 					uint32_t *th4_input_len)
128 {
129 	struct th4 th4;
130 
131 	/*Encode th2*/
132 	th4._th4_th_3.value = th3;
133 	th4._th4_th_3.len = th3_len;
134 
135 	/*Encode ciphertext_3*/
136 	th4._th4_CIPHERTEXT_3.value = ciphertext_3;
137 	th4._th4_CIPHERTEXT_3.len = ciphertext_3_len;
138 
139 	size_t payload_len_out;
140 	TRY_EXPECT(cbor_encode_th4(th4_input, *th4_input_len, &th4,
141 				   &payload_len_out),
142 		   true);
143 
144 	*th4_input_len = (uint32_t) payload_len_out;
145 
146 	PRINT_ARRAY("Input to calculate TH_4 (CBOR Sequence)", th4_input,
147 		    *th4_input_len);
148 	return ok;
149 }
150 
th2_calculate(enum hash_alg alg,uint8_t * msg1,uint32_t msg1_len,uint8_t * g_y,uint32_t g_y_len,struct c_x * c_r,uint8_t * th2)151 enum err th2_calculate(enum hash_alg alg, uint8_t *msg1, uint32_t msg1_len,
152 		       uint8_t *g_y, uint32_t g_y_len, struct c_x *c_r,
153 		       uint8_t *th2)
154 {
155 	uint8_t th2_input[TH2_INPUT_DEFAULT_SIZE];
156 	uint32_t th2_input_len = sizeof(th2_input);
157 
158 	uint8_t hash_msg1[SHA_DEFAULT_SIZE];
159 	TRY(hash(alg, msg1, msg1_len, hash_msg1));
160 	PRINT_ARRAY("hash_msg1_raw", hash_msg1, SHA_DEFAULT_SIZE);
161 	TRY(th2_input_encode(hash_msg1, sizeof(hash_msg1), g_y, g_y_len, c_r,
162 			     th2_input, &th2_input_len));
163 	TRY(hash(alg, th2_input, th2_input_len, th2));
164 	PRINT_ARRAY("TH2", th2, SHA_DEFAULT_SIZE);
165 	return ok;
166 }
167 
th3_calculate(enum hash_alg alg,uint8_t * th2,uint32_t th2_len,uint8_t * ciphertext_2,uint32_t ciphertext_2_len,uint8_t * th3)168 enum err th3_calculate(enum hash_alg alg, uint8_t *th2, uint32_t th2_len,
169 		       uint8_t *ciphertext_2, uint32_t ciphertext_2_len,
170 		       uint8_t *th3)
171 {
172 	uint32_t th3_input_len = th2_len + ciphertext_2_len + 6;
173 	TRY(check_buffer_size(TH3_INPUT_DEFAULT_SIZE, th3_input_len));
174 	uint8_t th3_input[TH3_INPUT_DEFAULT_SIZE];
175 
176 	TRY(th3_input_encode(th2, th2_len, ciphertext_2, ciphertext_2_len,
177 			     th3_input, &th3_input_len));
178 	TRY(hash(alg, th3_input, th3_input_len, th3));
179 	PRINT_ARRAY("TH3", th3, SHA_DEFAULT_SIZE);
180 	return ok;
181 }
182 
th4_calculate(enum hash_alg alg,uint8_t * th3,uint32_t th3_len,uint8_t * ciphertext_3,uint32_t ciphertext_3_len,uint8_t * th4)183 enum err th4_calculate(enum hash_alg alg, uint8_t *th3, uint32_t th3_len,
184 		       uint8_t *ciphertext_3, uint32_t ciphertext_3_len,
185 		       uint8_t *th4)
186 {
187 	uint32_t th4_input_len = th3_len + ciphertext_3_len + ENCODING_OVERHEAD;
188 	TRY(check_buffer_size(TH4_INPUT_DEFAULT_SIZE, th4_input_len));
189 	uint8_t th4_input[TH4_INPUT_DEFAULT_SIZE];
190 
191 	TRY(th4_input_encode(th3, th3_len, ciphertext_3, ciphertext_3_len,
192 			     th4_input, &th4_input_len));
193 	TRY(hash(alg, th4_input, th4_input_len, th4));
194 	PRINT_ARRAY("TH4", th4, SHA_DEFAULT_SIZE);
195 	return ok;
196 }
197