• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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