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