1 /*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include "private-lib-core.h"
26 #include "private-lib-jose-jwe.h"
27
28 /*
29 * NOTICE this is AESGCM content encryption, it's not AES GCM key wrapping
30 *
31 *
32 * This section defines the specifics of performing authenticated
33 * encryption with AES in Galois/Counter Mode (GCM) ([AES] and
34 * [NIST.800-38D]).
35 *
36 * The CEK is used as the encryption key.
37 *
38 * Use of an IV of size 96 bits is REQUIRED with this algorithm.
39 *
40 * The requested size of the Authentication Tag output MUST be 128 bits,
41 * regardless of the key size.
42 *
43 * For decrypt: decrypt the KEK, then decrypt the payload
44 *
45 * For encrypt: encrypt the payload, then encrypt the KEK
46 */
47
48 /*
49 * encrypting... enc_cek is unencrypted
50 */
51
52 int
lws_jwe_encrypt_gcm(struct lws_jwe * jwe,uint8_t * enc_cek,uint8_t * aad,int aad_len)53 lws_jwe_encrypt_gcm(struct lws_jwe *jwe,
54 uint8_t *enc_cek, uint8_t *aad, int aad_len)
55 {
56 struct lws_gencrypto_keyelem el;
57 struct lws_genaes_ctx aesctx;
58 size_t ivs = LWS_AESGCM_IV;
59 int n;
60
61 /* Some sanity checks on what came in */
62
63 /* MUST be 128-bit for all sizes */
64 if (jwe->jws.map.len[LJWE_ATAG] != LWS_AESGCM_TAG) {
65 lwsl_notice("%s: AESGCM tag size must be 128b, got %d\n",
66 __func__, jwe->jws.map.len[LJWE_ATAG]);
67 return -1;
68 }
69
70 if (jwe->jws.map.len[LJWE_IV] != LWS_AESGCM_IV) { /* MUST be 96-bit */
71 lwsl_notice("%s: AESGCM IV must be 128b, got %d\n", __func__,
72 jwe->jws.map.len[LJWE_IV]);
73 return -1;
74 }
75
76 /* EKEY is directly the CEK KEY */
77 el.buf = enc_cek;
78 el.len = jwe->jose.enc_alg->keybits_fixed / 8;
79
80 if (lws_genaes_create(&aesctx, LWS_GAESO_ENC, LWS_GAESM_GCM,
81 &el, LWS_GAESP_NO_PADDING, NULL)) {
82 lwsl_err("%s: lws_genaes_create failed\n", __func__);
83
84 return -1;
85 }
86
87 /* aad */
88
89 n = lws_genaes_crypt(&aesctx, aad, (unsigned int)aad_len, NULL,
90 (uint8_t *)jwe->jws.map.buf[LJWE_IV],
91 (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs,
92 LWS_AESGCM_TAG);
93 if (n) {
94 lwsl_err("%s: lws_genaes_crypt aad failed\n", __func__);
95 return -1;
96 }
97
98 /* payload */
99 n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
100 jwe->jws.map.len[LJWE_CTXT],
101 (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
102 (uint8_t *)jwe->jws.map.buf[LJWE_IV],
103 NULL, &ivs,
104 LWS_AESGCM_TAG);
105
106 n |= lws_genaes_destroy(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_ATAG],
107 LWS_AESGCM_TAG);
108 if (n) {
109 lwsl_err("%s: lws_genaes_crypt failed\n", __func__);
110 return -1;
111 }
112
113 return (int)jwe->jws.map.len[LJWE_CTXT];
114 }
115
116 int
lws_jwe_auth_and_decrypt_gcm(struct lws_jwe * jwe,uint8_t * enc_cek,uint8_t * aad,int aad_len)117 lws_jwe_auth_and_decrypt_gcm(struct lws_jwe *jwe,
118 uint8_t *enc_cek, uint8_t *aad, int aad_len)
119 {
120 struct lws_gencrypto_keyelem el;
121 struct lws_genaes_ctx aesctx;
122 size_t ivs = LWS_AESGCM_IV;
123 uint8_t tag[LWS_AESGCM_TAG];
124 int n;
125
126 /* Some sanity checks on what came in */
127
128 /* Tag MUST be 128-bit for all sizes */
129 if (jwe->jws.map.len[LJWE_ATAG] != LWS_AESGCM_TAG) {
130 lwsl_notice("%s: AESGCM tag size must be 128b, got %d\n",
131 __func__, jwe->jws.map.len[LJWE_ATAG]);
132 return -1;
133 }
134
135 if (jwe->jws.map.len[LJWE_IV] != LWS_AESGCM_IV) { /* MUST be 96-bit */
136 lwsl_notice("%s: AESGCM IV must be 128b, got %d\n", __func__,
137 jwe->jws.map.len[LJWE_IV]);
138 return -1;
139 }
140
141 /* EKEY is directly the CEK KEY */
142 el.buf = enc_cek;
143 el.len = jwe->jose.enc_alg->keybits_fixed / 8;
144
145 if (lws_genaes_create(&aesctx, LWS_GAESO_DEC, LWS_GAESM_GCM,
146 &el, LWS_GAESP_NO_PADDING, NULL)) {
147 lwsl_err("%s: lws_genaes_create failed\n", __func__);
148
149 return -1;
150 }
151
152 n = lws_genaes_crypt(&aesctx, aad, (unsigned int)aad_len,
153 NULL,
154 (uint8_t *)jwe->jws.map.buf[LJWE_IV],
155 (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs, 16);
156 if (n) {
157 lwsl_err("%s: lws_genaes_crypt aad failed\n", __func__);
158 return -1;
159 }
160 n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
161 jwe->jws.map.len[LJWE_CTXT],
162 (uint8_t *)jwe->jws.map.buf[LJWE_CTXT],
163 (uint8_t *)jwe->jws.map.buf[LJWE_IV],
164 (uint8_t *)jwe->jws.map.buf[LJWE_ATAG], &ivs, 16);
165
166 n |= lws_genaes_destroy(&aesctx, tag, sizeof(tag));
167 if (n) {
168 lwsl_err("%s: lws_genaes_crypt failed\n", __func__);
169 return -1;
170 }
171
172 return (int)jwe->jws.map.len[LJWE_CTXT];
173 }
174