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/buffer_sizes.h"
13 
14 #include "edhoc/th.h"
15 #include "edhoc/bstr_encode_decode.h"
16 #include "edhoc/int_encode_decode.h"
17 
18 #include "common/crypto_wrapper.h"
19 #include "common/oscore_edhoc_error.h"
20 #include "common/memcpy_s.h"
21 #include "common/print_util.h"
22 
23 #include "cbor/edhoc_encode_data_2.h"
24 #include "cbor/edhoc_encode_th2.h"
25 
26 /**
27  * @brief   			Setups a data structure used as input for th2,
28  * 				namely CBOR sequence H( G_Y, C_R, H(message_1)).
29  *
30  * @param[in] hash_msg1 	Hash of message 1.
31  * @param[in] g_y 		Ephemeral public DH key.
32  * @param[out] th2_input	The result.
33  * @retval			Ok or error.
34  */
th2_input_encode(struct byte_array * hash_msg1,struct byte_array * g_y,struct byte_array * th2_input)35 static inline enum err th2_input_encode(struct byte_array *hash_msg1,
36 					struct byte_array *g_y,
37 					struct byte_array *th2_input)
38 {
39 	size_t payload_len_out;
40 	struct th2 th2;
41 
42 	/*Encode hash_msg1*/
43 	th2.th2_hash_msg1.value = hash_msg1->ptr;
44 	th2.th2_hash_msg1.len = hash_msg1->len;
45 
46 	/*Encode G_Y*/
47 	th2.th2_G_Y.value = g_y->ptr;
48 	th2.th2_G_Y.len = g_y->len;
49 
50 	TRY_EXPECT(cbor_encode_th2(th2_input->ptr, th2_input->len, &th2,
51 				   &payload_len_out),
52 		   0);
53 
54 	/* Get the the total th2 length */
55 	th2_input->len = (uint32_t)payload_len_out;
56 
57 	PRINT_ARRAY("Input to calculate TH_2 (CBOR Sequence)", th2_input->ptr,
58 		    th2_input->len);
59 	return ok;
60 }
61 
62 /**
63  * @brief   			Setups a data structure used as input for
64  * 				th3 or th4.
65  *
66  * @param[in] th23 		th2 or th3.
67  * @param[in] plaintext_23 	Plaintext 2 or plaintext 3.
68  * @param[in] cred		The credential.
69  * @param[out] th34_input 	The result.
70  * @retval			Ok or error code.
71  */
th34_input_encode(struct byte_array * th23,struct byte_array * plaintext_23,const struct byte_array * cred,struct byte_array * th34_input)72 static enum err th34_input_encode(struct byte_array *th23,
73 				  struct byte_array *plaintext_23,
74 				  const struct byte_array *cred,
75 				  struct byte_array *th34_input)
76 {
77 	PRINT_ARRAY("th23", th23->ptr, th23->len);
78 	PRINT_ARRAY("plaintext_23", plaintext_23->ptr, plaintext_23->len);
79 	PRINT_ARRAY("cred", cred->ptr, cred->len);
80 
81 	TRY(encode_bstr(th23, th34_input));
82 	uint32_t tmp_len = th34_input->len;
83 
84 	TRY(_memcpy_s(th34_input->ptr + tmp_len,
85 		      th34_input->len - tmp_len - cred->len, plaintext_23->ptr,
86 		      plaintext_23->len));
87 
88 	tmp_len += plaintext_23->len;
89 
90 	TRY(_memcpy_s(th34_input->ptr + tmp_len, th34_input->len - tmp_len,
91 		      cred->ptr, cred->len));
92 
93 	th34_input->len = tmp_len + cred->len;
94 
95 	PRINT_ARRAY("Input to calculate TH_3/TH_4 (CBOR Sequence)",
96 		    th34_input->ptr, th34_input->len);
97 	return ok;
98 }
99 
100 /**
101  * @brief 			Computes TH_3 or TH4. Where:
102  * 				TH_3 = H(TH_2, PLAINTEXT_2)
103  * 				TH_4 = H(TH_3, PLAINTEXT_3)
104  *
105  * @param alg 			The hash algorithm to be used.
106  * @param[in] th23 		th2 if we compute TH_3, th3 if we compute TH_4.
107  * @param[in] plaintext_23 	The plaintext.
108  * @param[in] cred		The credential.
109  * @param[out] th34 		The result.
110  * @return 			Ok or error.
111  */
th34_calculate(enum hash_alg alg,struct byte_array * th23,struct byte_array * plaintext_23,const struct byte_array * cred,struct byte_array * th34)112 enum err th34_calculate(enum hash_alg alg, struct byte_array *th23,
113 			struct byte_array *plaintext_23,
114 			const struct byte_array *cred, struct byte_array *th34)
115 {
116 	uint32_t th34_input_len =
117 		AS_BSTR_SIZE(get_hash_len(alg)) + plaintext_23->len + cred->len;
118 	BYTE_ARRAY_NEW(th34_input, TH34_INPUT_SIZE, th34_input_len);
119 
120 	TRY(th34_input_encode(th23, plaintext_23, cred, &th34_input));
121 	TRY(hash(alg, &th34_input, th34));
122 	PRINT_ARRAY("TH34", th34->ptr, th34->len);
123 	return ok;
124 }
125 
th2_calculate(enum hash_alg alg,struct byte_array * msg1_hash,struct byte_array * g_y,struct byte_array * th2)126 enum err th2_calculate(enum hash_alg alg, struct byte_array *msg1_hash,
127 		       struct byte_array *g_y, struct byte_array *th2)
128 {
129 	BYTE_ARRAY_NEW(th2_input, TH2_INPUT_SIZE,
130 		       AS_BSTR_SIZE(g_y->len) +
131 			       AS_BSTR_SIZE(get_hash_len(alg)));
132 	PRINT_ARRAY("hash_msg1_raw", msg1_hash->ptr, msg1_hash->len);
133 	TRY(th2_input_encode(msg1_hash, g_y, &th2_input));
134 	TRY(hash(alg, &th2_input, th2));
135 	PRINT_ARRAY("TH2", th2->ptr, th2->len);
136 	return ok;
137 }
138