Mercurial > hg > nginx
comparison src/event/ngx_event_quic.c @ 8177:76e29ff31cd3 quic
AEAD routines, introduced ngx_quic_tls_open()/ngx_quic_tls_seal().
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Fri, 28 Feb 2020 13:09:52 +0300 |
parents | 4daf03d2bd0a |
children | a9ff4392ecde |
comparison
equal
deleted
inserted
replaced
8176:8964cc6ecc4a | 8177:76e29ff31cd3 |
---|---|
161 | 161 |
162 #endif | 162 #endif |
163 | 163 |
164 return NGX_OK; | 164 return NGX_OK; |
165 } | 165 } |
166 | |
167 | |
168 ngx_int_t | |
169 ngx_quic_tls_open(ngx_connection_t *c, const ngx_aead_cipher_t *cipher, | |
170 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | |
171 ngx_str_t *ad) | |
172 { | |
173 out->len = in->len - EVP_GCM_TLS_TAG_LEN; | |
174 out->data = ngx_pnalloc(c->pool, out->len); | |
175 if (out->data == NULL) { | |
176 return NGX_ERROR; | |
177 } | |
178 | |
179 #ifdef OPENSSL_IS_BORINGSSL | |
180 EVP_AEAD_CTX *ctx; | |
181 | |
182 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, | |
183 EVP_AEAD_DEFAULT_TAG_LENGTH); | |
184 if (ctx == NULL) { | |
185 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_new() failed"); | |
186 return NGX_ERROR; | |
187 } | |
188 | |
189 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len, | |
190 in->data, in->len, ad->data, ad->len) | |
191 != 1) | |
192 { | |
193 EVP_AEAD_CTX_free(ctx); | |
194 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_open() failed"); | |
195 return NGX_ERROR; | |
196 } | |
197 | |
198 EVP_AEAD_CTX_free(ctx); | |
199 #else | |
200 int len; | |
201 u_char *tag; | |
202 EVP_CIPHER_CTX *ctx; | |
203 | |
204 ctx = EVP_CIPHER_CTX_new(); | |
205 if (ctx == NULL) { | |
206 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_CIPHER_CTX_new() failed"); | |
207 return NGX_ERROR; | |
208 } | |
209 | |
210 if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) { | |
211 EVP_CIPHER_CTX_free(ctx); | |
212 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptInit_ex() failed"); | |
213 return NGX_ERROR; | |
214 } | |
215 | |
216 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL) | |
217 == 0) | |
218 { | |
219 EVP_CIPHER_CTX_free(ctx); | |
220 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
221 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed"); | |
222 return NGX_ERROR; | |
223 } | |
224 | |
225 if (EVP_DecryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) { | |
226 EVP_CIPHER_CTX_free(ctx); | |
227 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptInit_ex() failed"); | |
228 return NGX_ERROR; | |
229 } | |
230 | |
231 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) { | |
232 EVP_CIPHER_CTX_free(ctx); | |
233 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptUpdate() failed"); | |
234 return NGX_ERROR; | |
235 } | |
236 | |
237 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data, | |
238 in->len - EVP_GCM_TLS_TAG_LEN) | |
239 != 1) | |
240 { | |
241 EVP_CIPHER_CTX_free(ctx); | |
242 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptUpdate() failed"); | |
243 return NGX_ERROR; | |
244 } | |
245 | |
246 out->len = len; | |
247 tag = in->data + in->len - EVP_GCM_TLS_TAG_LEN; | |
248 | |
249 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag) | |
250 == 0) | |
251 { | |
252 EVP_CIPHER_CTX_free(ctx); | |
253 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
254 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_TAG) failed"); | |
255 return NGX_ERROR; | |
256 } | |
257 | |
258 if (EVP_DecryptFinal_ex(ctx, out->data + len, &len) <= 0) { | |
259 EVP_CIPHER_CTX_free(ctx); | |
260 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptFinal_ex failed"); | |
261 return NGX_ERROR; | |
262 } | |
263 | |
264 out->len += len; | |
265 | |
266 EVP_CIPHER_CTX_free(ctx); | |
267 #endif | |
268 | |
269 return NGX_OK; | |
270 } | |
271 | |
272 | |
273 ngx_int_t | |
274 ngx_quic_tls_seal(ngx_connection_t *c, const ngx_aead_cipher_t *cipher, | |
275 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | |
276 ngx_str_t *ad) | |
277 { | |
278 out->len = in->len + EVP_GCM_TLS_TAG_LEN; | |
279 out->data = ngx_pnalloc(c->pool, out->len); | |
280 if (out->data == NULL) { | |
281 return NGX_ERROR; | |
282 } | |
283 | |
284 #ifdef OPENSSL_IS_BORINGSSL | |
285 EVP_AEAD_CTX *ctx; | |
286 | |
287 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, | |
288 EVP_AEAD_DEFAULT_TAG_LENGTH); | |
289 if (ctx == NULL) { | |
290 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_new() failed"); | |
291 return NGX_ERROR; | |
292 } | |
293 | |
294 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len, | |
295 in->data, in->len, ad->data, ad->len) | |
296 != 1) | |
297 { | |
298 EVP_AEAD_CTX_free(ctx); | |
299 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_seal() failed"); | |
300 return NGX_ERROR; | |
301 } | |
302 | |
303 EVP_AEAD_CTX_free(ctx); | |
304 #else | |
305 int len; | |
306 EVP_CIPHER_CTX *ctx; | |
307 | |
308 ctx = EVP_CIPHER_CTX_new(); | |
309 if (ctx == NULL) { | |
310 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_CIPHER_CTX_new() failed"); | |
311 return NGX_ERROR; | |
312 } | |
313 | |
314 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) { | |
315 EVP_CIPHER_CTX_free(ctx); | |
316 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed"); | |
317 return NGX_ERROR; | |
318 } | |
319 | |
320 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL) | |
321 == 0) | |
322 { | |
323 EVP_CIPHER_CTX_free(ctx); | |
324 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
325 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed"); | |
326 return NGX_ERROR; | |
327 } | |
328 | |
329 if (EVP_EncryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) { | |
330 EVP_CIPHER_CTX_free(ctx); | |
331 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed"); | |
332 return NGX_ERROR; | |
333 } | |
334 | |
335 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) { | |
336 EVP_CIPHER_CTX_free(ctx); | |
337 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed"); | |
338 return NGX_ERROR; | |
339 } | |
340 | |
341 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) { | |
342 EVP_CIPHER_CTX_free(ctx); | |
343 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed"); | |
344 return NGX_ERROR; | |
345 } | |
346 | |
347 out->len = len; | |
348 | |
349 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) { | |
350 EVP_CIPHER_CTX_free(ctx); | |
351 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptFinal_ex failed"); | |
352 return NGX_ERROR; | |
353 } | |
354 | |
355 out->len += len; | |
356 | |
357 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, | |
358 out->data + in->len) | |
359 == 0) | |
360 { | |
361 EVP_CIPHER_CTX_free(ctx); | |
362 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
363 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_GET_TAG) failed"); | |
364 return NGX_ERROR; | |
365 } | |
366 | |
367 EVP_CIPHER_CTX_free(ctx); | |
368 | |
369 out->len += EVP_GCM_TLS_TAG_LEN; | |
370 #endif | |
371 | |
372 return NGX_OK; | |
373 } |