xref: /aosp_15_r20/external/libwebsockets/lib/cose/cose_sign.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
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