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