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