Mercurial > hg > nginx
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 { |