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 * RFC3394 Key Wrap uses a 128-bit key, and bloats what it is wrapping by
30 * one 8-byte block. So, if you had a 32 byte plaintext CEK to wrap, after
31 * wrapping it becomes a 40 byte wrapped, enciphered, key.
32 *
33 * The CEK comes in from and goes out in LJWE_EKEY. So LJWE_EKEY length
34 * increases by 8 from calling this.
35 */
36
37 int
lws_jwe_encrypt_aeskw_cbc_hs(struct lws_jwe * jwe,char * temp,int * temp_len)38 lws_jwe_encrypt_aeskw_cbc_hs(struct lws_jwe *jwe, char *temp, int *temp_len)
39 {
40 struct lws_genaes_ctx aesctx;
41 /* we are wrapping a key, so size for the worst case after wrap */
42 uint8_t enc_cek[LWS_JWE_LIMIT_KEY_ELEMENT_BYTES +
43 LWS_JWE_RFC3394_OVERHEAD_BYTES];
44 int n, m, hlen = (int)lws_genhmac_size(jwe->jose.enc_alg->hmac_type),
45 ot = *temp_len;
46
47 if (jwe->jws.jwk->kty != LWS_GENCRYPTO_KTY_OCT) {
48 lwsl_err("%s: unexpected kty %d\n", __func__, jwe->jws.jwk->kty);
49
50 return -1;
51 }
52
53 /* create a b64 version of the JOSE header, needed for hashing */
54
55 if (lws_jws_encode_b64_element(&jwe->jws.map_b64, LJWE_JOSE,
56 temp, temp_len,
57 jwe->jws.map.buf[LJWE_JOSE],
58 jwe->jws.map.len[LJWE_JOSE]))
59 return -1;
60
61 /* Allocate temp space for ATAG and IV */
62
63 if (lws_jws_alloc_element(&jwe->jws.map, LJWE_ATAG, temp + (ot - *temp_len),
64 temp_len, (unsigned int)hlen / 2, 0))
65 return -1;
66
67 if (lws_jws_alloc_element(&jwe->jws.map, LJWE_IV, temp + (ot - *temp_len),
68 temp_len, LWS_JWE_AES_IV_BYTES, 0))
69 return -1;
70
71 /* 1) Encrypt the payload... */
72
73 /* the CEK is 256-bit in the example encrypted with a 128-bit key */
74
75 n = lws_jwe_encrypt_cbc_hs(jwe, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY],
76 (uint8_t *)jwe->jws.map_b64.buf[LJWE_JOSE],
77 (int)jwe->jws.map_b64.len[LJWE_JOSE]);
78 if (n < 0) {
79 lwsl_err("%s: lws_jwe_encrypt_cbc_hs failed\n", __func__);
80 return -1;
81 }
82
83 /* 2) Encrypt the JWE Encrypted Key: RFC3394 Key Wrap uses 64 bit blocks
84 * and 128-bit input key*/
85
86 if (lws_genaes_create(&aesctx, LWS_GAESO_ENC, LWS_GAESM_KW,
87 jwe->jws.jwk->e, 1, NULL)) {
88
89 lwsl_notice("%s: lws_genaes_create\n", __func__);
90 return -1;
91 }
92
93 /* tag size is determined by enc cipher key length */
94
95 n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY],
96 jwe->jws.map.len[LJWE_EKEY], enc_cek, NULL, NULL, NULL,
97 lws_gencrypto_bits_to_bytes(
98 jwe->jose.enc_alg->keybits_fixed));
99 m = lws_genaes_destroy(&aesctx, NULL, 0);
100 if (n < 0) {
101 lwsl_err("%s: encrypt cek fail\n", __func__);
102 return -1;
103 }
104 if (m < 0) {
105 lwsl_err("%s: lws_genaes_destroy fail\n", __func__);
106 return -1;
107 }
108
109 jwe->jws.map.len[LJWE_EKEY] += LWS_JWE_RFC3394_OVERHEAD_BYTES;
110 memcpy((uint8_t *)jwe->jws.map.buf[LJWE_EKEY], enc_cek,
111 jwe->jws.map.len[LJWE_EKEY]);
112
113 return (int)jwe->jws.map.len[LJWE_CTXT];
114 }
115
116
117 int
lws_jwe_auth_and_decrypt_aeskw_cbc_hs(struct lws_jwe * jwe)118 lws_jwe_auth_and_decrypt_aeskw_cbc_hs(struct lws_jwe *jwe)
119 {
120 struct lws_genaes_ctx aesctx;
121 uint8_t enc_cek[LWS_JWE_LIMIT_KEY_ELEMENT_BYTES +
122 LWS_JWE_RFC3394_OVERHEAD_BYTES];
123 int n, m;
124
125 if (jwe->jws.jwk->kty != LWS_GENCRYPTO_KTY_OCT) {
126 lwsl_err("%s: unexpected kty %d\n", __func__, jwe->jws.jwk->kty);
127
128 return -1;
129 }
130
131 /* the CEK is 256-bit in the example encrypted with a 128-bit key */
132
133 if (jwe->jws.map.len[LJWE_EKEY] > sizeof(enc_cek))
134 return -1;
135
136 /* 1) Decrypt the JWE Encrypted Key to get the raw MAC / CEK */
137
138 if (lws_genaes_create(&aesctx, LWS_GAESO_DEC, LWS_GAESM_KW,
139 jwe->jws.jwk->e, 1, NULL)) {
140
141 lwsl_notice("%s: lws_genaes_create\n", __func__);
142 return -1;
143 }
144
145 /*
146 * Decrypt the CEK into enc_cek
147 * tag size is determined by enc cipher key length */
148
149 n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY],
150 jwe->jws.map.len[LJWE_EKEY], enc_cek, NULL, NULL, NULL,
151 lws_gencrypto_bits_to_bytes(
152 jwe->jose.enc_alg->keybits_fixed));
153 m = lws_genaes_destroy(&aesctx, NULL, 0);
154 if (n < 0) {
155 lwsl_err("%s: decrypt CEK fail\n", __func__);
156 return -1;
157 }
158 if (m < 0) {
159 lwsl_err("%s: lws_genaes_destroy fail\n", __func__);
160 return -1;
161 }
162
163 /* 2) Decrypt the payload */
164
165 n = lws_jwe_auth_and_decrypt_cbc_hs(jwe, enc_cek,
166 (uint8_t *)jwe->jws.map_b64.buf[LJWE_JOSE],
167 (int)jwe->jws.map_b64.len[LJWE_JOSE]);
168 if (n < 0) {
169 lwsl_err("%s: lws_jwe_auth_and_decrypt_cbc_hs failed\n",
170 __func__);
171 return -1;
172 }
173
174 return (int)jwe->jws.map.len[LJWE_CTXT];
175 }
176
177
178