]> git.kaiwu.me - nginx.git/commitdiff
QUIC: use AEAD to encrypt address validation tokens.
authorRoman Arutyunyan <arut@nginx.com>
Thu, 8 Jun 2023 10:58:01 +0000 (14:58 +0400)
committerRoman Arutyunyan <arut@nginx.com>
Thu, 8 Jun 2023 10:58:01 +0000 (14:58 +0400)
Previously used AES256-CBC is now substituted with AES256-GCM.  Although there
seem to be no tangible consequences of token integrity loss.

src/event/quic/ngx_event_quic_tokens.c
src/event/quic/ngx_event_quic_tokens.h

index e67825aabaa46fc299c9f64db5cdefa787435ff1..c1da0d4726083cf39c5c1091b5c1d57917cd4313 100644 (file)
@@ -69,11 +69,10 @@ ngx_quic_new_token(ngx_log_t *log, struct sockaddr *sockaddr,
 
     len = p - in;
 
-    cipher = EVP_aes_256_cbc();
-    iv_len = NGX_QUIC_AES_256_CBC_IV_LEN;
+    cipher = EVP_aes_256_gcm();
+    iv_len = NGX_QUIC_AES_256_GCM_IV_LEN;
 
-    if ((size_t) (iv_len + len + NGX_QUIC_AES_256_CBC_BLOCK_SIZE) > token->len)
-    {
+    if ((size_t) (iv_len + len + NGX_QUIC_AES_256_GCM_TAG_LEN) > token->len) {
         ngx_log_error(NGX_LOG_ALERT, log, 0, "quic token buffer is too small");
         return NGX_ERROR;
     }
@@ -108,6 +107,17 @@ ngx_quic_new_token(ngx_log_t *log, struct sockaddr *sockaddr,
 
     token->len += len;
 
+    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
+                            NGX_QUIC_AES_256_GCM_TAG_LEN,
+                            token->data + token->len)
+        == 0)
+    {
+        EVP_CIPHER_CTX_free(ctx);
+        return NGX_ERROR;
+    }
+
+    token->len += NGX_QUIC_AES_256_GCM_TAG_LEN;
+
     EVP_CIPHER_CTX_free(ctx);
 
 #ifdef NGX_QUIC_DEBUG_PACKETS
@@ -184,17 +194,19 @@ ngx_quic_validate_token(ngx_connection_t *c, u_char *key,
 
     /* Retry token or NEW_TOKEN in a previous connection */
 
-    cipher = EVP_aes_256_cbc();
+    cipher = EVP_aes_256_gcm();
     iv = pkt->token.data;
-    iv_len = NGX_QUIC_AES_256_CBC_IV_LEN;
+    iv_len = NGX_QUIC_AES_256_GCM_IV_LEN;
 
     /* sanity checks */
 
-    if (pkt->token.len < (size_t) iv_len + NGX_QUIC_AES_256_CBC_BLOCK_SIZE) {
+    if (pkt->token.len < (size_t) iv_len + NGX_QUIC_AES_256_GCM_TAG_LEN) {
         goto garbage;
     }
 
-    if (pkt->token.len > (size_t) iv_len + NGX_QUIC_MAX_TOKEN_SIZE) {
+    if (pkt->token.len > (size_t) iv_len + NGX_QUIC_MAX_TOKEN_SIZE
+                         + NGX_QUIC_AES_256_GCM_TAG_LEN)
+    {
         goto garbage;
     }
 
@@ -209,15 +221,23 @@ ngx_quic_validate_token(ngx_connection_t *c, u_char *key,
     }
 
     p = pkt->token.data + iv_len;
-    len = pkt->token.len - iv_len;
+    len = pkt->token.len - iv_len - NGX_QUIC_AES_256_GCM_TAG_LEN;
+
+    if (EVP_DecryptUpdate(ctx, tdec, &tlen, p, len) != 1) {
+        EVP_CIPHER_CTX_free(ctx);
+        goto garbage;
+    }
+    total = tlen;
 
-    if (EVP_DecryptUpdate(ctx, tdec, &len, p, len) != 1) {
+    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+                            NGX_QUIC_AES_256_GCM_TAG_LEN, p + len)
+        == 0)
+    {
         EVP_CIPHER_CTX_free(ctx);
         goto garbage;
     }
-    total = len;
 
-    if (EVP_DecryptFinal_ex(ctx, tdec + len, &tlen) <= 0) {
+    if (EVP_DecryptFinal_ex(ctx, tdec + tlen, &tlen) <= 0) {
         EVP_CIPHER_CTX_free(ctx);
         goto garbage;
     }
index 4a40f7b3aa434c5736cb706545abf9bd9a99a17f..ee3fe5b9a00b633a986fb1323fbbb85fee7787f0 100644 (file)
 #define NGX_QUIC_MAX_TOKEN_SIZE              64
     /* SHA-1(addr)=20 + sizeof(time_t) + retry(1) + odcid.len(1) + odcid */
 
-/* RFC 3602, 2.1 and 2.4 for AES-CBC block size and IV length */
-#define NGX_QUIC_AES_256_CBC_IV_LEN          16
-#define NGX_QUIC_AES_256_CBC_BLOCK_SIZE      16
+#define NGX_QUIC_AES_256_GCM_IV_LEN          12
+#define NGX_QUIC_AES_256_GCM_TAG_LEN         16
 
-#define NGX_QUIC_TOKEN_BUF_SIZE             (NGX_QUIC_AES_256_CBC_IV_LEN      \
+#define NGX_QUIC_TOKEN_BUF_SIZE             (NGX_QUIC_AES_256_GCM_IV_LEN      \
                                              + NGX_QUIC_MAX_TOKEN_SIZE        \
-                                             + NGX_QUIC_AES_256_CBC_BLOCK_SIZE)
+                                             + NGX_QUIC_AES_256_GCM_TAG_LEN)
 
 
 ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid,