xref: /aosp_15_r20/external/libwebsockets/lib/jose/jwe/enc/aesgcm.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 - 2020 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-jose-jwe.h"
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker /*
29*1c60b9acSAndroid Build Coastguard Worker  * NOTICE this is AESGCM content encryption, it's not AES GCM key wrapping
30*1c60b9acSAndroid Build Coastguard Worker  *
31*1c60b9acSAndroid Build Coastguard Worker  *
32*1c60b9acSAndroid Build Coastguard Worker  * This section defines the specifics of performing authenticated
33*1c60b9acSAndroid Build Coastguard Worker  * encryption with AES in Galois/Counter Mode (GCM) ([AES] and
34*1c60b9acSAndroid Build Coastguard Worker  * [NIST.800-38D]).
35*1c60b9acSAndroid Build Coastguard Worker  *
36*1c60b9acSAndroid Build Coastguard Worker  * The CEK is used as the encryption key.
37*1c60b9acSAndroid Build Coastguard Worker  *
38*1c60b9acSAndroid Build Coastguard Worker  * Use of an IV of size 96 bits is REQUIRED with this algorithm.
39*1c60b9acSAndroid Build Coastguard Worker  *
40*1c60b9acSAndroid Build Coastguard Worker  * The requested size of the Authentication Tag output MUST be 128 bits,
41*1c60b9acSAndroid Build Coastguard Worker  * regardless of the key size.
42*1c60b9acSAndroid Build Coastguard Worker  *
43*1c60b9acSAndroid Build Coastguard Worker  * For decrypt: decrypt the KEK, then decrypt the payload
44*1c60b9acSAndroid Build Coastguard Worker  *
45*1c60b9acSAndroid Build Coastguard Worker  * For encrypt: encrypt the payload, then encrypt the KEK
46*1c60b9acSAndroid Build Coastguard Worker  */
47*1c60b9acSAndroid Build Coastguard Worker 
48*1c60b9acSAndroid Build Coastguard Worker /*
49*1c60b9acSAndroid Build Coastguard Worker  * encrypting... enc_cek is unencrypted
50*1c60b9acSAndroid Build Coastguard Worker  */
51*1c60b9acSAndroid Build Coastguard Worker 
52*1c60b9acSAndroid Build Coastguard Worker int
lws_jwe_encrypt_gcm(struct lws_jwe * jwe,uint8_t * enc_cek,uint8_t * aad,int aad_len)53*1c60b9acSAndroid Build Coastguard Worker lws_jwe_encrypt_gcm(struct lws_jwe *jwe,
54*1c60b9acSAndroid Build Coastguard Worker 		    uint8_t *enc_cek, uint8_t *aad, int aad_len)
55*1c60b9acSAndroid Build Coastguard Worker {
56*1c60b9acSAndroid Build Coastguard Worker 	struct lws_gencrypto_keyelem el;
57*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genaes_ctx aesctx;
58*1c60b9acSAndroid Build Coastguard Worker 	size_t ivs = LWS_AESGCM_IV;
59*1c60b9acSAndroid Build Coastguard Worker 	int n;
60*1c60b9acSAndroid Build Coastguard Worker 
61*1c60b9acSAndroid Build Coastguard Worker 	/* Some sanity checks on what came in */
62*1c60b9acSAndroid Build Coastguard Worker 
63*1c60b9acSAndroid Build Coastguard Worker 	/* MUST be 128-bit for all sizes */
64*1c60b9acSAndroid Build Coastguard Worker 	if (jwe->jws.map.len[LJWE_ATAG] != LWS_AESGCM_TAG) {
65*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: AESGCM tag size must be 128b, got %d\n",
66*1c60b9acSAndroid Build Coastguard Worker 				__func__, jwe->jws.map.len[LJWE_ATAG]);
67*1c60b9acSAndroid Build Coastguard Worker 		return -1;
68*1c60b9acSAndroid Build Coastguard Worker 	}
69*1c60b9acSAndroid Build Coastguard Worker 
70*1c60b9acSAndroid Build Coastguard Worker 	if (jwe->jws.map.len[LJWE_IV] != LWS_AESGCM_IV) { /* MUST be 96-bit */
71*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: AESGCM IV must be 128b, got %d\n", __func__,
72*1c60b9acSAndroid Build Coastguard Worker 				jwe->jws.map.len[LJWE_IV]);
73*1c60b9acSAndroid Build Coastguard Worker 		return -1;
74*1c60b9acSAndroid Build Coastguard Worker 	}
75*1c60b9acSAndroid Build Coastguard Worker 
76*1c60b9acSAndroid Build Coastguard Worker 	/* EKEY is directly the CEK KEY */
77*1c60b9acSAndroid Build Coastguard Worker 	el.buf = enc_cek;
78*1c60b9acSAndroid Build Coastguard Worker 	el.len = jwe->jose.enc_alg->keybits_fixed / 8;
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genaes_create(&aesctx, LWS_GAESO_ENC, LWS_GAESM_GCM,
81*1c60b9acSAndroid Build Coastguard Worker 			      &el, LWS_GAESP_NO_PADDING, NULL)) {
82*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_create failed\n", __func__);
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker 		return -1;
85*1c60b9acSAndroid Build Coastguard Worker 	}
86*1c60b9acSAndroid Build Coastguard Worker 
87*1c60b9acSAndroid Build Coastguard Worker 	/* aad */
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker 	n = lws_genaes_crypt(&aesctx, aad, (unsigned int)aad_len, NULL,
90*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_IV],
91*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs,
92*1c60b9acSAndroid Build Coastguard Worker 			     LWS_AESGCM_TAG);
93*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
94*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_crypt aad failed\n", __func__);
95*1c60b9acSAndroid Build Coastguard Worker 		return -1;
96*1c60b9acSAndroid Build Coastguard Worker 	}
97*1c60b9acSAndroid Build Coastguard Worker 
98*1c60b9acSAndroid Build Coastguard Worker 	/* payload */
99*1c60b9acSAndroid Build Coastguard Worker 	n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
100*1c60b9acSAndroid Build Coastguard Worker 			     jwe->jws.map.len[LJWE_CTXT],
101*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
102*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_IV],
103*1c60b9acSAndroid Build Coastguard Worker 			     NULL, &ivs,
104*1c60b9acSAndroid Build Coastguard Worker 			     LWS_AESGCM_TAG);
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 	n |= lws_genaes_destroy(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_ATAG],
107*1c60b9acSAndroid Build Coastguard Worker 				LWS_AESGCM_TAG);
108*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
109*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_crypt failed\n", __func__);
110*1c60b9acSAndroid Build Coastguard Worker 		return -1;
111*1c60b9acSAndroid Build Coastguard Worker 	}
112*1c60b9acSAndroid Build Coastguard Worker 
113*1c60b9acSAndroid Build Coastguard Worker 	return (int)jwe->jws.map.len[LJWE_CTXT];
114*1c60b9acSAndroid Build Coastguard Worker }
115*1c60b9acSAndroid Build Coastguard Worker 
116*1c60b9acSAndroid Build Coastguard Worker int
lws_jwe_auth_and_decrypt_gcm(struct lws_jwe * jwe,uint8_t * enc_cek,uint8_t * aad,int aad_len)117*1c60b9acSAndroid Build Coastguard Worker lws_jwe_auth_and_decrypt_gcm(struct lws_jwe *jwe,
118*1c60b9acSAndroid Build Coastguard Worker 			     uint8_t *enc_cek, uint8_t *aad, int aad_len)
119*1c60b9acSAndroid Build Coastguard Worker {
120*1c60b9acSAndroid Build Coastguard Worker 	struct lws_gencrypto_keyelem el;
121*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genaes_ctx aesctx;
122*1c60b9acSAndroid Build Coastguard Worker 	size_t ivs = LWS_AESGCM_IV;
123*1c60b9acSAndroid Build Coastguard Worker 	uint8_t tag[LWS_AESGCM_TAG];
124*1c60b9acSAndroid Build Coastguard Worker 	int n;
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	/* Some sanity checks on what came in */
127*1c60b9acSAndroid Build Coastguard Worker 
128*1c60b9acSAndroid Build Coastguard Worker 	/* Tag MUST be 128-bit for all sizes */
129*1c60b9acSAndroid Build Coastguard Worker 	if (jwe->jws.map.len[LJWE_ATAG] != LWS_AESGCM_TAG) {
130*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: AESGCM tag size must be 128b, got %d\n",
131*1c60b9acSAndroid Build Coastguard Worker 				__func__, jwe->jws.map.len[LJWE_ATAG]);
132*1c60b9acSAndroid Build Coastguard Worker 		return -1;
133*1c60b9acSAndroid Build Coastguard Worker 	}
134*1c60b9acSAndroid Build Coastguard Worker 
135*1c60b9acSAndroid Build Coastguard Worker 	if (jwe->jws.map.len[LJWE_IV] != LWS_AESGCM_IV) { /* MUST be 96-bit */
136*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: AESGCM IV must be 128b, got %d\n", __func__,
137*1c60b9acSAndroid Build Coastguard Worker 				jwe->jws.map.len[LJWE_IV]);
138*1c60b9acSAndroid Build Coastguard Worker 		return -1;
139*1c60b9acSAndroid Build Coastguard Worker 	}
140*1c60b9acSAndroid Build Coastguard Worker 
141*1c60b9acSAndroid Build Coastguard Worker 	/* EKEY is directly the CEK KEY */
142*1c60b9acSAndroid Build Coastguard Worker 	el.buf = enc_cek;
143*1c60b9acSAndroid Build Coastguard Worker 	el.len = jwe->jose.enc_alg->keybits_fixed / 8;
144*1c60b9acSAndroid Build Coastguard Worker 
145*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genaes_create(&aesctx, LWS_GAESO_DEC, LWS_GAESM_GCM,
146*1c60b9acSAndroid Build Coastguard Worker 			      &el, LWS_GAESP_NO_PADDING, NULL)) {
147*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_create failed\n", __func__);
148*1c60b9acSAndroid Build Coastguard Worker 
149*1c60b9acSAndroid Build Coastguard Worker 		return -1;
150*1c60b9acSAndroid Build Coastguard Worker 	}
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker 	n = lws_genaes_crypt(&aesctx, aad, (unsigned int)aad_len,
153*1c60b9acSAndroid Build Coastguard Worker 			     NULL,
154*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_IV],
155*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs, 16);
156*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
157*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_crypt aad failed\n", __func__);
158*1c60b9acSAndroid Build Coastguard Worker 		return -1;
159*1c60b9acSAndroid Build Coastguard Worker 	}
160*1c60b9acSAndroid Build Coastguard Worker 	n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
161*1c60b9acSAndroid Build Coastguard Worker 			     jwe->jws.map.len[LJWE_CTXT],
162*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
163*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_IV],
164*1c60b9acSAndroid Build Coastguard Worker 			     (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs, 16);
165*1c60b9acSAndroid Build Coastguard Worker 
166*1c60b9acSAndroid Build Coastguard Worker 	n |= lws_genaes_destroy(&aesctx, tag, sizeof(tag));
167*1c60b9acSAndroid Build Coastguard Worker 	if (n) {
168*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: lws_genaes_crypt failed\n", __func__);
169*1c60b9acSAndroid Build Coastguard Worker 		return -1;
170*1c60b9acSAndroid Build Coastguard Worker 	}
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker 	return (int)jwe->jws.map.len[LJWE_CTXT];
173*1c60b9acSAndroid Build Coastguard Worker }
174