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
38enum enum_genrsa_mode {
39 LGRSAM_PKCS1_1_5,
40 LGRSAM_PKCS1_OAEP_PSS,
41
42 LGRSAM_COUNT
43};
44
45struct 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 */
76LWS_VISIBLE LWS_EXTERN int
77lws_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 */
93LWS_VISIBLE LWS_EXTERN void
94lws_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 */
114LWS_VISIBLE LWS_EXTERN int
115lws_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 */
132LWS_VISIBLE LWS_EXTERN int
133lws_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 */
149LWS_VISIBLE LWS_EXTERN int
150lws_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 */
167LWS_VISIBLE LWS_EXTERN int
168lws_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 */
185LWS_VISIBLE LWS_EXTERN int
186lws_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 */
206LWS_VISIBLE LWS_EXTERN int
207lws_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 */
227LWS_VISIBLE LWS_EXTERN int
228lws_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 */
240LWS_VISIBLE LWS_EXTERN void
241lws_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 */
252LWS_VISIBLE LWS_EXTERN int
253lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private,
254 uint8_t *pkey_asn1, size_t pkey_asn1_len);
255///@}
256