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