1d4afb5ceSopenharmony_ci /* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2019 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 * lws_genaes provides an abstraction api for AES in lws that works the 25d4afb5ceSopenharmony_ci * same whether you are using openssl or mbedtls hash functions underneath. 26d4afb5ceSopenharmony_ci */ 27d4afb5ceSopenharmony_ci#include "private-lib-core.h" 28d4afb5ceSopenharmony_ci#if defined(LWS_WITH_JOSE) 29d4afb5ceSopenharmony_ci#include "private-lib-jose.h" 30d4afb5ceSopenharmony_ci#endif 31d4afb5ceSopenharmony_ci 32d4afb5ceSopenharmony_cistatic int operation_map[] = { MBEDTLS_AES_ENCRYPT, MBEDTLS_AES_DECRYPT }; 33d4afb5ceSopenharmony_ci 34d4afb5ceSopenharmony_cistatic unsigned int 35d4afb5ceSopenharmony_ci_write_pkcs7_pad(uint8_t *p, int len) 36d4afb5ceSopenharmony_ci{ 37d4afb5ceSopenharmony_ci unsigned int n = 0, padlen = LWS_AES_CBC_BLOCKLEN * ((unsigned int)len / 38d4afb5ceSopenharmony_ci LWS_AES_CBC_BLOCKLEN + 1) - (unsigned int)len; 39d4afb5ceSopenharmony_ci 40d4afb5ceSopenharmony_ci p += len; 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci while (n++ < padlen) 43d4afb5ceSopenharmony_ci *p++ = (uint8_t)padlen; 44d4afb5ceSopenharmony_ci 45d4afb5ceSopenharmony_ci return padlen; 46d4afb5ceSopenharmony_ci} 47d4afb5ceSopenharmony_ci 48d4afb5ceSopenharmony_ciint 49d4afb5ceSopenharmony_cilws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op, 50d4afb5ceSopenharmony_ci enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el, 51d4afb5ceSopenharmony_ci enum enum_aes_padding padding, void *engine) 52d4afb5ceSopenharmony_ci{ 53d4afb5ceSopenharmony_ci int n = 0; 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_ci ctx->mode = mode; 56d4afb5ceSopenharmony_ci ctx->k = el; 57d4afb5ceSopenharmony_ci ctx->op = (enum enum_aes_operation)operation_map[op]; 58d4afb5ceSopenharmony_ci ctx->underway = 0; 59d4afb5ceSopenharmony_ci ctx->padding = padding == LWS_GAESP_WITH_PADDING; 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci switch (ctx->mode) { 62d4afb5ceSopenharmony_ci case LWS_GAESM_XTS: 63d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_XTS) 64d4afb5ceSopenharmony_ci mbedtls_aes_xts_init(&ctx->u.ctx_xts); 65d4afb5ceSopenharmony_ci break; 66d4afb5ceSopenharmony_ci#else 67d4afb5ceSopenharmony_ci return -1; 68d4afb5ceSopenharmony_ci#endif 69d4afb5ceSopenharmony_ci case LWS_GAESM_GCM: 70d4afb5ceSopenharmony_ci mbedtls_gcm_init(&ctx->u.ctx_gcm); 71d4afb5ceSopenharmony_ci n = mbedtls_gcm_setkey(&ctx->u.ctx_gcm, MBEDTLS_CIPHER_ID_AES, 72d4afb5ceSopenharmony_ci ctx->k->buf, ctx->k->len * 8); 73d4afb5ceSopenharmony_ci if (n) { 74d4afb5ceSopenharmony_ci lwsl_notice("%s: mbedtls_gcm_setkey: -0x%x\n", 75d4afb5ceSopenharmony_ci __func__, -n); 76d4afb5ceSopenharmony_ci return n; 77d4afb5ceSopenharmony_ci } 78d4afb5ceSopenharmony_ci return n; 79d4afb5ceSopenharmony_ci default: 80d4afb5ceSopenharmony_ci mbedtls_aes_init(&ctx->u.ctx); 81d4afb5ceSopenharmony_ci break; 82d4afb5ceSopenharmony_ci } 83d4afb5ceSopenharmony_ci 84d4afb5ceSopenharmony_ci switch (op) { 85d4afb5ceSopenharmony_ci case LWS_GAESO_ENC: 86d4afb5ceSopenharmony_ci if (ctx->mode == LWS_GAESM_XTS) 87d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_XTS) 88d4afb5ceSopenharmony_ci n = mbedtls_aes_xts_setkey_enc(&ctx->u.ctx_xts, 89d4afb5ceSopenharmony_ci ctx->k->buf, 90d4afb5ceSopenharmony_ci ctx->k->len * 8); 91d4afb5ceSopenharmony_ci#else 92d4afb5ceSopenharmony_ci return -1; 93d4afb5ceSopenharmony_ci#endif 94d4afb5ceSopenharmony_ci else 95d4afb5ceSopenharmony_ci n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf, 96d4afb5ceSopenharmony_ci ctx->k->len * 8); 97d4afb5ceSopenharmony_ci break; 98d4afb5ceSopenharmony_ci case LWS_GAESO_DEC: 99d4afb5ceSopenharmony_ci switch (ctx->mode) { 100d4afb5ceSopenharmony_ci case LWS_GAESM_XTS: 101d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_XTS) 102d4afb5ceSopenharmony_ci n = mbedtls_aes_xts_setkey_dec(&ctx->u.ctx_xts, 103d4afb5ceSopenharmony_ci ctx->k->buf, 104d4afb5ceSopenharmony_ci ctx->k->len * 8); 105d4afb5ceSopenharmony_ci break; 106d4afb5ceSopenharmony_ci#else 107d4afb5ceSopenharmony_ci return -1; 108d4afb5ceSopenharmony_ci#endif 109d4afb5ceSopenharmony_ci 110d4afb5ceSopenharmony_ci case LWS_GAESM_CFB128: 111d4afb5ceSopenharmony_ci case LWS_GAESM_CFB8: 112d4afb5ceSopenharmony_ci case LWS_GAESM_CTR: 113d4afb5ceSopenharmony_ci case LWS_GAESM_OFB: 114d4afb5ceSopenharmony_ci n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf, 115d4afb5ceSopenharmony_ci ctx->k->len * 8); 116d4afb5ceSopenharmony_ci break; 117d4afb5ceSopenharmony_ci default: 118d4afb5ceSopenharmony_ci n = mbedtls_aes_setkey_dec(&ctx->u.ctx, ctx->k->buf, 119d4afb5ceSopenharmony_ci ctx->k->len * 8); 120d4afb5ceSopenharmony_ci break; 121d4afb5ceSopenharmony_ci } 122d4afb5ceSopenharmony_ci break; 123d4afb5ceSopenharmony_ci } 124d4afb5ceSopenharmony_ci 125d4afb5ceSopenharmony_ci if (n) 126d4afb5ceSopenharmony_ci lwsl_notice("%s: setting key: -0x%x\n", __func__, -n); 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_ci return n; 129d4afb5ceSopenharmony_ci} 130d4afb5ceSopenharmony_ci 131d4afb5ceSopenharmony_ciint 132d4afb5ceSopenharmony_cilws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen) 133d4afb5ceSopenharmony_ci{ 134d4afb5ceSopenharmony_ci#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 135d4afb5ceSopenharmony_ci size_t last_len = 0; 136d4afb5ceSopenharmony_ci uint8_t last[16]; 137d4afb5ceSopenharmony_ci#endif 138d4afb5ceSopenharmony_ci int n; 139d4afb5ceSopenharmony_ci 140d4afb5ceSopenharmony_ci if (ctx->mode == LWS_GAESM_GCM) { 141d4afb5ceSopenharmony_ci#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 142d4afb5ceSopenharmony_ci n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, last, sizeof(last), 143d4afb5ceSopenharmony_ci &last_len, tag, tlen); 144d4afb5ceSopenharmony_ci#else 145d4afb5ceSopenharmony_ci n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, tag, tlen); 146d4afb5ceSopenharmony_ci#endif 147d4afb5ceSopenharmony_ci 148d4afb5ceSopenharmony_ci if (n) 149d4afb5ceSopenharmony_ci lwsl_notice("%s: mbedtls_gcm_finish: -0x%x\n", 150d4afb5ceSopenharmony_ci __func__, -n); 151d4afb5ceSopenharmony_ci if (tag && ctx->op == MBEDTLS_AES_DECRYPT && !n) { 152d4afb5ceSopenharmony_ci if (lws_timingsafe_bcmp(ctx->tag, tag, (unsigned int)ctx->taglen)) { 153d4afb5ceSopenharmony_ci lwsl_err("%s: lws_genaes_crypt tag " 154d4afb5ceSopenharmony_ci "mismatch (bad first)\n", 155d4afb5ceSopenharmony_ci __func__); 156d4afb5ceSopenharmony_ci lwsl_hexdump_notice(tag, tlen); 157d4afb5ceSopenharmony_ci lwsl_hexdump_notice(ctx->tag, (unsigned int)ctx->taglen); 158d4afb5ceSopenharmony_ci n = -1; 159d4afb5ceSopenharmony_ci } 160d4afb5ceSopenharmony_ci } 161d4afb5ceSopenharmony_ci mbedtls_gcm_free(&ctx->u.ctx_gcm); 162d4afb5ceSopenharmony_ci return n; 163d4afb5ceSopenharmony_ci } 164d4afb5ceSopenharmony_ci if (ctx->mode == LWS_GAESM_XTS) 165d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_XTS) 166d4afb5ceSopenharmony_ci mbedtls_aes_xts_free(&ctx->u.ctx_xts); 167d4afb5ceSopenharmony_ci#else 168d4afb5ceSopenharmony_ci return -1; 169d4afb5ceSopenharmony_ci#endif 170d4afb5ceSopenharmony_ci else 171d4afb5ceSopenharmony_ci mbedtls_aes_free(&ctx->u.ctx); 172d4afb5ceSopenharmony_ci 173d4afb5ceSopenharmony_ci return 0; 174d4afb5ceSopenharmony_ci} 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_mbedtls_internal_aes_encrypt) 177d4afb5ceSopenharmony_cistatic int 178d4afb5ceSopenharmony_cilws_genaes_rfc3394_wrap(int wrap, int cek_bits, const uint8_t *kek, 179d4afb5ceSopenharmony_ci int kek_bits, const uint8_t *in, uint8_t *out) 180d4afb5ceSopenharmony_ci{ 181d4afb5ceSopenharmony_ci int n, m, ret = -1, c64 = cek_bits / 64; 182d4afb5ceSopenharmony_ci mbedtls_aes_context ctx; 183d4afb5ceSopenharmony_ci uint8_t a[8], b[16]; 184d4afb5ceSopenharmony_ci 185d4afb5ceSopenharmony_ci /* 186d4afb5ceSopenharmony_ci * notice the KEK key used to perform the wrapping or unwrapping is 187d4afb5ceSopenharmony_ci * always the size of the AES key used, eg, A128KW == 128 bits. The 188d4afb5ceSopenharmony_ci * key being wrapped or unwrapped may be larger and is set by the 189d4afb5ceSopenharmony_ci * 'bits' parameter. 190d4afb5ceSopenharmony_ci * 191d4afb5ceSopenharmony_ci * If it's larger than the KEK key size bits, we iterate over it 192d4afb5ceSopenharmony_ci */ 193d4afb5ceSopenharmony_ci 194d4afb5ceSopenharmony_ci mbedtls_aes_init(&ctx); 195d4afb5ceSopenharmony_ci 196d4afb5ceSopenharmony_ci if (wrap) { 197d4afb5ceSopenharmony_ci /* 198d4afb5ceSopenharmony_ci * The inputs to the key wrapping process are the KEK and the 199d4afb5ceSopenharmony_ci * plaintext to be wrapped. The plaintext consists of n 64-bit 200d4afb5ceSopenharmony_ci * blocks, containing the key data being wrapped. 201d4afb5ceSopenharmony_ci * 202d4afb5ceSopenharmony_ci * Inputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}, 203d4afb5ceSopenharmony_ci * and Key, K (the KEK). 204d4afb5ceSopenharmony_ci * Outputs: Ciphertext, (n+1) 64-bit values 205d4afb5ceSopenharmony_ci * {C0, C1, ..., Cn}. 206d4afb5ceSopenharmony_ci * 207d4afb5ceSopenharmony_ci * The default initial value (IV) is defined to be the 208d4afb5ceSopenharmony_ci * hexadecimal constant: 209d4afb5ceSopenharmony_ci * 210d4afb5ceSopenharmony_ci * A[0] = IV = A6A6A6A6A6A6A6A6 211d4afb5ceSopenharmony_ci */ 212d4afb5ceSopenharmony_ci memset(out, 0xa6, 8); 213d4afb5ceSopenharmony_ci memcpy(out + 8, in, 8 * (unsigned int)c64); 214d4afb5ceSopenharmony_ci n = mbedtls_aes_setkey_enc(&ctx, kek, (unsigned int)kek_bits); 215d4afb5ceSopenharmony_ci } else { 216d4afb5ceSopenharmony_ci /* 217d4afb5ceSopenharmony_ci * 2.2.2 Key Unwrap 218d4afb5ceSopenharmony_ci * 219d4afb5ceSopenharmony_ci * The inputs to the unwrap process are the KEK and (n+1) 220d4afb5ceSopenharmony_ci * 64-bit blocks of ciphertext consisting of previously 221d4afb5ceSopenharmony_ci * wrapped key. It returns n blocks of plaintext consisting 222d4afb5ceSopenharmony_ci * of the n 64-bit blocks of the decrypted key data. 223d4afb5ceSopenharmony_ci * 224d4afb5ceSopenharmony_ci * Inputs: Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn}, 225d4afb5ceSopenharmony_ci * and Key, K (the KEK). 226d4afb5ceSopenharmony_ci * 227d4afb5ceSopenharmony_ci * Outputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}. 228d4afb5ceSopenharmony_ci */ 229d4afb5ceSopenharmony_ci memcpy(a, in, 8); 230d4afb5ceSopenharmony_ci memcpy(out, in + 8, 8 * (unsigned int)c64); 231d4afb5ceSopenharmony_ci n = mbedtls_aes_setkey_dec(&ctx, kek, (unsigned int)kek_bits); 232d4afb5ceSopenharmony_ci } 233d4afb5ceSopenharmony_ci 234d4afb5ceSopenharmony_ci if (n < 0) { 235d4afb5ceSopenharmony_ci lwsl_err("%s: setkey failed\n", __func__); 236d4afb5ceSopenharmony_ci goto bail; 237d4afb5ceSopenharmony_ci } 238d4afb5ceSopenharmony_ci 239d4afb5ceSopenharmony_ci if (wrap) { 240d4afb5ceSopenharmony_ci for (n = 0; n <= 5; n++) { 241d4afb5ceSopenharmony_ci uint8_t *r = out + 8; 242d4afb5ceSopenharmony_ci for (m = 1; m <= c64; m++) { 243d4afb5ceSopenharmony_ci memcpy(b, out, 8); 244d4afb5ceSopenharmony_ci memcpy(b + 8, r, 8); 245d4afb5ceSopenharmony_ci if (mbedtls_internal_aes_encrypt(&ctx, b, b)) 246d4afb5ceSopenharmony_ci goto bail; 247d4afb5ceSopenharmony_ci 248d4afb5ceSopenharmony_ci memcpy(out, b, 8); 249d4afb5ceSopenharmony_ci out[7] ^= (uint8_t)(c64 * n + m); 250d4afb5ceSopenharmony_ci memcpy(r, b + 8, 8); 251d4afb5ceSopenharmony_ci r += 8; 252d4afb5ceSopenharmony_ci } 253d4afb5ceSopenharmony_ci } 254d4afb5ceSopenharmony_ci ret = 0; 255d4afb5ceSopenharmony_ci } else { 256d4afb5ceSopenharmony_ci /* 257d4afb5ceSopenharmony_ci * 258d4afb5ceSopenharmony_ci */ 259d4afb5ceSopenharmony_ci for (n = 5; n >= 0; n--) { 260d4afb5ceSopenharmony_ci uint8_t *r = out + (c64 - 1) * 8; 261d4afb5ceSopenharmony_ci for (m = c64; m >= 1; m--) { 262d4afb5ceSopenharmony_ci memcpy(b, a, 8); 263d4afb5ceSopenharmony_ci b[7] ^= (uint8_t)(c64 * n + m); 264d4afb5ceSopenharmony_ci memcpy(b + 8, r, 8); 265d4afb5ceSopenharmony_ci if (mbedtls_internal_aes_decrypt(&ctx, b, b)) 266d4afb5ceSopenharmony_ci goto bail; 267d4afb5ceSopenharmony_ci 268d4afb5ceSopenharmony_ci memcpy(a, b, 8); 269d4afb5ceSopenharmony_ci memcpy(r, b + 8, 8); 270d4afb5ceSopenharmony_ci r -= 8; 271d4afb5ceSopenharmony_ci } 272d4afb5ceSopenharmony_ci } 273d4afb5ceSopenharmony_ci 274d4afb5ceSopenharmony_ci ret = 0; 275d4afb5ceSopenharmony_ci for (n = 0; n < 8; n++) 276d4afb5ceSopenharmony_ci if (a[n] != 0xa6) 277d4afb5ceSopenharmony_ci ret = -1; 278d4afb5ceSopenharmony_ci } 279d4afb5ceSopenharmony_ci 280d4afb5ceSopenharmony_cibail: 281d4afb5ceSopenharmony_ci if (ret) 282d4afb5ceSopenharmony_ci lwsl_notice("%s: failed\n", __func__); 283d4afb5ceSopenharmony_ci mbedtls_aes_free(&ctx); 284d4afb5ceSopenharmony_ci 285d4afb5ceSopenharmony_ci return ret; 286d4afb5ceSopenharmony_ci} 287d4afb5ceSopenharmony_ci#endif 288d4afb5ceSopenharmony_ci 289d4afb5ceSopenharmony_ciint 290d4afb5ceSopenharmony_cilws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len, 291d4afb5ceSopenharmony_ci uint8_t *out, uint8_t *iv_or_nonce_ctr_or_data_unit_16, 292d4afb5ceSopenharmony_ci uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen) 293d4afb5ceSopenharmony_ci{ 294d4afb5ceSopenharmony_ci uint8_t iv[LWS_JWE_AES_IV_BYTES], sb[16]; 295d4afb5ceSopenharmony_ci int n = 0; 296d4afb5ceSopenharmony_ci 297d4afb5ceSopenharmony_ci switch (ctx->mode) { 298d4afb5ceSopenharmony_ci case LWS_GAESM_KW: 299d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_mbedtls_internal_aes_encrypt) 300d4afb5ceSopenharmony_ci /* a key of length ctx->k->len is wrapped by a 128-bit KEK */ 301d4afb5ceSopenharmony_ci n = lws_genaes_rfc3394_wrap(ctx->op == MBEDTLS_AES_ENCRYPT, 302d4afb5ceSopenharmony_ci (ctx->op == MBEDTLS_AES_ENCRYPT ? (int)len * 8 : 303d4afb5ceSopenharmony_ci ((int)len - 8) * 8), ctx->k->buf, 304d4afb5ceSopenharmony_ci (int)ctx->k->len * 8, 305d4afb5ceSopenharmony_ci in, out); 306d4afb5ceSopenharmony_ci break; 307d4afb5ceSopenharmony_ci#else 308d4afb5ceSopenharmony_ci lwsl_err("%s: your mbedtls is too old\n", __func__); 309d4afb5ceSopenharmony_ci return -1; 310d4afb5ceSopenharmony_ci#endif 311d4afb5ceSopenharmony_ci case LWS_GAESM_CBC: 312d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 313d4afb5ceSopenharmony_ci 314d4afb5ceSopenharmony_ci /* 315d4afb5ceSopenharmony_ci * If encrypting, we do the PKCS#7 padding. 316d4afb5ceSopenharmony_ci * During decryption, the caller will need to unpad. 317d4afb5ceSopenharmony_ci */ 318d4afb5ceSopenharmony_ci if (ctx->padding && ctx->op == MBEDTLS_AES_ENCRYPT) { 319d4afb5ceSopenharmony_ci /* 320d4afb5ceSopenharmony_ci * Since we don't want to burden the caller with 321d4afb5ceSopenharmony_ci * the over-allocation at the end of the input, 322d4afb5ceSopenharmony_ci * we have to allocate a temp with space for it 323d4afb5ceSopenharmony_ci */ 324d4afb5ceSopenharmony_ci uint8_t *padin = (uint8_t *)lws_malloc( 325d4afb5ceSopenharmony_ci lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN, len), 326d4afb5ceSopenharmony_ci __func__); 327d4afb5ceSopenharmony_ci 328d4afb5ceSopenharmony_ci if (!padin) 329d4afb5ceSopenharmony_ci return -1; 330d4afb5ceSopenharmony_ci 331d4afb5ceSopenharmony_ci memcpy(padin, in, len); 332d4afb5ceSopenharmony_ci len += _write_pkcs7_pad((uint8_t *)padin, (int)len); 333d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv, 334d4afb5ceSopenharmony_ci padin, out); 335d4afb5ceSopenharmony_ci lws_free(padin); 336d4afb5ceSopenharmony_ci } else 337d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, (int)ctx->op, len, iv, 338d4afb5ceSopenharmony_ci in, out); 339d4afb5ceSopenharmony_ci 340d4afb5ceSopenharmony_ci break; 341d4afb5ceSopenharmony_ci 342d4afb5ceSopenharmony_ci case LWS_GAESM_CFB128: 343d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 344d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_cfb128(&ctx->u.ctx, (int)ctx->op, len, 345d4afb5ceSopenharmony_ci nc_or_iv_off, iv, in, out); 346d4afb5ceSopenharmony_ci break; 347d4afb5ceSopenharmony_ci 348d4afb5ceSopenharmony_ci case LWS_GAESM_CFB8: 349d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 350d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_cfb8(&ctx->u.ctx, (int)ctx->op, len, iv, 351d4afb5ceSopenharmony_ci in, out); 352d4afb5ceSopenharmony_ci break; 353d4afb5ceSopenharmony_ci 354d4afb5ceSopenharmony_ci case LWS_GAESM_CTR: 355d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 356d4afb5ceSopenharmony_ci memcpy(sb, stream_block_16, 16); 357d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_ctr(&ctx->u.ctx, len, nc_or_iv_off, 358d4afb5ceSopenharmony_ci iv, sb, in, out); 359d4afb5ceSopenharmony_ci memcpy(iv_or_nonce_ctr_or_data_unit_16, iv, 16); 360d4afb5ceSopenharmony_ci memcpy(stream_block_16, sb, 16); 361d4afb5ceSopenharmony_ci break; 362d4afb5ceSopenharmony_ci 363d4afb5ceSopenharmony_ci case LWS_GAESM_ECB: 364d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_ecb(&ctx->u.ctx, (int)ctx->op, in, out); 365d4afb5ceSopenharmony_ci break; 366d4afb5ceSopenharmony_ci 367d4afb5ceSopenharmony_ci case LWS_GAESM_OFB: 368d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_OFB) 369d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 370d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_ofb(&ctx->u.ctx, len, nc_or_iv_off, iv, 371d4afb5ceSopenharmony_ci in, out); 372d4afb5ceSopenharmony_ci break; 373d4afb5ceSopenharmony_ci#else 374d4afb5ceSopenharmony_ci return -1; 375d4afb5ceSopenharmony_ci#endif 376d4afb5ceSopenharmony_ci 377d4afb5ceSopenharmony_ci case LWS_GAESM_XTS: 378d4afb5ceSopenharmony_ci#if defined(MBEDTLS_CIPHER_MODE_XTS) 379d4afb5ceSopenharmony_ci memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16); 380d4afb5ceSopenharmony_ci n = mbedtls_aes_crypt_xts(&ctx->u.ctx_xts, (int)ctx->op, len, iv, 381d4afb5ceSopenharmony_ci in, out); 382d4afb5ceSopenharmony_ci break; 383d4afb5ceSopenharmony_ci#else 384d4afb5ceSopenharmony_ci return -1; 385d4afb5ceSopenharmony_ci#endif 386d4afb5ceSopenharmony_ci case LWS_GAESM_GCM: 387d4afb5ceSopenharmony_ci if (!ctx->underway) { 388d4afb5ceSopenharmony_ci ctx->underway = 1; 389d4afb5ceSopenharmony_ci 390d4afb5ceSopenharmony_ci memcpy(ctx->tag, stream_block_16, (unsigned int)taglen); 391d4afb5ceSopenharmony_ci ctx->taglen = taglen; 392d4afb5ceSopenharmony_ci 393d4afb5ceSopenharmony_ci /* 394d4afb5ceSopenharmony_ci * iv: iv_or_nonce_ctr_or_data_unit_16 395d4afb5ceSopenharmony_ci * iv_len: *nc_or_iv_off 396d4afb5ceSopenharmony_ci * stream_block_16: pointer to tag 397d4afb5ceSopenharmony_ci * additional data: in 398d4afb5ceSopenharmony_ci * additional data len: len 399d4afb5ceSopenharmony_ci */ 400d4afb5ceSopenharmony_ci 401d4afb5ceSopenharmony_ci#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 402d4afb5ceSopenharmony_ci n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, (int)ctx->op, 403d4afb5ceSopenharmony_ci iv_or_nonce_ctr_or_data_unit_16, 404d4afb5ceSopenharmony_ci *nc_or_iv_off); 405d4afb5ceSopenharmony_ci if (!n) 406d4afb5ceSopenharmony_ci n = mbedtls_gcm_update_ad(&ctx->u.ctx_gcm, 407d4afb5ceSopenharmony_ci in, len); 408d4afb5ceSopenharmony_ci#else 409d4afb5ceSopenharmony_ci n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, (int)ctx->op, 410d4afb5ceSopenharmony_ci iv_or_nonce_ctr_or_data_unit_16, 411d4afb5ceSopenharmony_ci *nc_or_iv_off, in, len); 412d4afb5ceSopenharmony_ci#endif 413d4afb5ceSopenharmony_ci if (n) { 414d4afb5ceSopenharmony_ci lwsl_notice("%s: mbedtls_gcm_starts: -0x%x\n", 415d4afb5ceSopenharmony_ci __func__, -n); 416d4afb5ceSopenharmony_ci 417d4afb5ceSopenharmony_ci return -1; 418d4afb5ceSopenharmony_ci } 419d4afb5ceSopenharmony_ci break; 420d4afb5ceSopenharmony_ci } 421d4afb5ceSopenharmony_ci 422d4afb5ceSopenharmony_ci#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 423d4afb5ceSopenharmony_ci { 424d4afb5ceSopenharmony_ci size_t al; 425d4afb5ceSopenharmony_ci 426d4afb5ceSopenharmony_ci n = mbedtls_gcm_update(&ctx->u.ctx_gcm, in, len, out, len, &al); 427d4afb5ceSopenharmony_ci } 428d4afb5ceSopenharmony_ci#else 429d4afb5ceSopenharmony_ci n = mbedtls_gcm_update(&ctx->u.ctx_gcm, len, in, out); 430d4afb5ceSopenharmony_ci#endif 431d4afb5ceSopenharmony_ci if (n) { 432d4afb5ceSopenharmony_ci lwsl_notice("%s: mbedtls_gcm_update: -0x%x\n", 433d4afb5ceSopenharmony_ci __func__, -n); 434d4afb5ceSopenharmony_ci 435d4afb5ceSopenharmony_ci return -1; 436d4afb5ceSopenharmony_ci } 437d4afb5ceSopenharmony_ci break; 438d4afb5ceSopenharmony_ci } 439d4afb5ceSopenharmony_ci 440d4afb5ceSopenharmony_ci if (n) { 441d4afb5ceSopenharmony_ci lwsl_notice("%s: failed: -0x%x, len %d\n", __func__, -n, (int)len); 442d4afb5ceSopenharmony_ci 443d4afb5ceSopenharmony_ci return -1; 444d4afb5ceSopenharmony_ci } 445d4afb5ceSopenharmony_ci 446d4afb5ceSopenharmony_ci return 0; 447d4afb5ceSopenharmony_ci} 448