comparison src/event/quic/ngx_event_quic_protection.c @ 9173:904a54092d5b

QUIC: common code for crypto open and seal operations.
author Sergey Kandaurov <pluknet@nginx.com>
date Fri, 20 Oct 2023 18:05:07 +0400
parents 4ccb0d973206
children 31702c53d2db
comparison
equal deleted inserted replaced
9172:4ccb0d973206 9173:904a54092d5b
26 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask, 26 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
27 uint64_t *largest_pn); 27 uint64_t *largest_pn);
28 28
29 static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, 29 static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
30 u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log); 30 u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
31 #ifndef OPENSSL_IS_BORINGSSL
32 static ngx_int_t ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out,
33 u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
34 #endif
31 static ngx_int_t ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher, 35 static ngx_int_t ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
32 ngx_quic_secret_t *s, u_char *out, u_char *in); 36 ngx_quic_secret_t *s, u_char *out, u_char *in);
33 37
34 static ngx_int_t ngx_quic_create_packet(ngx_quic_header_t *pkt, 38 static ngx_int_t ngx_quic_create_packet(ngx_quic_header_t *pkt,
35 ngx_str_t *res); 39 ngx_str_t *res);
424 428
425 static ngx_int_t 429 static ngx_int_t
426 ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, 430 ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce,
427 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log) 431 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
428 { 432 {
429 ngx_quic_crypto_ctx_t *ctx;
430
431 ctx = s->ctx;
432
433 #ifdef OPENSSL_IS_BORINGSSL 433 #ifdef OPENSSL_IS_BORINGSSL
434 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len, 434 if (EVP_AEAD_CTX_open(s->ctx, out->data, &out->len, out->len, nonce,
435 in->data, in->len, ad->data, ad->len) 435 s->iv.len, in->data, in->len, ad->data, ad->len)
436 != 1) 436 != 1)
437 { 437 {
438 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed"); 438 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed");
439 return NGX_ERROR; 439 return NGX_ERROR;
440 } 440 }
441
442 return NGX_OK;
441 #else 443 #else
442 int len; 444 return ngx_quic_crypto_common(s, out, nonce, in, ad, log);
443 445 #endif
444 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) {
445 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
446 return NGX_ERROR;
447 }
448
449 in->len -= NGX_QUIC_TAG_LEN;
450
451 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN,
452 in->data + in->len)
453 == 0)
454 {
455 ngx_ssl_error(NGX_LOG_INFO, log, 0,
456 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_TAG) failed");
457 return NGX_ERROR;
458 }
459
460 if (EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(ctx)) == EVP_CIPH_CCM_MODE
461 && EVP_DecryptUpdate(ctx, NULL, &len, NULL, in->len) != 1)
462 {
463 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
464 return NGX_ERROR;
465 }
466
467 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
468 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
469 return NGX_ERROR;
470 }
471
472 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
473 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
474 return NGX_ERROR;
475 }
476
477 out->len = len;
478
479 if (EVP_DecryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
480 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptFinal_ex failed");
481 return NGX_ERROR;
482 }
483
484 out->len += len;
485 #endif
486
487 return NGX_OK;
488 } 446 }
489 447
490 448
491 ngx_int_t 449 ngx_int_t
492 ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, 450 ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce,
493 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log) 451 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
494 { 452 {
453 #ifdef OPENSSL_IS_BORINGSSL
454 if (EVP_AEAD_CTX_seal(s->ctx, out->data, &out->len, out->len, nonce,
455 s->iv.len, in->data, in->len, ad->data, ad->len)
456 != 1)
457 {
458 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed");
459 return NGX_ERROR;
460 }
461
462 return NGX_OK;
463 #else
464 return ngx_quic_crypto_common(s, out, nonce, in, ad, log);
465 #endif
466 }
467
468
469 #ifndef OPENSSL_IS_BORINGSSL
470
471 static ngx_int_t
472 ngx_quic_crypto_common(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce,
473 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
474 {
475 int len, enc;
495 ngx_quic_crypto_ctx_t *ctx; 476 ngx_quic_crypto_ctx_t *ctx;
496 477
497 ctx = s->ctx; 478 ctx = s->ctx;
498 479 enc = EVP_CIPHER_CTX_encrypting(ctx);
499 #ifdef OPENSSL_IS_BORINGSSL 480
500 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len, 481 if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, enc) != 1) {
501 in->data, in->len, ad->data, ad->len) 482 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherInit_ex() failed");
502 != 1) 483 return NGX_ERROR;
503 { 484 }
504 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed"); 485
505 return NGX_ERROR; 486 if (enc == 0) {
506 } 487 in->len -= NGX_QUIC_TAG_LEN;
507 #else 488
508 int len; 489 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN,
509 490 in->data + in->len)
510 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) { 491 == 0)
511 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed"); 492 {
512 return NGX_ERROR; 493 ngx_ssl_error(NGX_LOG_INFO, log, 0,
494 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_TAG) failed");
495 return NGX_ERROR;
496 }
513 } 497 }
514 498
515 if (EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(ctx)) == EVP_CIPH_CCM_MODE 499 if (EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(ctx)) == EVP_CIPH_CCM_MODE
516 && EVP_EncryptUpdate(ctx, NULL, &len, NULL, in->len) != 1) 500 && EVP_CipherUpdate(ctx, NULL, &len, NULL, in->len) != 1)
517 { 501 {
518 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 502 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherUpdate() failed");
519 return NGX_ERROR; 503 return NGX_ERROR;
520 } 504 }
521 505
522 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) { 506 if (EVP_CipherUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
523 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 507 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherUpdate() failed");
524 return NGX_ERROR; 508 return NGX_ERROR;
525 } 509 }
526 510
527 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) { 511 if (EVP_CipherUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
528 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 512 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherUpdate() failed");
529 return NGX_ERROR; 513 return NGX_ERROR;
530 } 514 }
531 515
532 out->len = len; 516 out->len = len;
533 517
534 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) { 518 if (EVP_CipherFinal_ex(ctx, out->data + out->len, &len) <= 0) {
535 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_ex failed"); 519 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherFinal_ex failed");
536 return NGX_ERROR; 520 return NGX_ERROR;
537 } 521 }
538 522
539 out->len += len; 523 out->len += len;
540 524
541 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, NGX_QUIC_TAG_LEN, 525 if (enc == 1) {
542 out->data + out->len) 526 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, NGX_QUIC_TAG_LEN,
543 == 0) 527 out->data + out->len)
544 { 528 == 0)
545 ngx_ssl_error(NGX_LOG_INFO, log, 0, 529 {
546 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_GET_TAG) failed"); 530 ngx_ssl_error(NGX_LOG_INFO, log, 0,
547 return NGX_ERROR; 531 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_GET_TAG) failed");
548 } 532 return NGX_ERROR;
549 533 }
550 out->len += NGX_QUIC_TAG_LEN; 534
551 #endif 535 out->len += NGX_QUIC_TAG_LEN;
552 536 }
553 return NGX_OK; 537
554 } 538 return NGX_OK;
539 }
540
541 #endif
555 542
556 543
557 void 544 void
558 ngx_quic_crypto_cleanup(ngx_quic_secret_t *s) 545 ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
559 { 546 {