1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 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 genericRSA Generic RSA 26 * ## Generic RSA related functions 27 * 28 * Lws provides generic RSA functions that abstract the ones 29 * provided by whatever OpenSSL 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 /* include/libwebsockets/lws-jwk.h must be included before this */ 37 38 enum enum_genrsa_mode { 39 LGRSAM_PKCS1_1_5, 40 LGRSAM_PKCS1_OAEP_PSS, 41 42 LGRSAM_COUNT 43 }; 44 45 struct lws_genrsa_ctx { 46 #if defined(LWS_WITH_MBEDTLS) 47 mbedtls_rsa_context *ctx; 48 #else 49 BIGNUM *bn[LWS_GENCRYPTO_RSA_KEYEL_COUNT]; 50 EVP_PKEY_CTX *ctx; 51 RSA *rsa; 52 #endif 53 struct lws_context *context; 54 enum enum_genrsa_mode mode; 55 }; 56 57 /** lws_genrsa_public_decrypt_create() - Create RSA public decrypt context 58 * 59 * \param ctx: your struct lws_genrsa_ctx 60 * \param el: struct prepared with key element data 61 * \param context: lws_context for RNG 62 * \param mode: RSA mode, one of LGRSAM_ constants 63 * \param oaep_hashid: the lws genhash id for the hash used in MFG1 hash 64 * used in OAEP mode - normally, SHA1 65 * 66 * Creates an RSA context with a public key associated with it, formed from 67 * the key elements in \p el. 68 * 69 * Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses. It's 70 * recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations. 71 * 72 * Returns 0 for OK or nonzero for error. 73 * 74 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 75 */ 76 LWS_VISIBLE LWS_EXTERN int 77 lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_gencrypto_keyelem *el, 78 struct lws_context *context, enum enum_genrsa_mode mode, 79 enum lws_genhash_types oaep_hashid); 80 81 /** lws_genrsa_destroy_elements() - Free allocations in genrsa_elements 82 * 83 * \param el: your struct lws_gencrypto_keyelem 84 * 85 * This is a helper for user code making use of struct lws_gencrypto_keyelem 86 * where the elements are allocated on the heap, it frees any non-NULL 87 * buf element and sets the buf to NULL. 88 * 89 * NB: lws_genrsa_public_... apis do not need this as they take care of the key 90 * creation and destruction themselves. 91 */ 92 LWS_VISIBLE LWS_EXTERN void 93 lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el); 94 95 /** lws_genrsa_new_keypair() - Create new RSA keypair 96 * 97 * \param context: your struct lws_context (may be used for RNG) 98 * \param ctx: your struct lws_genrsa_ctx 99 * \param mode: RSA mode, one of LGRSAM_ constants 100 * \param el: struct to get the new key element data allocated into it 101 * \param bits: key size, eg, 4096 102 * 103 * Creates a new RSA context and generates a new keypair into it, with \p bits 104 * bits. 105 * 106 * Returns 0 for OK or nonzero for error. 107 * 108 * Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses. It's 109 * recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations. 110 * 111 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 112 */ 113 LWS_VISIBLE LWS_EXTERN int 114 lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx, 115 enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el, 116 int bits); 117 118 /** lws_genrsa_public_encrypt() - Perform RSA public key encryption 119 * 120 * \param ctx: your struct lws_genrsa_ctx 121 * \param in: plaintext input 122 * \param in_len: length of plaintext input 123 * \param out: encrypted output 124 * 125 * Performs PKCS1 v1.5 Encryption 126 * 127 * Returns <0 for error, or length of decrypted data. 128 * 129 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 130 */ 131 LWS_VISIBLE LWS_EXTERN int 132 lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, 133 size_t in_len, uint8_t *out); 134 135 /** lws_genrsa_private_encrypt() - Perform RSA private key encryption 136 * 137 * \param ctx: your struct lws_genrsa_ctx 138 * \param in: plaintext input 139 * \param in_len: length of plaintext input 140 * \param out: encrypted output 141 * 142 * Performs PKCS1 v1.5 Encryption 143 * 144 * Returns <0 for error, or length of decrypted data. 145 * 146 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 147 */ 148 LWS_VISIBLE LWS_EXTERN int 149 lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, 150 size_t in_len, uint8_t *out); 151 152 /** lws_genrsa_public_decrypt() - Perform RSA public key decryption 153 * 154 * \param ctx: your struct lws_genrsa_ctx 155 * \param in: encrypted input 156 * \param in_len: length of encrypted input 157 * \param out: decrypted output 158 * \param out_max: size of output buffer 159 * 160 * Performs PKCS1 v1.5 Decryption 161 * 162 * Returns <0 for error, or length of decrypted data. 163 * 164 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 165 */ 166 LWS_VISIBLE LWS_EXTERN int 167 lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, 168 size_t in_len, uint8_t *out, size_t out_max); 169 170 /** lws_genrsa_private_decrypt() - Perform RSA private key decryption 171 * 172 * \param ctx: your struct lws_genrsa_ctx 173 * \param in: encrypted input 174 * \param in_len: length of encrypted input 175 * \param out: decrypted output 176 * \param out_max: size of output buffer 177 * 178 * Performs PKCS1 v1.5 Decryption 179 * 180 * Returns <0 for error, or length of decrypted data. 181 * 182 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 183 */ 184 LWS_VISIBLE LWS_EXTERN int 185 lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, 186 size_t in_len, uint8_t *out, size_t out_max); 187 188 /** lws_genrsa_hash_sig_verify() - Verifies RSA signature on a given hash 189 * 190 * \param ctx: your struct lws_genrsa_ctx 191 * \param in: input to be hashed 192 * \param hash_type: one of LWS_GENHASH_TYPE_ 193 * \param sig: pointer to the signature we received with the payload 194 * \param sig_len: length of the signature we are checking in bytes 195 * 196 * Returns <0 for error, or 0 if signature matches the payload + key. 197 * 198 * This just looks at a hash... that's why there's no input length 199 * parameter, it's decided by the choice of hash. It's up to you to confirm 200 * separately the actual payload matches the hash that was confirmed by this to 201 * be validly signed. 202 * 203 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 204 */ 205 LWS_VISIBLE LWS_EXTERN int 206 lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in, 207 enum lws_genhash_types hash_type, 208 const uint8_t *sig, size_t sig_len); 209 210 /** lws_genrsa_hash_sign() - Creates an ECDSA signature for a hash you provide 211 * 212 * \param ctx: your struct lws_genrsa_ctx 213 * \param in: input to be hashed and signed 214 * \param hash_type: one of LWS_GENHASH_TYPE_ 215 * \param sig: pointer to buffer to take signature 216 * \param sig_len: length of the buffer (must be >= length of key N) 217 * 218 * Returns <0 for error, or 0 for success. 219 * 220 * This creates an RSA signature for a hash you already computed and provide. 221 * You should have created the hash before calling this by iterating over the 222 * actual payload you need to confirm. 223 * 224 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 225 */ 226 LWS_VISIBLE LWS_EXTERN int 227 lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in, 228 enum lws_genhash_types hash_type, 229 uint8_t *sig, size_t sig_len); 230 231 /** lws_genrsa_public_decrypt_destroy() - Destroy RSA public decrypt context 232 * 233 * \param ctx: your struct lws_genrsa_ctx 234 * 235 * Destroys any allocations related to \p ctx. 236 * 237 * This and related APIs operate identically with OpenSSL or mbedTLS backends. 238 */ 239 LWS_VISIBLE LWS_EXTERN void 240 lws_genrsa_destroy(struct lws_genrsa_ctx *ctx); 241 242 /** lws_genrsa_render_pkey_asn1() - Exports public or private key to ASN1/DER 243 * 244 * \param ctx: your struct lws_genrsa_ctx 245 * \param _private: 0 = public part only, 1 = all parts of the key 246 * \param pkey_asn1: pointer to buffer to take the ASN1 247 * \param pkey_asn1_len: max size of the pkey_asn1_len 248 * 249 * Returns length of pkey_asn1 written, or -1 for error. 250 */ 251 LWS_VISIBLE LWS_EXTERN int 252 lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private, 253 uint8_t *pkey_asn1, size_t pkey_asn1_len); 254 ///@} 255