1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include "private-lib-core.h" 26d4afb5ceSopenharmony_ci#include "private-lib-jose-jwe.h" 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ci/* 29d4afb5ceSopenharmony_ci * RFC3394 Key Wrap uses a 128-bit key, and bloats what it is wrapping by 30d4afb5ceSopenharmony_ci * one 8-byte block. So, if you had a 32 byte plaintext CEK to wrap, after 31d4afb5ceSopenharmony_ci * wrapping it becomes a 40 byte wrapped, enciphered, key. 32d4afb5ceSopenharmony_ci * 33d4afb5ceSopenharmony_ci * The CEK comes in from and goes out in LJWE_EKEY. So LJWE_EKEY length 34d4afb5ceSopenharmony_ci * increases by 8 from calling this. 35d4afb5ceSopenharmony_ci */ 36d4afb5ceSopenharmony_ci 37d4afb5ceSopenharmony_ciint 38d4afb5ceSopenharmony_cilws_jwe_encrypt_aeskw_cbc_hs(struct lws_jwe *jwe, char *temp, int *temp_len) 39d4afb5ceSopenharmony_ci{ 40d4afb5ceSopenharmony_ci struct lws_genaes_ctx aesctx; 41d4afb5ceSopenharmony_ci /* we are wrapping a key, so size for the worst case after wrap */ 42d4afb5ceSopenharmony_ci uint8_t enc_cek[LWS_JWE_LIMIT_KEY_ELEMENT_BYTES + 43d4afb5ceSopenharmony_ci LWS_JWE_RFC3394_OVERHEAD_BYTES]; 44d4afb5ceSopenharmony_ci int n, m, hlen = (int)lws_genhmac_size(jwe->jose.enc_alg->hmac_type), 45d4afb5ceSopenharmony_ci ot = *temp_len; 46d4afb5ceSopenharmony_ci 47d4afb5ceSopenharmony_ci if (jwe->jws.jwk->kty != LWS_GENCRYPTO_KTY_OCT) { 48d4afb5ceSopenharmony_ci lwsl_err("%s: unexpected kty %d\n", __func__, jwe->jws.jwk->kty); 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_ci return -1; 51d4afb5ceSopenharmony_ci } 52d4afb5ceSopenharmony_ci 53d4afb5ceSopenharmony_ci /* create a b64 version of the JOSE header, needed for hashing */ 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_ci if (lws_jws_encode_b64_element(&jwe->jws.map_b64, LJWE_JOSE, 56d4afb5ceSopenharmony_ci temp, temp_len, 57d4afb5ceSopenharmony_ci jwe->jws.map.buf[LJWE_JOSE], 58d4afb5ceSopenharmony_ci jwe->jws.map.len[LJWE_JOSE])) 59d4afb5ceSopenharmony_ci return -1; 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci /* Allocate temp space for ATAG and IV */ 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci if (lws_jws_alloc_element(&jwe->jws.map, LJWE_ATAG, temp + (ot - *temp_len), 64d4afb5ceSopenharmony_ci temp_len, (unsigned int)hlen / 2, 0)) 65d4afb5ceSopenharmony_ci return -1; 66d4afb5ceSopenharmony_ci 67d4afb5ceSopenharmony_ci if (lws_jws_alloc_element(&jwe->jws.map, LJWE_IV, temp + (ot - *temp_len), 68d4afb5ceSopenharmony_ci temp_len, LWS_JWE_AES_IV_BYTES, 0)) 69d4afb5ceSopenharmony_ci return -1; 70d4afb5ceSopenharmony_ci 71d4afb5ceSopenharmony_ci /* 1) Encrypt the payload... */ 72d4afb5ceSopenharmony_ci 73d4afb5ceSopenharmony_ci /* the CEK is 256-bit in the example encrypted with a 128-bit key */ 74d4afb5ceSopenharmony_ci 75d4afb5ceSopenharmony_ci n = lws_jwe_encrypt_cbc_hs(jwe, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY], 76d4afb5ceSopenharmony_ci (uint8_t *)jwe->jws.map_b64.buf[LJWE_JOSE], 77d4afb5ceSopenharmony_ci (int)jwe->jws.map_b64.len[LJWE_JOSE]); 78d4afb5ceSopenharmony_ci if (n < 0) { 79d4afb5ceSopenharmony_ci lwsl_err("%s: lws_jwe_encrypt_cbc_hs failed\n", __func__); 80d4afb5ceSopenharmony_ci return -1; 81d4afb5ceSopenharmony_ci } 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci /* 2) Encrypt the JWE Encrypted Key: RFC3394 Key Wrap uses 64 bit blocks 84d4afb5ceSopenharmony_ci * and 128-bit input key*/ 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_ci if (lws_genaes_create(&aesctx, LWS_GAESO_ENC, LWS_GAESM_KW, 87d4afb5ceSopenharmony_ci jwe->jws.jwk->e, 1, NULL)) { 88d4afb5ceSopenharmony_ci 89d4afb5ceSopenharmony_ci lwsl_notice("%s: lws_genaes_create\n", __func__); 90d4afb5ceSopenharmony_ci return -1; 91d4afb5ceSopenharmony_ci } 92d4afb5ceSopenharmony_ci 93d4afb5ceSopenharmony_ci /* tag size is determined by enc cipher key length */ 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_ci n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY], 96d4afb5ceSopenharmony_ci jwe->jws.map.len[LJWE_EKEY], enc_cek, NULL, NULL, NULL, 97d4afb5ceSopenharmony_ci lws_gencrypto_bits_to_bytes( 98d4afb5ceSopenharmony_ci jwe->jose.enc_alg->keybits_fixed)); 99d4afb5ceSopenharmony_ci m = lws_genaes_destroy(&aesctx, NULL, 0); 100d4afb5ceSopenharmony_ci if (n < 0) { 101d4afb5ceSopenharmony_ci lwsl_err("%s: encrypt cek fail\n", __func__); 102d4afb5ceSopenharmony_ci return -1; 103d4afb5ceSopenharmony_ci } 104d4afb5ceSopenharmony_ci if (m < 0) { 105d4afb5ceSopenharmony_ci lwsl_err("%s: lws_genaes_destroy fail\n", __func__); 106d4afb5ceSopenharmony_ci return -1; 107d4afb5ceSopenharmony_ci } 108d4afb5ceSopenharmony_ci 109d4afb5ceSopenharmony_ci jwe->jws.map.len[LJWE_EKEY] += LWS_JWE_RFC3394_OVERHEAD_BYTES; 110d4afb5ceSopenharmony_ci memcpy((uint8_t *)jwe->jws.map.buf[LJWE_EKEY], enc_cek, 111d4afb5ceSopenharmony_ci jwe->jws.map.len[LJWE_EKEY]); 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci return (int)jwe->jws.map.len[LJWE_CTXT]; 114d4afb5ceSopenharmony_ci} 115d4afb5ceSopenharmony_ci 116d4afb5ceSopenharmony_ci 117d4afb5ceSopenharmony_ciint 118d4afb5ceSopenharmony_cilws_jwe_auth_and_decrypt_aeskw_cbc_hs(struct lws_jwe *jwe) 119d4afb5ceSopenharmony_ci{ 120d4afb5ceSopenharmony_ci struct lws_genaes_ctx aesctx; 121d4afb5ceSopenharmony_ci uint8_t enc_cek[LWS_JWE_LIMIT_KEY_ELEMENT_BYTES + 122d4afb5ceSopenharmony_ci LWS_JWE_RFC3394_OVERHEAD_BYTES]; 123d4afb5ceSopenharmony_ci int n, m; 124d4afb5ceSopenharmony_ci 125d4afb5ceSopenharmony_ci if (jwe->jws.jwk->kty != LWS_GENCRYPTO_KTY_OCT) { 126d4afb5ceSopenharmony_ci lwsl_err("%s: unexpected kty %d\n", __func__, jwe->jws.jwk->kty); 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_ci return -1; 129d4afb5ceSopenharmony_ci } 130d4afb5ceSopenharmony_ci 131d4afb5ceSopenharmony_ci /* the CEK is 256-bit in the example encrypted with a 128-bit key */ 132d4afb5ceSopenharmony_ci 133d4afb5ceSopenharmony_ci if (jwe->jws.map.len[LJWE_EKEY] > sizeof(enc_cek)) 134d4afb5ceSopenharmony_ci return -1; 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_ci /* 1) Decrypt the JWE Encrypted Key to get the raw MAC / CEK */ 137d4afb5ceSopenharmony_ci 138d4afb5ceSopenharmony_ci if (lws_genaes_create(&aesctx, LWS_GAESO_DEC, LWS_GAESM_KW, 139d4afb5ceSopenharmony_ci jwe->jws.jwk->e, 1, NULL)) { 140d4afb5ceSopenharmony_ci 141d4afb5ceSopenharmony_ci lwsl_notice("%s: lws_genaes_create\n", __func__); 142d4afb5ceSopenharmony_ci return -1; 143d4afb5ceSopenharmony_ci } 144d4afb5ceSopenharmony_ci 145d4afb5ceSopenharmony_ci /* 146d4afb5ceSopenharmony_ci * Decrypt the CEK into enc_cek 147d4afb5ceSopenharmony_ci * tag size is determined by enc cipher key length */ 148d4afb5ceSopenharmony_ci 149d4afb5ceSopenharmony_ci n = lws_genaes_crypt(&aesctx, (uint8_t *)jwe->jws.map.buf[LJWE_EKEY], 150d4afb5ceSopenharmony_ci jwe->jws.map.len[LJWE_EKEY], enc_cek, NULL, NULL, NULL, 151d4afb5ceSopenharmony_ci lws_gencrypto_bits_to_bytes( 152d4afb5ceSopenharmony_ci jwe->jose.enc_alg->keybits_fixed)); 153d4afb5ceSopenharmony_ci m = lws_genaes_destroy(&aesctx, NULL, 0); 154d4afb5ceSopenharmony_ci if (n < 0) { 155d4afb5ceSopenharmony_ci lwsl_err("%s: decrypt CEK fail\n", __func__); 156d4afb5ceSopenharmony_ci return -1; 157d4afb5ceSopenharmony_ci } 158d4afb5ceSopenharmony_ci if (m < 0) { 159d4afb5ceSopenharmony_ci lwsl_err("%s: lws_genaes_destroy fail\n", __func__); 160d4afb5ceSopenharmony_ci return -1; 161d4afb5ceSopenharmony_ci } 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci /* 2) Decrypt the payload */ 164d4afb5ceSopenharmony_ci 165d4afb5ceSopenharmony_ci n = lws_jwe_auth_and_decrypt_cbc_hs(jwe, enc_cek, 166d4afb5ceSopenharmony_ci (uint8_t *)jwe->jws.map_b64.buf[LJWE_JOSE], 167d4afb5ceSopenharmony_ci (int)jwe->jws.map_b64.len[LJWE_JOSE]); 168d4afb5ceSopenharmony_ci if (n < 0) { 169d4afb5ceSopenharmony_ci lwsl_err("%s: lws_jwe_auth_and_decrypt_cbc_hs failed\n", 170d4afb5ceSopenharmony_ci __func__); 171d4afb5ceSopenharmony_ci return -1; 172d4afb5ceSopenharmony_ci } 173d4afb5ceSopenharmony_ci 174d4afb5ceSopenharmony_ci return (int)jwe->jws.map.len[LJWE_CTXT]; 175d4afb5ceSopenharmony_ci} 176d4afb5ceSopenharmony_ci 177d4afb5ceSopenharmony_ci 178