1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker */
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
26*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-cose.h"
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_sign_context *
lws_cose_sign_create(const lws_cose_sign_create_info_t * info)29*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_create(const lws_cose_sign_create_info_t *info)
30*1c60b9acSAndroid Build Coastguard Worker {
31*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_sign_context *csc;
32*1c60b9acSAndroid Build Coastguard Worker
33*1c60b9acSAndroid Build Coastguard Worker /* you have to have prepared a cbor output context for us to use */
34*1c60b9acSAndroid Build Coastguard Worker assert(info->lec);
35*1c60b9acSAndroid Build Coastguard Worker /* you have to provide at least one key in a cose_keyset */
36*1c60b9acSAndroid Build Coastguard Worker assert(info->keyset);
37*1c60b9acSAndroid Build Coastguard Worker /* you have to provide an lws_context (for crypto random) */
38*1c60b9acSAndroid Build Coastguard Worker assert(info->cx);
39*1c60b9acSAndroid Build Coastguard Worker
40*1c60b9acSAndroid Build Coastguard Worker if (info->sigtype == SIGTYPE_MAC) {
41*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: only mac0 supported for signing\n", __func__);
42*1c60b9acSAndroid Build Coastguard Worker return NULL;
43*1c60b9acSAndroid Build Coastguard Worker }
44*1c60b9acSAndroid Build Coastguard Worker
45*1c60b9acSAndroid Build Coastguard Worker csc = lws_zalloc(sizeof(*csc), __func__);
46*1c60b9acSAndroid Build Coastguard Worker if (!csc)
47*1c60b9acSAndroid Build Coastguard Worker return NULL;
48*1c60b9acSAndroid Build Coastguard Worker
49*1c60b9acSAndroid Build Coastguard Worker csc->info = *info;
50*1c60b9acSAndroid Build Coastguard Worker
51*1c60b9acSAndroid Build Coastguard Worker return csc;
52*1c60b9acSAndroid Build Coastguard Worker }
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker int
lws_cose_sign_add(struct lws_cose_sign_context * csc,cose_param_t alg,const lws_cose_key_t * ck)55*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_add(struct lws_cose_sign_context *csc, cose_param_t alg,
56*1c60b9acSAndroid Build Coastguard Worker const lws_cose_key_t *ck)
57*1c60b9acSAndroid Build Coastguard Worker {
58*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *si = lws_cose_sign_alg_create(csc->info.cx, ck, alg,
59*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKKO_SIGN);
60*1c60b9acSAndroid Build Coastguard Worker
61*1c60b9acSAndroid Build Coastguard Worker if (!si)
62*1c60b9acSAndroid Build Coastguard Worker return 1;
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_tail(&si->list, &csc->algs);
65*1c60b9acSAndroid Build Coastguard Worker
66*1c60b9acSAndroid Build Coastguard Worker return 0;
67*1c60b9acSAndroid Build Coastguard Worker }
68*1c60b9acSAndroid Build Coastguard Worker
69*1c60b9acSAndroid Build Coastguard Worker static signed char cose_tags[] = {
70*1c60b9acSAndroid Build Coastguard Worker 0,
71*1c60b9acSAndroid Build Coastguard Worker LWSCOAP_CONTENTFORMAT_COSE_SIGN,
72*1c60b9acSAndroid Build Coastguard Worker LWSCOAP_CONTENTFORMAT_COSE_SIGN1,
73*1c60b9acSAndroid Build Coastguard Worker LWSCOAP_CONTENTFORMAT_COSE_SIGN,
74*1c60b9acSAndroid Build Coastguard Worker LWSCOAP_CONTENTFORMAT_COSE_MAC,
75*1c60b9acSAndroid Build Coastguard Worker LWSCOAP_CONTENTFORMAT_COSE_MAC0
76*1c60b9acSAndroid Build Coastguard Worker };
77*1c60b9acSAndroid Build Coastguard Worker
78*1c60b9acSAndroid Build Coastguard Worker static void
lws_cose_sign_hashing(struct lws_cose_sign_context * csc,const uint8_t * in,size_t in_len)79*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(struct lws_cose_sign_context *csc,
80*1c60b9acSAndroid Build Coastguard Worker const uint8_t *in, size_t in_len)
81*1c60b9acSAndroid Build Coastguard Worker {
82*1c60b9acSAndroid Build Coastguard Worker //lwsl_hexdump_warn(in, in_len);
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard Worker assert(in_len);
85*1c60b9acSAndroid Build Coastguard Worker
86*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
87*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&csc->algs)) {
88*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg = lws_container_of(p,
89*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
90*1c60b9acSAndroid Build Coastguard Worker
91*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_sign_alg_hash(alg, in, in_len))
92*1c60b9acSAndroid Build Coastguard Worker alg->failed = 1;
93*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
94*1c60b9acSAndroid Build Coastguard Worker }
95*1c60b9acSAndroid Build Coastguard Worker
96*1c60b9acSAndroid Build Coastguard Worker /*
97*1c60b9acSAndroid Build Coastguard Worker * These chunks may be payload or application AAD being emitted into the
98*1c60b9acSAndroid Build Coastguard Worker * signed object somewhere else. But we do not emit them ourselves here
99*1c60b9acSAndroid Build Coastguard Worker * (since other non-emitted things are also hashed by us) and so can always
100*1c60b9acSAndroid Build Coastguard Worker * deal with the whole in_len in one step.
101*1c60b9acSAndroid Build Coastguard Worker */
102*1c60b9acSAndroid Build Coastguard Worker
103*1c60b9acSAndroid Build Coastguard Worker enum lws_lec_pctx_ret
lws_cose_sign_payload_chunk(struct lws_cose_sign_context * csc,const uint8_t * in,size_t in_len)104*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_payload_chunk(struct lws_cose_sign_context *csc,
105*1c60b9acSAndroid Build Coastguard Worker const uint8_t *in, size_t in_len)
106*1c60b9acSAndroid Build Coastguard Worker {
107*1c60b9acSAndroid Build Coastguard Worker uint8_t lbuf[MAX_BLOBBED_PARAMS], lb[9];
108*1c60b9acSAndroid Build Coastguard Worker const struct lws_gencrypto_keyelem *ke;
109*1c60b9acSAndroid Build Coastguard Worker enum lws_lec_pctx_ret ret;
110*1c60b9acSAndroid Build Coastguard Worker lws_lec_pctx_t lec, lec1;
111*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg;
112*1c60b9acSAndroid Build Coastguard Worker uint8_t c;
113*1c60b9acSAndroid Build Coastguard Worker size_t s;
114*1c60b9acSAndroid Build Coastguard Worker
115*1c60b9acSAndroid Build Coastguard Worker switch (csc->tli) {
116*1c60b9acSAndroid Build Coastguard Worker case ST_UNKNOWN:
117*1c60b9acSAndroid Build Coastguard Worker /*
118*1c60b9acSAndroid Build Coastguard Worker * We need to figure out what signing structure we need to use,
119*1c60b9acSAndroid Build Coastguard Worker * given the algorithms that are in it. So let's have a look
120*1c60b9acSAndroid Build Coastguard Worker * and decide.
121*1c60b9acSAndroid Build Coastguard Worker */
122*1c60b9acSAndroid Build Coastguard Worker
123*1c60b9acSAndroid Build Coastguard Worker if (!csc->algs.count) {
124*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: must add at least one signature\n", __func__);
125*1c60b9acSAndroid Build Coastguard Worker return 1;
126*1c60b9acSAndroid Build Coastguard Worker }
127*1c60b9acSAndroid Build Coastguard Worker
128*1c60b9acSAndroid Build Coastguard Worker csc->type = SIGTYPE_MULTI;
129*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(csc->algs.head, lws_cose_sig_alg_t, list);
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker switch (alg->cose_alg) {
132*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKAHMAC_256_64:
133*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKAHMAC_256_256:
134*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKAHMAC_384_384:
135*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKAHMAC_512_512:
136*1c60b9acSAndroid Build Coastguard Worker // if (csc->info.sigtype == SIGTYPE_MAC0)
137*1c60b9acSAndroid Build Coastguard Worker csc->type = SIGTYPE_MAC0;
138*1c60b9acSAndroid Build Coastguard Worker // else
139*1c60b9acSAndroid Build Coastguard Worker // csc->type = SIGTYPE_MAC;
140*1c60b9acSAndroid Build Coastguard Worker break;
141*1c60b9acSAndroid Build Coastguard Worker }
142*1c60b9acSAndroid Build Coastguard Worker
143*1c60b9acSAndroid Build Coastguard Worker if (csc->algs.count == 1) {
144*1c60b9acSAndroid Build Coastguard Worker if (!csc->info.sigtype && csc->type == SIGTYPE_MAC) {
145*1c60b9acSAndroid Build Coastguard Worker if (csc->info.flags & LCSC_FL_ADD_CBOR_PREFER_MAC0)
146*1c60b9acSAndroid Build Coastguard Worker csc->type = SIGTYPE_MAC0;
147*1c60b9acSAndroid Build Coastguard Worker } else
148*1c60b9acSAndroid Build Coastguard Worker if (!csc->info.sigtype ||
149*1c60b9acSAndroid Build Coastguard Worker csc->info.sigtype == SIGTYPE_SINGLE) /* ie, if no hint */
150*1c60b9acSAndroid Build Coastguard Worker csc->type = SIGTYPE_SINGLE;
151*1c60b9acSAndroid Build Coastguard Worker }
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: decided on type %d\n", __func__, csc->type);
154*1c60b9acSAndroid Build Coastguard Worker
155*1c60b9acSAndroid Build Coastguard Worker /*
156*1c60b9acSAndroid Build Coastguard Worker * Start emitting the appropriate tag if that's requested
157*1c60b9acSAndroid Build Coastguard Worker */
158*1c60b9acSAndroid Build Coastguard Worker
159*1c60b9acSAndroid Build Coastguard Worker if (csc->info.flags & LCSC_FL_ADD_CBOR_TAG) {
160*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "%t(",
161*1c60b9acSAndroid Build Coastguard Worker cose_tags[csc->type]);
162*1c60b9acSAndroid Build Coastguard Worker
163*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
164*1c60b9acSAndroid Build Coastguard Worker return ret;
165*1c60b9acSAndroid Build Coastguard Worker }
166*1c60b9acSAndroid Build Coastguard Worker
167*1c60b9acSAndroid Build Coastguard Worker /* The */
168*1c60b9acSAndroid Build Coastguard Worker c = 0;
169*1c60b9acSAndroid Build Coastguard Worker switch (csc->type) {
170*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC0:
171*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
172*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_SINGLE:
173*1c60b9acSAndroid Build Coastguard Worker c = 0x84;
174*1c60b9acSAndroid Build Coastguard Worker break;
175*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
176*1c60b9acSAndroid Build Coastguard Worker c = 0x85;
177*1c60b9acSAndroid Build Coastguard Worker break;
178*1c60b9acSAndroid Build Coastguard Worker default:
179*1c60b9acSAndroid Build Coastguard Worker break;
180*1c60b9acSAndroid Build Coastguard Worker }
181*1c60b9acSAndroid Build Coastguard Worker
182*1c60b9acSAndroid Build Coastguard Worker /* The outer array */
183*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->scratch[csc->info.lec->scratch_len++] = c;
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker /*
186*1c60b9acSAndroid Build Coastguard Worker * Then, let's start hashing with the sigtype constant part
187*1c60b9acSAndroid Build Coastguard Worker */
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, sig_mctx[csc->type],
190*1c60b9acSAndroid Build Coastguard Worker sig_mctx_len[csc->type]);
191*1c60b9acSAndroid Build Coastguard Worker
192*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_OUTER_PROTECTED;
193*1c60b9acSAndroid Build Coastguard Worker csc->subsequent = 0;
194*1c60b9acSAndroid Build Coastguard Worker
195*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
196*1c60b9acSAndroid Build Coastguard Worker
197*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker /*
200*1c60b9acSAndroid Build Coastguard Worker * We need to list and emit any outer protected data as a map
201*1c60b9acSAndroid Build Coastguard Worker * into its own buffer, then emit that into the output as a bstr
202*1c60b9acSAndroid Build Coastguard Worker */
203*1c60b9acSAndroid Build Coastguard Worker
204*1c60b9acSAndroid Build Coastguard Worker switch (csc->type) {
205*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_SINGLE:
206*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC0:
207*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(csc->algs.head,
208*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
209*1c60b9acSAndroid Build Coastguard Worker
210*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec, lbuf, sizeof(lbuf));
211*1c60b9acSAndroid Build Coastguard Worker
212*1c60b9acSAndroid Build Coastguard Worker /* we know it will fit */
213*1c60b9acSAndroid Build Coastguard Worker lws_lec_printf(&lec, "{1:%lld}",
214*1c60b9acSAndroid Build Coastguard Worker (long long)alg->cose_alg);
215*1c60b9acSAndroid Build Coastguard Worker lws_lec_scratch(&lec);
216*1c60b9acSAndroid Build Coastguard Worker
217*1c60b9acSAndroid Build Coastguard Worker if (!csc->subsequent) {
218*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
219*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0,
220*1c60b9acSAndroid Build Coastguard Worker lec.used);
221*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec1.scratch,
222*1c60b9acSAndroid Build Coastguard Worker lec1.scratch_len);
223*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec.start, lec.used);
224*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "%.*b",
225*1c60b9acSAndroid Build Coastguard Worker (int)lec.used, lec.start);
226*1c60b9acSAndroid Build Coastguard Worker
227*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
228*1c60b9acSAndroid Build Coastguard Worker return ret;
229*1c60b9acSAndroid Build Coastguard Worker csc->subsequent = 1;
230*1c60b9acSAndroid Build Coastguard Worker }
231*1c60b9acSAndroid Build Coastguard Worker break;
232*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
233*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
234*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec, lbuf, sizeof(lbuf));
235*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec, LWS_CBOR_MAJTYP_BSTR, 0, 0);
236*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_BSTR, 0, 0);
237*1c60b9acSAndroid Build Coastguard Worker lws_lec_scratch(&lec);
238*1c60b9acSAndroid Build Coastguard Worker lec.used = lws_ptr_diff_size_t(lec.buf, lec.start);
239*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec.start,
240*1c60b9acSAndroid Build Coastguard Worker lec.used);
241*1c60b9acSAndroid Build Coastguard Worker break;
242*1c60b9acSAndroid Build Coastguard Worker default:
243*1c60b9acSAndroid Build Coastguard Worker lec.used = 0;
244*1c60b9acSAndroid Build Coastguard Worker break;
245*1c60b9acSAndroid Build Coastguard Worker }
246*1c60b9acSAndroid Build Coastguard Worker
247*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_OUTER_UNPROTECTED;
248*1c60b9acSAndroid Build Coastguard Worker
249*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
250*1c60b9acSAndroid Build Coastguard Worker
251*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
252*1c60b9acSAndroid Build Coastguard Worker
253*1c60b9acSAndroid Build Coastguard Worker /*
254*1c60b9acSAndroid Build Coastguard Worker * We need to list and emit any outer unprotected data, as
255*1c60b9acSAndroid Build Coastguard Worker * an inline cbor map
256*1c60b9acSAndroid Build Coastguard Worker */
257*1c60b9acSAndroid Build Coastguard Worker
258*1c60b9acSAndroid Build Coastguard Worker switch (csc->type) {
259*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_SINGLE:
260*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC0:
261*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(csc->algs.head,
262*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
263*1c60b9acSAndroid Build Coastguard Worker ke = &alg->cose_key->meta[COSEKEY_META_KID];
264*1c60b9acSAndroid Build Coastguard Worker if (ke->len) {
265*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "{%d:%.*b}",
266*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKL_KID,
267*1c60b9acSAndroid Build Coastguard Worker (int)ke->len, ke->buf);
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
270*1c60b9acSAndroid Build Coastguard Worker return ret;
271*1c60b9acSAndroid Build Coastguard Worker }
272*1c60b9acSAndroid Build Coastguard Worker /* hack for no extra data */
273*1c60b9acSAndroid Build Coastguard Worker
274*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
275*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0, 0);
276*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec1.scratch,
277*1c60b9acSAndroid Build Coastguard Worker lec1.scratch_len);
278*1c60b9acSAndroid Build Coastguard Worker break;
279*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
280*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
281*1c60b9acSAndroid Build Coastguard Worker
282*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_BSTR, 0, 0);
283*1c60b9acSAndroid Build Coastguard Worker
284*1c60b9acSAndroid Build Coastguard Worker /*
285*1c60b9acSAndroid Build Coastguard Worker * For cose-sign, we need to feed each sig alg its alg-
286*1c60b9acSAndroid Build Coastguard Worker * specific protected data into the hash before letting
287*1c60b9acSAndroid Build Coastguard Worker * all the hashes see the payload
288*1c60b9acSAndroid Build Coastguard Worker */
289*1c60b9acSAndroid Build Coastguard Worker
290*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
291*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&csc->algs)) {
292*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(p, lws_cose_sig_alg_t, list);
293*1c60b9acSAndroid Build Coastguard Worker
294*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec, lbuf, sizeof(lbuf));
295*1c60b9acSAndroid Build Coastguard Worker
296*1c60b9acSAndroid Build Coastguard Worker /* we know it will fit */
297*1c60b9acSAndroid Build Coastguard Worker lws_lec_printf(&lec, "{1:%lld}",
298*1c60b9acSAndroid Build Coastguard Worker (long long)alg->cose_alg);
299*1c60b9acSAndroid Build Coastguard Worker
300*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
301*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0,
302*1c60b9acSAndroid Build Coastguard Worker lec.used);
303*1c60b9acSAndroid Build Coastguard Worker
304*1c60b9acSAndroid Build Coastguard Worker // lwsl_hexdump_warn(lec1.scratch, lec1.scratch_len);
305*1c60b9acSAndroid Build Coastguard Worker // lwsl_hexdump_warn(lec.start, lec.used);
306*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_sign_alg_hash(alg, lec1.scratch,
307*1c60b9acSAndroid Build Coastguard Worker lec1.scratch_len))
308*1c60b9acSAndroid Build Coastguard Worker alg->failed = 1;
309*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_sign_alg_hash(alg, lec.start,
310*1c60b9acSAndroid Build Coastguard Worker lec.used))
311*1c60b9acSAndroid Build Coastguard Worker alg->failed = 1;
312*1c60b9acSAndroid Build Coastguard Worker
313*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
314*1c60b9acSAndroid Build Coastguard Worker
315*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
316*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0, 0);
317*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec1.scratch,
318*1c60b9acSAndroid Build Coastguard Worker lec1.scratch_len);
319*1c60b9acSAndroid Build Coastguard Worker
320*1c60b9acSAndroid Build Coastguard Worker break;
321*1c60b9acSAndroid Build Coastguard Worker default:
322*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "{}");
323*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
324*1c60b9acSAndroid Build Coastguard Worker return ret;
325*1c60b9acSAndroid Build Coastguard Worker break;
326*1c60b9acSAndroid Build Coastguard Worker }
327*1c60b9acSAndroid Build Coastguard Worker
328*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_OUTER_PAYLOAD;
329*1c60b9acSAndroid Build Coastguard Worker csc->subsequent = 0;
330*1c60b9acSAndroid Build Coastguard Worker
331*1c60b9acSAndroid Build Coastguard Worker /* Prepare the payload BSTR */
332*1c60b9acSAndroid Build Coastguard Worker
333*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_BSTR, 0,
334*1c60b9acSAndroid Build Coastguard Worker csc->info.inline_payload_len);
335*1c60b9acSAndroid Build Coastguard Worker
336*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
337*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0,
338*1c60b9acSAndroid Build Coastguard Worker csc->info.inline_payload_len);
339*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, lec1.scratch,
340*1c60b9acSAndroid Build Coastguard Worker lec1.scratch_len);
341*1c60b9acSAndroid Build Coastguard Worker
342*1c60b9acSAndroid Build Coastguard Worker lws_lec_scratch(csc->info.lec);
343*1c60b9acSAndroid Build Coastguard Worker
344*1c60b9acSAndroid Build Coastguard Worker csc->rem_pay = csc->info.inline_payload_len;
345*1c60b9acSAndroid Build Coastguard Worker
346*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
347*1c60b9acSAndroid Build Coastguard Worker
348*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PAYLOAD:
349*1c60b9acSAndroid Build Coastguard Worker
350*1c60b9acSAndroid Build Coastguard Worker if (csc->along) {
351*1c60b9acSAndroid Build Coastguard Worker in += csc->along;
352*1c60b9acSAndroid Build Coastguard Worker in_len -= csc->along;
353*1c60b9acSAndroid Build Coastguard Worker }
354*1c60b9acSAndroid Build Coastguard Worker
355*1c60b9acSAndroid Build Coastguard Worker lws_lec_scratch(csc->info.lec);
356*1c60b9acSAndroid Build Coastguard Worker
357*1c60b9acSAndroid Build Coastguard Worker if (csc->rem_pay) {
358*1c60b9acSAndroid Build Coastguard Worker
359*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_hashing(csc, in, in_len);
360*1c60b9acSAndroid Build Coastguard Worker
361*1c60b9acSAndroid Build Coastguard Worker /*
362*1c60b9acSAndroid Build Coastguard Worker * in / in_len is the payload chunk
363*1c60b9acSAndroid Build Coastguard Worker */
364*1c60b9acSAndroid Build Coastguard Worker
365*1c60b9acSAndroid Build Coastguard Worker s = lws_ptr_diff_size_t(csc->info.lec->end,
366*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->buf);
367*1c60b9acSAndroid Build Coastguard Worker if (s > (size_t)csc->rem_pay)
368*1c60b9acSAndroid Build Coastguard Worker s = (size_t)csc->rem_pay;
369*1c60b9acSAndroid Build Coastguard Worker if (s > in_len)
370*1c60b9acSAndroid Build Coastguard Worker s = in_len;
371*1c60b9acSAndroid Build Coastguard Worker
372*1c60b9acSAndroid Build Coastguard Worker memcpy(csc->info.lec->buf, in, s);
373*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->buf += s;
374*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->used = lws_ptr_diff_size_t(
375*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->buf,
376*1c60b9acSAndroid Build Coastguard Worker csc->info.lec->start);
377*1c60b9acSAndroid Build Coastguard Worker csc->rem_pay -= s;
378*1c60b9acSAndroid Build Coastguard Worker
379*1c60b9acSAndroid Build Coastguard Worker csc->along = s;
380*1c60b9acSAndroid Build Coastguard Worker
381*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_AGAIN;
382*1c60b9acSAndroid Build Coastguard Worker }
383*1c60b9acSAndroid Build Coastguard Worker
384*1c60b9acSAndroid Build Coastguard Worker /* finished with rem_pay */
385*1c60b9acSAndroid Build Coastguard Worker
386*1c60b9acSAndroid Build Coastguard Worker if (csc->type == SIGTYPE_MULTI) {
387*1c60b9acSAndroid Build Coastguard Worker
388*1c60b9acSAndroid Build Coastguard Worker csc->alg = lws_container_of(csc->algs.head,
389*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
390*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
391*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_ARRAY, 0,
392*1c60b9acSAndroid Build Coastguard Worker csc->algs.count);
393*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_ARRAY, 0,
394*1c60b9acSAndroid Build Coastguard Worker csc->algs.count);
395*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_INNER_PROTECTED;
396*1c60b9acSAndroid Build Coastguard Worker goto inner_protected;
397*1c60b9acSAndroid Build Coastguard Worker }
398*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_OUTER_SIGN1_SIGNATURE;
399*1c60b9acSAndroid Build Coastguard Worker csc->along = 0;
400*1c60b9acSAndroid Build Coastguard Worker
401*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
402*1c60b9acSAndroid Build Coastguard Worker
403*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN1_SIGNATURE:
404*1c60b9acSAndroid Build Coastguard Worker
405*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(lws_dll2_get_head(&csc->algs),
406*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
407*1c60b9acSAndroid Build Coastguard Worker
408*1c60b9acSAndroid Build Coastguard Worker if (!alg->completed)
409*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_alg_complete(alg);
410*1c60b9acSAndroid Build Coastguard Worker if (alg->failed)
411*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_FAIL;
412*1c60b9acSAndroid Build Coastguard Worker
413*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "%.*b",
414*1c60b9acSAndroid Build Coastguard Worker (int)alg->rhash_len, alg->rhash);
415*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
416*1c60b9acSAndroid Build Coastguard Worker return ret;
417*1c60b9acSAndroid Build Coastguard Worker
418*1c60b9acSAndroid Build Coastguard Worker if (csc->type == SIGTYPE_MAC) {
419*1c60b9acSAndroid Build Coastguard Worker csc->alg = lws_container_of(csc->algs.head,
420*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
421*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
422*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_ARRAY, 0,
423*1c60b9acSAndroid Build Coastguard Worker csc->algs.count);
424*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_ARRAY, 0,
425*1c60b9acSAndroid Build Coastguard Worker csc->algs.count);
426*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_INNER_PROTECTED;
427*1c60b9acSAndroid Build Coastguard Worker goto inner_protected;
428*1c60b9acSAndroid Build Coastguard Worker }
429*1c60b9acSAndroid Build Coastguard Worker
430*1c60b9acSAndroid Build Coastguard Worker break;
431*1c60b9acSAndroid Build Coastguard Worker
432*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
433*1c60b9acSAndroid Build Coastguard Worker inner_protected:
434*1c60b9acSAndroid Build Coastguard Worker
435*1c60b9acSAndroid Build Coastguard Worker /*
436*1c60b9acSAndroid Build Coastguard Worker * We need to list and emit any outer protected data as a map
437*1c60b9acSAndroid Build Coastguard Worker * into its own buffer, then emit that into the output as a bstr
438*1c60b9acSAndroid Build Coastguard Worker */
439*1c60b9acSAndroid Build Coastguard Worker
440*1c60b9acSAndroid Build Coastguard Worker switch (csc->type) {
441*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
442*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
443*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
444*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_ARRAY, 0, 3);
445*1c60b9acSAndroid Build Coastguard Worker
446*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(csc->info.lec, LWS_CBOR_MAJTYP_ARRAY, 0, 3);
447*1c60b9acSAndroid Build Coastguard Worker
448*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec, lbuf, sizeof(lbuf));
449*1c60b9acSAndroid Build Coastguard Worker
450*1c60b9acSAndroid Build Coastguard Worker /* we know it will fit */
451*1c60b9acSAndroid Build Coastguard Worker lws_lec_printf(&lec, "{1:%lld}",
452*1c60b9acSAndroid Build Coastguard Worker (long long)csc->alg->cose_alg);
453*1c60b9acSAndroid Build Coastguard Worker
454*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec1, lb, sizeof(lb));
455*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(&lec1, LWS_CBOR_MAJTYP_BSTR, 0,
456*1c60b9acSAndroid Build Coastguard Worker lec.used);
457*1c60b9acSAndroid Build Coastguard Worker lws_lec_printf(csc->info.lec, "{1:%lld}",
458*1c60b9acSAndroid Build Coastguard Worker (long long)csc->alg->cose_alg);
459*1c60b9acSAndroid Build Coastguard Worker break;
460*1c60b9acSAndroid Build Coastguard Worker default:
461*1c60b9acSAndroid Build Coastguard Worker lec.used = 0;
462*1c60b9acSAndroid Build Coastguard Worker break;
463*1c60b9acSAndroid Build Coastguard Worker }
464*1c60b9acSAndroid Build Coastguard Worker
465*1c60b9acSAndroid Build Coastguard Worker
466*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_INNER_UNPROTECTED;
467*1c60b9acSAndroid Build Coastguard Worker
468*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
469*1c60b9acSAndroid Build Coastguard Worker
470*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
471*1c60b9acSAndroid Build Coastguard Worker
472*1c60b9acSAndroid Build Coastguard Worker switch (csc->type) {
473*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
474*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(csc->algs.head,
475*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
476*1c60b9acSAndroid Build Coastguard Worker ke = &alg->cose_key->meta[COSEKEY_META_KID];
477*1c60b9acSAndroid Build Coastguard Worker if (ke->len) {
478*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "{%d:%.*b}",
479*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKL_KID,
480*1c60b9acSAndroid Build Coastguard Worker (int)ke->len, ke->buf);
481*1c60b9acSAndroid Build Coastguard Worker
482*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
483*1c60b9acSAndroid Build Coastguard Worker return ret;
484*1c60b9acSAndroid Build Coastguard Worker }
485*1c60b9acSAndroid Build Coastguard Worker break;
486*1c60b9acSAndroid Build Coastguard Worker default:
487*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "{}");
488*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
489*1c60b9acSAndroid Build Coastguard Worker return ret;
490*1c60b9acSAndroid Build Coastguard Worker break;
491*1c60b9acSAndroid Build Coastguard Worker }
492*1c60b9acSAndroid Build Coastguard Worker
493*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_alg_complete(csc->alg);
494*1c60b9acSAndroid Build Coastguard Worker if (csc->alg->failed)
495*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_FAIL;
496*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_INNER_SIGNATURE;
497*1c60b9acSAndroid Build Coastguard Worker
498*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
499*1c60b9acSAndroid Build Coastguard Worker
500*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_SIGNATURE:
501*1c60b9acSAndroid Build Coastguard Worker
502*1c60b9acSAndroid Build Coastguard Worker ret = lws_lec_printf(csc->info.lec, "%.*b",
503*1c60b9acSAndroid Build Coastguard Worker (int)csc->alg->rhash_len, csc->alg->rhash);
504*1c60b9acSAndroid Build Coastguard Worker if (ret != LWS_LECPCTX_RET_FINISHED)
505*1c60b9acSAndroid Build Coastguard Worker return ret;
506*1c60b9acSAndroid Build Coastguard Worker
507*1c60b9acSAndroid Build Coastguard Worker if (csc->alg->list.next) {
508*1c60b9acSAndroid Build Coastguard Worker csc->alg = (lws_cose_sig_alg_t *)csc->alg->list.next;
509*1c60b9acSAndroid Build Coastguard Worker csc->tli = ST_INNER_PROTECTED;
510*1c60b9acSAndroid Build Coastguard Worker }
511*1c60b9acSAndroid Build Coastguard Worker break;
512*1c60b9acSAndroid Build Coastguard Worker
513*1c60b9acSAndroid Build Coastguard Worker }
514*1c60b9acSAndroid Build Coastguard Worker
515*1c60b9acSAndroid Build Coastguard Worker return 0;
516*1c60b9acSAndroid Build Coastguard Worker }
517*1c60b9acSAndroid Build Coastguard Worker
518*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_sign_destroy(struct lws_cose_sign_context ** _csc)519*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_destroy(struct lws_cose_sign_context **_csc)
520*1c60b9acSAndroid Build Coastguard Worker {
521*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_sign_context *csc = *_csc;
522*1c60b9acSAndroid Build Coastguard Worker
523*1c60b9acSAndroid Build Coastguard Worker if (!csc)
524*1c60b9acSAndroid Build Coastguard Worker return;
525*1c60b9acSAndroid Build Coastguard Worker
526*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
527*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&csc->algs)) {
528*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg = lws_container_of(p,
529*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
530*1c60b9acSAndroid Build Coastguard Worker
531*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(p);
532*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_alg_destroy(&alg);
533*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
534*1c60b9acSAndroid Build Coastguard Worker
535*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(*_csc);
536*1c60b9acSAndroid Build Coastguard Worker }
537