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 /*! \defgroup generic AES 26 * ## Generic AES related functions 27 * 28 * Lws provides generic AES functions that abstract the ones 29 * provided by whatever tls library you are linking against. 30 * 31 * It lets you use the same code if you build against mbedtls or OpenSSL 32 * for example. 33 */ 34 ///@{ 35 36 #if defined(LWS_WITH_MBEDTLS) 37 #include <mbedtls/aes.h> 38 #include <mbedtls/gcm.h> 39 #endif 40 41 enum enum_aes_modes { 42 LWS_GAESM_CBC, 43 LWS_GAESM_CFB128, 44 LWS_GAESM_CFB8, 45 LWS_GAESM_CTR, 46 LWS_GAESM_ECB, 47 LWS_GAESM_OFB, 48 LWS_GAESM_XTS, /* care... requires double-length key */ 49 LWS_GAESM_GCM, 50 LWS_GAESM_KW, 51 }; 52 53 enum enum_aes_operation { 54 LWS_GAESO_ENC, 55 LWS_GAESO_DEC 56 }; 57 58 enum enum_aes_padding { 59 LWS_GAESP_NO_PADDING, 60 LWS_GAESP_WITH_PADDING 61 }; 62 63 /* include/libwebsockets/lws-jwk.h must be included before this */ 64 65 #define LWS_AES_BLOCKSIZE 128 66 #define LWS_AES_CBC_BLOCKLEN 16 67 68 struct lws_genaes_ctx { 69 #if defined(LWS_WITH_MBEDTLS) 70 union { 71 mbedtls_aes_context ctx; 72 #if defined(MBEDTLS_CIPHER_MODE_XTS) 73 mbedtls_aes_xts_context ctx_xts; 74 #endif 75 mbedtls_gcm_context ctx_gcm; 76 } u; 77 #else 78 EVP_CIPHER_CTX *ctx; 79 const EVP_CIPHER *cipher; 80 ENGINE *engine; 81 char init; 82 #endif 83 unsigned char tag[16]; 84 struct lws_gencrypto_keyelem *k; 85 enum enum_aes_operation op; 86 enum enum_aes_modes mode; 87 enum enum_aes_padding padding; 88 int taglen; 89 char underway; 90 }; 91 92 /** lws_genaes_create() - Create RSA public decrypt context 93 * 94 * \param ctx: your struct lws_genaes_ctx 95 * \param op: LWS_GAESO_ENC or LWS_GAESO_DEC 96 * \param mode: one of LWS_GAESM_ 97 * \param el: struct prepared with key element data 98 * \param padding: 0 = no padding, 1 = padding 99 * \param engine: if openssl engine used, pass the pointer here 100 * 101 * Creates an RSA context with a public key associated with it, formed from 102 * the key elements in \p el. 103 * 104 * Returns 0 for OK or nonzero for error. 105 * 106 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 107 */ 108 LWS_VISIBLE LWS_EXTERN int 109 lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op, 110 enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el, 111 enum enum_aes_padding padding, void *engine); 112 113 /** lws_genaes_destroy() - Destroy genaes AES context 114 * 115 * \param ctx: your struct lws_genaes_ctx 116 * \param tag: NULL, or, GCM-only: buffer to receive tag 117 * \param tlen: 0, or, GCM-only: length of tag buffer 118 * 119 * Destroys any allocations related to \p ctx. 120 * 121 * For GCM only, up to tlen bytes of tag buffer will be set on exit. 122 * 123 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 124 */ 125 LWS_VISIBLE LWS_EXTERN int 126 lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen); 127 128 /** lws_genaes_crypt() - Encrypt or decrypt 129 * 130 * \param ctx: your struct lws_genaes_ctx 131 * \param in: input plaintext or ciphertext 132 * \param len: length of input (which is always length of output) 133 * \param out: output plaintext or ciphertext 134 * \param iv_or_nonce_ctr_or_data_unit_16: NULL, iv, nonce_ctr16, or data_unit16 135 * \param stream_block_16: pointer to 16-byte stream block for CTR mode only 136 * \param nc_or_iv_off: NULL or pointer to nc, or iv_off 137 * \param taglen: length of tag 138 * 139 * Encrypts or decrypts using the AES mode set when the ctx was created. 140 * The last three arguments have different meanings depending on the mode: 141 * 142 * KW CBC CFB128 CFB8 CTR ECB OFB XTS 143 * iv_or_nonce_ct.._unit_16 : iv iv iv iv nonce NULL iv dataunt 144 * stream_block_16 : NULL NULL NULL NULL stream NULL NULL NULL 145 * nc_or_iv_off : NULL NULL iv_off NULL nc_off NULL iv_off NULL 146 * 147 * For GCM: 148 * 149 * iv_or_nonce_ctr_or_data_unit_16 : iv 150 * stream_block_16 : pointer to tag 151 * nc_or_iv_off : set pointed-to size_t to iv length 152 * in : first call: additional data, subsequently 153 * : input data 154 * len : first call: add data length, subsequently 155 * : input / output length 156 * 157 * The length of the optional arg is always 16 if used, regardless of the mode. 158 * 159 * Returns 0 for OK or nonzero for error. 160 * 161 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 162 */ 163 LWS_VISIBLE LWS_EXTERN int 164 lws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len, 165 uint8_t *out, 166 uint8_t *iv_or_nonce_ctr_or_data_unit_16, 167 uint8_t *stream_block_16, 168 size_t *nc_or_iv_off, int taglen); 169 170 ///@} 171