Branch data Line data Source code
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 <stdint.h>
13 : :
14 : : #include "edhoc/buffer_sizes.h"
15 : : #include "edhoc/edhoc_cose.h"
16 : : #include "edhoc/hkdf_info.h"
17 : : #include "edhoc/okm.h"
18 : : #include "edhoc/suites.h"
19 : : #include "edhoc/signature_or_mac_msg.h"
20 : : #include "edhoc/bstr_encode_decode.h"
21 : : #include "edhoc/int_encode_decode.h"
22 : :
23 : : #include "common/print_util.h"
24 : : #include "common/crypto_wrapper.h"
25 : : #include "common/oscore_edhoc_error.h"
26 : : #include "common/memcpy_s.h"
27 : :
28 : : #include "cbor/edhoc_encode_enc_structure.h"
29 : : #include "cbor/edhoc_encode_sig_structure.h"
30 : :
31 : : /**
32 : : * @brief Forms a serialized data structure from a set of
33 : : * data items and computes a MAC over it.
34 : : *
35 : : * @param[in] prk The key to be used for the mac.
36 : : * @param[in] c_r Connection identifier of the requester
37 : : * @param[in] th Transcript hash.
38 : : * @param[in] id_cred ID of the credential.
39 : : * @param[in] cred The credential.
40 : : * @param[in] ead External authorization data.
41 : : * @param mac_label An info label.
42 : : * @param static_dh True if static DH is used for authentication.
43 : : * @param suite The used crypto suite.
44 : : * @param[out] mac The computed mac.
45 : : * @return Ok or error code.
46 : : */
47 : 12 : static enum err mac(const struct byte_array *prk, const struct byte_array *c_r,
48 : : const struct byte_array *th,
49 : : const struct byte_array *id_cred,
50 : : const struct byte_array *cred, const struct byte_array *ead,
51 : : enum info_label mac_label, bool static_dh,
52 : : struct suite *suite, struct byte_array *mac)
53 : : {
54 : : /*encode th as bstr*/
55 [ + - - + : 12 : BYTE_ARRAY_NEW(th_enc, AS_BSTR_SIZE(HASH_SIZE), AS_BSTR_SIZE(th->len));
- - - + +
- - + - -
- + + - -
+ - - ]
56 [ - + ]: 12 : TRY(encode_bstr(th, &th_enc));
57 : :
58 : : /**/
59 [ - + - - : 12 : BYTE_ARRAY_NEW(context_mac, CONTEXT_MAC_SIZE,
- - - + -
+ - - - -
- + - + -
- - - ]
60 : : AS_BSTR_SIZE(c_r->len) + id_cred->len + cred->len +
61 : : ead->len + th_enc.len);
62 : 12 : uint32_t capacity = context_mac.len;
63 : 12 : context_mac.len = 0;
64 [ + + ]: 12 : if (c_r->len != 0) {
65 [ - + - - : 6 : BYTE_ARRAY_NEW(c_r_enc, AS_BSTR_SIZE(C_R_SIZE),
- - - + -
+ - - - -
- + - + -
- - - ]
66 : : AS_BSTR_SIZE(c_r->len));
67 [ - + ]: 6 : if (c_r_is_raw_int(c_r)) {
68 [ # # ]: 0 : TRY(encode_int((const int32_t *)c_r->ptr, c_r->len,
69 : : &c_r_enc));
70 : : } else {
71 [ - + ]: 6 : TRY(encode_bstr(c_r, &c_r_enc));
72 : : }
73 [ - + ]: 6 : TRY(byte_array_append(&context_mac, &c_r_enc, capacity));
74 : : }
75 [ - + ]: 12 : TRY(byte_array_append(&context_mac, id_cred, capacity));
76 [ - + ]: 12 : TRY(byte_array_append(&context_mac, &th_enc, capacity));
77 [ - + ]: 12 : TRY(byte_array_append(&context_mac, cred, capacity));
78 : :
79 [ - + ]: 12 : if (0 < ead->len) {
80 [ # # ]: 0 : TRY(byte_array_append(&context_mac, ead, capacity));
81 : : }
82 : :
83 : 12 : PRINT_ARRAY("MAC context", context_mac.ptr, context_mac.len);
84 : :
85 [ - + ]: 12 : if (static_dh) {
86 : 0 : mac->len = suite->edhoc_mac_len_static_dh;
87 : :
88 : : } else {
89 : 12 : mac->len = get_hash_len(suite->edhoc_hash);
90 : : }
91 : :
92 [ - + ]: 12 : TRY(edhoc_kdf(suite->edhoc_hash, prk, mac_label, &context_mac, mac));
93 : :
94 : 12 : PRINT_ARRAY("MAC 2/3", mac->ptr, mac->len);
95 : 12 : return ok;
96 : : }
97 : :
98 : : /**
99 : : * @brief Creates a byte array to be ready for signing.
100 : : *
101 : : * @param[in] th Transcript hash.
102 : : * @param[in] id_cred Id of the credential.
103 : : * @param[in] cred The credential.
104 : : * @param[in] ead External Authorization Data.
105 : : * @param[in] mac Message Authentication Code.
106 : : * @param[out] out The result.
107 : : * @return Ok or error code.
108 : : */
109 : 12 : static enum err signature_struct_gen(const struct byte_array *th,
110 : : const struct byte_array *id_cred,
111 : : const struct byte_array *cred,
112 : : const struct byte_array *ead,
113 : : const struct byte_array *mac,
114 : : struct byte_array *out)
115 : : {
116 [ - + ]: 12 : BYTE_ARRAY_NEW(th_enc, AS_BSTR_SIZE(HASH_SIZE),
117 : : AS_BSTR_SIZE(HASH_SIZE));
118 : :
119 [ - + ]: 12 : TRY(encode_bstr(th, &th_enc));
120 : :
121 [ - + - + ]: 12 : BYTE_ARRAY_NEW(tmp,
122 : : (CRED_MAX_SIZE + AS_BSTR_SIZE(HASH_SIZE) + EAD_SIZE),
123 : : (th_enc.len + cred->len + ead->len));
124 : :
125 : 12 : memcpy(tmp.ptr, th_enc.ptr, th_enc.len);
126 : 12 : memcpy(tmp.ptr + th_enc.len, cred->ptr, cred->len);
127 [ - + ]: 12 : if (ead->len != 0) {
128 : 0 : memcpy(tmp.ptr + th_enc.len + cred->len, ead->ptr, ead->len);
129 : : }
130 : :
131 : 12 : uint8_t context_str[] = { "Signature1" };
132 : 12 : struct byte_array str = BYTE_ARRAY_INIT(
133 : : context_str, (uint32_t)strlen((char *)context_str));
134 : :
135 [ - + ]: 12 : TRY(cose_sig_structure_encode(&str, id_cred, &tmp, mac, out));
136 : 12 : PRINT_ARRAY("COSE_Sign1 object to be signed", out->ptr, out->len);
137 : 12 : return ok;
138 : : }
139 : :
140 : : enum err
141 : 12 : signature_or_mac(enum sgn_or_mac_op op, bool static_dh, struct suite *suite,
142 : : const struct byte_array *sk, const struct byte_array *pk,
143 : : const struct byte_array *prk, const struct byte_array *c_r,
144 : : const struct byte_array *th, const struct byte_array *id_cred,
145 : : const struct byte_array *cred, const struct byte_array *ead,
146 : : enum info_label mac_label, struct byte_array *signature_or_mac)
147 : : {
148 [ + + ]: 12 : if (op == GENERATE) {
149 : : /*we always calculate the mac*/
150 [ - + ]: 6 : TRY(mac(prk, c_r, th, id_cred, cred, ead, mac_label, static_dh,
151 : : suite, signature_or_mac));
152 : :
153 [ - + ]: 6 : if (static_dh) {
154 : : /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
155 : 0 : return ok;
156 : : } else {
157 : 6 : PRINTF("SIG_STRUCT_SIZE: %d\n", SIG_STRUCT_SIZE);
158 [ + - + + : 6 : uint32_t sig_struct_size = SIG_STRUCT_SIZE_CALC(
+ - + - -
+ - - + -
+ - - + -
- + - + -
- + - - +
- + - - +
- - + - -
+ - - ]
159 : : COSE_SIGN1_STR_LEN, id_cred->len,
160 : : (AS_BSTR_SIZE(th->len) + cred->len + ead->len),
161 : : signature_or_mac->len);
162 : :
163 : 6 : PRINTF("sig_struct_size: %d\n", sig_struct_size);
164 [ - + - + ]: 6 : BYTE_ARRAY_NEW(sign_struct, SIG_STRUCT_SIZE,
165 : : sig_struct_size);
166 [ - + ]: 6 : TRY(signature_struct_gen(th, id_cred, cred, ead,
167 : : signature_or_mac,
168 : : &sign_struct));
169 : :
170 : 6 : signature_or_mac->len =
171 : 6 : get_signature_len(suite->edhoc_sign);
172 : :
173 [ - + ]: 6 : TRY(sign(suite->edhoc_sign, sk, pk, &sign_struct,
174 : : signature_or_mac->ptr));
175 : 6 : PRINT_ARRAY("signature_or_mac (is signature)",
176 : : signature_or_mac->ptr,
177 : : signature_or_mac->len);
178 : : }
179 : : } else { /*we verify here*/
180 [ - + - + ]: 6 : BYTE_ARRAY_NEW(_mac, HASH_SIZE,
181 : : get_hash_len(suite->edhoc_hash));
182 : :
183 [ - + ]: 6 : TRY(mac(prk, c_r, th, id_cred, cred, ead, mac_label, static_dh,
184 : : suite, &_mac));
185 : :
186 [ - + ]: 6 : if (static_dh) {
187 : : /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
188 : :
189 [ # # ]: 0 : if (0 != memcmp(_mac.ptr, signature_or_mac->ptr,
190 : : signature_or_mac->len)) {
191 : 0 : return mac_authentication_failed;
192 : : }
193 : :
194 : : } else {
195 : 6 : PRINTF("SIG_STRUCT_SIZE: %d\n", SIG_STRUCT_SIZE);
196 [ + - + + : 6 : uint32_t sig_struct_size = SIG_STRUCT_SIZE_CALC(
+ - + - -
+ - - + -
+ - - + -
- + - + -
- + - - +
- + - - +
- - + - -
+ - - ]
197 : : COSE_SIGN1_STR_LEN, id_cred->len,
198 : : (AS_BSTR_SIZE(th->len) + cred->len + ead->len),
199 : : _mac.len);
200 : :
201 : 6 : PRINTF("sig_struct_size: %d\n", sig_struct_size);
202 [ - + - + ]: 6 : BYTE_ARRAY_NEW(sign_struct, SIG_STRUCT_SIZE,
203 : : sig_struct_size);
204 [ - + ]: 6 : TRY(signature_struct_gen(th, id_cred, cred, ead, &_mac,
205 : : &sign_struct));
206 : :
207 : : bool result;
208 : 6 : PRINT_ARRAY("pk", pk->ptr, pk->len);
209 : 6 : PRINT_ARRAY("signature_struct", sign_struct.ptr,
210 : : sign_struct.len);
211 : 6 : PRINT_ARRAY("signature_or_mac", signature_or_mac->ptr,
212 : : signature_or_mac->len);
213 : :
214 [ - + ]: 6 : TRY(verify(suite->edhoc_sign, pk,
215 : : (struct const_byte_array *)&sign_struct,
216 : : (struct const_byte_array *)signature_or_mac,
217 : : &result));
218 [ - + ]: 6 : if (!result) {
219 : 0 : return signature_authentication_failed;
220 : : }
221 : 6 : PRINT_MSG(
222 : : "Signature or MAC verification successful!\n");
223 : : }
224 : : }
225 : 12 : return ok;
226 : : }
|