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.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
22 #include "common/print_util.h"
23 #include "common/crypto_wrapper.h"
24 #include "common/oscore_edhoc_error.h"
25 #include "common/memcpy_s.h"
26
27 #include "cbor/edhoc_encode_enc_structure.h"
28 #include "cbor/edhoc_encode_sig_structure.h"
29
mac(const uint8_t * prk,uint32_t prk_len,const uint8_t * th,uint32_t th_len,const uint8_t * id_cred,uint32_t id_cred_len,const uint8_t * cred,uint32_t cred_len,const uint8_t * ead,uint32_t ead_len,enum info_label mac_label,bool static_dh,struct suite * suite,uint8_t * mac,uint32_t * mac_len)30 enum err mac(const uint8_t *prk, uint32_t prk_len, const uint8_t *th,
31 uint32_t th_len, const uint8_t *id_cred, uint32_t id_cred_len,
32 const uint8_t *cred, uint32_t cred_len, const uint8_t *ead,
33 uint32_t ead_len, enum info_label mac_label, bool static_dh,
34 struct suite *suite, uint8_t *mac, uint32_t *mac_len)
35 {
36 /*encode th as bstr*/
37 uint32_t th_encoded_len = th_len + 2;
38 TRY(check_buffer_size(HASH_DEFAULT_SIZE + 2, th_encoded_len));
39 uint8_t th_encoded[HASH_DEFAULT_SIZE + 2];
40 TRY(encode_byte_string(th, th_len, th_encoded, &th_encoded_len));
41
42 /**/
43 uint32_t context_mac_len =
44 id_cred_len + cred_len + ead_len + th_encoded_len;
45 TRY(check_buffer_size(CONTEXT_MAC_DEFAULT_SIZE, context_mac_len));
46 uint8_t context_mac[CONTEXT_MAC_DEFAULT_SIZE];
47 TRY(_memcpy_s(context_mac, context_mac_len, id_cred, id_cred_len));
48
49 TRY(_memcpy_s((context_mac + id_cred_len),
50 (context_mac_len - id_cred_len), th_encoded,
51 th_encoded_len));
52
53 TRY(_memcpy_s((context_mac + id_cred_len + th_encoded_len),
54 (context_mac_len - id_cred_len - th_encoded_len), cred,
55 cred_len));
56
57 if (0 < ead_len) {
58 TRY(_memcpy_s(
59 (context_mac + id_cred_len + th_encoded_len + cred_len),
60 (context_mac_len - id_cred_len - th_encoded_len - cred_len),
61 ead, ead_len));
62 }
63
64
65 PRINT_ARRAY("MAC context", context_mac, context_mac_len);
66
67 if (static_dh) {
68 *mac_len = suite->edhoc_mac_len_static_dh;
69
70 } else {
71 *mac_len = get_hash_len(suite->edhoc_hash);
72 }
73
74 TRY(edhoc_kdf(suite->edhoc_hash, prk, prk_len, mac_label, context_mac,
75 context_mac_len, *mac_len, mac));
76
77 PRINT_ARRAY("MAC 2/3", mac, *mac_len);
78 return ok;
79 }
80
signature_struct_gen(const uint8_t * th,uint32_t th_len,const uint8_t * id_cred,uint32_t id_cred_len,const uint8_t * cred,uint32_t cred_len,const uint8_t * ead,uint32_t ead_len,const uint8_t * mac,uint32_t mac_len,uint8_t * out,uint32_t * out_len)81 static enum err signature_struct_gen(const uint8_t *th, uint32_t th_len,
82 const uint8_t *id_cred,
83 uint32_t id_cred_len, const uint8_t *cred,
84 uint32_t cred_len, const uint8_t *ead,
85 uint32_t ead_len, const uint8_t *mac,
86 uint32_t mac_len, uint8_t *out,
87 uint32_t *out_len)
88 {
89 uint8_t th_enc[HASH_DEFAULT_SIZE + 2];
90 uint32_t th_enc_len = sizeof(th_enc);
91
92 TRY(encode_byte_string(th, th_len, th_enc, &th_enc_len));
93
94 uint32_t tmp_len = th_enc_len + cred_len + ead_len;
95
96 TRY(check_buffer_size(CRED_DEFAULT_SIZE + HASH_DEFAULT_SIZE +
97 AD_DEFAULT_SIZE,
98 tmp_len));
99 uint8_t tmp[CRED_DEFAULT_SIZE + HASH_DEFAULT_SIZE + AD_DEFAULT_SIZE];
100
101 memcpy(tmp, th_enc, th_enc_len);
102 memcpy(tmp + th_enc_len, cred, cred_len);
103 if (ead_len != 0) {
104 memcpy(tmp + th_enc_len + cred_len, ead, ead_len);
105 }
106
107 uint8_t context_str[] = { "Signature1" };
108 TRY(cose_sig_structure_encode(
109 context_str, (uint32_t)strlen((char *)context_str), id_cred,
110 id_cred_len, tmp, tmp_len, mac, mac_len, out, out_len));
111 PRINT_ARRAY("COSE_Sign1 object to be signed", out, *out_len);
112 return ok;
113 }
114
signature_or_mac(enum sgn_or_mac_op op,bool static_dh,struct suite * suite,const uint8_t * sk,uint32_t sk_len,const uint8_t * pk,uint32_t pk_len,const uint8_t * prk,uint32_t prk_len,const uint8_t * th,uint32_t th_len,const uint8_t * id_cred,uint32_t id_cred_len,const uint8_t * cred,uint32_t cred_len,const uint8_t * ead,uint32_t ead_len,enum info_label mac_label,uint8_t * signature_or_mac,uint32_t * signature_or_mac_len)115 enum err signature_or_mac(enum sgn_or_mac_op op, bool static_dh,
116 struct suite *suite, const uint8_t *sk,
117 uint32_t sk_len, const uint8_t *pk, uint32_t pk_len,
118 const uint8_t *prk, uint32_t prk_len,
119 const uint8_t *th, uint32_t th_len,
120 const uint8_t *id_cred, uint32_t id_cred_len,
121 const uint8_t *cred, uint32_t cred_len,
122 const uint8_t *ead, uint32_t ead_len,
123 enum info_label mac_label, uint8_t *signature_or_mac,
124 uint32_t *signature_or_mac_len)
125 {
126 if (op == GENERATE) {
127 /*we always calculate the mac*/
128 TRY(mac(prk, prk_len, th, th_len, id_cred, id_cred_len, cred,
129 cred_len, ead, ead_len, mac_label, static_dh, suite,
130 signature_or_mac, signature_or_mac_len));
131
132 if (static_dh) {
133 /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
134 return ok;
135 } else {
136 uint8_t signature_struct[SIGNATURE_STRUCT_DEFAULT_SIZE];
137 uint32_t signature_struct_len =
138 sizeof(signature_struct);
139 TRY(signature_struct_gen(
140 th, th_len, id_cred, id_cred_len, cred,
141 cred_len, ead, ead_len, signature_or_mac,
142 *signature_or_mac_len, signature_struct,
143 &signature_struct_len));
144
145 *signature_or_mac_len =
146 get_signature_len(suite->edhoc_sign);
147
148 TRY(sign(suite->edhoc_sign, sk, sk_len, pk,
149 signature_struct, signature_struct_len,
150 signature_or_mac));
151 PRINT_ARRAY("signature_or_mac (is signature)",
152 signature_or_mac, *signature_or_mac_len);
153 }
154 } else { /*we verify here*/
155 uint32_t mac_buf_len = get_hash_len(suite->edhoc_hash);
156 TRY(check_buffer_size(HASH_DEFAULT_SIZE, mac_buf_len));
157 uint8_t mac_buf[HASH_DEFAULT_SIZE];
158
159 TRY(mac(prk, prk_len, th, th_len, id_cred, id_cred_len, cred,
160 cred_len, ead, ead_len, mac_label, static_dh, suite,
161 mac_buf, &mac_buf_len));
162
163 if (static_dh) {
164 /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
165
166 if (0 != memcmp(mac_buf, signature_or_mac,
167 *signature_or_mac_len)) {
168 return mac_authentication_failed;
169 }
170
171 } else {
172 uint8_t signature_struct[SIGNATURE_STRUCT_DEFAULT_SIZE];
173 uint32_t signature_struct_len =
174 sizeof(signature_struct);
175 TRY(signature_struct_gen(
176 th, th_len, id_cred, id_cred_len, cred,
177 cred_len, ead, ead_len, mac_buf, mac_buf_len,
178 signature_struct, &signature_struct_len));
179
180 bool result;
181 PRINT_ARRAY("pk", pk, pk_len);
182 PRINT_ARRAY("signature_struct", signature_struct,
183 signature_struct_len);
184 PRINT_ARRAY("signature_or_mac", signature_or_mac,
185 *signature_or_mac_len);
186
187 TRY(verify(suite->edhoc_sign, pk, pk_len,
188 signature_struct, signature_struct_len,
189 signature_or_mac, *signature_or_mac_len,
190 &result));
191 if (!result) {
192 return signature_authentication_failed;
193 }
194 PRINT_MSG(
195 "Signature or MAC verification successful!\n");
196 }
197 }
198 return ok;
199 }
200