import UBI gnutls-3.8.3-4.el9_4

This commit is contained in:
eabdullin 2024-04-30 14:09:30 +00:00
parent 5b4e8a67cb
commit 9f91a88d77
39 changed files with 976 additions and 8071 deletions

5
.gitignore vendored
View File

@ -1,4 +1,3 @@
SOURCES/gmp-6.2.1.tar.xz
SOURCES/gnutls-3.7.6.tar.xz
SOURCES/gnutls-3.7.6.tar.xz.sig
SOURCES/gnutls-release-keyring.gpg
SOURCES/gnutls-3.8.3.tar.xz
SOURCES/gnutls-3.8.3.tar.xz.sig

View File

@ -1,4 +1,3 @@
0578d48607ec0e272177d175fd1807c30b00fdf2 SOURCES/gmp-6.2.1.tar.xz
47591374259451fe2cd86c5fe7c345e769a6c79b SOURCES/gnutls-3.7.6.tar.xz
0ebda3673eafa2ab34068a7ea798d6e385440d56 SOURCES/gnutls-3.7.6.tar.xz.sig
befcf25b9dcd1d36b8bdb754c80c639eca45baa0 SOURCES/gnutls-release-keyring.gpg
806156ac9563caab642d6274496b9cc5b2117612 SOURCES/gnutls-3.8.3.tar.xz
dd7822b360953108a86dc3dbc7d07214563cc678 SOURCES/gnutls-3.8.3.tar.xz.sig

View File

@ -1,11 +0,0 @@
--- a/guile/src/Makefile.in 2019-03-27 11:51:55.984398001 +0100
+++ b/guile/src/Makefile.in 2019-03-27 11:52:27.259626076 +0100
@@ -1472,7 +1472,7 @@
# Use '-module' to build a "dlopenable module", in Libtool terms.
# Use '-undefined' to placate Libtool on Windows; see
# <https://lists.gnutls.org/pipermail/gnutls-devel/2014-December/007294.html>.
-guile_gnutls_v_2_la_LDFLAGS = -module -no-undefined
+guile_gnutls_v_2_la_LDFLAGS = -module -no-undefined -Wl,-z,lazy
# Linking against GnuTLS.
GNUTLS_CORE_LIBS = $(top_builddir)/lib/libgnutls.la

View File

@ -1,26 +1,28 @@
From 71b1812bf9a785b66e3f17175580d3d20cea9c0c Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 12 Oct 2021 13:33:31 +0200
Subject: [PATCH] x86: port Intel CET support
From 1688e614451ac93a95702d49461c9971351ee614 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 16 Nov 2023 17:01:57 +0900
Subject: [PATCH] gnutls-3.7.2-enable-intel-cet.patch
Signed-off-by: Daiki Ueno <ueno@gnu.org>
Signed-off-by: rpm-build <rpm-build>
---
lib/accelerated/x86/elf/aes-ssse3-x86.s | 30 ++++++++++++++
lib/accelerated/x86/elf/aes-ssse3-x86_64.s | 26 +++++++++++++
lib/accelerated/x86/elf/aesni-gcm-x86_64.s | 21 ++++++++++
lib/accelerated/x86/elf/aesni-x86.s | 39 +++++++++++++++++++
lib/accelerated/x86/elf/aesni-x86_64.s | 32 +++++++++++++++
lib/accelerated/x86/elf/ghash-x86_64.s | 27 +++++++++++++
lib/accelerated/x86/elf/sha1-ssse3-x86.s | 18 +++++++++
lib/accelerated/x86/elf/sha1-ssse3-x86_64.s | 21 ++++++++++
lib/accelerated/x86/elf/sha256-ssse3-x86.s | 18 +++++++++
lib/accelerated/x86/elf/sha256-ssse3-x86_64.s | 21 ++++++++++
lib/accelerated/x86/elf/sha512-ssse3-x86.s | 18 +++++++++
lib/accelerated/x86/elf/sha512-ssse3-x86_64.s | 21 ++++++++++
12 files changed, 292 insertions(+)
lib/accelerated/x86/elf/aes-ssse3-x86.s | 30 ++
lib/accelerated/x86/elf/aes-ssse3-x86_64.s | 26 ++
lib/accelerated/x86/elf/aesni-gcm-x86_64.s | 21 ++
lib/accelerated/x86/elf/aesni-x86.s | 39 +++
lib/accelerated/x86/elf/aesni-x86_64.s | 32 ++
lib/accelerated/x86/elf/e_padlock-x86.s | 306 ++++++++++--------
lib/accelerated/x86/elf/e_padlock-x86_64.s | 242 +++++++++-----
lib/accelerated/x86/elf/ghash-x86_64.s | 27 ++
lib/accelerated/x86/elf/sha1-ssse3-x86.s | 18 ++
lib/accelerated/x86/elf/sha1-ssse3-x86_64.s | 21 ++
lib/accelerated/x86/elf/sha256-ssse3-x86.s | 18 ++
lib/accelerated/x86/elf/sha256-ssse3-x86_64.s | 21 ++
lib/accelerated/x86/elf/sha512-ssse3-x86.s | 18 ++
lib/accelerated/x86/elf/sha512-ssse3-x86_64.s | 21 ++
14 files changed, 625 insertions(+), 215 deletions(-)
diff --git a/lib/accelerated/x86/elf/aes-ssse3-x86.s b/lib/accelerated/x86/elf/aes-ssse3-x86.s
index 265e28a7ef..7be53059f7 100644
index 265e28a..7be5305 100644
--- a/lib/accelerated/x86/elf/aes-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/aes-ssse3-x86.s
@@ -71,6 +71,7 @@
@ -150,7 +152,7 @@ index 265e28a7ef..7be53059f7 100644
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/aes-ssse3-x86_64.s b/lib/accelerated/x86/elf/aes-ssse3-x86_64.s
index ea1216baf7..5a3f336f26 100644
index ea1216b..5a3f336 100644
--- a/lib/accelerated/x86/elf/aes-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/aes-ssse3-x86_64.s
@@ -635,6 +635,7 @@ _vpaes_schedule_mangle:
@ -221,7 +223,7 @@ index ea1216baf7..5a3f336f26 100644
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/aesni-gcm-x86_64.s b/lib/accelerated/x86/elf/aesni-gcm-x86_64.s
index 461dd026b9..ea5398bc2c 100644
index 461dd02..ea5398b 100644
--- a/lib/accelerated/x86/elf/aesni-gcm-x86_64.s
+++ b/lib/accelerated/x86/elf/aesni-gcm-x86_64.s
@@ -826,5 +826,26 @@ aesni_gcm_encrypt:
@ -252,7 +254,7 @@ index 461dd026b9..ea5398bc2c 100644
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/aesni-x86.s b/lib/accelerated/x86/elf/aesni-x86.s
index 6e4860209f..f41d5f9ef3 100644
index 0c13b39..3ec4a23 100644
--- a/lib/accelerated/x86/elf/aesni-x86.s
+++ b/lib/accelerated/x86/elf/aesni-x86.s
@@ -43,6 +43,7 @@
@ -433,7 +435,7 @@ index 6e4860209f..f41d5f9ef3 100644
movl 12(%esp),%edx
@@ -3275,4 +3297,21 @@ aesni_set_decrypt_key:
.byte 115,108,46,111,114,103,62,0
.comm _gnutls_x86_cpuid_s,16,4
.comm GNUTLS_x86_cpuid_s,16,4
+ .section ".note.gnu.property", "a"
+ .p2align 2
@ -454,7 +456,7 @@ index 6e4860209f..f41d5f9ef3 100644
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/aesni-x86_64.s b/lib/accelerated/x86/elf/aesni-x86_64.s
index acc7c2c555..e3f9d5a995 100644
index b844198..7edf5f1 100644
--- a/lib/accelerated/x86/elf/aesni-x86_64.s
+++ b/lib/accelerated/x86/elf/aesni-x86_64.s
@@ -44,6 +44,7 @@
@ -572,285 +574,8 @@ index acc7c2c555..e3f9d5a995 100644
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/ghash-x86_64.s b/lib/accelerated/x86/elf/ghash-x86_64.s
index 1e4d18b341..8da3f294c7 100644
--- a/lib/accelerated/x86/elf/ghash-x86_64.s
+++ b/lib/accelerated/x86/elf/ghash-x86_64.s
@@ -45,6 +45,7 @@
.align 16
gcm_gmult_4bit:
.cfi_startproc
+.byte 243,15,30,250
pushq %rbx
.cfi_adjust_cfa_offset 8
.cfi_offset %rbx,-16
@@ -156,6 +157,7 @@ gcm_gmult_4bit:
.align 16
gcm_ghash_4bit:
.cfi_startproc
+.byte 243,15,30,250
pushq %rbx
.cfi_adjust_cfa_offset 8
.cfi_offset %rbx,-16
@@ -903,6 +905,7 @@ gcm_init_clmul:
.align 16
gcm_gmult_clmul:
.cfi_startproc
+.byte 243,15,30,250
.L_gmult_clmul:
movdqu (%rdi),%xmm0
movdqa .Lbswap_mask(%rip),%xmm5
@@ -956,6 +959,7 @@ gcm_gmult_clmul:
.align 32
gcm_ghash_clmul:
.cfi_startproc
+.byte 243,15,30,250
.L_ghash_clmul:
movdqa .Lbswap_mask(%rip),%xmm10
@@ -1450,6 +1454,7 @@ gcm_init_avx:
.align 32
gcm_gmult_avx:
.cfi_startproc
+.byte 243,15,30,250
jmp .L_gmult_clmul
.cfi_endproc
.size gcm_gmult_avx,.-gcm_gmult_avx
@@ -1458,6 +1463,7 @@ gcm_gmult_avx:
.align 32
gcm_ghash_avx:
.cfi_startproc
+.byte 243,15,30,250
vzeroupper
vmovdqu (%rdi),%xmm10
@@ -1884,5 +1890,26 @@ gcm_ghash_avx:
.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha1-ssse3-x86.s b/lib/accelerated/x86/elf/sha1-ssse3-x86.s
index 8bfbcb6b39..57b6ba58f6 100644
--- a/lib/accelerated/x86/elf/sha1-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha1-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha1_block_data_order:
.L_sha1_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -1417,4 +1418,21 @@ sha1_block_data_order:
.byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
.byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
index d34f34497c..54095050c8 100644
--- a/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
@@ -5487,5 +5487,26 @@ K_XX_XX:
.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0
.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha256-ssse3-x86.s b/lib/accelerated/x86/elf/sha256-ssse3-x86.s
index 8d9aaa4a81..6d16b9140e 100644
--- a/lib/accelerated/x86/elf/sha256-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha256-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha256_block_data_order:
.L_sha256_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -3384,4 +3385,21 @@ sha256_block_data_order:
ret
.size sha256_block_data_order,.-.L_sha256_block_data_order_begin
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
index d196c6a793..1514ee45c0 100644
--- a/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
@@ -5493,5 +5493,26 @@ sha256_block_data_order_avx2:
.byte 0xf3,0xc3
.cfi_endproc
.size sha256_block_data_order_avx2,.-sha256_block_data_order_avx2
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha512-ssse3-x86.s b/lib/accelerated/x86/elf/sha512-ssse3-x86.s
index 481c777154..afca4eae7b 100644
--- a/lib/accelerated/x86/elf/sha512-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha512-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha512_block_data_order:
.L_sha512_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -602,4 +603,21 @@ sha512_block_data_order:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
index 446c06a3e6..a7be2cd444 100644
--- a/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
@@ -5498,5 +5498,26 @@ sha512_block_data_order_avx2:
.byte 0xf3,0xc3
.cfi_endproc
.size sha512_block_data_order_avx2,.-sha512_block_data_order_avx2
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
--
2.31.1
diff --git a/lib/accelerated/x86/elf/e_padlock-x86.s b/lib/accelerated/x86/elf/e_padlock-x86.s
index ed8681ee4..dd56518f6 100644
index ed8681e..dd56518 100644
--- a/lib/accelerated/x86/elf/e_padlock-x86.s
+++ b/lib/accelerated/x86/elf/e_padlock-x86.s
@@ -1,4 +1,4 @@
@ -1753,7 +1478,7 @@ index ed8681ee4..dd56518f6 100644
-
-
diff --git a/lib/accelerated/x86/elf/e_padlock-x86_64.s b/lib/accelerated/x86/elf/e_padlock-x86_64.s
index c161f0a73..f92da756c 100644
index c161f0a..f92da75 100644
--- a/lib/accelerated/x86/elf/e_padlock-x86_64.s
+++ b/lib/accelerated/x86/elf/e_padlock-x86_64.s
@@ -1,4 +1,4 @@
@ -2563,3 +2288,280 @@ index c161f0a73..f92da756c 100644
.section .note.GNU-stack,"",%progbits
-
-
diff --git a/lib/accelerated/x86/elf/ghash-x86_64.s b/lib/accelerated/x86/elf/ghash-x86_64.s
index 856ff17..20e3c6b 100644
--- a/lib/accelerated/x86/elf/ghash-x86_64.s
+++ b/lib/accelerated/x86/elf/ghash-x86_64.s
@@ -45,6 +45,7 @@
.align 16
gcm_gmult_4bit:
.cfi_startproc
+.byte 243,15,30,250
pushq %rbx
.cfi_adjust_cfa_offset 8
.cfi_offset %rbx,-16
@@ -156,6 +157,7 @@ gcm_gmult_4bit:
.align 16
gcm_ghash_4bit:
.cfi_startproc
+.byte 243,15,30,250
pushq %rbx
.cfi_adjust_cfa_offset 8
.cfi_offset %rbx,-16
@@ -903,6 +905,7 @@ gcm_init_clmul:
.align 16
gcm_gmult_clmul:
.cfi_startproc
+.byte 243,15,30,250
.L_gmult_clmul:
movdqu (%rdi),%xmm0
movdqa .Lbswap_mask(%rip),%xmm5
@@ -956,6 +959,7 @@ gcm_gmult_clmul:
.align 32
gcm_ghash_clmul:
.cfi_startproc
+.byte 243,15,30,250
.L_ghash_clmul:
movdqa .Lbswap_mask(%rip),%xmm10
@@ -1450,6 +1454,7 @@ gcm_init_avx:
.align 32
gcm_gmult_avx:
.cfi_startproc
+.byte 243,15,30,250
jmp .L_gmult_clmul
.cfi_endproc
.size gcm_gmult_avx,.-gcm_gmult_avx
@@ -1458,6 +1463,7 @@ gcm_gmult_avx:
.align 32
gcm_ghash_avx:
.cfi_startproc
+.byte 243,15,30,250
vzeroupper
vmovdqu (%rdi),%xmm10
@@ -1884,5 +1890,26 @@ gcm_ghash_avx:
.byte 71,72,65,83,72,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha1-ssse3-x86.s b/lib/accelerated/x86/elf/sha1-ssse3-x86.s
index 8bfbcb6..57b6ba5 100644
--- a/lib/accelerated/x86/elf/sha1-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha1-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha1_block_data_order:
.L_sha1_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -1417,4 +1418,21 @@ sha1_block_data_order:
.byte 89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112
.byte 114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
index d85d9ff..623aa69 100644
--- a/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha1-ssse3-x86_64.s
@@ -5487,5 +5487,26 @@ K_XX_XX:
.byte 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0
.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 64
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha256-ssse3-x86.s b/lib/accelerated/x86/elf/sha256-ssse3-x86.s
index 8d9aaa4..6d16b91 100644
--- a/lib/accelerated/x86/elf/sha256-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha256-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha256_block_data_order:
.L_sha256_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -3384,4 +3385,21 @@ sha256_block_data_order:
ret
.size sha256_block_data_order,.-.L_sha256_block_data_order_begin
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
index 874062e..813aeb2 100644
--- a/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha256-ssse3-x86_64.s
@@ -5493,5 +5493,26 @@ sha256_block_data_order_avx2:
.byte 0xf3,0xc3
.cfi_endproc
.size sha256_block_data_order_avx2,.-sha256_block_data_order_avx2
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha512-ssse3-x86.s b/lib/accelerated/x86/elf/sha512-ssse3-x86.s
index 481c777..afca4ea 100644
--- a/lib/accelerated/x86/elf/sha512-ssse3-x86.s
+++ b/lib/accelerated/x86/elf/sha512-ssse3-x86.s
@@ -43,6 +43,7 @@
.align 16
sha512_block_data_order:
.L_sha512_block_data_order_begin:
+.byte 243,15,30,251
pushl %ebp
pushl %ebx
pushl %esi
@@ -602,4 +603,21 @@ sha512_block_data_order:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
+ .section ".note.gnu.property", "a"
+ .p2align 2
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ .asciz "GNU"
+1:
+ .p2align 2
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 2
+4:
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s b/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
index 039b1d7..bad63fd 100644
--- a/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
+++ b/lib/accelerated/x86/elf/sha512-ssse3-x86_64.s
@@ -5498,5 +5498,26 @@ sha512_block_data_order_avx2:
.byte 0xf3,0xc3
.cfi_endproc
.size sha512_block_data_order_avx2,.-sha512_block_data_order_avx2
+ .section ".note.gnu.property", "a"
+ .p2align 3
+ .long 1f - 0f
+ .long 4f - 1f
+ .long 5
+0:
+ # "GNU" encoded with .byte, since .asciz isn't supported
+ # on Solaris.
+ .byte 0x47
+ .byte 0x4e
+ .byte 0x55
+ .byte 0
+1:
+ .p2align 3
+ .long 0xc0000002
+ .long 3f - 2f
+2:
+ .long 3
+3:
+ .p2align 3
+4:
.section .note.GNU-stack,"",%progbits
--
2.41.0

View File

@ -1,24 +1,25 @@
From 36a92d984020df16296784a7ad613c9693469d23 Mon Sep 17 00:00:00 2001
From c7f4ce40eaecafdefbf4db0ac2d3665bc0c41b33 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Tue, 21 Dec 2021 16:28:09 +0100
Subject: [PATCH 1/2] Remove GNUTLS_NO_EXPLICIT_INIT compatibility
Date: Tue, 21 Nov 2023 14:13:38 +0900
Subject: [PATCH] gnutls-3.7.2-no-explicit-init.patch
Signed-off-by: rpm-build <rpm-build>
---
lib/global.c | 8 --------
1 file changed, 8 deletions(-)
lib/global.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/lib/global.c b/lib/global.c
index 3731418..1384045 100644
index 924ec94..3baa202 100644
--- a/lib/global.c
+++ b/lib/global.c
@@ -500,14 +500,6 @@ static void _CONSTRUCTOR lib_init(void)
@@ -510,15 +510,6 @@ static void _CONSTRUCTOR lib_init(void)
return;
}
- e = secure_getenv("GNUTLS_NO_EXPLICIT_INIT");
- if (e != NULL) {
- _gnutls_debug_log("GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
- _gnutls_debug_log(
- "GNUTLS_NO_EXPLICIT_INIT is deprecated; use GNUTLS_NO_IMPLICIT_INIT\n");
- ret = atoi(e);
- if (ret == 1)
- return;
@ -26,7 +27,7 @@ index 3731418..1384045 100644
-
ret = _gnutls_global_init(1);
if (ret < 0) {
fprintf(stderr, "Error in GnuTLS initialization: %s\n", gnutls_strerror(ret));
fprintf(stderr, "Error in GnuTLS initialization: %s\n",
--
2.31.1
2.41.0

View File

@ -1,720 +0,0 @@
From 2f61f102169e4d6652c9b82246353cd276366809 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 27 Jun 2022 11:14:50 +0900
Subject: [PATCH] cipher: limit plaintext length supplied to AES-GCM
According to SP800-38D 5.2.1.1, input data length of AES-GCM
encryption function must be less than or equal to 2^39-256 bits.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
NEWS | 3 +
lib/accelerated/aarch64/aes-aarch64.h | 15 ++++
lib/accelerated/aarch64/aes-gcm-aarch64.c | 9 +++
lib/accelerated/x86/aes-gcm-padlock.c | 29 ++++---
lib/accelerated/x86/aes-gcm-x86-aesni.c | 30 +++++---
lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c | 9 +++
lib/accelerated/x86/aes-gcm-x86-pclmul.c | 9 +++
lib/accelerated/x86/aes-gcm-x86-ssse3.c | 30 +++++---
lib/accelerated/x86/aes-x86.h | 15 ++++
lib/nettle/cipher.c | 41 ++++++++++
tests/slow/cipher-api-test.c | 79 ++++++++++++++++++++
11 files changed, 240 insertions(+), 29 deletions(-)
diff --git a/lib/accelerated/aarch64/aes-aarch64.h b/lib/accelerated/aarch64/aes-aarch64.h
index 692d8620d7..0e64f4ed8d 100644
--- a/lib/accelerated/aarch64/aes-aarch64.h
+++ b/lib/accelerated/aarch64/aes-aarch64.h
@@ -20,6 +20,21 @@ typedef struct {
if (s != 16 && s != 24 && s != 32) \
return GNUTLS_E_INVALID_REQUEST
+#include <intprops.h>
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
+static inline int
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
+ size_t sum;
+
+ if (!INT_ADD_OK(*counter, size, &sum) ||
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ *counter = sum;
+
+ return 0;
+}
+
int aes_v8_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
int aes_v8_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
void aes_v8_cbc_encrypt(const unsigned char *in, unsigned char *out,
diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c b/lib/accelerated/aarch64/aes-gcm-aarch64.c
index 901bd9f60f..be1e69c784 100644
--- a/lib/accelerated/aarch64/aes-gcm-aarch64.c
+++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c
@@ -62,6 +62,7 @@ struct aes_gcm_ctx {
struct gcm128_context gcm;
unsigned finished;
unsigned auth_finished;
+ size_t rekey_counter;
};
void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]);
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
ctx->gcm.H.u[1] = bswap_64(ctx->gcm.H.u[1]);
gcm_init_v8(ctx->gcm.Htable, ctx->gcm.H.u);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -141,6 +143,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
ctx->finished = 0;
ctx->auth_finished = 0;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -229,6 +232,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
int exp_blocks = blocks * GCM_BLOCK_SIZE;
int rest = src_size - (exp_blocks);
uint32_t counter;
+ int ret;
if (unlikely(ctx->finished))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -236,6 +240,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
if (blocks > 0) {
ctr32_encrypt_blocks(src, dst,
blocks,
diff --git a/lib/accelerated/x86/aes-gcm-padlock.c b/lib/accelerated/x86/aes-gcm-padlock.c
index a9c7441d65..739883ab1b 100644
--- a/lib/accelerated/x86/aes-gcm-padlock.c
+++ b/lib/accelerated/x86/aes-gcm-padlock.c
@@ -43,7 +43,10 @@
* Actually padlock doesn't include GCM mode. We just use
* the ECB part of padlock and nettle for everything else.
*/
-struct gcm_padlock_aes_ctx GCM_CTX(struct padlock_ctx);
+struct gcm_padlock_aes_ctx {
+ struct GCM_CTX(struct padlock_ctx) inner;
+ size_t rekey_counter;
+};
static void padlock_aes_encrypt(const void *_ctx,
size_t length, uint8_t * dst,
@@ -78,7 +81,7 @@ static void padlock_aes256_set_encrypt_key(struct padlock_ctx *_ctx,
static void aes_gcm_deinit(void *_ctx)
{
- struct padlock_ctx *ctx = _ctx;
+ struct gcm_padlock_aes_ctx *ctx = _ctx;
zeroize_temp_key(ctx, sizeof(*ctx));
gnutls_free(ctx);
@@ -108,14 +111,15 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize)
struct gcm_padlock_aes_ctx *ctx = _ctx;
if (keysize == 16) {
- GCM_SET_KEY(ctx, padlock_aes128_set_encrypt_key, padlock_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, padlock_aes128_set_encrypt_key, padlock_aes_encrypt,
key);
} else if (keysize == 32) {
- GCM_SET_KEY(ctx, padlock_aes256_set_encrypt_key, padlock_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, padlock_aes256_set_encrypt_key, padlock_aes_encrypt,
key);
} else
return GNUTLS_E_INVALID_REQUEST;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -126,8 +130,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
if (iv_size != GCM_BLOCK_SIZE - 4)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- GCM_SET_IV(ctx, iv_size, iv);
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -136,11 +141,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
void *dst, size_t length)
{
struct gcm_padlock_aes_ctx *ctx = _ctx;
+ int ret;
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_ENCRYPT(ctx, padlock_aes_encrypt, src_size, dst, src);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ GCM_ENCRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -154,7 +165,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(dst_size < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_DECRYPT(ctx, padlock_aes_encrypt, src_size, dst, src);
+ GCM_DECRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -162,7 +173,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
{
struct gcm_padlock_aes_ctx *ctx = _ctx;
- GCM_UPDATE(ctx, src_size, src);
+ GCM_UPDATE(&ctx->inner, src_size, src);
return 0;
}
@@ -171,7 +182,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
{
struct gcm_padlock_aes_ctx *ctx = _ctx;
- GCM_DIGEST(ctx, padlock_aes_encrypt, tagsize, tag);
+ GCM_DIGEST(&ctx->inner, padlock_aes_encrypt, tagsize, tag);
}
#include "aes-gcm-aead.h"
diff --git a/lib/accelerated/x86/aes-gcm-x86-aesni.c b/lib/accelerated/x86/aes-gcm-x86-aesni.c
index b0edaebfba..3be63ddd97 100644
--- a/lib/accelerated/x86/aes-gcm-x86-aesni.c
+++ b/lib/accelerated/x86/aes-gcm-x86-aesni.c
@@ -36,12 +36,14 @@
#include <x86-common.h>
#include <byteswap.h>
#include <nettle/gcm.h>
-#include <aes-x86.h>
/* GCM mode
* It is used when the CPU doesn't include the PCLMUL instructions.
*/
-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY);
+struct gcm_x86_aes_ctx {
+ struct GCM_CTX(AES_KEY) inner;
+ size_t rekey_counter;
+};
static void x86_aes_encrypt(const void *_ctx,
size_t length, uint8_t * dst,
@@ -101,17 +103,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t length)
struct gcm_x86_aes_ctx *ctx = _ctx;
if (length == 16) {
- GCM_SET_KEY(ctx, x86_aes128_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes128_set_encrypt_key, x86_aes_encrypt,
key);
} else if (length == 24) {
- GCM_SET_KEY(ctx, x86_aes192_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes192_set_encrypt_key, x86_aes_encrypt,
key);
} else if (length == 32) {
- GCM_SET_KEY(ctx, x86_aes256_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes256_set_encrypt_key, x86_aes_encrypt,
key);
} else
return GNUTLS_E_INVALID_REQUEST;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -122,8 +125,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
if (iv_size != GCM_BLOCK_SIZE - 4)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- GCM_SET_IV(ctx, iv_size, iv);
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -132,11 +136,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
void *dst, size_t length)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
+ int ret;
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -150,7 +160,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(dst_size < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
+ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -158,7 +168,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
- GCM_UPDATE(ctx, src_size, src);
+ GCM_UPDATE(&ctx->inner, src_size, src);
return 0;
}
@@ -167,7 +177,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag);
+ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag);
}
static void aes_gcm_deinit(void *_ctx)
diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
index 21aef94440..fbefe432f4 100644
--- a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
+++ b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c
@@ -61,6 +61,7 @@ struct aes_gcm_ctx {
struct gcm128_context gcm;
unsigned finished;
unsigned auth_finished;
+ size_t rekey_counter;
};
void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]);
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
gcm_init_avx(ctx->gcm.Htable, ctx->gcm.H.u);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
ctx->finished = 0;
ctx->auth_finished = 0;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
int exp_blocks = blocks * GCM_BLOCK_SIZE;
int rest = src_size - (exp_blocks);
uint32_t counter;
+ int ret;
if (unlikely(ctx->finished))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
if (blocks > 0) {
aesni_ctr32_encrypt_blocks(src, dst,
blocks,
diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul.c b/lib/accelerated/x86/aes-gcm-x86-pclmul.c
index e6b4990cbf..5385acbb6b 100644
--- a/lib/accelerated/x86/aes-gcm-x86-pclmul.c
+++ b/lib/accelerated/x86/aes-gcm-x86-pclmul.c
@@ -60,6 +60,7 @@ struct aes_gcm_ctx {
struct gcm128_context gcm;
unsigned finished;
unsigned auth_finished;
+ size_t rekey_counter;
};
void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]);
@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
gcm_init_clmul(ctx->gcm.Htable, ctx->gcm.H.u);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2;
ctx->finished = 0;
ctx->auth_finished = 0;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
int exp_blocks = blocks * GCM_BLOCK_SIZE;
int rest = src_size - (exp_blocks);
uint32_t counter;
+ int ret;
if (unlikely(ctx->finished))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
if (blocks > 0) {
aesni_ctr32_encrypt_blocks(src, dst,
blocks,
diff --git a/lib/accelerated/x86/aes-gcm-x86-ssse3.c b/lib/accelerated/x86/aes-gcm-x86-ssse3.c
index 7a2ac50869..f074cb1096 100644
--- a/lib/accelerated/x86/aes-gcm-x86-ssse3.c
+++ b/lib/accelerated/x86/aes-gcm-x86-ssse3.c
@@ -36,13 +36,15 @@
#include <x86-common.h>
#include <byteswap.h>
#include <nettle/gcm.h>
-#include <aes-x86.h>
#include <assert.h>
/* GCM mode
* It is used when the CPU doesn't include the PCLMUL instructions.
*/
-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY);
+struct gcm_x86_aes_ctx {
+ struct GCM_CTX(AES_KEY) inner;
+ size_t rekey_counter;
+};
static void x86_aes_encrypt(const void *_ctx,
size_t length, uint8_t * dst,
@@ -110,17 +112,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize)
struct gcm_x86_aes_ctx *ctx = _ctx;
if (keysize == 16) {
- GCM_SET_KEY(ctx, x86_aes_128_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes_128_set_encrypt_key, x86_aes_encrypt,
key);
} else if (keysize == 24) {
- GCM_SET_KEY(ctx, x86_aes_192_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes_192_set_encrypt_key, x86_aes_encrypt,
key);
} else if (keysize == 32) {
- GCM_SET_KEY(ctx, x86_aes_256_set_encrypt_key, x86_aes_encrypt,
+ GCM_SET_KEY(&ctx->inner, x86_aes_256_set_encrypt_key, x86_aes_encrypt,
key);
} else
return GNUTLS_E_INVALID_REQUEST;
+ ctx->rekey_counter = 0;
return 0;
}
@@ -131,8 +134,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size)
if (iv_size != GCM_BLOCK_SIZE - 4)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- GCM_SET_IV(ctx, iv_size, iv);
+ GCM_SET_IV(&ctx->inner, iv_size, iv);
+ ctx->rekey_counter = 0;
return 0;
}
@@ -141,11 +145,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size,
void *dst, size_t length)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
+ int ret;
if (unlikely(length < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -159,7 +169,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size,
if (unlikely(dst_size < src_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src);
+ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src);
return 0;
}
@@ -167,7 +177,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
- GCM_UPDATE(ctx, src_size, src);
+ GCM_UPDATE(&ctx->inner, src_size, src);
return 0;
}
@@ -176,7 +186,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize)
{
struct gcm_x86_aes_ctx *ctx = _ctx;
- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag);
+ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag);
}
static void aes_gcm_deinit(void *_ctx)
diff --git a/lib/accelerated/x86/aes-x86.h b/lib/accelerated/x86/aes-x86.h
index 023b5f7be6..349d3d5d9c 100644
--- a/lib/accelerated/x86/aes-x86.h
+++ b/lib/accelerated/x86/aes-x86.h
@@ -22,6 +22,21 @@ typedef struct {
if (s != 16 && s != 24 && s != 32) \
return GNUTLS_E_INVALID_REQUEST
+#include <intprops.h>
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
+static inline int
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
+ size_t sum;
+
+ if (!INT_ADD_OK(*counter, size, &sum) ||
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ *counter = sum;
+
+ return 0;
+}
+
void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY * key, int enc);
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index ab4c46d2d0..b41862d1ea 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -63,6 +63,7 @@
#include <nettle/xts.h>
#include <nettle/siv-cmac.h>
#include <fips.h>
+#include <intprops.h>
struct nettle_cipher_ctx;
@@ -120,8 +121,23 @@ struct nettle_cipher_ctx {
unsigned iv_size;
bool enc;
+ size_t rekey_counter;
};
+#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32)
+static inline int
+record_aes_gcm_encrypt_size(size_t *counter, size_t size) {
+ size_t sum;
+
+ if (!INT_ADD_OK(*counter, size, &sum) ||
+ sum > AES_GCM_ENCRYPT_MAX_BYTES) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ *counter = sum;
+
+ return 0;
+}
+
static void
_stream_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
const uint8_t * src)
@@ -1133,6 +1149,16 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize)
else
ctx->cipher->set_decrypt_key(ctx->ctx_ptr, key);
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_GCM:
+ case GNUTLS_CIPHER_AES_192_GCM:
+ case GNUTLS_CIPHER_AES_256_GCM:
+ ctx->rekey_counter = 0;
+ break;
+ default:
+ break;
+ }
+
return 0;
}
@@ -1147,6 +1173,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t iv_size)
case GNUTLS_CIPHER_AES_192_GCM:
case GNUTLS_CIPHER_AES_256_GCM:
FIPS_RULE(iv_size < GCM_IV_SIZE, GNUTLS_E_INVALID_REQUEST, "access to short GCM nonce size\n");
+ ctx->rekey_counter = 0;
break;
case GNUTLS_CIPHER_SALSA20_256:
case GNUTLS_CIPHER_ESTREAM_SALSA20_256:
@@ -1207,10 +1234,24 @@ wrap_nettle_cipher_encrypt(void *_ctx, const void *plain, size_t plain_size,
void *encr, size_t encr_size)
{
struct nettle_cipher_ctx *ctx = _ctx;
+ int ret;
if (unlikely(ctx->cipher->encrypt == NULL))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_GCM:
+ case GNUTLS_CIPHER_AES_192_GCM:
+ case GNUTLS_CIPHER_AES_256_GCM:
+ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, plain_size);
+ if (ret < 0) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ default:
+ break;
+ }
+
ctx->cipher->encrypt(ctx, plain_size, encr, plain);
return 0;
diff --git a/tests/slow/cipher-api-test.c b/tests/slow/cipher-api-test.c
index fc880bcc9f..1d267ce312 100644
--- a/tests/slow/cipher-api-test.c
+++ b/tests/slow/cipher-api-test.c
@@ -21,6 +21,7 @@
*/
#include <config.h>
+#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -48,6 +49,11 @@ int main(int argc, char **argv)
#include <assert.h>
#include <utils.h>
+#define AES_GCM_ENCRYPT_PLAINTEXT_MAX ((1ULL << 36) - 32)
+#if SIZE_MAX >= AES_GCM_ENCRYPT_PLAINTEXT_MAX
+#define TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE 1
+#endif
+
static void tls_log_func(int level, const char *str)
{
fprintf(stderr, "<%d>| %s", level, str);
@@ -401,6 +407,74 @@ static void test_aead_invalid_short_decrypt(int algo)
return;
}
+#ifdef TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE
+/* Test whether an invalid call to gnutls_cipher_encrypt() with too
+ * long message is caught */
+static void test_aead_invalid_too_long_encrypt(int algo)
+{
+ int ret;
+ gnutls_cipher_hd_t ch;
+ uint8_t key16[64];
+ uint8_t iv16[32];
+ uint8_t data[128];
+ gnutls_datum_t key, iv;
+
+ if (algo != GNUTLS_CIPHER_AES_128_GCM &&
+ algo != GNUTLS_CIPHER_AES_192_GCM &&
+ algo != GNUTLS_CIPHER_AES_256_GCM) {
+ return;
+ }
+
+ key.data = key16;
+ key.size = gnutls_cipher_get_key_size(algo);
+ assert(key.size <= sizeof(key16));
+
+ iv.data = iv16;
+ iv.size = gnutls_cipher_get_iv_size(algo);
+ assert(iv.size <= sizeof(iv16));
+
+ memset(iv.data, 0xff, iv.size);
+ memset(key.data, 0xfe, key.size);
+ memset(data, 0xfa, sizeof(data));
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ ret = global_init();
+ if (ret < 0) {
+ fail("Cannot initialize library\n"); /*errcode 1 */
+ }
+
+ ret = gnutls_cipher_init(&ch, algo, &key, &iv);
+ if (ret < 0)
+ fail("gnutls_cipher_init failed\n"); /*errcode 1 */
+
+ /* Test exceeding AES-GCM plaintext limit */
+ ret = gnutls_cipher_encrypt(ch, data, sizeof(data));
+ if (ret < 0)
+ fail("could not encrypt data\n");
+
+ /* A few blocks larger than AES_GCM_ENCRYPT_PLAINTEXT_MAX combined with
+ * the previous call. Use NULL for PLAINTEXT so the access to the first
+ * block always results in page fault (in case the limit is not
+ * enforced).
+ */
+ ret = gnutls_cipher_encrypt(ch, NULL, AES_GCM_ENCRYPT_PLAINTEXT_MAX);
+ if (ret >= 0)
+ fail("succeeded in encrypting too long data\n");
+ if (ret != GNUTLS_E_INVALID_REQUEST)
+ fail("wrong kind of error on encrypting too long data,"
+ "%s instead of GNUTLS_E_INVALID_REQUEST\n",
+ gnutls_strerror_name(ret));
+
+ gnutls_cipher_deinit(ch);
+
+ gnutls_global_deinit();
+ return;
+}
+#endif
+
static void check_status(int status)
{
if (WEXITSTATUS(status) != 0 ||
@@ -464,6 +538,11 @@ void start(const char *name, int algo, unsigned aead)
success("trying %s: test_aead_invalid_short_decrypt\n", name);
fork_subtest(test_aead_invalid_short_decrypt, algo);
+
+#if TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE
+ success("trying %s: test_aead_invalid_too_long_encrypt\n", name);
+ fork_subtest(test_aead_invalid_too_long_encrypt, algo);
+#endif
}
}
--
2.37.1

View File

@ -1,183 +0,0 @@
From 2e5f198d9440e508be13cdbad6e3f3ab47898037 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Thu, 11 Jan 2024 15:45:11 +0900
Subject: [PATCH] x509: detect loop in certificate chain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There can be a loop in a certificate chain, when multiple CA
certificates are cross-signed with each other, such as A → B, B → C,
and C → A. Previously, the verification logic was not capable of
handling this scenario while sorting the certificates in the chain in
_gnutls_sort_clist, resulting in an assertion failure. This patch
properly detects such loop and aborts further processing in a graceful
manner.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/x509/common.c | 4 ++
tests/test-chains.h | 125 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+)
diff --git a/lib/x509/common.c b/lib/x509/common.c
index ca0b71cb69..1a022f91af 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1796,6 +1796,10 @@ unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist,
break;
}
+ if (insorted[prev]) { /* loop detected */
+ break;
+ }
+
sorted[i] = clist[prev];
insorted[prev] = 1;
}
diff --git a/tests/test-chains.h b/tests/test-chains.h
index dd7ccf0e40..09a5461ebf 100644
--- a/tests/test-chains.h
+++ b/tests/test-chains.h
@@ -4263,6 +4263,129 @@ static const char *rsa_sha1_not_in_trusted_ca[] = {
NULL
};
+static const char *cross_signed[] = {
+ /* server (signed by A1) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBqDCCAVqgAwIBAgIUejlil+8DBffazcnMNwyOOP6yCCowBQYDK2VwMBoxGDAW\n"
+ "BgNVBAMTD0ludGVybWVkaWF0ZSBBMTAgFw0yNDAxMTEwNjI3MjJaGA85OTk5MTIz\n"
+ "MTIzNTk1OVowNzEbMBkGA1UEChMSR251VExTIHRlc3Qgc2VydmVyMRgwFgYDVQQD\n"
+ "Ew90ZXN0LmdudXRscy5vcmcwKjAFBgMrZXADIQA1ZVS0PcNeTPQMZ+FuVz82AHrj\n"
+ "qL5hWEpCDgpG4M4fxaOBkjCBjzAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3Rl\n"
+ "c3QuZ251dGxzLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMC\n"
+ "B4AwHQYDVR0OBBYEFGtEUv+JSt+zPoO3lu0IiObZVoiNMB8GA1UdIwQYMBaAFPnY\n"
+ "v6Pw0IvKSqIlb6ewHyEAmTA3MAUGAytlcANBAAS2lyc87kH/aOvNKzPjqDwUYxPA\n"
+ "CfYjyaKea2d0DZLBM5+Bjnj/4aWwTKgVTJzWhLJcLtaSdVHrXqjr9NhEhQ0=\n"
+ "-----END CERTIFICATE-----\n",
+ /* A1 (signed by A) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBUjCCAQSgAwIBAgIUe/R+NVp04e74ySw2qgI6KZgFR20wBQYDK2VwMBExDzAN\n"
+ "BgNVBAMTBlJvb3QgQTAgFw0yNDAxMTEwNjI1MDFaGA85OTk5MTIzMTIzNTk1OVow\n"
+ "GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIEExMCowBQYDK2VwAyEAlkTNqwz973sy\n"
+ "u3whMjSiUMs77CZu5YA7Gi5KcakExrKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYD\n"
+ "VR0PAQH/BAQDAgIEMB0GA1UdDgQWBBT52L+j8NCLykqiJW+nsB8hAJkwNzAfBgNV\n"
+ "HSMEGDAWgBRbYgOkRGsd3Z74+CauX4htzLg0lzAFBgMrZXADQQBM0NBaFVPd3cTJ\n"
+ "DSaZNT34fsHuJk4eagpn8mBxKQpghq4s8Ap+nYtp2KiXjcizss53PeLXVnkfyLi0\n"
+ "TLVBHvUJ\n"
+ "-----END CERTIFICATE-----\n",
+ /* A (signed by B) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhQtdJpg+qlPcLoRW8iiztJUD4xNvDAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBCMCAXDTI0MDExMTA2MTk1OVoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEEwKjAFBgMrZXADIQA0vDYyg3tgotSETL1Wq2hBs32p\n"
+ "WbnINkmOSNmOiZlGHKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFFtiA6REax3dnvj4Jq5fiG3MuDSXMB8GA1UdIwQYMBaAFJFA\n"
+ "s2rg6j8w9AKItRnOOOjG2FG6MAUGAytlcANBAPv674p9ek5GjRcRfVQhgN+kQlHU\n"
+ "u774wL3Vx3fWA1E7+WchdMzcHrPoa5OKtKmxjIKUTO4SeDZL/AVpvulrWwk=\n"
+ "-----END CERTIFICATE-----\n",
+ /* A (signed by C) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhReNpCiVn7eFDUox3mvM5qE942AVzAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBDMCAXDTI0MDExMTA2MjEyMVoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEIwKjAFBgMrZXADIQAYX92hS97OGKbMzwrD7ReVifwM\n"
+ "3iz5tnfQHWQSkvvYMKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFJFAs2rg6j8w9AKItRnOOOjG2FG6MB8GA1UdIwQYMBaAFEh/\n"
+ "XKjIuMeEavX5QVoy39Q+GhnwMAUGAytlcANBAIwghH3gelXty8qtoTGIEJb0+EBv\n"
+ "BH4YOUh7TamxjxkjvvIhDA7ZdheofFb7NrklJco7KBcTATUSOvxakYRP9Q8=\n"
+ "-----END CERTIFICATE-----\n",
+ /* B1 (signed by B) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBUjCCAQSgAwIBAgIUfpmrVDc1XBA5/7QYMyGBuB9mTtUwBQYDK2VwMBExDzAN\n"
+ "BgNVBAMTBlJvb3QgQjAgFw0yNDAxMTEwNjI1MjdaGA85OTk5MTIzMTIzNTk1OVow\n"
+ "GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIEIxMCowBQYDK2VwAyEAh6ZTuJWsweVB\n"
+ "a5fsye5iq89kWDC2Y/Hlc0htLmjzMP+jYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYD\n"
+ "VR0PAQH/BAQDAgIEMB0GA1UdDgQWBBTMQu37PKyLjKfPODZgxYCaayff+jAfBgNV\n"
+ "HSMEGDAWgBSRQLNq4Oo/MPQCiLUZzjjoxthRujAFBgMrZXADQQBblmguY+lnYvOK\n"
+ "rAZJnqpEUGfm1tIFyu3rnlE7WOVcXRXMIoNApLH2iHIipQjlvNWuSBFBTC1qdewh\n"
+ "/e+0cgQB\n"
+ "-----END CERTIFICATE-----\n",
+ /* B (signed by A) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhRpEm+dWNX6DMZh/nottkFfFFrXXDAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBBMCAXDTI0MDExMTA2MTcyNloYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEIwKjAFBgMrZXADIQAYX92hS97OGKbMzwrD7ReVifwM\n"
+ "3iz5tnfQHWQSkvvYMKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFJFAs2rg6j8w9AKItRnOOOjG2FG6MB8GA1UdIwQYMBaAFFti\n"
+ "A6REax3dnvj4Jq5fiG3MuDSXMAUGAytlcANBAFvmcK3Ida5ViVYDzxKVLPcPsCHe\n"
+ "3hxz99lBrerJC9iJSvRYTJoPBvjTxDYnBn5EFrQYMrUED+6i71lmGXNU9gs=\n"
+ "-----END CERTIFICATE-----\n",
+ /* B (signed by C) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhReNpCiVn7eFDUox3mvM5qE942AVzAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBDMCAXDTI0MDExMTA2MjEyMVoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEIwKjAFBgMrZXADIQAYX92hS97OGKbMzwrD7ReVifwM\n"
+ "3iz5tnfQHWQSkvvYMKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFJFAs2rg6j8w9AKItRnOOOjG2FG6MB8GA1UdIwQYMBaAFEh/\n"
+ "XKjIuMeEavX5QVoy39Q+GhnwMAUGAytlcANBAIwghH3gelXty8qtoTGIEJb0+EBv\n"
+ "BH4YOUh7TamxjxkjvvIhDA7ZdheofFb7NrklJco7KBcTATUSOvxakYRP9Q8=\n"
+ "-----END CERTIFICATE-----\n",
+ /* C1 (signed by C) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBUjCCAQSgAwIBAgIUSKsfY1wD3eD2VmaaK1wt5naPckMwBQYDK2VwMBExDzAN\n"
+ "BgNVBAMTBlJvb3QgQzAgFw0yNDAxMTEwNjI1NDdaGA85OTk5MTIzMTIzNTk1OVow\n"
+ "GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIEMxMCowBQYDK2VwAyEA/t7i1chZlKkV\n"
+ "qxJOrmmyATn8XnpK+nV/iT4OMHSHfAyjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYD\n"
+ "VR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRmpF3JjoP3NiBzE5J5ANT0bvfRmjAfBgNV\n"
+ "HSMEGDAWgBRIf1yoyLjHhGr1+UFaMt/UPhoZ8DAFBgMrZXADQQAeRBXv6WCTOp0G\n"
+ "3wgd8bbEGrrILfpi+qH7aj/MywgkPIlppDYRQ3jL6ASd+So/408dlE0DV9DXKBi0\n"
+ "725XUUYO\n"
+ "-----END CERTIFICATE-----\n",
+ /* C (signed by A) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhRvbZv3SRTjDOiAbyFWHH4y0yMZkjAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBBMCAXDTI0MDExMTA2MTg1MVoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEMwKjAFBgMrZXADIQDxm6Ubhsa0gSa1vBCIO5e+qZEH\n"
+ "8Oocz+buNHfIJbh5NaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFEh/XKjIuMeEavX5QVoy39Q+GhnwMB8GA1UdIwQYMBaAFFti\n"
+ "A6REax3dnvj4Jq5fiG3MuDSXMAUGAytlcANBAPl+SyiOfXJnjSWx8hFMhJ7w92mn\n"
+ "tkGifCFHBpUhYcBIMeMtLw0RBLXqaaN0EKlTFimiEkLClsU7DKYrpEEJegs=\n"
+ "-----END CERTIFICATE-----\n",
+ /* C (signed by B) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBSDCB+6ADAgECAhQU1OJWRVOLrGrgJiLwexd1/MwKkTAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBCMCAXDTI0MDExMTA2MjAzMFoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEMwKjAFBgMrZXADIQDxm6Ubhsa0gSa1vBCIO5e+qZEH\n"
+ "8Oocz+buNHfIJbh5NaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFEh/XKjIuMeEavX5QVoy39Q+GhnwMB8GA1UdIwQYMBaAFJFA\n"
+ "s2rg6j8w9AKItRnOOOjG2FG6MAUGAytlcANBALXeyuj8vj6Q8j4l17VzZwmJl0gN\n"
+ "bCGoKMl0J/0NiN/fQRIsdbwQDh0RUN/RN3I6DTtB20ER6f3VdnzAh8nXkQ4=\n"
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
+static const char *cross_signed_ca[] = {
+ /* A (self-signed) */
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIBJzCB2qADAgECAhQs1Ur+gzPs1ISxs3Tbs700q0CZcjAFBgMrZXAwETEPMA0G\n"
+ "A1UEAxMGUm9vdCBBMCAXDTI0MDExMTA2MTYwMFoYDzk5OTkxMjMxMjM1OTU5WjAR\n"
+ "MQ8wDQYDVQQDEwZSb290IEEwKjAFBgMrZXADIQA0vDYyg3tgotSETL1Wq2hBs32p\n"
+ "WbnINkmOSNmOiZlGHKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
+ "AgQwHQYDVR0OBBYEFFtiA6REax3dnvj4Jq5fiG3MuDSXMAUGAytlcANBAHrVv7E9\n"
+ "5scuOVCH9gNRRm8Z9SUoLakRHAPnySdg6z/kI3vOgA/OM7reArpnW8l1H2FapgpL\n"
+ "bDeZ2XJH+BdVFwg=\n"
+ "-----END CERTIFICATE-----\n",
+ NULL
+};
+
#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4442,6 +4565,8 @@ static struct
rsa_sha1_not_in_trusted, rsa_sha1_not_in_trusted_ca,
GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM),
GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1620118136, 1},
+ { "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0,
+ 1704955300 },
{ NULL, NULL, NULL, 0, 0}
};
--
2.43.0

View File

@ -1,119 +0,0 @@
From 8ff391fa011e02c88b0d099061ca62e88ab68011 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 15 Aug 2022 09:39:18 +0900
Subject: [PATCH] accelerated: clear AVX bits if it cannot be queried through
XSAVE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The algorithm to detect AVX is described in 14.3 of "Intel® 64 and IA-32
Architectures Software Developers Manual".
GnuTLS previously only followed that algorithm when registering the
crypto backend, while the CRYPTOGAMS derived SHA code assembly expects
that the extension bits are propagated to _gnutls_x86_cpuid_s.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/accelerated/x86/x86-common.c | 49 +++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c
index 7ddaa594e6..b7a88ddeca 100644
--- a/lib/accelerated/x86/x86-common.c
+++ b/lib/accelerated/x86/x86-common.c
@@ -81,6 +81,26 @@ unsigned int _gnutls_x86_cpuid_s[4];
# define bit_AVX 0x10000000
#endif
+#ifndef bit_AVX2
+# define bit_AVX2 0x00000020
+#endif
+
+#ifndef bit_AVX512F
+# define bit_AVX512F 0x00010000
+#endif
+
+#ifndef bit_AVX512IFMA
+# define bit_AVX512IFMA 0x00200000
+#endif
+
+#ifndef bit_AVX512BW
+# define bit_AVX512BW 0x40000000
+#endif
+
+#ifndef bit_AVX512VL
+# define bit_AVX512VL 0x80000000
+#endif
+
#ifndef bit_OSXSAVE
# define bit_OSXSAVE 0x8000000
#endif
@@ -89,10 +109,6 @@ unsigned int _gnutls_x86_cpuid_s[4];
# define bit_MOVBE 0x00400000
#endif
-#ifndef OSXSAVE_MASK
-# define OSXSAVE_MASK (bit_OSXSAVE|bit_MOVBE)
-#endif
-
#define bit_PADLOCK (0x3 << 6)
#define bit_PADLOCK_PHE (0x3 << 10)
#define bit_PADLOCK_PHE_SHA512 (0x3 << 25)
@@ -148,7 +164,7 @@ static unsigned check_4th_gen_intel_features(unsigned ecx)
{
uint32_t xcr0;
- if ((ecx & OSXSAVE_MASK) != OSXSAVE_MASK)
+ if ((ecx & bit_OSXSAVE) != bit_OSXSAVE)
return 0;
#if defined(_MSC_VER) && !defined(__clang__)
@@ -190,8 +206,9 @@ static void capabilities_to_intel_cpuid(unsigned capabilities)
}
if (capabilities & INTEL_AVX) {
- if ((a[1] & bit_AVX) && check_4th_gen_intel_features(a[1])) {
- _gnutls_x86_cpuid_s[1] |= bit_AVX|OSXSAVE_MASK;
+ if ((a[1] & bit_AVX) && (a[1] & bit_MOVBE) &&
+ check_4th_gen_intel_features(a[1])) {
+ _gnutls_x86_cpuid_s[1] |= bit_AVX|bit_MOVBE;
} else {
_gnutls_debug_log
("AVX acceleration requested but not available\n");
@@ -236,10 +253,7 @@ static unsigned check_sha(void)
#ifdef ASM_X86_64
static unsigned check_avx_movbe(void)
{
- if (check_4th_gen_intel_features(_gnutls_x86_cpuid_s[1]) == 0)
- return 0;
-
- return ((_gnutls_x86_cpuid_s[1] & bit_AVX));
+ return (_gnutls_x86_cpuid_s[1] & (bit_AVX|bit_MOVBE)) == (bit_AVX|bit_MOVBE);
}
static unsigned check_pclmul(void)
@@ -884,6 +898,19 @@ void register_x86_intel_crypto(unsigned capabilities)
if (capabilities == 0) {
if (!read_cpuid_vals(_gnutls_x86_cpuid_s))
return;
+ if (!check_4th_gen_intel_features(_gnutls_x86_cpuid_s[1])) {
+ _gnutls_x86_cpuid_s[1] &= ~bit_AVX;
+
+ /* Clear AVX2 bits as well, according to what
+ * OpenSSL does. Should we clear
+ * bit_AVX512DQ, bit_AVX512PF, bit_AVX512ER,
+ * and bit_AVX512CD? */
+ _gnutls_x86_cpuid_s[2] &= ~(bit_AVX2|
+ bit_AVX512F|
+ bit_AVX512IFMA|
+ bit_AVX512BW|
+ bit_AVX512BW);
+ }
} else {
capabilities_to_intel_cpuid(capabilities);
}
--
2.37.2

View File

@ -1,6 +1,6 @@
From 3035e884b3abc68bcebff5adec5bd8819bbc6d7b Mon Sep 17 00:00:00 2001
From 968de8a9779788a853a4c0cd75beda779cb15f52 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 5 Aug 2022 16:16:42 +0900
Date: Thu, 16 Nov 2023 17:09:58 +0900
Subject: [PATCH] gnutls-3.7.6-drbg-reseed.patch
Signed-off-by: rpm-build <rpm-build>
@ -9,21 +9,21 @@ Signed-off-by: rpm-build <rpm-build>
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/nettle/sysrng-linux.c b/lib/nettle/sysrng-linux.c
index 6b3971c..dae9061 100644
index 25d74fe..8b9cc46 100644
--- a/lib/nettle/sysrng-linux.c
+++ b/lib/nettle/sysrng-linux.c
@@ -31,6 +31,9 @@
# include <num.h>
# include <errno.h>
# include <rnd-common.h>
+# include "fips.h"
#include "num.h"
#include <errno.h>
#include "rnd-common.h"
+#include "fips.h"
+#else
+# define _gnutls_fips_mode_enabled() 0
+#define _gnutls_fips_mode_enabled() 0
#endif
#include <sys/types.h>
@@ -103,7 +106,12 @@ static int force_getrandom(void *buf, size_t buflen, unsigned int flags)
static int _rnd_get_system_entropy_getrandom(void* _rnd, size_t size)
@@ -104,7 +107,12 @@ static int force_getrandom(void *buf, size_t buflen, unsigned int flags)
static int _rnd_get_system_entropy_getrandom(void *_rnd, size_t size)
{
int ret;
- ret = force_getrandom(_rnd, size, 0);
@ -37,5 +37,5 @@ index 6b3971c..dae9061 100644
int e = errno;
gnutls_assert();
--
2.37.1
2.41.0

View File

@ -1,331 +0,0 @@
From 26b2caef673aba8bfd10db3b1b8117f941c18e58 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 21 Oct 2022 15:48:39 +0900
Subject: [PATCH] cipher: add restriction on CCM tag length under FIPS mode
This change prohibits any use of tag length other than 4, 6, 8, 10,
12, 14, and 16 bytes in CCM used under FIPS mode, in accordance with
SP800-38C A.1. While use of tag lengths smaller than 8 bytes is not
recommended, we simply allow 4 and 6 bytes tags for now.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/accelerated/aarch64/aes-ccm-aarch64.c | 39 ++++++++++
lib/accelerated/x86/aes-ccm-x86-aesni.c | 39 ++++++++++
lib/nettle/cipher.c | 55 ++++++++++++++
tests/fips-test.c | 87 ++++++++++++++++++++++-
4 files changed, 218 insertions(+), 2 deletions(-)
diff --git a/lib/accelerated/aarch64/aes-ccm-aarch64.c b/lib/accelerated/aarch64/aes-ccm-aarch64.c
index a2ba259e99..b415d4ddfb 100644
--- a/lib/accelerated/aarch64/aes-ccm-aarch64.c
+++ b/lib/accelerated/aarch64/aes-ccm-aarch64.c
@@ -36,6 +36,7 @@
#include <byteswap.h>
#include <nettle/ccm.h>
#include <aes-aarch64.h>
+#include <fips.h>
typedef struct ccm_aarch64_aes_ctx {
AES_KEY key;
@@ -103,6 +104,25 @@ aes_ccm_aead_encrypt(void *_ctx,
if (unlikely(encr_size < plain_size + tag_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ /* SP800-38C A.1 says Tlen must be a multiple of 16 between 32
+ * and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64 should not be used
+ * under sufficient restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+
ccm_encrypt_message(&ctx->key, aarch64_aes_encrypt,
nonce_size, nonce,
auth_size, auth,
@@ -129,6 +149,25 @@ aes_ccm_aead_decrypt(void *_ctx,
if (unlikely(plain_size < encr_size - tag_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ /* SP800-38C A.1 says Tlen must be a multiple of 16 between 32
+ * and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64 should not be used
+ * under sufficient restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+
ret = ccm_decrypt_message(&ctx->key, aarch64_aes_encrypt,
nonce_size, nonce,
auth_size, auth,
diff --git a/lib/accelerated/x86/aes-ccm-x86-aesni.c b/lib/accelerated/x86/aes-ccm-x86-aesni.c
index 701c0f992a..9ebbdd7b2a 100644
--- a/lib/accelerated/x86/aes-ccm-x86-aesni.c
+++ b/lib/accelerated/x86/aes-ccm-x86-aesni.c
@@ -37,6 +37,7 @@
#include <byteswap.h>
#include <nettle/ccm.h>
#include <aes-x86.h>
+#include <fips.h>
typedef struct ccm_x86_aes_ctx {
AES_KEY key;
@@ -95,6 +96,25 @@ aes_ccm_aead_encrypt(void *_ctx,
if (unlikely(encr_size < plain_size + tag_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ /* SP800-38C A.1 says Tlen must be a multiple of 16 between 32
+ * and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64 should not be used
+ * under sufficient restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+
ccm_encrypt_message(&ctx->key, x86_aes_encrypt,
nonce_size, nonce,
auth_size, auth,
@@ -121,6 +141,25 @@ aes_ccm_aead_decrypt(void *_ctx,
if (unlikely(plain_size < encr_size - tag_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ /* SP800-38C A.1 says Tlen must be a multiple of 16 between 32
+ * and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64 should not be used
+ * under sufficient restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+
ret = ccm_decrypt_message(&ctx->key, x86_aes_encrypt,
nonce_size, nonce,
auth_size, auth,
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index 9c2ce19e7e..8c23d11252 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -1253,6 +1253,34 @@ wrap_nettle_cipher_aead_encrypt(void *_ctx,
ctx->cipher->tag(ctx->ctx_ptr, tag_size, ((uint8_t*)encr) + plain_size);
} else {
/* CCM-style cipher */
+
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_CCM:
+ case GNUTLS_CIPHER_AES_256_CCM:
+ /* SP800-38C A.1 says Tlen must be a multiple of 16
+ * between 32 and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64
+ * should not be used under sufficient
+ * restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
ctx->cipher->aead_encrypt(ctx,
nonce_size, nonce,
auth_size, auth,
@@ -1302,6 +1330,33 @@ wrap_nettle_cipher_aead_decrypt(void *_ctx,
if (unlikely(plain_size < encr_size))
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_CCM:
+ case GNUTLS_CIPHER_AES_256_CCM:
+ /* SP800-38C A.1 says Tlen must be a multiple of 16
+ * between 32 and 128.
+ */
+ switch (tag_size) {
+ case 4: case 6:
+ /* SP800-38C B.2 says Tlen smaller than 64
+ * should not be used under sufficient
+ * restriction. We simply allow those for now.
+ */
+ FALLTHROUGH;
+ case 8: case 10: case 12: case 14: case 16:
+ break;
+ default:
+ if (_gnutls_fips_mode_enabled()) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
ret = ctx->cipher->aead_decrypt(ctx,
nonce_size, nonce,
auth_size, auth,
diff --git a/tests/fips-test.c b/tests/fips-test.c
index f7556d7bbb..c43503fba0 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -1,4 +1,5 @@
#include <config.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -213,14 +214,96 @@ test_cipher_disallowed(gnutls_cipher_algorithm_t cipher)
FIPS_POP_CONTEXT(ERROR);
}
+static void
+test_ccm_cipher(gnutls_cipher_algorithm_t cipher, size_t tag_length,
+ bool expect_encryption_fail,
+ gnutls_fips140_operation_state_t expected_state)
+{
+ int ret;
+ unsigned key_size = gnutls_cipher_get_key_size(cipher);
+ gnutls_aead_cipher_hd_t h;
+ gnutls_datum_t key = { key_data, key_size };
+ unsigned char buffer[256];
+ size_t length;
+ gnutls_memset(key_data, 0, key_size);
+
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_aead_cipher_init(&h, cipher, &key);
+ if (ret < 0) {
+ fail("gnutls_aead_cipher_init failed for %s\n",
+ gnutls_cipher_get_name(cipher));
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
+ fips_push_context(fips_context);
+ memset(buffer, 0, sizeof(buffer));
+ length = sizeof(buffer);
+ ret = gnutls_aead_cipher_encrypt(h, iv_data,
+ gnutls_cipher_get_iv_size(cipher),
+ NULL, 0, tag_length,
+ buffer, length - tag_length,
+ buffer, &length);
+ if (expect_encryption_fail) {
+ if (ret != GNUTLS_E_INVALID_REQUEST) {
+ fail("gnutls_aead_cipher_encrypt(%s) returned %d "
+ "while %d is expected\n",
+ gnutls_cipher_get_name(cipher),
+ ret, GNUTLS_E_INVALID_REQUEST);
+ }
+ } else if (ret < 0) {
+ fail("gnutls_aead_cipher_encrypt failed for %s\n",
+ gnutls_cipher_get_name(cipher));
+ }
+ fips_pop_context(fips_context, expected_state);
+
+ fips_push_context(fips_context);
+ length = sizeof(buffer);
+ ret = gnutls_aead_cipher_decrypt(h, iv_data,
+ gnutls_cipher_get_iv_size(cipher),
+ NULL, 0, tag_length,
+ buffer, length,
+ buffer, &length);
+ if (expect_encryption_fail) {
+ if (ret != GNUTLS_E_INVALID_REQUEST) {
+ fail("gnutls_aead_cipher_decrypt(%s) returned %d "
+ "while %d is expected\n",
+ gnutls_cipher_get_name(cipher),
+ ret, GNUTLS_E_INVALID_REQUEST);
+ }
+ } else if (ret < 0) {
+ fail("gnutls_aead_cipher_decrypt failed for %s\n",
+ gnutls_cipher_get_name(cipher));
+ }
+ fips_pop_context(fips_context, expected_state);
+
+ gnutls_aead_cipher_deinit(h);
+}
+
static inline void
test_ciphers(void)
{
+ size_t i;
+
test_cipher_approved(GNUTLS_CIPHER_AES_128_CBC);
test_cipher_approved(GNUTLS_CIPHER_AES_192_CBC);
test_cipher_approved(GNUTLS_CIPHER_AES_256_CBC);
- test_aead_cipher_approved(GNUTLS_CIPHER_AES_128_CCM);
- test_aead_cipher_approved(GNUTLS_CIPHER_AES_256_CCM);
+
+ /* Check for all allowed Tlen */
+ for (i = 4; i <= 16; i += 2) {
+ test_ccm_cipher(GNUTLS_CIPHER_AES_128_CCM, i,
+ false, GNUTLS_FIPS140_OP_APPROVED);
+ test_ccm_cipher(GNUTLS_CIPHER_AES_256_CCM, i,
+ false, GNUTLS_FIPS140_OP_APPROVED);
+ }
+ test_ccm_cipher(GNUTLS_CIPHER_AES_128_CCM, 3,
+ true, GNUTLS_FIPS140_OP_ERROR);
+ test_ccm_cipher(GNUTLS_CIPHER_AES_256_CCM, 3,
+ true, GNUTLS_FIPS140_OP_ERROR);
+ test_ccm_cipher(GNUTLS_CIPHER_AES_128_CCM, 5,
+ true, GNUTLS_FIPS140_OP_ERROR);
+ test_ccm_cipher(GNUTLS_CIPHER_AES_256_CCM, 5,
+ true, GNUTLS_FIPS140_OP_ERROR);
+
test_aead_cipher_approved(GNUTLS_CIPHER_AES_128_CCM_8);
test_aead_cipher_approved(GNUTLS_CIPHER_AES_256_CCM_8);
test_cipher_approved(GNUTLS_CIPHER_AES_128_CFB8);
--
2.38.1

View File

@ -1,427 +0,0 @@
From 171b934a8c054e98b110892cae4130e1db64e656 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 29 Sep 2022 21:28:19 +0900
Subject: [PATCH] gnutls-3.7.6-fips-ecdsa-hash-check.patch
---
lib/crypto-backend.h | 12 ++--
lib/nettle/pk.c | 33 +++++-----
lib/privkey.c | 42 ++++++++----
lib/pubkey.c | 5 +-
tests/fips-test.c | 150 ++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 205 insertions(+), 37 deletions(-)
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index f0f68c3..4dd1ae2 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -247,11 +247,13 @@ typedef enum {
GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH = 4
} gnutls_pk_flag_t;
-#define FIX_SIGN_PARAMS(params, flags, dig) do { \
- if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \
- (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \
- (params).dsa_dig = (dig); \
- } \
+#define FIX_SIGN_PARAMS(params, flags, dig) do { \
+ if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \
+ (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \
+ } \
+ if ((params).pk == GNUTLS_PK_DSA || (params).pk == GNUTLS_PK_ECDSA) { \
+ (params).dsa_dig = (dig); \
+ } \
} while (0)
void gnutls_pk_params_release(gnutls_pk_params_st * p);
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index f38016b..c098e2a 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -1104,8 +1104,16 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
me = _gnutls_dsa_q_to_hash(pk_params,
&hash_len);
+ if (hash_len > vdata->size) {
+ gnutls_assert();
+ _gnutls_debug_log
+ ("Security level of algorithm requires hash %s(%d) or better\n",
+ _gnutls_mac_get_name(me), hash_len);
+ hash_len = vdata->size;
+ }
+
/* Only SHA-2 is allowed in FIPS 140-3 */
- switch (me->id) {
+ switch (DIG_TO_MAC(sign_params->dsa_dig)) {
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
@@ -1115,14 +1123,6 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
not_approved = true;
}
- if (hash_len > vdata->size) {
- gnutls_assert();
- _gnutls_debug_log
- ("Security level of algorithm requires hash %s(%d) or better\n",
- _gnutls_mac_get_name(me), hash_len);
- hash_len = vdata->size;
- }
-
mpz_init(k);
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
@@ -1545,7 +1545,6 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
struct dsa_signature sig;
int curve_id = pk_params->curve;
const struct ecc_curve *curve;
- const mac_entry_st *me;
curve = get_supported_nist_curve(curve_id);
if (curve == NULL) {
@@ -1571,11 +1570,14 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
memcpy(sig.r, tmp[0], SIZEOF_MPZT);
memcpy(sig.s, tmp[1], SIZEOF_MPZT);
- me = _gnutls_dsa_q_to_hash(pk_params, &hash_len);
+ (void)_gnutls_dsa_q_to_hash(pk_params, &hash_len);
+
+ if (hash_len > vdata->size)
+ hash_len = vdata->size;
/* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
* mode */
- switch (me->id) {
+ switch (DIG_TO_MAC(sign_params->dsa_dig)) {
case GNUTLS_MAC_SHA1:
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
@@ -1586,9 +1588,6 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
not_approved = true;
}
- if (hash_len > vdata->size)
- hash_len = vdata->size;
-
ret =
ecdsa_verify(&pub, hash_len, vdata->data,
&sig);
@@ -2390,8 +2389,10 @@ static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* param
if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) {
unsigned hash_len;
+ const mac_entry_st *me;
- _gnutls_dsa_q_to_hash(params, &hash_len);
+ me = _gnutls_dsa_q_to_hash(params, &hash_len);
+ spki.dsa_dig = MAC_TO_DIG(me->id);
gen_data = gnutls_malloc(hash_len);
gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len);
diff --git a/lib/privkey.c b/lib/privkey.c
index 0b77443..2069fc0 100644
--- a/lib/privkey.c
+++ b/lib/privkey.c
@@ -1251,27 +1251,36 @@ gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
} else {
se = _gnutls_sign_to_entry(algo);
- if (unlikely(se == NULL))
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-
+ if (unlikely(se == NULL)) {
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
}
ret = _gnutls_privkey_get_spki_params(signer, &params);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
flags, &params);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
FIX_SIGN_PARAMS(params, flags, se->hash);
- return privkey_sign_prehashed(signer, se, hash_data, signature, &params);
+ ret = privkey_sign_prehashed(signer, se, hash_data, signature, &params);
+
+ cleanup:
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ }
+ return ret;
}
int
@@ -1366,14 +1375,14 @@ gnutls_privkey_sign_hash(gnutls_privkey_t signer,
ret = _gnutls_privkey_get_spki_params(signer, &params);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
hash_algo, flags, &params);
if (ret < 0) {
gnutls_assert();
- return ret;
+ goto cleanup;
}
/* legacy callers of this API could use a hash algorithm of 0 (unknown)
@@ -1391,13 +1400,22 @@ gnutls_privkey_sign_hash(gnutls_privkey_t signer,
se = _gnutls_pk_to_sign_entry(params.pk, hash_algo);
}
- if (unlikely(se == NULL))
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ if (unlikely(se == NULL)) {
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
FIX_SIGN_PARAMS(params, flags, hash_algo);
- return privkey_sign_prehashed(signer, se,
- hash_data, signature, &params);
+ ret = privkey_sign_prehashed(signer, se,
+ hash_data, signature, &params);
+ cleanup:
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ }
+ return ret;
}
static int
diff --git a/lib/pubkey.c b/lib/pubkey.c
index eba1f5b..35126f3 100644
--- a/lib/pubkey.c
+++ b/lib/pubkey.c
@@ -1985,7 +1985,7 @@ gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key,
* parameters (if any) with the signature algorithm */
static
int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_entry_st *se,
- const mac_entry_st *me, gnutls_x509_spki_st *params)
+ const mac_entry_st *me, gnutls_x509_spki_st *params)
{
unsigned bits;
@@ -2018,6 +2018,9 @@ int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_e
if (params->rsa_pss_dig != se->hash)
return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
+ } else if (params->pk == GNUTLS_PK_DSA ||
+ params->pk == GNUTLS_PK_ECDSA) {
+ params->dsa_dig = se->hash;
}
return 0;
diff --git a/tests/fips-test.c b/tests/fips-test.c
index 788f4ab..ec0f4b4 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -80,8 +80,22 @@ static const gnutls_datum_t rsa2342_sha1_sig = {
.size = sizeof(rsa2342_sha1_sig_data),
};
+static const uint8_t ecc256_sha1_sig_data[] = {
+ 0x30, 0x45, 0x02, 0x21, 0x00, 0x9a, 0x28, 0xc9, 0xbf, 0xc8, 0x70, 0x4f,
+ 0x27, 0x2d, 0xe1, 0x66, 0xc4, 0xa5, 0xc6, 0xf2, 0xdc, 0x33, 0xb9, 0x41,
+ 0xdf, 0x78, 0x98, 0x8a, 0x22, 0x4d, 0x29, 0x37, 0xa0, 0x0f, 0x6f, 0xd4,
+ 0xed, 0x02, 0x20, 0x0b, 0x15, 0xca, 0x30, 0x09, 0x2d, 0x55, 0x44, 0xb4,
+ 0x1d, 0x3f, 0x48, 0x7a, 0xc3, 0xd1, 0x2a, 0xc1, 0x0e, 0x47, 0xfa, 0xe6,
+ 0xe9, 0x0f, 0x03, 0xe2, 0x01, 0x4e, 0xe4, 0x73, 0x37, 0xa7, 0x90,
+};
+
+static const gnutls_datum_t ecc256_sha1_sig = {
+ .data = (unsigned char *)ecc256_sha1_sig_data,
+ .size = sizeof(ecc256_sha1_sig_data),
+};
+
static void
-rsa_import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey,
+import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey,
const char *filename)
{
const char *srcdir;
@@ -274,6 +288,8 @@ void doit(void)
gnutls_datum_t signature;
unsigned int bits;
uint8_t hmac[64];
+ uint8_t hash[64];
+ gnutls_datum_t hashed_data;
uint8_t pbkdf2[64];
gnutls_datum_t temp_key = { NULL, 0 };
@@ -473,7 +489,7 @@ void doit(void)
/* Import 2432-bit RSA key; not a security function */
FIPS_PUSH_CONTEXT();
- rsa_import_keypair(&privkey, &pubkey, "rsa-2432.pem");
+ import_keypair(&privkey, &pubkey, "rsa-2432.pem");
FIPS_POP_CONTEXT(INITIAL);
/* Create a signature with 2432-bit RSA and SHA256; approved */
@@ -519,7 +535,7 @@ void doit(void)
/* Import 512-bit RSA key; not a security function */
FIPS_PUSH_CONTEXT();
- rsa_import_keypair(&privkey, &pubkey, "rsa-512.pem");
+ import_keypair(&privkey, &pubkey, "rsa-512.pem");
FIPS_POP_CONTEXT(INITIAL);
/* Create a signature with 512-bit RSA and SHA256; not approved */
@@ -543,6 +559,134 @@ void doit(void)
gnutls_pubkey_deinit(pubkey);
gnutls_privkey_deinit(privkey);
+ /* Import ECDSA key; not a security function */
+ FIPS_PUSH_CONTEXT();
+ import_keypair(&privkey, &pubkey, "ecc256.pem");
+ FIPS_POP_CONTEXT(INITIAL);
+
+ /* Create a signature with ECDSA and SHA256; approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* Verify a signature with ECDSA and SHA256; approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA256, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with ECDSA and SHA256 (old API); approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_data failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* Create a SHA256 hashed data for 2-pass signature API; not a
+ * crypto operation */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_hash_fast(GNUTLS_DIG_SHA256, data.data, data.size, hash);
+ if (ret < 0) {
+ fail("gnutls_hash_fast failed\n");
+ }
+ hashed_data.data = hash;
+ hashed_data.size = 32;
+ FIPS_POP_CONTEXT(INITIAL);
+
+ /* Create a signature with ECDSA and SHA256 (2-pass API); not-approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0,
+ &hashed_data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_hash2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with ECDSA and SHA256 (2-pass old API); not-approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA256, 0,
+ &hashed_data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_hash failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with ECDSA and SHA-1; not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* Verify a signature created with ECDSA and SHA-1; approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1,
+ GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data,
+ &ecc256_sha1_sig);
+ if (ret < 0) {
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with ECDSA and SHA-1 (old API); not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_data failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a SHA1 hashed data for 2-pass signature API; not a
+ * crypto operation */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, data.data, data.size, hash);
+ if (ret < 0) {
+ fail("gnutls_hash_fast failed\n");
+ }
+ hashed_data.data = hash;
+ hashed_data.size = 20;
+ FIPS_POP_CONTEXT(INITIAL);
+
+ /* Create a signature with ECDSA and SHA1 (2-pass API); not-approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0,
+ &hashed_data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_hash2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with ECDSA and SHA1 (2-pass old API); not-approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0,
+ &hashed_data, &signature);
+ if (ret < 0) {
+ fail("gnutls_privkey_sign_hash failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
+
+ gnutls_pubkey_deinit(pubkey);
+ gnutls_privkey_deinit(privkey);
+
/* Test RND functions */
FIPS_PUSH_CONTEXT();
ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16));
--
2.37.3

View File

@ -1,805 +0,0 @@
From 4751e1e2d4012404af9bc52535aa73ac88bc7bea Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Thu, 13 Jul 2023 16:14:08 +0200
Subject: [PATCH] gnutls-3.7.6-fips-ems.patch
---
doc/cha-gtls-app.texi | 5 +
lib/gnutls_int.h | 6 +
lib/handshake.c | 35 ++++-
lib/nettle/int/tls1-prf.c | 19 +++
lib/priority.c | 41 +++++
lib/priority_options.gperf | 1 +
tests/Makefile.am | 4 +-
tests/multi-alerts.c | 8 +
tests/no-extensions.c | 7 +
.../ocsp-tests/ocsp-must-staple-connection.sh | 60 +++----
tests/rehandshake-ext-secret.c | 8 +
tests/resume.c | 26 ++-
tests/status-request.c | 8 +-
tests/system-override-session-hash.sh | 144 +++++++++++++++++
tests/tls-force-ems.c | 148 ++++++++++++++++++
15 files changed, 477 insertions(+), 43 deletions(-)
create mode 100755 tests/system-override-session-hash.sh
create mode 100644 tests/tls-force-ems.c
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index bd44478..57e7d50 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -1547,6 +1547,11 @@ This is implied by the PFS keyword.
will prevent the advertizing the TLS extended master secret (session hash)
extension.
+@item %FORCE_SESSION_HASH @tab
+negotiate the TLS extended master secret (session hash) extension.
+Specifying both %NO_SESSION_HASH and %FORCE_SESSION_HASH is not
+supported, and the behavior is undefined.
+
@item %SERVER_PRECEDENCE @tab
The ciphersuite will be selected according to server priorities
and not the client's.
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 8c7bdaa..c6bf154 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -926,6 +926,11 @@ typedef struct sign_algo_list_st {
#include "atomic.h"
+typedef enum ext_master_secret_t {
+ EMS_REQUEST,
+ EMS_REQUIRE
+} ext_master_secret_t;
+
/* For the external api */
struct gnutls_priority_st {
priority_st protocol;
@@ -965,6 +970,7 @@ struct gnutls_priority_st {
bool force_etm;
unsigned int additional_verify_flags;
bool tls13_compat_mode;
+ ext_master_secret_t force_ext_master_secret;
/* TLS_FALLBACK_SCSV */
bool fallback;
diff --git a/lib/handshake.c b/lib/handshake.c
index 21edc5e..1e33b84 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -875,6 +875,15 @@ read_client_hello(gnutls_session_t session, uint8_t * data,
if (_gnutls_version_priority(session, vers->id) < 0)
return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET);
+ /* check if EMS is required */
+ if (!vers->tls13_sem && vers->id != GNUTLS_SSL3 &&
+ vers->id != GNUTLS_DTLS0_9 &&
+ session->internals.priorities->force_ext_master_secret ==
+ EMS_REQUIRE &&
+ !session->security_parameters.ext_master_secret) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
+ }
+
_gnutls_handshake_log("HSK[%p]: Selected version %s\n", session, vers->name);
/* select appropriate compression method */
@@ -2062,11 +2071,27 @@ read_server_hello(gnutls_session_t session,
if (ret < 0)
return gnutls_assert_val(ret);
- /* check if EtM is required */
- if (!vers->tls13_sem && session->internals.priorities->force_etm && !session->security_parameters.etm) {
- const cipher_entry_st *cipher = cipher_to_entry(session->security_parameters.cs->block_algorithm);
- if (_gnutls_cipher_type(cipher) == CIPHER_BLOCK)
- return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
+ if (!vers->tls13_sem) {
+ /* check if EtM is required */
+ if (session->internals.priorities->force_etm &&
+ !session->security_parameters.etm) {
+ const cipher_entry_st *cipher =
+ cipher_to_entry(session->security_parameters.
+ cs->block_algorithm);
+ if (_gnutls_cipher_type(cipher) == CIPHER_BLOCK)
+ return
+ gnutls_assert_val
+ (GNUTLS_E_UNWANTED_ALGORITHM);
+ }
+
+ /* check if EMS is required */
+ if (vers->id != GNUTLS_SSL3 && vers->id != GNUTLS_DTLS0_9 &&
+ session->internals.priorities->force_ext_master_secret ==
+ EMS_REQUIRE &&
+ !session->security_parameters.ext_master_secret) {
+ return
+ gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
+ }
}
diff --git a/lib/nettle/int/tls1-prf.c b/lib/nettle/int/tls1-prf.c
index 19ca5d3..fd9b5a4 100644
--- a/lib/nettle/int/tls1-prf.c
+++ b/lib/nettle/int/tls1-prf.c
@@ -28,6 +28,7 @@
#endif
#include <gnutls_int.h>
+#include "fips.h"
#include <stdlib.h>
#include <string.h>
@@ -152,8 +153,26 @@ tls12_prf(void *mac_ctx,
size_t seed_size, const uint8_t *seed,
size_t length, uint8_t *dst)
{
+#define MASTER_SECRET "master secret"
+#define MASTER_SECRET_SIZE (sizeof(MASTER_SECRET) - 1)
+
P_hash(mac_ctx, update, digest, digest_size,
seed_size, seed, label_size, label, length, dst);
+ /* Since May 16, 2023, the use of extended master secret is
+ * mandatory according to FIPS 140-3 IG D.Q. Instead of
+ * allowing the "extended master secret" label specifically,
+ * we mark the use of non-EMS label, i.e., "master secret" as
+ * non-approved, because it is still useful to call the
+ * gnutls_prf_raw function with arbitrary label, e.g., in
+ * self-tests.
+ */
+ if (label_size == MASTER_SECRET_SIZE &&
+ memcmp(label, MASTER_SECRET, MASTER_SECRET_SIZE) == 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
+ }
+
return 1;
}
diff --git a/lib/priority.c b/lib/priority.c
index d163d81..4adf4c7 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -906,6 +906,12 @@ static void enable_no_ext_master_secret(gnutls_priority_t c)
{
c->_no_ext_master_secret = 1;
}
+
+static void enable_force_ext_master_secret(gnutls_priority_t c)
+{
+ c->force_ext_master_secret = EMS_REQUIRE;
+}
+
static void enable_no_etm(gnutls_priority_t c)
{
c->_no_etm = 1;
@@ -1040,6 +1046,9 @@ struct cfg {
gnutls_kx_algorithm_t kxs[MAX_ALGOS+1];
gnutls_sign_algorithm_t sigs[MAX_ALGOS+1];
gnutls_protocol_t versions[MAX_ALGOS+1];
+
+ ext_master_secret_t force_ext_master_secret;
+ bool force_ext_master_secret_set;
};
static inline void
@@ -1141,6 +1150,8 @@ cfg_steal(struct cfg *dst, struct cfg *src)
dst->allowlisting = src->allowlisting;
dst->ktls_enabled = src->ktls_enabled;
+ dst->force_ext_master_secret = src->force_ext_master_secret;
+ dst->force_ext_master_secret_set = src->force_ext_master_secret_set;
memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers));
memcpy(dst->macs, src->macs, sizeof(src->macs));
memcpy(dst->groups, src->groups, sizeof(src->groups));
@@ -1748,6 +1759,21 @@ static int cfg_ini_handler(void *_ctx, const char *section, const char *name, co
}
cfg->kxs[i] = algo;
cfg->kxs[i+1] = 0;
+ } else if (c_strcasecmp(name, "tls-session-hash") == 0) {
+ if (c_strcasecmp(value, "request") == 0) {
+ cfg->force_ext_master_secret = EMS_REQUEST;
+ cfg->force_ext_master_secret_set = true;
+ } else if (c_strcasecmp(value, "require") == 0) {
+ cfg->force_ext_master_secret = EMS_REQUIRE;
+ cfg->force_ext_master_secret_set = true;
+ } else {
+ _gnutls_debug_log(
+ "cfg: unknown value for %s: %s\n", name,
+ value);
+ if (fail_on_invalid_config)
+ return 0;
+ goto exit;
+ }
} else {
_gnutls_debug_log("unknown parameter %s\n", name);
if (fail_on_invalid_config)
@@ -2744,6 +2770,12 @@ gnutls_priority_init(gnutls_priority_t * priority_cache,
(*priority_cache)->min_record_version = 1;
gnutls_atomic_init(&(*priority_cache)->usage_cnt);
+ if (_gnutls_fips_mode_enabled()) {
+ (*priority_cache)->force_ext_master_secret = EMS_REQUIRE;
+ } else {
+ (*priority_cache)->force_ext_master_secret = EMS_REQUEST;
+ }
+
if (system_wide_config.allowlisting && !priorities) {
priorities = "@" LEVEL_SYSTEM;
}
@@ -2997,6 +3029,15 @@ gnutls_priority_init(gnutls_priority_t * priority_cache,
goto error;
}
+ /* This needs to be done after parsing modifiers, as
+ * tls-session-hash has precedence over modifiers.
+ */
+ if (system_wide_config.force_ext_master_secret_set) {
+ (*priority_cache)->force_ext_master_secret =
+ system_wide_config.force_ext_master_secret;
+ (*priority_cache)->_no_ext_master_secret = false;
+ }
+
ret = set_ciphersuite_list(*priority_cache);
if (ret < 0) {
if (err_pos)
diff --git a/lib/priority_options.gperf b/lib/priority_options.gperf
index 5a041b7..5bb250a 100644
--- a/lib/priority_options.gperf
+++ b/lib/priority_options.gperf
@@ -13,6 +13,7 @@ NO_TICKETS_TLS12, enable_no_tickets_tls12
NO_ETM, enable_no_etm
FORCE_ETM, enable_force_etm
NO_SESSION_HASH, enable_no_ext_master_secret
+FORCE_SESSION_HASH, enable_force_ext_master_secret
STATELESS_COMPRESSION, dummy_func
VERIFY_ALLOW_BROKEN, enable_verify_allow_broken
VERIFY_ALLOW_SIGN_RSA_MD5, enable_verify_allow_rsa_md5
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 23d309d..e5f7fa6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
testpkcs11-certs/client.key testpkcs11-certs/server.crt testpkcs11-certs/server-tmpl \
testpkcs11-certs/ca.key testpkcs11-certs/client.crt testpkcs11-certs/client-tmpl testpkcs11-certs/server.key \
crt_type-neg-common.c \
- system-override-default-priority-string.bad.config system-override-default-priority-string.none.config system-override-default-priority-string.only-tls13.config \
+ system-override-default-priority-string.bad.config system-override-default-priority-string.none.config system-override-default-priority-string.only-tls13.config system-override-session-hash.sh \
client-secrets.h server-secrets.h
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
@@ -234,7 +234,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
x509-upnconstraint cipher-padding xts-key-check pkcs7-verify-double-free \
- fips-rsa-sizes tls12-rehandshake-ticket
+ fips-rsa-sizes tls12-rehandshake-ticket tls-force-ems
ctests += tls-channel-binding
diff --git a/tests/multi-alerts.c b/tests/multi-alerts.c
index 84a412c..27be63b 100644
--- a/tests/multi-alerts.c
+++ b/tests/multi-alerts.c
@@ -198,6 +198,14 @@ void doit(void)
int sockets[2];
int err;
+ /* This test does not work under FIPS, as extended master
+ * secret extension needs to be negotiated through extensions,
+ * but the fixture does not contain the extension.
+ */
+ if (gnutls_fips140_mode_enabled()) {
+ exit(77);
+ }
+
err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
if (err == -1) {
perror("socketpair");
diff --git a/tests/no-extensions.c b/tests/no-extensions.c
index 3bd9d06..e5b9578 100644
--- a/tests/no-extensions.c
+++ b/tests/no-extensions.c
@@ -205,6 +205,13 @@ void start(const char *prio, gnutls_protocol_t exp_version)
void doit(void)
{
+ /* This test does not work under FIPS, as extended master
+ * secret extension needs to be negotiated through extensions.
+ */
+ if (gnutls_fips140_mode_enabled()) {
+ exit(77);
+ }
+
start("NORMAL:-VERS-ALL:+VERS-TLS1.0:%NO_EXTENSIONS", GNUTLS_TLS1_0);
start("NORMAL:-VERS-ALL:+VERS-TLS1.1:%NO_EXTENSIONS", GNUTLS_TLS1_1);
start("NORMAL:-VERS-ALL:+VERS-TLS1.2:%NO_EXTENSIONS", GNUTLS_TLS1_2);
diff --git a/tests/ocsp-tests/ocsp-must-staple-connection.sh b/tests/ocsp-tests/ocsp-must-staple-connection.sh
index 049491a..594e854 100755
--- a/tests/ocsp-tests/ocsp-must-staple-connection.sh
+++ b/tests/ocsp-tests/ocsp-must-staple-connection.sh
@@ -402,39 +402,43 @@ kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
-echo "=== Test 7: OSCP response error - client doesn't send status_request ==="
-
-eval "${GETPORT}"
-# Port for gnutls-serv
-TLS_SERVER_PORT=$PORT
-PORT=${TLS_SERVER_PORT}
-launch_bare_server \
- datefudge "${TESTDATE}" \
- "${SERV}" --echo --disable-client-cert \
- --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \
- --x509certfile="${SERVER_CERT_FILE}" \
- --port="${TLS_SERVER_PORT}" \
- --ocsp-response="${srcdir}/ocsp-tests/response3.der" --ignore-ocsp-response-errors
-TLS_SERVER_PID="${!}"
-wait_server $TLS_SERVER_PID
+if test "${GNUTLS_FORCE_FIPS_MODE}" != 1; then
+
+ echo "=== Test 7: OSCP response error - client doesn't send status_request ==="
+
+ eval "${GETPORT}"
+ # Port for gnutls-serv
+ TLS_SERVER_PORT=$PORT
+ PORT=${TLS_SERVER_PORT}
+ launch_bare_server \
+ datefudge "${TESTDATE}" \
+ "${SERV}" --echo --disable-client-cert \
+ --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \
+ --x509certfile="${SERVER_CERT_FILE}" \
+ --port="${TLS_SERVER_PORT}" \
+ --ocsp-response="${srcdir}/ocsp-tests/response3.der" --ignore-ocsp-response-errors
+ TLS_SERVER_PID="${!}"
+ wait_server $TLS_SERVER_PID
+
+ wait_for_port "${TLS_SERVER_PORT}"
+
+ echo "test 123456" | \
+ datefudge -s "${TESTDATE}" \
+ "${CLI}" --priority "NORMAL:%NO_EXTENSIONS" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \
+ --port="${TLS_SERVER_PORT}" localhost
+ rc=$?
-wait_for_port "${TLS_SERVER_PORT}"
+ if test "${rc}" != "0"; then
+ echo "Connecting to server with valid certificate and OCSP error response failed"
+ exit ${rc}
+ fi
-echo "test 123456" | \
- datefudge -s "${TESTDATE}" \
- "${CLI}" --priority "NORMAL:%NO_EXTENSIONS" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \
- --port="${TLS_SERVER_PORT}" localhost
-rc=$?
+ kill "${TLS_SERVER_PID}"
+ wait "${TLS_SERVER_PID}"
+ unset TLS_SERVER_PID
-if test "${rc}" != "0"; then
- echo "Connecting to server with valid certificate and OCSP error response failed"
- exit ${rc}
fi
-kill "${TLS_SERVER_PID}"
-wait "${TLS_SERVER_PID}"
-unset TLS_SERVER_PID
-
echo "=== Test 8: OSCP response error - client sends status_request, no TLS feature extension ==="
eval "${GETPORT}"
diff --git a/tests/rehandshake-ext-secret.c b/tests/rehandshake-ext-secret.c
index 94279f0..8d68c9b 100644
--- a/tests/rehandshake-ext-secret.c
+++ b/tests/rehandshake-ext-secret.c
@@ -142,6 +142,14 @@ static void try(unsigned onclient)
void doit(void)
{
+ /* This test does not work with TLS 1.2 under FIPS, as
+ * extended master secret extension needs to be negotiated
+ * through extensions, while %NO_SESSION_HASH is set.
+ */
+ if (gnutls_fips140_mode_enabled()) {
+ exit(77);
+ }
+
try(0);
reset_buffers();
try(1);
diff --git a/tests/resume.c b/tests/resume.c
index 93838c0..aa3c60c 100644
--- a/tests/resume.c
+++ b/tests/resume.c
@@ -91,6 +91,7 @@ struct params_res {
int change_ciphersuite;
int early_start;
int no_early_start;
+ int no_fips;
};
pid_t child;
@@ -126,16 +127,18 @@ struct params_res resume_tests[] = {
.enable_session_ticket_client = ST_NONE,
.expect_resume = 0,
.first_no_ext_master = 0,
- .second_no_ext_master = 1},
+ .second_no_ext_master = 1,
+ .no_fips = 1},
{.desc = "try to resume from db (none -> ext master secret)",
.enable_db = 1,
.enable_session_ticket_server = ST_NONE,
.enable_session_ticket_client = ST_NONE,
.expect_resume = 0,
.first_no_ext_master = 1,
- .second_no_ext_master = 0},
-#endif
-#if defined(TLS13)
+ .second_no_ext_master = 0,
+ .no_fips = 1},
+# endif
+# if defined(TLS13)
/* only makes sense under TLS1.3 as negotiation involves a new
* handshake with different parameters */
{.desc = "try to resume from session ticket (different cipher order)",
@@ -211,14 +214,17 @@ struct params_res resume_tests[] = {
.enable_session_ticket_client = ST_ALL,
.expect_resume = 0,
.first_no_ext_master = 0,
- .second_no_ext_master = 1},
- {.desc = "try to resume from session ticket (none -> ext master secret)",
+ .second_no_ext_master = 1,
+ .no_fips = 1},
+ {.desc =
+ "try to resume from session ticket (none -> ext master secret)",
.enable_db = 0,
.enable_session_ticket_server = ST_ALL,
.enable_session_ticket_client = ST_ALL,
.expect_resume = 0,
.first_no_ext_master = 1,
- .second_no_ext_master = 0},
+ .second_no_ext_master = 0,
+ .no_fips = 1},
{.desc = "try to resume from session ticket (server only)",
.enable_db = 0,
.enable_session_ticket_server = ST_ALL,
@@ -942,6 +948,12 @@ void doit(void)
int client_sds[SESSIONS], server_sds[SESSIONS];
int j;
+ if (resume_tests[i].no_fips && gnutls_fips140_mode_enabled()) {
+ success("skipping %s under FIPS mode\n",
+ resume_tests[i].desc);
+ continue;
+ }
+
printf("%s\n", resume_tests[i].desc);
for (j = 0; j < SESSIONS; j++) {
diff --git a/tests/status-request.c b/tests/status-request.c
index 07c7918..cd2cc54 100644
--- a/tests/status-request.c
+++ b/tests/status-request.c
@@ -289,7 +289,13 @@ void start(const char *prio)
void doit(void)
{
- start("NORMAL:-VERS-ALL:+VERS-TLS1.2");
+ /* This test does not work with TLS 1.2 under FIPS, as
+ * extended master secret extension needs to be negotiated
+ * through extensions.
+ */
+ if (!gnutls_fips140_mode_enabled()) {
+ start("NORMAL:-VERS-ALL:+VERS-TLS1.2");
+ }
start("NORMAL:-VERS-ALL:+VERS-TLS1.3");
start("NORMAL");
}
diff --git a/tests/system-override-session-hash.sh b/tests/system-override-session-hash.sh
new file mode 100755
index 0000000..97f11fa
--- /dev/null
+++ b/tests/system-override-session-hash.sh
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+# Copyright (C) 2021 Red Hat, Inc.
+#
+# Author: Alexander Sosedkin
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS. If not, see <https://www.gnu.org/licenses/>.
+
+: ${srcdir=.}
+: ${SERV=../src/gnutls-serv${EXEEXT}}
+: ${CLI=../src/gnutls-cli${EXEEXT}}
+
+if ! test -x "${SERV}"; then
+ exit 77
+fi
+
+if ! test -x "${CLI}"; then
+ exit 77
+fi
+
+${CLI} --fips140-mode
+if test $? = 0;then
+ echo "Cannot run this test in FIPS140 mode"
+ exit 77
+fi
+
+. "${srcdir}/scripts/common.sh"
+
+testdir=`create_testdir cfg`
+
+cat <<_EOF_ > "$testdir/request.cfg"
+[overrides]
+
+tls-session-hash = request
+_EOF_
+
+cat <<_EOF_ > "$testdir/require.cfg"
+[overrides]
+
+tls-session-hash = require
+_EOF_
+
+eval "${GETPORT}"
+
+KEY=${srcdir}/../doc/credentials/x509/key-rsa-pss.pem
+CERT=${srcdir}/../doc/credentials/x509/cert-rsa-pss.pem
+CA=${srcdir}/../doc/credentials/x509/ca.pem
+
+unset GNUTLS_SYSTEM_PRIORITY_FILE
+unset GNUTLS_DEBUG_LEVEL
+
+launch_server --echo --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --x509keyfile ${KEY} --x509certfile ${CERT}
+PID=$!
+wait_server ${PID}
+
+export GNUTLS_SYSTEM_PRIORITY_FILE="$testdir/request.cfg"
+export GNUTLS_DEBUG_LEVEL=3
+
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail "expected connection to succeed (1)"
+
+# "tls-session-hash" has precedence over %FORCE_SESSION_HASH
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%FORCE_SESSION_HASH" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail "expected connection to succeed (2)"
+
+echo kill ${PID}
+kill ${PID}
+wait
+
+unset GNUTLS_SYSTEM_PRIORITY_FILE
+unset GNUTLS_DEBUG_LEVEL
+
+export GNUTLS_SYSTEM_PRIORITY_FILE="$testdir/request.cfg"
+
+# "tls-session-hash" has precedence over %FORCE_SESSION_HASH
+launch_server --echo --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%FORCE_SESSION_HASH" --x509keyfile ${KEY} --x509certfile ${CERT}
+PID=$!
+wait_server ${PID}
+
+export GNUTLS_DEBUG_LEVEL=3
+
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (3)"
+
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%NO_SESSION_HASH" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (4)"
+
+kill ${PID}
+wait
+
+unset GNUTLS_SYSTEM_PRIORITY_FILE
+unset GNUTLS_DEBUG_LEVEL
+
+launch_server --echo --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --x509keyfile ${KEY} --x509certfile ${CERT}
+PID=$!
+wait_server ${PID}
+
+export GNUTLS_SYSTEM_PRIORITY_FILE="$testdir/require.cfg"
+export GNUTLS_DEBUG_LEVEL=3
+
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (5)"
+
+# "tls-session-hash" has precedence over %NO_SESSION_HASH
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%NO_SESSION_HASH" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (6)"
+
+kill ${PID}
+wait
+
+unset GNUTLS_SYSTEM_PRIORITY_FILE
+unset GNUTLS_DEBUG_LEVEL
+
+export GNUTLS_SYSTEM_PRIORITY_FILE="$testdir/require.cfg"
+
+# "tls-session-hash" has precedence over %NO_SESSION_HASH
+launch_server --echo --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%NO_SESSION_HASH" --x509keyfile ${KEY} --x509certfile ${CERT}
+PID=$!
+wait_server ${PID}
+
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (7)"
+
+# "tls-session-hash" has precedence over %NO_SESSION_HASH
+"${CLI}" -p "${PORT}" 127.0.0.1 --priority "NORMAL:-VERS-ALL:+VERS-TLS1.2:%NO_SESSION_HASH" --verify-hostname=localhost --x509cafile ${CA} --logfile="$testdir/client.log" </dev/null >/dev/null ||
+ fail ${PID} "expected connection to succeed (8)"
+
+kill ${PID}
+wait
+
+rm -rf "$testdir"
diff --git a/tests/tls-force-ems.c b/tests/tls-force-ems.c
new file mode 100644
index 0000000..35e7010
--- /dev/null
+++ b/tests/tls-force-ems.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "utils.h"
+#include "cert-common.h"
+#include "eagain-common.h"
+
+/* This program tests whether forced extended master secret is
+ * negotiated as expected.
+ */
+
+const char *side;
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "%s|<%d>| %s", side, level, str);
+}
+
+static void
+try(const char *name, const char *sprio, const char *cprio, int serr, int cerr)
+{
+ int sret, cret;
+ gnutls_certificate_credentials_t scred, ccred;
+ gnutls_session_t server, client;
+
+ success("Running %s\n", name);
+
+ assert(gnutls_certificate_allocate_credentials(&scred) >= 0);
+
+ assert(gnutls_certificate_set_x509_key_mem
+ (scred, &server_ca3_localhost_cert,
+ &server_ca3_key, GNUTLS_X509_FMT_PEM) >= 0);
+
+ assert(gnutls_certificate_allocate_credentials(&ccred) >= 0);
+
+ assert(gnutls_certificate_set_x509_trust_mem
+ (ccred, &ca3_cert, GNUTLS_X509_FMT_PEM) >= 0);
+
+ assert(gnutls_init(&server, GNUTLS_SERVER) >= 0);
+ assert(gnutls_init(&client, GNUTLS_CLIENT) >= 0);
+
+ gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, scred);
+ gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred);
+
+ gnutls_transport_set_push_function(server, server_push);
+ gnutls_transport_set_pull_function(server, server_pull);
+ gnutls_transport_set_ptr(server, server);
+ assert(gnutls_priority_set_direct(server, sprio, 0) >= 0);
+
+ gnutls_transport_set_push_function(client, client_push);
+ gnutls_transport_set_pull_function(client, client_pull);
+ gnutls_transport_set_ptr(client, client);
+ assert(gnutls_priority_set_direct(client, cprio, 0) >= 0);
+
+ HANDSHAKE_EXPECT(client, server, cerr, serr);
+
+ gnutls_deinit(server);
+ gnutls_deinit(client);
+ gnutls_certificate_free_credentials(scred);
+ gnutls_certificate_free_credentials(ccred);
+
+ reset_buffers();
+}
+
+#define AES_GCM "NORMAL:-VERS-ALL:+VERS-TLS1.2"
+
+void doit(void)
+{
+ gnutls_fips140_context_t fips_context;
+
+ global_init();
+
+ /* General init. */
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(2);
+
+ assert(gnutls_fips140_context_init(&fips_context) >= 0);
+
+ /* Default: EMS is requested in non-FIPS mode, while it is
+ * required in FIPS mode.
+ */
+ FIPS_PUSH_CONTEXT();
+ try("default", AES_GCM, AES_GCM, 0, 0);
+ FIPS_POP_CONTEXT(APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+ try("both force EMS", AES_GCM ":%FORCE_SESSION_HASH",
+ AES_GCM ":%FORCE_SESSION_HASH", 0, 0);
+ FIPS_POP_CONTEXT(APPROVED);
+
+ if (gnutls_fips140_mode_enabled()) {
+ try("neither negotiates EMS", AES_GCM ":%NO_SESSION_HASH",
+ AES_GCM ":%NO_SESSION_HASH", GNUTLS_E_INSUFFICIENT_SECURITY,
+ GNUTLS_E_AGAIN);
+ } else {
+ try("neither negotiates EMS", AES_GCM ":%NO_SESSION_HASH",
+ AES_GCM ":%NO_SESSION_HASH", 0, 0);
+ }
+ /* Note that the error codes are swapped based on FIPS mode:
+ * in FIPS mode, the server doesn't send the extension which
+ * causes the client to not send the one either, and then the
+ * server doesn't like the situation. On the other hand, in
+ * non-FIPS mode, it's the client to decide to abort the
+ * connection.
+ */
+ if (gnutls_fips140_mode_enabled()) {
+ try("server doesn't negotiate EMS, client forces EMS",
+ AES_GCM ":%NO_SESSION_HASH", AES_GCM ":%FORCE_SESSION_HASH",
+ GNUTLS_E_INSUFFICIENT_SECURITY, GNUTLS_E_AGAIN);
+ } else {
+ try("server doesn't negotiate EMS, client forces EMS",
+ AES_GCM ":%NO_SESSION_HASH", AES_GCM ":%FORCE_SESSION_HASH",
+ GNUTLS_E_AGAIN, GNUTLS_E_INSUFFICIENT_SECURITY);
+ }
+ try("server forces EMS, client doesn't negotiate EMS",
+ AES_GCM ":%FORCE_SESSION_HASH", AES_GCM ":%NO_SESSION_HASH",
+ GNUTLS_E_INSUFFICIENT_SECURITY, GNUTLS_E_AGAIN);
+
+ gnutls_fips140_context_deinit(fips_context);
+
+ gnutls_global_deinit();
+}
--
2.41.0

View File

@ -1,40 +0,0 @@
From 65911d48d49116a6ba49402824864e5f2f3ac1e1 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Fri, 12 Jan 2024 11:12:14 +0100
Subject: [PATCH] fips: Zeroize temporary values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The standard says "temporary value(s) generated during the integrity
test of the module's software […] shall be zeroised from the module upon
completion of the integrity test".
That includes the computed HMAC value, which is currently not zeroized
after the test. Add explicit calls to gnutls_memset() to fix that.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
lib/fips.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/fips.c b/lib/fips.c
index e9c27f6df6..8f4ff22fb9 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -380,10 +380,12 @@ static int check_lib_hmac(struct hmac_entry *entry,
if (gnutls_memcmp(entry->hmac, hmac, HMAC_SIZE)) {
_gnutls_debug_log("Calculated MAC for %s does not match\n", path);
+ gnutls_memset(hmac, 0, HMAC_SIZE);
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
}
_gnutls_debug_log("Successfully verified MAC for %s\n", path);
+ gnutls_memset(hmac, 0, HMAC_SIZE);
return 0;
}
--
2.43.0

View File

@ -1,58 +0,0 @@
From de09280b2a8314eb98ec9a2b84eebe3eec2f49bd Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Thu, 4 Aug 2022 16:37:51 +0900
Subject: [PATCH] _gnutls_decrypt_pbes1_des_md5_data: use public crypto API
This is a follow-up of e7f9267342bc2231149a640163c82b63c86f1dfd. In
the decryption code path with PBES1, algorithm checks for FIPS was not
applied, because it used internal functions that bypass those checks.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/x509/privkey_pkcs8_pbes1.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/lib/x509/privkey_pkcs8_pbes1.c b/lib/x509/privkey_pkcs8_pbes1.c
index c296807974..983530e46a 100644
--- a/lib/x509/privkey_pkcs8_pbes1.c
+++ b/lib/x509/privkey_pkcs8_pbes1.c
@@ -140,7 +140,7 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password,
{
int result;
gnutls_datum_t dkey, d_iv;
- cipher_hd_st ch;
+ gnutls_cipher_hd_t ch;
uint8_t key[16];
const unsigned block_size = 8;
@@ -158,16 +158,14 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password,
dkey.size = 8;
d_iv.data = &key[8];
d_iv.size = 8;
- result =
- _gnutls_cipher_init(&ch, cipher_to_entry(GNUTLS_CIPHER_DES_CBC),
- &dkey, &d_iv, 0);
+ result = gnutls_cipher_init(&ch, GNUTLS_CIPHER_DES_CBC, &dkey, &d_iv);
if (result < 0) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(result);
}
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
- result = _gnutls_cipher_decrypt(&ch, encrypted_data->data, encrypted_data->size);
+ result = gnutls_cipher_decrypt(ch, encrypted_data->data, encrypted_data->size);
if (result < 0) {
gnutls_assert();
goto error;
@@ -184,7 +182,7 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password,
result = 0;
error:
- _gnutls_cipher_deinit(&ch);
+ gnutls_cipher_deinit(ch);
return result;
}
--
2.37.1

View File

@ -1,476 +0,0 @@
From 237695d30c9f716333cfa077554a6e1ae0d2c589 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Sat, 20 Aug 2022 09:52:08 +0900
Subject: [PATCH] gnutls-3.7.6-fips-rsa-key-sizes.patch
---
lib/nettle/pk.c | 54 ++++---
tests/Makefile.am | 3 +-
tests/fips-rsa-sizes.c | 328 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 361 insertions(+), 24 deletions(-)
create mode 100644 tests/fips-rsa-sizes.c
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index eba246f..f38016b 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -1247,20 +1247,20 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
_rsa_params_to_privkey(pk_params, &priv);
- /* RSA key size should be 2048-bit or larger in FIPS
- * 140-3. In addition to this, only SHA-2 is allowed
- * for SigGen; it is checked in pk_prepare_hash lib/pk.c
- */
- if (unlikely(priv.size < 256)) {
- not_approved = true;
- }
-
ret = _rsa_params_to_pubkey(pk_params, &pub);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
+ /* RSA modulus size should be 2048-bit or larger in FIPS
+ * 140-3. In addition to this, only SHA-2 is allowed
+ * for SigGen; it is checked in pk_prepare_hash lib/pk.c
+ */
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
+ not_approved = true;
+ }
+
mpz_init(s);
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST)
@@ -1298,22 +1298,22 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
_rsa_params_to_privkey(pk_params, &priv);
- /* RSA key size should be 2048-bit or larger in FIPS
+ ret = _rsa_params_to_pubkey(pk_params, &pub);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ /* RSA modulus size should be 2048-bit or larger in FIPS
* 140-3. In addition to this, only SHA-2 is allowed
* for SigGen; however, Nettle only support SHA256,
* SHA384, and SHA512 for RSA-PSS (see
* _rsa_pss_sign_digest_tr in this file for details).
*/
- if (unlikely(priv.size < 256)) {
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
not_approved = true;
}
- ret = _rsa_params_to_pubkey(pk_params, &pub);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
-
mpz_init(s);
ret =
@@ -1643,6 +1643,7 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
case GNUTLS_PK_RSA:
{
struct rsa_public_key pub;
+ size_t bits;
ret = _rsa_params_to_pubkey(pk_params, &pub);
if (ret < 0) {
@@ -1650,12 +1651,19 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
goto cleanup;
}
- /* RSA key size should be 2048-bit or larger in FIPS
- * 140-3. In addition to this, only SHA-1 and SHA-2 are
- * allowed for SigVer; it is checked in
- * _pkcs1_rsa_verify_sig in lib/pubkey.c
+ bits = mpz_sizeinbase(pub.n, 2);
+
+ /* In FIPS 140-3, RSA key size should be larger than
+ * 2048-bit or one of the known lengths (1024, 1280,
+ * 1536, 1792; i.e., multiple of 256-bits).
+ *
+ * In addition to this, only SHA-1 and SHA-2 are allowed
+ * for SigVer; it is checked in _pkcs1_rsa_verify_sig in
+ * lib/pubkey.c.
*/
- if (unlikely(pub.size < 256)) {
+ if (unlikely(bits < 2048 &&
+ bits != 1024 && bits != 1280 &&
+ bits != 1536 && bits != 1792)) {
not_approved = true;
}
@@ -1701,13 +1709,13 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
goto cleanup;
}
- /* RSA key size should be 2048-bit or larger in FIPS
+ /* RSA modulus size should be 2048-bit or larger in FIPS
* 140-3. In addition to this, only SHA-1 and SHA-2 are
* allowed for SigVer, while Nettle only supports
* SHA256, SHA384, and SHA512 for RSA-PSS (see
* _rsa_pss_verify_digest in this file for the details).
*/
- if (unlikely(pub.size < 256)) {
+ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
not_approved = true;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7a7a4af..dd21e45 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -233,7 +233,8 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
tls13-without-timeout-func buffer status-request-revoked \
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
- x509-upnconstraint pkcs7-verify-double-free
+ x509-upnconstraint pkcs7-verify-double-free \
+ fips-rsa-sizes
ctests += tls-channel-binding
diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c
new file mode 100644
index 0000000..84b9aff
--- /dev/null
+++ b/tests/fips-rsa-sizes.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Alexander Sosedkin
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <utils.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+#include <gnutls/x509.h>
+
+#define FIPS_PUSH_CONTEXT() do { \
+ ret = gnutls_fips140_push_context(fips_context); \
+ if (ret < 0) { \
+ fail("gnutls_fips140_push_context failed\n"); \
+ } \
+} while (0)
+
+#define FIPS_POP_CONTEXT(state) do { \
+ ret = gnutls_fips140_pop_context(); \
+ if (ret < 0) { \
+ fail("gnutls_fips140_context_pop failed\n"); \
+ } \
+ fips_state = gnutls_fips140_get_operation_state(fips_context); \
+ if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
+ fail("operation state is not " # state " (%d)\n", \
+ fips_state); \
+ } \
+} while (0)
+
+
+void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
+ unsigned int size);
+void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
+ unsigned int size);
+void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey);
+void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
+ gnutls_pubkey_t pubkey);
+void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey);
+
+
+void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
+ unsigned int size)
+{
+ int ret;
+ gnutls_x509_privkey_t xprivkey;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ fprintf(stderr, "%d-bit\n", size);
+
+ /* x509 generation as well just because why not */
+ FIPS_PUSH_CONTEXT();
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
+ FIPS_POP_CONTEXT(APPROVED);
+ gnutls_x509_privkey_deinit(xprivkey);
+
+ FIPS_PUSH_CONTEXT();
+ assert(gnutls_privkey_init(privkey) == 0);
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit privkey_init (%d)\n", size, ret);
+ FIPS_POP_CONTEXT(APPROVED);
+
+ assert(gnutls_pubkey_init(pubkey) == 0);
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey,
+ GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret);
+ FIPS_POP_CONTEXT(INITIAL);
+
+ gnutls_fips140_context_deinit(fips_context);
+}
+
+
+void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
+ unsigned int size)
+{
+ int ret;
+ gnutls_x509_privkey_t xprivkey;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ fprintf(stderr, "%d-bit\n", size);
+
+ /* short x509 generation: ERROR, blocked */
+ FIPS_PUSH_CONTEXT();
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_PK_GENERATION_ERROR)
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
+ FIPS_POP_CONTEXT(ERROR);
+ gnutls_x509_privkey_deinit(xprivkey);
+
+ /* short key generation: ERROR, blocked */
+ FIPS_PUSH_CONTEXT();
+ assert(gnutls_privkey_init(privkey) == 0);
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_PK_GENERATION_ERROR)
+ fail("%d-bit privkey_init (%d)\n", size, ret);
+ FIPS_POP_CONTEXT(ERROR);
+ gnutls_privkey_deinit(*privkey);
+
+ /* Disable FIPS to generate them anyway */
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
+ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX);
+
+ assert(gnutls_x509_privkey_init(&xprivkey) == 0);
+ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit x509_privkey_init (%d)\n", size, ret);
+ gnutls_x509_privkey_deinit(xprivkey);
+
+ assert(gnutls_privkey_init(privkey) == 0);
+ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit privkey_init (%d)\n", size, ret);
+
+ assert(gnutls_pubkey_init(pubkey) == 0);
+ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey,
+ GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
+ if (ret != GNUTLS_E_SUCCESS)
+ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret);
+
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0);
+ assert(gnutls_fips140_mode_enabled());
+
+ gnutls_fips140_context_deinit(fips_context);
+}
+
+
+void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
+ int ret;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
+
+ gnutls_datum_t signature;
+ gnutls_datum_t plaintext = {
+ .data = (unsigned char* const) "Hello world!",
+ .size = 12
+ };
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ /* RSA sign: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_privkey_sign_data failed\n");
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* RSA verify: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ FIPS_POP_CONTEXT(APPROVED);
+
+ gnutls_free(signature.data);
+ gnutls_fips140_context_deinit(fips_context);
+}
+
+
+void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
+ gnutls_pubkey_t pubkey) {
+ int ret;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
+
+ gnutls_datum_t signature;
+ gnutls_datum_t plaintext = {
+ .data = (unsigned char* const) "Hello world!",
+ .size = 12
+ };
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ /* small key RSA sign: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_privkey_sign_data failed\n");
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* small key RSA verify: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ gnutls_free(signature.data);
+ gnutls_pubkey_deinit(pubkey);
+ gnutls_privkey_deinit(privkey);
+ gnutls_fips140_context_deinit(fips_context);
+}
+
+
+void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
+ int ret;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
+
+ gnutls_datum_t signature;
+ gnutls_datum_t plaintext = {
+ .data = (unsigned char* const) "Hello world!",
+ .size = 12
+ };
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ /* 1024, 1280, 1536, 1792 key RSA sign: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_privkey_sign_data failed\n");
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* Disable FIPS to sign them anyway */
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
+ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX);
+
+ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_privkey_sign_data failed\n");
+
+ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0);
+ assert(gnutls_fips140_mode_enabled());
+
+ /* 1024, 1280, 1536, 1792 key RSA verify: approved (exception) */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
+ &plaintext, &signature);
+ if (ret < 0)
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ FIPS_POP_CONTEXT(APPROVED);
+
+ gnutls_free(signature.data);
+ gnutls_pubkey_deinit(pubkey);
+ gnutls_privkey_deinit(privkey);
+ gnutls_fips140_context_deinit(fips_context);
+}
+
+
+void doit(void)
+{
+ gnutls_fips140_context_t fips_context;
+ gnutls_privkey_t privkey;
+ gnutls_pubkey_t pubkey;
+
+ if (gnutls_fips140_mode_enabled() == 0) {
+ success("We are not in FIPS140 mode\n");
+ exit(77); /* SKIP */
+ }
+
+ assert(gnutls_fips140_context_init(&fips_context) == 0);
+
+ /* 512-bit RSA: no generate, no sign, no verify */
+ generate_unsuccessfully(&privkey, &pubkey, 512);
+ sign_verify_unsuccessfully(privkey, pubkey);
+ /* 512-bit RSA again (to be safer about going in and out of FIPS) */
+ generate_unsuccessfully(&privkey, &pubkey, 512);
+ sign_verify_unsuccessfully(privkey, pubkey);
+ /* 600-bit RSA: no generate, no sign, no verify */
+ generate_unsuccessfully(&privkey, &pubkey, 600);
+ sign_verify_unsuccessfully(privkey, pubkey);
+
+ /* 768-bit RSA not-an-exception: nogenerate, nosign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 768);
+ sign_verify_unsuccessfully(privkey, pubkey);
+ /* 1024-bit RSA exception: nogenerate, nosign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 1024);
+ nosign_verify(privkey, pubkey);
+ /* 1280-bit RSA exception: nogenerate, nosign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 1280);
+ nosign_verify(privkey, pubkey);
+ /* 1500-bit RSA not-an-exception: nogenerate, nosign, noverify */
+ generate_unsuccessfully(&privkey, &pubkey, 1500);
+ sign_verify_unsuccessfully(privkey, pubkey);
+ /* 1536-bit RSA exception: nogenerate, nosign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 1536);
+ nosign_verify(privkey, pubkey);
+ /* 1792-bit RSA exception: nogenerate, nosign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 1792);
+ nosign_verify(privkey, pubkey);
+ /* 2000-bit RSA not-an-exception: nogenerate, nosign, noverify */
+ generate_unsuccessfully(&privkey, &pubkey, 2000);
+ sign_verify_unsuccessfully(privkey, pubkey);
+
+ /* 2048-bit RSA: generate, sign, verify */
+ generate_successfully(&privkey, &pubkey, 2048);
+ sign_verify_successfully(privkey, pubkey);
+ /* 2432-bit RSA: nogenerate, sign, verify */
+ generate_unsuccessfully(&privkey, &pubkey, 2432);
+ sign_verify_successfully(privkey, pubkey);
+ /* 3072-bit RSA: generate, sign, verify */
+ generate_successfully(&privkey, &pubkey, 3072);
+ sign_verify_successfully(privkey, pubkey);
+
+ gnutls_fips140_context_deinit(fips_context);
+}
--
2.37.2

View File

@ -1,163 +0,0 @@
From 3bd42dc88ff062bf9ede2b593e1ad1afa6f68f62 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Wed, 16 Nov 2022 23:02:13 +0900
Subject: [PATCH] nettle: mark non-compliant RSA-PSS salt length to be
not-approved
According to FIPS 186-5 5.4, the salt length must be in the range
between 0 and the hash length inclusive. While the use of those salt
lengths is still allowed for compatibility, it is reported as
non-approved operation through FIPS service indicator.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/nettle/pk.c | 9 ++++++++
tests/rsa-rsa-pss.c | 54 ++++++++++++++++++++++++++++++++++++---------
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index c098e2aa45..7732e90542 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -1316,6 +1316,15 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
mpz_init(s);
+ me = hash_to_entry(sign_params->rsa_pss_dig);
+
+ /* According to FIPS 186-5 5.4, the salt length must be
+ * in the range between 0 and the hash length inclusive.
+ */
+ if (sign_params->salt_size > _gnutls_mac_get_algo_len(me)) {
+ not_approved = true;
+ }
+
ret =
_rsa_pss_sign_digest_tr(sign_params->rsa_pss_dig,
&pub, &priv,
diff --git a/tests/rsa-rsa-pss.c b/tests/rsa-rsa-pss.c
index 19a175b722..d7799c1961 100644
--- a/tests/rsa-rsa-pss.c
+++ b/tests/rsa-rsa-pss.c
@@ -46,6 +46,8 @@ const gnutls_datum_t raw_data = {
11
};
+static gnutls_fips140_context_t fips_context;
+
static void inv_sign_check(unsigned sigalgo,
gnutls_privkey_t privkey, int exp_error)
{
@@ -86,13 +88,16 @@ static void inv_encryption_check(gnutls_pk_algorithm_t algorithm,
static void sign_verify_data(unsigned sigalgo, gnutls_privkey_t privkey,
unsigned int sign_flags, unsigned int verify_flags,
- int sign_exp_error, int verify_exp_error)
+ int sign_exp_error, int verify_exp_error,
+ gnutls_fips140_operation_state_t sign_exp_state)
{
int ret;
gnutls_datum_t signature = { NULL, 0 };
+ fips_push_context(fips_context);
ret = gnutls_privkey_sign_data2(privkey, sigalgo, sign_flags,
&raw_data, &signature);
+ fips_pop_context(fips_context, sign_exp_state);
if (ret != sign_exp_error)
fail("gnutls_x509_privkey_sign_data returned unexpected error: %s\n",
gnutls_strerror(ret));
@@ -180,11 +185,16 @@ void doit(void)
if (debug)
gnutls_global_set_log_level(4711);
+ assert(gnutls_fips140_context_init(&fips_context) >= 0);
+
prepare_keys(&pkey_rsa_pss, &pkey_rsa, GNUTLS_DIG_SHA256, 32);
- sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss, 0, 0, 0, 0);
- sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa, 0, 0, 0, 0);
- sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa, 0, 0, 0, 0);
+ sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss, 0, 0, 0, 0,
+ GNUTLS_FIPS140_OP_APPROVED);
+ sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa, 0, 0, 0, 0,
+ GNUTLS_FIPS140_OP_APPROVED);
+ sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa, 0, 0, 0, 0,
+ GNUTLS_FIPS140_OP_APPROVED);
if (debug)
success("success signing with RSA-PSS-SHA256\n");
@@ -213,41 +223,65 @@ void doit(void)
gnutls_privkey_deinit(pkey_rsa_pss);
gnutls_privkey_deinit(pkey_rsa);
+ /* Restrict key to use salt length larger than hash output
+ * length (not approved in FIPS).
+ */
+ prepare_keys(&pkey_rsa_pss, &pkey_rsa, GNUTLS_DIG_SHA256, 33);
+
+ sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss, 0, 0, 0, 0,
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
+
+ gnutls_privkey_deinit(pkey_rsa_pss);
+ gnutls_privkey_deinit(pkey_rsa);
+
/* Use the mismatched salt length with the digest length */
prepare_keys(&pkey_rsa_pss, &pkey_rsa, GNUTLS_DIG_SHA256, 48);
sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa_pss,
- 0, 0, 0, 0);
+ 0, 0, 0, 0, GNUTLS_FIPS140_OP_NOT_APPROVED);
sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss,
GNUTLS_PRIVKEY_FLAG_RSA_PSS_FIXED_SALT_LENGTH,
0,
GNUTLS_E_CONSTRAINT_ERROR,
- 0);
+ 0,
+ /* The error is caught before calling the actual
+ * signing operation.
+ */
+ GNUTLS_FIPS140_OP_INITIAL);
sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss,
0,
GNUTLS_VERIFY_RSA_PSS_FIXED_SALT_LENGTH,
0,
- GNUTLS_E_PK_SIG_VERIFY_FAILED);
+ GNUTLS_E_PK_SIG_VERIFY_FAILED,
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
assert(gnutls_x509_spki_init(&spki)>=0);
gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA256, 48);
assert(gnutls_privkey_set_spki(pkey_rsa, spki, 0)>=0);
- sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa, 0, 0, 0, 0);
+ sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa, 0, 0, 0, 0,
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa,
GNUTLS_PRIVKEY_FLAG_RSA_PSS_FIXED_SALT_LENGTH,
0,
GNUTLS_E_CONSTRAINT_ERROR,
- 0);
+ 0,
+ /* The error is caught before calling the actual
+ * signing operation.
+ */
+ GNUTLS_FIPS140_OP_INITIAL);
sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa,
0,
GNUTLS_VERIFY_RSA_PSS_FIXED_SALT_LENGTH,
0,
- GNUTLS_E_PK_SIG_VERIFY_FAILED);
+ GNUTLS_E_PK_SIG_VERIFY_FAILED,
+ GNUTLS_FIPS140_OP_NOT_APPROVED);
gnutls_privkey_deinit(pkey_rsa_pss);
gnutls_privkey_deinit(pkey_rsa);
gnutls_x509_spki_deinit(spki);
+ gnutls_fips140_context_deinit(fips_context);
+
gnutls_global_deinit();
}
--
2.38.1

View File

@ -1,640 +0,0 @@
From 036fb360e5775f01ef25f5e712024a29930c462e Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 3 Jun 2022 15:43:00 +0900
Subject: [PATCH] fips: provide function to manually run FIPS self-tests
FIPS140-3 IG 10.3.E Periodic Self-Testing says:
At security levels 1 and 2, acceptable means for initiating the
periodic self-tests include a provided service, resetting, rebooting
or power cycling.
Neither resetting, rebooting, nor power-cycling is suitable because
those involve operations outside of the module. Therefore this patch
adds a new API to manually run the substance of FIPS140 self-tests.
Suggeested by Richard Costa and Stephan Mueller in:
https://gitlab.com/gnutls/gnutls/-/issues/1364
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
NEWS | 5 ++
devel/libgnutls.abignore | 2 +
devel/symbols.last | 2 +
doc/Makefile.am | 2 +
doc/manpages/Makefile.am | 1 +
lib/fips.c | 139 ++++++++++++++++----------------
lib/global.c | 14 +++-
lib/includes/gnutls/gnutls.h.in | 2 +
lib/libgnutls.map | 8 ++
tests/fips-test.c | 7 ++
10 files changed, 110 insertions(+), 72 deletions(-)
diff --git a/NEWS b/NEWS
index 70dd8a12b5..389be8acaa 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,11 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc.
Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
See the end for copying conditions.
+* Version 3.7.7 (unreleased)
+
+** API and ABI modifications:
+gnutls_fips140_run_self_tests: New function
+
* Version 3.7.6 (released 2022-05-27)
** libgnutls: Fixed invalid write when gnutls_realloc_zero()
diff --git a/doc/Makefile.am b/doc/Makefile.am
index d20a021d97..34ef43866c 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1096,6 +1096,8 @@ FUNCS += functions/gnutls_fips140_pop_context
FUNCS += functions/gnutls_fips140_pop_context.short
FUNCS += functions/gnutls_fips140_push_context
FUNCS += functions/gnutls_fips140_push_context.short
+FUNCS += functions/gnutls_fips140_run_self_tests
+FUNCS += functions/gnutls_fips140_run_self_tests.short
FUNCS += functions/gnutls_fips140_set_mode
FUNCS += functions/gnutls_fips140_set_mode.short
FUNCS += functions/gnutls_get_library_config
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index d8c5f2854d..90906b0574 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -380,6 +380,7 @@ APIMANS += gnutls_fips140_get_operation_state.3
APIMANS += gnutls_fips140_mode_enabled.3
APIMANS += gnutls_fips140_pop_context.3
APIMANS += gnutls_fips140_push_context.3
+APIMANS += gnutls_fips140_run_self_tests.3
APIMANS += gnutls_fips140_set_mode.3
APIMANS += gnutls_get_library_config.3
APIMANS += gnutls_get_system_config_file.3
diff --git a/lib/fips.c b/lib/fips.c
index e9c27f6df6..656d43e74a 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -419,8 +419,6 @@ int _gnutls_fips_perform_self_checks1(void)
{
int ret;
- _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
-
/* Tests the FIPS algorithms used by nettle internally.
* In our case we test AES-CBC since nettle's AES is used by
* the DRBG-AES.
@@ -429,193 +427,153 @@ int _gnutls_fips_perform_self_checks1(void)
/* ciphers - one test per cipher */
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_128_CBC);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
return 0;
-
-error:
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
- _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n");
-
- return GNUTLS_E_SELF_TEST_ERROR;
}
int _gnutls_fips_perform_self_checks2(void)
{
int ret;
- _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
-
/* Tests the FIPS algorithms */
/* ciphers - one test per cipher */
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_3DES_CBC);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CBC);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_GCM);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_XTS);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CFB8);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* Digest tests */
ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_224);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_384);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_512);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* MAC (includes message digest test) */
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA1);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA224);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA384);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA512);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_mac_self_test(0, GNUTLS_MAC_AES_CMAC_256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* PK */
ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_pk_self_test(0, GNUTLS_PK_EC);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
ret = gnutls_pk_self_test(0, GNUTLS_PK_DH);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* HKDF */
ret = gnutls_hkdf_self_test(0, GNUTLS_MAC_SHA256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* PBKDF2 */
ret = gnutls_pbkdf2_self_test(0, GNUTLS_MAC_SHA256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* TLS-PRF */
ret = gnutls_tlsprf_self_test(0, GNUTLS_MAC_SHA256);
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
if (_gnutls_rnd_ops.self_test == NULL) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
/* this does not require rng initialization */
ret = _gnutls_rnd_ops.self_test();
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
if (_skip_integrity_checks == 0) {
ret = check_binary_integrity();
if (ret < 0) {
- gnutls_assert();
- goto error;
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
}
}
return 0;
-
-error:
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
- _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n");
-
- return GNUTLS_E_SELF_TEST_ERROR;
}
#endif
@@ -894,3 +852,48 @@ _gnutls_switch_fips_state(gnutls_fips140_operation_state_t state)
(void)state;
#endif
}
+
+/**
+ * gnutls_fips140_run_self_tests:
+ *
+ * Manually perform the second round of the FIPS140 self-tests,
+ * including:
+ *
+ * - Known answer tests (KAT) for the selected set of symmetric
+ * cipher, MAC, public key, KDF, and DRBG
+ * - Library integrity checks
+ *
+ * Upon failure with FIPS140 mode enabled, it makes the library
+ * unusable. This function is not thread-safe.
+ *
+ * Returns: 0 upon success, a negative error code otherwise
+ *
+ * Since: 3.7.7
+ */
+int
+gnutls_fips140_run_self_tests(void)
+{
+#ifdef ENABLE_FIPS140
+ int ret;
+ unsigned prev_lib_state;
+
+ /* Temporarily switch to LIB_STATE_SELFTEST as some of the
+ * algorithms are implemented using special constructs in
+ * self-tests (such as deterministic variants) */
+ prev_lib_state = _gnutls_get_lib_state();
+ _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
+
+ ret = _gnutls_fips_perform_self_checks2();
+ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED &&
+ ret < 0) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n");
+ } else {
+ /* Restore the previous library state */
+ _gnutls_switch_lib_state(prev_lib_state);
+ }
+ return ret;
+#else
+ return 0;
+#endif
+}
diff --git a/lib/global.c b/lib/global.c
index faa7f0afb2..1b372c15bd 100644
--- a/lib/global.c
+++ b/lib/global.c
@@ -336,9 +336,12 @@ static int _gnutls_global_init(unsigned constructor)
/* first round of self checks, these are done on the
* nettle algorithms which are used internally */
+ _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
ret = _gnutls_fips_perform_self_checks1();
- if (res != 2) {
- if (ret < 0) {
+ if (ret < 0) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n");
+ if (res != 2) {
gnutls_assert();
goto out;
}
@@ -355,9 +358,12 @@ static int _gnutls_global_init(unsigned constructor)
* (e.g., AESNI overridden AES). They are after _gnutls_register_accel_crypto()
* intentionally */
if (res != 0) {
+ _gnutls_switch_lib_state(LIB_STATE_SELFTEST);
ret = _gnutls_fips_perform_self_checks2();
- if (res != 2) {
- if (ret < 0) {
+ if (ret < 0) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n");
+ if (res != 2) {
gnutls_assert();
goto out;
}
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index f7fc5d114a..5840f331e9 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -3416,6 +3416,8 @@ gnutls_fips140_get_operation_state(gnutls_fips140_context_t context);
int gnutls_fips140_push_context(gnutls_fips140_context_t context);
int gnutls_fips140_pop_context(void);
+int gnutls_fips140_run_self_tests(void);
+
/* Gnutls error codes. The mapping to a TLS alert is also shown in
* comments.
*/
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 0241946c8a..f42d5f9fae 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1399,6 +1399,14 @@ GNUTLS_3_7_5
*;
} GNUTLS_3_7_4;
+GNUTLS_3_7_7
+{
+ global:
+ gnutls_fips140_run_self_tests;
+ local:
+ *;
+} GNUTLS_3_7_5;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
diff --git a/tests/fips-test.c b/tests/fips-test.c
index a6a283fa67..31a5e26111 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -525,6 +525,13 @@ void doit(void)
}
gnutls_fips140_context_deinit(fips_context);
+
+ /* run self-tests manually */
+ ret = gnutls_fips140_run_self_tests();
+ if (ret < 0) {
+ fail("gnutls_fips140_run_self_tests failed\n");
+ }
+
gnutls_global_deinit();
return;
}
--
2.36.1
From 354027c0c09db60d3083fa48ae791046d336957b Mon Sep 17 00:00:00 2001
From: Alexander Sosedkin <asosedkin@redhat.com>
Date: Tue, 28 Jun 2022 17:22:36 +0200
Subject: [PATCH] tests/fips-test: minor extension
Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
---
tests/fips-test.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/tests/fips-test.c b/tests/fips-test.c
index 31a5e26111..f9bd34586a 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -427,34 +427,43 @@ void doit(void)
rsa_import_keypair(&privkey, &pubkey, "rsa-2432.pem");
FIPS_POP_CONTEXT(INITIAL);
- /* Create a signature with SHA256; approved */
+ /* Create a signature with 2432-bit RSA and SHA256; approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
&data, &signature);
if (ret < 0) {
fail("gnutls_privkey_sign_data failed\n");
}
- gnutls_free(signature.data);
FIPS_POP_CONTEXT(APPROVED);
- /* Create a signature with SHA-1; not approved */
+ /* Verify a signature with 2432-bit RSA and SHA256; approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+ gnutls_free(signature.data);
+
+ /* Create a signature with 2432-bit RSA and SHA-1; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0,
&data, &signature);
if (ret < 0) {
fail("gnutls_privkey_sign_data failed\n");
}
- gnutls_free(signature.data);
FIPS_POP_CONTEXT(NOT_APPROVED);
- /* Verify a signature created with SHA-1; approved */
+ /* Verify a signature created with 2432-bit RSA and SHA-1; approved */
FIPS_PUSH_CONTEXT();
- ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &data,
- &rsa2342_sha1_sig);
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0,
+ &data, &rsa2342_sha1_sig);
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}
FIPS_POP_CONTEXT(APPROVED);
+ gnutls_free(signature.data);
gnutls_pubkey_deinit(pubkey);
gnutls_privkey_deinit(privkey);
@@ -463,15 +472,24 @@ void doit(void)
rsa_import_keypair(&privkey, &pubkey, "rsa-512.pem");
FIPS_POP_CONTEXT(INITIAL);
- /* Create a signature; not approved */
+ /* Create a signature with 512-bit RSA and SHA256; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0,
&data, &signature);
if (ret < 0) {
fail("gnutls_privkey_sign_data failed\n");
}
- gnutls_free(signature.data);
FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* Verify a signature with 512-bit RSA and SHA256; not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0,
+ &data, &signature);
+ if (ret < 0) {
+ fail("gnutls_pubkey_verify_data2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ gnutls_free(signature.data);
gnutls_pubkey_deinit(pubkey);
gnutls_privkey_deinit(privkey);
--
2.37.3
From 5a745120148861d873f47c1428c8c6dcadcf109b Mon Sep 17 00:00:00 2001
From: Richard Costa <richard.costa@suse.com>
Date: Sat, 9 Jul 2022 00:50:21 +0000
Subject: [PATCH] Add self-test code inside a FIPS context
Self-test code exercise lots of different FIPS-related code with
side-effects. So, in order to prevent it from losing information when
executing inside another context, we create an appropriated one.
If the self-test fails, then the library is placed in error state, so it
doesn't matter for other contexts.
Signed-off-by: Richard Maciel Costa <richard.costa@suse.com>
---
lib/fips.c | 19 +++++++++++++++++++
tests/fips-test.c | 20 ++++++++++++--------
2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/lib/fips.c b/lib/fips.c
index 31a52a990f..7d143e608e 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -902,6 +902,16 @@ gnutls_fips140_run_self_tests(void)
#ifdef ENABLE_FIPS140
int ret;
unsigned prev_lib_state;
+ gnutls_fips140_context_t fips_context = NULL;
+
+ /* Save the FIPS context, because self tests change it */
+ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED) {
+ if (gnutls_fips140_context_init(&fips_context) < 0 ||
+ gnutls_fips140_push_context(fips_context) < 0) {
+ gnutls_fips140_context_deinit(fips_context);
+ fips_context = NULL;
+ }
+ }
/* Temporarily switch to LIB_STATE_SELFTEST as some of the
* algorithms are implemented using special constructs in
@@ -918,6 +928,15 @@ gnutls_fips140_run_self_tests(void)
/* Restore the previous library state */
_gnutls_switch_lib_state(prev_lib_state);
}
+
+ /* Restore the previous FIPS context */
+ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED && fips_context) {
+ if (gnutls_fips140_pop_context() < 0) {
+ _gnutls_switch_lib_state(LIB_STATE_ERROR);
+ _gnutls_audit_log(NULL, "FIPS140-2 context restoration failed\n");
+ }
+ gnutls_fips140_context_deinit(fips_context);
+ }
return ret;
#else
return 0;
diff --git a/tests/fips-test.c b/tests/fips-test.c
index f9bd34586a..475b739197 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -457,8 +457,9 @@ void doit(void)
/* Verify a signature created with 2432-bit RSA and SHA-1; approved */
FIPS_PUSH_CONTEXT();
- ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0,
- &data, &rsa2342_sha1_sig);
+ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1,
+ GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data,
+ &rsa2342_sha1_sig);
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}
@@ -501,6 +502,15 @@ void doit(void)
}
FIPS_POP_CONTEXT(APPROVED);
+ /* run self-tests manually */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16));
+ ret = gnutls_fips140_run_self_tests();
+ if (ret < 0) {
+ fail("gnutls_fips140_run_self_tests failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
/* Test when FIPS140 is set to error state */
_gnutls_lib_simulate_error();
@@ -544,12 +554,6 @@ void doit(void)
gnutls_fips140_context_deinit(fips_context);
- /* run self-tests manually */
- ret = gnutls_fips140_run_self_tests();
- if (ret < 0) {
- fail("gnutls_fips140_run_self_tests failed\n");
- }
-
gnutls_global_deinit();
return;
}
--
2.37.3

View File

@ -1,407 +0,0 @@
From e8b35d31817d207d8b4b87ccf104d3b93aa446e0 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 17 Oct 2022 11:11:43 +0900
Subject: [PATCH] tests: move FIPS service indicator functions to common file
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
tests/dh-compute.c | 36 +++++---------------------
tests/fips-rsa-sizes.c | 24 -----------------
tests/fips-test.c | 27 +++-----------------
tests/kdf-api.c | 27 +-------------------
tests/pkcs12_encode.c | 24 -----------------
tests/privkey-keygen.c | 24 -----------------
tests/utils.h | 58 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 69 insertions(+), 151 deletions(-)
diff --git a/tests/dh-compute.c b/tests/dh-compute.c
index 828fb05e9c..6c1d5328f6 100644
--- a/tests/dh-compute.c
+++ b/tests/dh-compute.c
@@ -156,34 +156,10 @@ void doit(void)
{ NULL }
};
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != state) { \
- fail("operation state is not %d (%d)\n", \
- state, fips_state); \
- } \
- } \
-} while (0)
-
for (int i = 0; test_data[i].name != NULL; i++) {
gnutls_datum_t priv_key, pub_key;
gnutls_dh_params_t dh_params;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
int ret;
if (gnutls_fips140_mode_enabled()) {
@@ -193,24 +169,24 @@ void doit(void)
}
}
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
params(&dh_params, &test_data[i].prime, &test_data[i].q,
&test_data[i].generator);
- FIPS_POP_CONTEXT(GNUTLS_FIPS140_OP_INITIAL);
+ fips_pop_context(fips_context, GNUTLS_FIPS140_OP_INITIAL);
success("%s genkey\n", test_data[i].name);
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
genkey(dh_params, &priv_key, &pub_key);
- FIPS_POP_CONTEXT(test_data[i].fips_state_genkey);
+ fips_pop_context(fips_context, test_data[i].fips_state_genkey);
success("%s compute_key\n", test_data[i].name);
- FIPS_PUSH_CONTEXT();
+ fips_push_context(fips_context);
compute_key(test_data[i].name, dh_params, &priv_key,
&pub_key, &test_data[i].peer_key,
test_data[i].expected_error, NULL, 0);
- FIPS_POP_CONTEXT(test_data[i].fips_state_compute_key);
+ fips_pop_context(fips_context, test_data[i].fips_state_compute_key);
gnutls_dh_params_deinit(dh_params);
gnutls_free(priv_key.data);
diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c
index 84b9affabb..5feb284503 100644
--- a/tests/fips-rsa-sizes.c
+++ b/tests/fips-rsa-sizes.c
@@ -27,25 +27,6 @@
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
-#define FIPS_PUSH_CONTEXT() do { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
-} while (0)
-
void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
unsigned int size);
@@ -63,7 +44,6 @@ void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
int ret;
gnutls_x509_privkey_t xprivkey;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
assert(gnutls_fips140_context_init(&fips_context) == 0);
fprintf(stderr, "%d-bit\n", size);
@@ -102,7 +82,6 @@ void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
int ret;
gnutls_x509_privkey_t xprivkey;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
assert(gnutls_fips140_context_init(&fips_context) == 0);
fprintf(stderr, "%d-bit\n", size);
@@ -156,7 +135,6 @@ void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey,
void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
@@ -190,7 +168,6 @@ void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
@@ -225,7 +202,6 @@ void sign_verify_unsuccessfully(gnutls_privkey_t privkey,
void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) {
int ret;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
gnutls_datum_t signature;
gnutls_datum_t plaintext = {
diff --git a/tests/fips-test.c b/tests/fips-test.c
index f789afb107..b0bae4ef9f 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -12,25 +12,6 @@
/* This does check the FIPS140 support.
*/
-#define FIPS_PUSH_CONTEXT() do { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
-} while (0)
-
void _gnutls_lib_simulate_error(void);
static void tls_log_func(int level, const char *str)
@@ -40,10 +21,9 @@ static void tls_log_func(int level, const char *str)
static uint8_t key16[16];
static uint8_t iv16[16];
-uint8_t key_data[64];
-uint8_t iv_data[16];
-gnutls_fips140_context_t fips_context;
-gnutls_fips140_operation_state_t fips_state;
+static uint8_t key_data[64];
+static uint8_t iv_data[16];
+static gnutls_fips140_context_t fips_context;
static const gnutls_datum_t data = { .data = (unsigned char *)"foo", 3 };
static const uint8_t rsa2342_sha1_sig_data[] = {
@@ -276,6 +256,7 @@ test_ciphers(void)
void doit(void)
{
int ret;
+ gnutls_fips140_operation_state_t fips_state;
unsigned int mode;
gnutls_cipher_hd_t ch;
gnutls_hmac_hd_t mh;
diff --git a/tests/kdf-api.c b/tests/kdf-api.c
index 9724502005..a28ce82a62 100644
--- a/tests/kdf-api.c
+++ b/tests/kdf-api.c
@@ -33,30 +33,7 @@
#define MAX_BUF 1024
static gnutls_fips140_context_t fips_context;
-static gnutls_fips140_operation_state_t fips_state;
-
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
+
static void
test_hkdf(gnutls_mac_algorithm_t mac,
@@ -74,7 +51,6 @@ test_hkdf(gnutls_mac_algorithm_t mac,
gnutls_datum_t prk;
gnutls_datum_t okm;
uint8_t buf[MAX_BUF];
- int ret;
success("HKDF test with %s\n", gnutls_mac_get_name(mac));
@@ -144,7 +120,6 @@ test_pbkdf2(gnutls_mac_algorithm_t mac,
gnutls_datum_t salt;
gnutls_datum_t okm;
uint8_t buf[MAX_BUF];
- int ret;
success("PBKDF2 test with %s\n", gnutls_mac_get_name(mac));
diff --git a/tests/pkcs12_encode.c b/tests/pkcs12_encode.c
index ea39f3d69e..dc55daccde 100644
--- a/tests/pkcs12_encode.c
+++ b/tests/pkcs12_encode.c
@@ -70,29 +70,6 @@ static void tls_log_func(int level, const char *str)
fprintf(stderr, "|<%d>| %s", level, str);
}
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
-
void doit(void)
{
gnutls_pkcs12_t pkcs12;
@@ -106,7 +83,6 @@ void doit(void)
size_t size;
unsigned i;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
size_t n_tests = 0;
struct tests {
const char *name;
diff --git a/tests/privkey-keygen.c b/tests/privkey-keygen.c
index 2766afee08..2531906d71 100644
--- a/tests/privkey-keygen.c
+++ b/tests/privkey-keygen.c
@@ -119,30 +119,6 @@ void doit(void)
gnutls_x509_privkey_t pkey, dst;
int ret, algorithm, i;
gnutls_fips140_context_t fips_context;
- gnutls_fips140_operation_state_t fips_state;
-
-#define FIPS_PUSH_CONTEXT() do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_push_context(fips_context); \
- if (ret < 0) { \
- fail("gnutls_fips140_push_context failed\n"); \
- } \
- } \
-} while (0)
-
-#define FIPS_POP_CONTEXT(state) do { \
- if (gnutls_fips140_mode_enabled()) { \
- ret = gnutls_fips140_pop_context(); \
- if (ret < 0) { \
- fail("gnutls_fips140_context_pop failed\n"); \
- } \
- fips_state = gnutls_fips140_get_operation_state(fips_context); \
- if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
- fail("operation state is not " # state " (%d)\n", \
- fips_state); \
- } \
- } \
-} while (0)
ret = global_init();
if (ret < 0)
diff --git a/tests/utils.h b/tests/utils.h
index d3a2ba8d16..4433a07057 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -210,4 +210,62 @@ inline static unsigned int get_dtls_retransmit_timeout(void) {
return (unsigned int) ul;
}
+static inline const char *
+fips_operation_state_to_string(gnutls_fips140_operation_state_t state)
+{
+ switch (state) {
+ case GNUTLS_FIPS140_OP_INITIAL:
+ return "INITIAL";
+ case GNUTLS_FIPS140_OP_APPROVED:
+ return "APPROVED";
+ case GNUTLS_FIPS140_OP_NOT_APPROVED:
+ return "NOT_APPROVED";
+ case GNUTLS_FIPS140_OP_ERROR:
+ return "ERROR";
+ default:
+ /*NOTREACHED*/
+ assert(0);
+ return NULL;
+ }
+}
+
+static inline void
+fips_push_context(gnutls_fips140_context_t context)
+{
+ if (gnutls_fips140_mode_enabled()) {
+ int ret;
+
+ ret = gnutls_fips140_push_context(context);
+ if (ret < 0) {
+ fail("gnutls_fips140_push_context failed\n");
+ }
+ }
+}
+
+static inline void
+fips_pop_context(gnutls_fips140_context_t context,
+ gnutls_fips140_operation_state_t expected_state)
+{
+ gnutls_fips140_operation_state_t state;
+
+ if (gnutls_fips140_mode_enabled()) {
+ int ret;
+
+ ret = gnutls_fips140_pop_context();
+ if (ret < 0) {
+ fail("gnutls_fips140_context_pop failed\n");
+ }
+ state = gnutls_fips140_get_operation_state(context);
+ if (state != expected_state) {
+ fail("operation state is not %s (%s)\n",
+ fips_operation_state_to_string(expected_state),
+ fips_operation_state_to_string(state));
+ }
+ }
+}
+
+/* To use those convenient macros, define fips_context variable. */
+#define FIPS_PUSH_CONTEXT() fips_push_context(fips_context)
+#define FIPS_POP_CONTEXT(state) fips_pop_context(fips_context, GNUTLS_FIPS140_OP_ ## state)
+
#endif /* GNUTLS_TESTS_UTILS_H */
--
2.38.1

View File

@ -1,9 +1,9 @@
From 00f62aac690ba55650c58fa125a3806a8a684214 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Sat, 29 Jul 2023 13:21:37 +0900
Subject: [PATCH] nettle: mark SHA-1 signature verification non-approved
From cc7473a9ea185e072ab1bae0903c77bd7d7cf5bc Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 20 Nov 2023 07:45:42 +0900
Subject: [PATCH] gnutls-3.7.6-fips-sha1-sigver.patch
Signed-off-by: Daiki Ueno <ueno@gnu.org>
Signed-off-by: rpm-build <rpm-build>
---
lib/nettle/pk.c | 13 +++++--------
lib/pubkey.c | 3 ---
@ -11,21 +11,21 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org>
3 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index c098e2aa45..f0b8b6d707 100644
index 4ddfcff..36a7c24 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -1575,10 +1575,7 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
if (hash_len > vdata->size)
hash_len = vdata->size;
@@ -1609,10 +1609,7 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
if (hash_len > vdata->size)
hash_len = vdata->size;
- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy
- * mode */
switch (DIG_TO_MAC(sign_params->dsa_dig)) {
- case GNUTLS_MAC_SHA1:
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
@@ -1656,8 +1653,8 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
switch (DIG_TO_MAC(sign_params->dsa_dig)) {
- case GNUTLS_MAC_SHA1:
case GNUTLS_MAC_SHA256:
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
@@ -1683,8 +1680,8 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
* 2048-bit or one of the known lengths (1024, 1280,
* 1536, 1792; i.e., multiple of 256-bits).
*
@ -35,11 +35,11 @@ index c098e2aa45..f0b8b6d707 100644
+ * SigVer; it is checked in _pkcs1_rsa_verify_sig in
* lib/pubkey.c.
*/
if (unlikely(bits < 2048 &&
@@ -1709,9 +1706,9 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
}
if (unlikely(bits < 2048 && bits != 1024 && bits != 1280 &&
@@ -1730,9 +1727,9 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
}
/* RSA modulus size should be 2048-bit or larger in FIPS
/* RSA modulus size should be 2048-bit or larger in FIPS
- * 140-3. In addition to this, only SHA-1 and SHA-2 are
- * allowed for SigVer, while Nettle only supports
- * SHA256, SHA384, and SHA512 for RSA-PSS (see
@ -48,12 +48,12 @@ index c098e2aa45..f0b8b6d707 100644
+ * SHA384, and SHA512 for RSA-PSS (see
* _rsa_pss_verify_digest in this file for the details).
*/
if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) {
diff --git a/lib/pubkey.c b/lib/pubkey.c
index be1b045fa7..052707d5da 100644
index 1139ad9..714806a 100644
--- a/lib/pubkey.c
+++ b/lib/pubkey.c
@@ -2370,10 +2370,7 @@ _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
@@ -2452,10 +2452,7 @@ static int _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
d.size = digest_size;
if (pk == GNUTLS_PK_RSA) {
@ -65,10 +65,10 @@ index be1b045fa7..052707d5da 100644
case GNUTLS_MAC_SHA384:
case GNUTLS_MAC_SHA512:
diff --git a/tests/fips-test.c b/tests/fips-test.c
index f789afb107..3549b727b9 100644
index 180da05..09120c1 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -471,7 +471,7 @@ void doit(void)
@@ -596,7 +596,7 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
@ -76,8 +76,8 @@ index f789afb107..3549b727b9 100644
+ /* Verify a signature created with 2432-bit RSA and SHA-1; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1,
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data,
@@ -479,7 +479,7 @@ void doit(void)
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1,
@@ -604,7 +604,7 @@ void doit(void)
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}
@ -86,7 +86,7 @@ index f789afb107..3549b727b9 100644
gnutls_free(signature.data);
gnutls_pubkey_deinit(pubkey);
gnutls_privkey_deinit(privkey);
@@ -583,7 +583,7 @@ void doit(void)
@@ -708,7 +708,7 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
@ -94,8 +94,8 @@ index f789afb107..3549b727b9 100644
+ /* Verify a signature created with ECDSA and SHA-1; not approved */
FIPS_PUSH_CONTEXT();
ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1,
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data,
@@ -591,7 +591,7 @@ void doit(void)
GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1,
@@ -716,7 +716,7 @@ void doit(void)
if (ret < 0) {
fail("gnutls_pubkey_verify_data2 failed\n");
}

View File

@ -1,310 +0,0 @@
From f8a8961cfa176fc74c153cb6e1e68aff5e2d42f2 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Tue, 27 Sep 2022 10:52:19 +0900
Subject: [PATCH] gnutls-3.7.6-fips-symkey-limit.patch
---
lib/crypto-api.c | 26 ++++++++++++++++++++++---
tests/fips-test.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
tests/kdf-api.c | 9 ++++++++-
3 files changed, 80 insertions(+), 4 deletions(-)
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index b3e1eec..35200fb 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -896,6 +896,7 @@ gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle)
int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
{
int ret;
+ bool not_approved = false;
FAIL_IF_LIB_ERROR;
@@ -912,17 +913,31 @@ int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
key->data = gnutls_malloc(key->size);
if (!key->data) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto error;
+ }
+
+ /* Key lengths of less than 112 bits are not approved */
+ if (key_size < 14) {
+ not_approved = true;
}
ret = gnutls_rnd(GNUTLS_RND_RANDOM, key->data, key->size);
if (ret < 0) {
gnutls_assert();
_gnutls_free_datum(key);
- return ret;
+ goto error;
}
- return 0;
+ error:
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else if (not_approved) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
+ }
+ return ret;
}
/* AEAD API */
@@ -2058,6 +2073,11 @@ gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
not_approved = true;
}
+ /* Key lengths and output sizes of less than 112 bits are not approved */
+ if (key->size < 14 || length < 14) {
+ not_approved = true;
+ }
+
ret = _gnutls_kdf_ops.pbkdf2(mac, key->data, key->size,
salt->data, salt->size, iter_count,
output, length);
diff --git a/tests/fips-test.c b/tests/fips-test.c
index 31a5e26..27da414 100644
--- a/tests/fips-test.c
+++ b/tests/fips-test.c
@@ -274,6 +274,8 @@ void doit(void)
gnutls_datum_t signature;
unsigned int bits;
uint8_t hmac[64];
+ uint8_t pbkdf2[64];
+ gnutls_datum_t temp_key = { NULL, 0 };
fprintf(stderr,
"Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n");
@@ -371,11 +373,58 @@ void doit(void)
}
FIPS_POP_CONTEXT(NOT_APPROVED);
+ /* PBKDF2 with key equal to or longer than 112 bits: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, sizeof(pbkdf2));
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* PBKDF2 with key shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ key.size = 13;
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, sizeof(pbkdf2));
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ key.size = sizeof(key16);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ /* PBKDF2 with output shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100,
+ &pbkdf2, 13);
+ if (ret < 0) {
+ fail("gnutls_pbkdf2 failed\n");
+ }
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16));
if (ret < 0) {
fail("gnutls_rnd failed\n");
}
+ /* Symmetric key generation equal to or longer than 112 bits: approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_key_generate(&temp_key, 14);
+ if (ret < 0) {
+ fail("gnutls_key_generate failed\n");
+ }
+ gnutls_free(temp_key.data);
+ FIPS_POP_CONTEXT(APPROVED);
+
+ /* Symmetric key generation shorter than 112 bits: not approved */
+ FIPS_PUSH_CONTEXT();
+ ret = gnutls_key_generate(&temp_key, 13);
+ if (ret < 0) {
+ fail("gnutls_key_generate failed\n");
+ }
+ gnutls_free(temp_key.data);
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
ret = gnutls_pubkey_init(&pubkey);
if (ret < 0) {
fail("gnutls_pubkey_init failed\n");
diff --git a/tests/kdf-api.c b/tests/kdf-api.c
index 25fbc6a..8a4677c 100644
--- a/tests/kdf-api.c
+++ b/tests/kdf-api.c
@@ -89,6 +89,7 @@ test_hkdf(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_hkdf_extract(mac, &ikm, &salt, buf) >= 0);
+ /* HKDF outside of TLS usage is not approved */
FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(ikm.data);
gnutls_free(salt.data);
@@ -110,6 +111,7 @@ test_hkdf(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_hkdf_expand(mac, &prk, &info, buf, length) >= 0);
+ /* HKDF outside of TLS usage is not approved */
FIPS_POP_CONTEXT(NOT_APPROVED);
gnutls_free(info.data);
@@ -151,7 +153,12 @@ test_pbkdf2(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0);
- FIPS_POP_CONTEXT(APPROVED);
+ /* Key sizes and output sizes less than 112-bit are not approved. */
+ if (ikm.size < 14 || length < 14) {
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+ } else {
+ FIPS_POP_CONTEXT(APPROVED);
+ }
gnutls_free(ikm.data);
gnutls_free(salt.data);
--
2.37.3
From 86eded166f77612c70201c0d85d3abe711edd77d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Thu, 29 Sep 2022 21:19:26 +0900
Subject: [PATCH] fips: only mark HMAC as approved in PBKDF2
As ACVP only allows HMAC used with PBKDF2[1], this change marks other
hash algorithms not-approved.
1. https://pages.nist.gov/ACVP/draft-celi-acvp-pbkdf.html
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/crypto-api.c | 5 ++++-
lib/fips.h | 16 +++++++++++++++-
tests/kdf-api.c | 30 +++++++++++++++++++++++++++++-
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index d3e601ab3a..9f7e18db11 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -2229,7 +2229,10 @@ gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
if (!is_mac_algo_allowed(mac)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
- } else if (!is_mac_algo_approved_in_fips(mac)) {
+ } else if (!is_mac_algo_hmac_approved_in_fips(mac)) {
+ /* ACVP only allows HMAC used with PBKDF2:
+ * https://pages.nist.gov/ACVP/draft-celi-acvp-pbkdf.html
+ */
not_approved = true;
}
diff --git a/lib/fips.h b/lib/fips.h
index 3a74f254e7..bf61b36741 100644
--- a/lib/fips.h
+++ b/lib/fips.h
@@ -76,7 +76,7 @@ void _gnutls_lib_simulate_error(void);
void _gnutls_lib_force_operational(void);
inline static bool
-is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
+is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo)
{
switch (algo) {
case GNUTLS_MAC_SHA1:
@@ -88,6 +88,20 @@ is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
case GNUTLS_MAC_SHA3_256:
case GNUTLS_MAC_SHA3_384:
case GNUTLS_MAC_SHA3_512:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline static bool
+is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo)
+{
+ if (is_mac_algo_hmac_approved_in_fips(algo)) {
+ return true;
+ }
+
+ switch (algo) {
case GNUTLS_MAC_AES_CMAC_128:
case GNUTLS_MAC_AES_CMAC_256:
case GNUTLS_MAC_AES_GMAC_128:
diff --git a/tests/kdf-api.c b/tests/kdf-api.c
index 577cbf7a17..4feb22688b 100644
--- a/tests/kdf-api.c
+++ b/tests/kdf-api.c
@@ -26,6 +26,7 @@
#include <gnutls/crypto.h>
#include <assert.h>
+#include <stdbool.h>
#include <stdint.h>
#include "utils.h"
@@ -133,6 +134,25 @@ test_hkdf(gnutls_mac_algorithm_t mac,
gnutls_free(hex.data);
}
+inline static bool
+is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo)
+{
+ switch (algo) {
+ case GNUTLS_MAC_SHA1:
+ case GNUTLS_MAC_SHA256:
+ case GNUTLS_MAC_SHA384:
+ case GNUTLS_MAC_SHA512:
+ case GNUTLS_MAC_SHA224:
+ case GNUTLS_MAC_SHA3_224:
+ case GNUTLS_MAC_SHA3_256:
+ case GNUTLS_MAC_SHA3_384:
+ case GNUTLS_MAC_SHA3_512:
+ return true;
+ default:
+ return false;
+ }
+}
+
static void
test_pbkdf2(gnutls_mac_algorithm_t mac,
const char *ikm_hex,
@@ -161,7 +181,8 @@ test_pbkdf2(gnutls_mac_algorithm_t mac,
FIPS_PUSH_CONTEXT();
assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0);
/* Key sizes and output sizes less than 112-bit are not approved. */
- if (ikm.size < 14 || length < 14) {
+ if (ikm.size < 14 || length < 14 ||
+ !is_mac_algo_hmac_approved_in_fips(mac)) {
FIPS_POP_CONTEXT(NOT_APPROVED);
} else {
FIPS_POP_CONTEXT(APPROVED);
@@ -208,5 +229,12 @@ doit(void)
20,
"4b007901b765489abead49d926f721d065a429c1");
+ test_pbkdf2(GNUTLS_MAC_AES_CMAC_128,
+ "70617373776f726470617373776f7264", /* "passwordpassword" */
+ "73616c74", /* "salt" */
+ 4096,
+ 20,
+ "c4c112c6e1e3b8757640603dec78825ff87605a7");
+
gnutls_fips140_context_deinit(fips_context);
}
--
2.37.3

View File

@ -1,3 +1,4 @@
From 3c931abeb7e9bbf744cde83fbaaf3bb011107834 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 19 Aug 2022 12:32:27 +0900
Subject: [PATCH] build: allow GMP to be statically linked
@ -16,11 +17,18 @@ and libhogweed in Nettle is also linked to the static library of GMP.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
diff --color -ruNp a/configure.ac b/configure.ac
--- a/configure.ac 2022-12-15 11:06:16.782726043 +0100
+++ b/configure.ac 2022-12-15 11:08:35.603451427 +0100
@@ -744,6 +744,8 @@ AC_CHECK_FUNCS(nettle_cmac_kuznyechik_up
LIBS=$save_LIBS
configure.ac | 14 +++++++++++++-
lib/fips.c | 18 +++++++++++++++++-
lib/fipshmac.c | 2 ++
lib/global.c | 2 ++
4 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index f81d93edc0..b38583c554 100644
--- a/configure.ac
+++ b/configure.ac
@@ -786,6 +786,8 @@ LIBS=$save_LIBS
AM_CONDITIONAL([NEED_SIV_GCM], [test "$ac_cv_func_nettle_siv_gcm_encrypt_message" != yes])
# Check sonames of the linked libraries needed for FIPS selftests.
+save_CFLAGS=$CFLAGS
@ -28,7 +36,7 @@ diff --color -ruNp a/configure.ac b/configure.ac
save_LIBS=$LIBS
LIBS="$LIBS $GMP_LIBS"
AC_MSG_CHECKING([gmp soname])
@@ -757,9 +759,14 @@ if test -z "$gmp_so"; then
@@ -799,9 +801,14 @@ if test -z "$gmp_so"; then
gmp_so=none
fi
AC_MSG_RESULT($gmp_so)
@ -44,7 +52,7 @@ diff --color -ruNp a/configure.ac b/configure.ac
save_LIBS=$LIBS
LIBS="$LIBS $NETTLE_LIBS"
AC_MSG_CHECKING([nettle soname])
@@ -775,7 +782,11 @@ fi
@@ -817,7 +824,11 @@ fi
AC_MSG_RESULT($nettle_so)
AC_DEFINE_UNQUOTED([NETTLE_LIBRARY_SONAME], ["$nettle_so"], [The soname of nettle library])
LIBS=$save_LIBS
@ -56,7 +64,7 @@ diff --color -ruNp a/configure.ac b/configure.ac
save_LIBS=$LIBS
LIBS="$LIBS $HOGWEED_LIBS"
AC_MSG_CHECKING([hogweed soname])
@@ -791,6 +802,7 @@ fi
@@ -833,6 +844,7 @@ fi
AC_MSG_RESULT($hogweed_so)
AC_DEFINE_UNQUOTED([HOGWEED_LIBRARY_SONAME], ["$hogweed_so"], [The soname of hogweed library])
LIBS=$save_LIBS
@ -64,22 +72,23 @@ diff --color -ruNp a/configure.ac b/configure.ac
gnutls_so=libgnutls.so.`expr "$LT_CURRENT" - "$LT_AGE"`
AC_DEFINE_UNQUOTED([GNUTLS_LIBRARY_SONAME], ["$gnutls_so"], [The soname of gnutls library])
diff --color -ruNp a/lib/fips.c b/lib/fips.c
--- a/lib/fips.c 2022-12-15 11:06:16.868727731 +0100
+++ b/lib/fips.c 2022-12-15 11:12:42.744303409 +0100
@@ -155,7 +155,11 @@ void _gnutls_fips_mode_reset_zombie(void
diff --git a/lib/fips.c b/lib/fips.c
index e337221267..c1859709da 100644
--- a/lib/fips.c
+++ b/lib/fips.c
@@ -157,7 +157,11 @@ void _gnutls_fips_mode_reset_zombie(void)
#define GNUTLS_LIBRARY_NAME GNUTLS_LIBRARY_SONAME
#define NETTLE_LIBRARY_NAME NETTLE_LIBRARY_SONAME
#define HOGWEED_LIBRARY_NAME HOGWEED_LIBRARY_SONAME
+
+/* GMP can be statically linked */
+/* GMP can be statically linked. */
+#ifdef GMP_LIBRARY_SONAME
#define GMP_LIBRARY_NAME GMP_LIBRARY_SONAME
+#endif
#define HMAC_SIZE 32
#define HMAC_ALGO GNUTLS_MAC_SHA256
@@ -173,7 +177,9 @@ struct hmac_file
@@ -173,14 +177,18 @@ struct hmac_file {
struct hmac_entry gnutls;
struct hmac_entry nettle;
struct hmac_entry hogweed;
@ -88,8 +97,7 @@ diff --color -ruNp a/lib/fips.c b/lib/fips.c
+#endif
};
struct lib_paths
@@ -181,7 +187,9 @@ struct lib_paths
struct lib_paths {
char gnutls[GNUTLS_PATH_MAX];
char nettle[GNUTLS_PATH_MAX];
char hogweed[GNUTLS_PATH_MAX];
@ -99,7 +107,7 @@ diff --color -ruNp a/lib/fips.c b/lib/fips.c
};
/*
@@ -245,8 +253,10 @@ static int handler(void *user, const cha
@@ -244,8 +252,10 @@ static int handler(void *user, const char *section, const char *name,
return lib_handler(&p->nettle, section, name, value);
} else if (!strcmp(section, HOGWEED_LIBRARY_NAME)) {
return lib_handler(&p->hogweed, section, name, value);
@ -110,7 +118,7 @@ diff --color -ruNp a/lib/fips.c b/lib/fips.c
} else {
return 0;
}
@@ -389,8 +399,10 @@ static int callback(struct dl_phdr_info
@@ -393,8 +403,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
_gnutls_str_cpy(paths->nettle, GNUTLS_PATH_MAX, path);
else if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
_gnutls_str_cpy(paths->hogweed, GNUTLS_PATH_MAX, path);
@ -121,7 +129,7 @@ diff --color -ruNp a/lib/fips.c b/lib/fips.c
return 0;
}
@@ -411,10 +423,12 @@ static int load_lib_paths(struct lib_pat
@@ -415,10 +427,12 @@ static int load_lib_paths(struct lib_paths *paths)
_gnutls_debug_log("Hogweed library path was not found\n");
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
}
@ -134,22 +142,24 @@ diff --color -ruNp a/lib/fips.c b/lib/fips.c
return GNUTLS_E_SUCCESS;
}
@@ -467,9 +481,11 @@ static int check_binary_integrity(void)
@@ -471,9 +485,11 @@ static int check_binary_integrity(void)
ret = check_lib_hmac(&hmac.hogweed, paths.hogweed);
if (ret < 0)
return ret;
- ret = check_lib_hmac(&hmac.gmp, paths.gmp);
+#ifdef GMP_LIBRARY_SONAME
ret = check_lib_hmac(&hmac.gmp, paths.gmp);
+ ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init");
if (ret < 0)
return ret;
+#endif
return 0;
}
diff --color -ruNp a/lib/fipshmac.c b/lib/fipshmac.c
--- a/lib/fipshmac.c 2022-12-15 11:06:16.785726102 +0100
+++ b/lib/fipshmac.c 2022-12-15 11:13:34.533320156 +0100
@@ -107,8 +107,10 @@ static int callback(struct dl_phdr_info
diff --git a/lib/fipshmac.c b/lib/fipshmac.c
index 51f38f18e5..6a4883a131 100644
--- a/lib/fipshmac.c
+++ b/lib/fipshmac.c
@@ -107,8 +107,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data)
return print_lib(path, soname);
if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
return print_lib(path, soname);
@ -157,13 +167,14 @@ diff --color -ruNp a/lib/fipshmac.c b/lib/fipshmac.c
if (!strcmp(soname, GMP_LIBRARY_SONAME))
return print_lib(path, soname);
+#endif
return 0;
return 0;
}
diff --color -ruNp a/lib/global.c b/lib/global.c
--- a/lib/global.c 2022-12-15 11:06:16.061711888 +0100
+++ b/lib/global.c 2022-12-15 11:08:35.604451446 +0100
@@ -540,7 +540,9 @@ static const struct gnutls_library_confi
diff --git a/lib/global.c b/lib/global.c
index 924ec945de..c197fd0e5f 100644
--- a/lib/global.c
+++ b/lib/global.c
@@ -564,7 +564,9 @@ static const struct gnutls_library_config_st _gnutls_library_config[] = {
{ "libgnutls-soname", GNUTLS_LIBRARY_SONAME },
{ "libnettle-soname", NETTLE_LIBRARY_SONAME },
{ "libhogweed-soname", HOGWEED_LIBRARY_SONAME },
@ -172,4 +183,7 @@ diff --color -ruNp a/lib/global.c b/lib/global.c
+#endif
{ "hardware-features", HW_FEATURES },
{ "tls-features", TLS_FEATURES },
{ NULL, NULL }
{ "default-system-config", SYSTEM_PRIORITY_FILE },
--
2.41.0

View File

@ -1,124 +0,0 @@
From f41151c8a218f255af08362b74cd6ee0dfd45c00 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franti=C5=A1ek=20Kren=C5=BEelok?=
<krenzelok.frantisek@gmail.com>
Date: Tue, 14 Jun 2022 16:16:11 +0200
Subject: [PATCH] KTLS: disable by default enable by config
KTLS will be disabled by default when build with `--enable-ktls` to
enable it, use config file option `ktls = true` in [global] section.
Signed-off-by: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
---
doc/cha-config.texi | 18 ++++++++----------
lib/gnutls_int.h | 2 +-
lib/handshake.c | 2 +-
lib/priority.c | 12 ++++++------
4 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/doc/cha-config.texi b/doc/cha-config.texi
index e550f2e4b1..eaab7fd799 100644
--- a/doc/cha-config.texi
+++ b/doc/cha-config.texi
@@ -26,7 +26,7 @@ used can be queried using @funcref{gnutls_get_system_config_file}.
* Querying for disabled algorithms and protocols::
* Overriding the parameter verification profile::
* Overriding the default priority string::
-* Disabling system/acceleration protocols::
+* Enabling/Disabling system/acceleration protocols::
@end menu
@node Application-specific priority strings
@@ -253,16 +253,14 @@ default-priority-string = SECURE128:-VERS-TLS-ALL:+VERS-TLS1.3
@end example
-@node Disabling system/acceleration protocols
-@section Disabling system/acceleration protocols
-When system/acceleration protocol is enabled during build, it is usually
-enabled by default. The following options can overwrite this behavior
-system-wide.
+@node Enabling/Disabling system/acceleration protocols
+@section Enabling/Disabling system/acceleration protocols
+The following options can overwrite default behavior of protocols system-wide.
@example
[global]
-ktls = false
+ktls = true
@end example
-@subsection Disabling KTLS
-When GnuTLS is build with -enable-ktls configuration, it uses KTLS by default.
-This can be overwritten by setting @code{ktls = false} in @code{[global]} section.
+@subsection Enabling KTLS
+When GnuTLS is build with -enable-ktls configuration, KTLS is disabled by default.
+This can be enabled by setting @code{ktls = true} in @code{[global]} section.
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 872188696b..8c7bdaa1db 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1649,6 +1649,6 @@ get_certificate_type(gnutls_session_t session,
extern unsigned int _gnutls_global_version;
-bool _gnutls_config_is_ktls_disabled(void);
+bool _gnutls_config_is_ktls_enabled(void);
#endif /* GNUTLS_LIB_GNUTLS_INT_H */
diff --git a/lib/handshake.c b/lib/handshake.c
index f3edbbdacb..4dd457bf22 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -2815,7 +2815,7 @@ int gnutls_handshake(gnutls_session_t session)
session->internals.ktls_enabled = 0;
#ifdef ENABLE_KTLS
- if (_gnutls_config_is_ktls_disabled() == false)
+ if (_gnutls_config_is_ktls_enabled() == true)
_gnutls_ktls_enable(session);
#endif
diff --git a/lib/priority.c b/lib/priority.c
index 7279c03c88..d163d8169f 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -1027,7 +1027,7 @@ static void dummy_func(gnutls_priority_t c)
struct cfg {
bool allowlisting;
- bool ktls_disabled;
+ bool ktls_enabled;
name_val_array_t priority_strings;
char *priority_string;
@@ -1140,7 +1140,7 @@ cfg_steal(struct cfg *dst, struct cfg *src)
src->default_priority_string = NULL;
dst->allowlisting = src->allowlisting;
- dst->ktls_disabled = src->ktls_disabled;
+ dst->ktls_enabled = src->ktls_enabled;
memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers));
memcpy(dst->macs, src->macs, sizeof(src->macs));
memcpy(dst->groups, src->groups, sizeof(src->groups));
@@ -1268,8 +1268,8 @@ static int global_ini_handler(void *ctx, const char *section, const char *name,
}
} else if (c_strcasecmp(name, "ktls") == 0) {
p = clear_spaces(value, str);
- if (c_strcasecmp(p, "false") == 0) {
- cfg->ktls_disabled = true;
+ if (c_strcasecmp(p, "true") == 0) {
+ cfg->ktls_enabled = true;
} else {
_gnutls_debug_log("cfg: unknown ktls mode %s\n",
p);
@@ -3490,6 +3490,6 @@ gnutls_priority_string_list(unsigned iter, unsigned int flags)
return NULL;
}
-bool _gnutls_config_is_ktls_disabled(void){
- return system_wide_config.ktls_disabled;
+bool _gnutls_config_is_ktls_enabled(void){
+ return system_wide_config.ktls_enabled;
}
--
2.36.1

View File

@ -1,348 +0,0 @@
From 7b700dbcd5907944a7dd2f74cd26ad8586cd4bac Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 28 Jun 2022 09:37:22 +0900
Subject: [PATCH 1/3] tests: enable KTLS config while running gnutls_ktls test
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
tests/Makefile.am | 9 +++++----
tests/gnutls_ktls.c | 4 ++--
tests/ktls.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 6 deletions(-)
create mode 100755 tests/ktls.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4deeb6462b..cba67e8db8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -441,10 +441,6 @@ ctests += x509self x509dn anonself pskself pskself2 dhepskself \
resume-with-record-size-limit
endif
-if ENABLE_KTLS
-ctests += gnutls_ktls
-endif
-
ctests += record-sendfile
gc_CPPFLAGS = $(AM_CPPFLAGS) \
@@ -500,6 +496,11 @@ if ENABLE_TPM2
dist_check_SCRIPTS += tpm2.sh
endif
+if ENABLE_KTLS
+indirect_tests += gnutls_ktls
+dist_check_SCRIPTS += ktls.sh
+endif
+
if !WINDOWS
#
diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c
index 3966e2b10a..8f9c5fa36e 100644
--- a/tests/gnutls_ktls.c
+++ b/tests/gnutls_ktls.c
@@ -84,7 +84,7 @@ static void client(int fd, const char *prio)
ret = gnutls_transport_is_ktls_enabled(session);
if (!(ret & GNUTLS_KTLS_RECV)){
- fail("client: KTLS was not properly inicialized\n");
+ fail("client: KTLS was not properly initialized\n");
goto end;
}
@@ -208,7 +208,7 @@ static void server(int fd, const char *prio)
ret = gnutls_transport_is_ktls_enabled(session);
if (!(ret & GNUTLS_KTLS_SEND)){
- fail("server: KTLS was not properly inicialized\n");
+ fail("server: KTLS was not properly initialized\n");
goto end;
}
do {
diff --git a/tests/ktls.sh b/tests/ktls.sh
new file mode 100755
index 0000000000..ba52bd5775
--- /dev/null
+++ b/tests/ktls.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Copyright (C) 2022 Red Hat, Inc.
+#
+# Author: Daiki Ueno
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+: ${builddir=.}
+
+. "$srcdir/scripts/common.sh"
+
+if ! grep '^tls ' /proc/modules 2>1 >& /dev/null; then
+ exit 77
+fi
+
+testdir=`create_testdir ktls`
+
+cfg="$testdir/config"
+
+cat <<EOF > "$cfg"
+[global]
+ktls = true
+EOF
+
+GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID=1 \
+GNUTLS_SYSTEM_PRIORITY_FILE="$cfg" \
+"$builddir/gnutls_ktls" "$@"
+rc=$?
+
+rm -rf "$testdir"
+exit $rc
--
2.36.1
From 4a492462535a7f3a831685d3cf420b50ef219511 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 28 Jun 2022 10:23:33 +0900
Subject: [PATCH 2/3] handshake: do not reset KTLS enablement in
gnutls_handshake
As gnutls_handshake can be repeatedly called upon non-blocking setup,
we shouldn't try to call setsockopt for KTLS upon every call.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/handshake.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/handshake.c b/lib/handshake.c
index 4dd457bf22..3886306eb4 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -2813,12 +2813,6 @@ int gnutls_handshake(gnutls_session_t session)
const version_entry_st *vers = get_version(session);
int ret;
- session->internals.ktls_enabled = 0;
-#ifdef ENABLE_KTLS
- if (_gnutls_config_is_ktls_enabled() == true)
- _gnutls_ktls_enable(session);
-#endif
-
if (unlikely(session->internals.initial_negotiation_completed)) {
if (vers->tls13_sem) {
if (session->security_parameters.entity == GNUTLS_CLIENT) {
@@ -2864,6 +2858,12 @@ int gnutls_handshake(gnutls_session_t session)
end->tv_nsec =
(start->tv_nsec + tmo_ms * 1000000LL) % 1000000000LL;
}
+
+#ifdef ENABLE_KTLS
+ if (_gnutls_config_is_ktls_enabled()) {
+ _gnutls_ktls_enable(session);
+ }
+#endif
}
if (session->internals.recv_state == RECV_STATE_FALSE_START) {
--
2.36.1
From ce13208e13b5dec73993c583d4c64ab7714e4a7a Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 28 Jun 2022 10:53:55 +0900
Subject: [PATCH 3/3] ktls: _gnutls_ktls_enable: fix GNUTLS_KTLS_SEND
calculation
Previously, if the first setsockopt for GNUTLS_KTLS_RECV fails and the
same socket is used for both sending and receiving, GNUTLS_KTLS_SEND
was unconditionally set. This fixes the conditions and also adds more
logging.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/system/ktls.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/system/ktls.c b/lib/system/ktls.c
index b9f7a73fb5..ddf27fac76 100644
--- a/lib/system/ktls.c
+++ b/lib/system/ktls.c
@@ -47,7 +47,7 @@
gnutls_transport_ktls_enable_flags_t
gnutls_transport_is_ktls_enabled(gnutls_session_t session){
if (unlikely(!session->internals.initial_negotiation_completed)){
- _gnutls_debug_log("Initial negotiation is not yet complete");
+ _gnutls_debug_log("Initial negotiation is not yet complete\n");
return 0;
}
@@ -57,16 +57,27 @@ gnutls_transport_is_ktls_enabled(gnutls_session_t session){
void _gnutls_ktls_enable(gnutls_session_t session)
{
int sockin, sockout;
+
gnutls_transport_get_int2(session, &sockin, &sockout);
- if (setsockopt(sockin, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0)
+ if (setsockopt(sockin, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) {
session->internals.ktls_enabled |= GNUTLS_KTLS_RECV;
+ if (sockin == sockout) {
+ session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
+ }
+ } else {
+ _gnutls_record_log("Unable to set TCP_ULP for read socket: %d\n",
+ errno);
+ }
if (sockin != sockout) {
- if (setsockopt(sockout, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0)
+ if (setsockopt(sockout, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) {
session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
- } else
- session->internals.ktls_enabled |= GNUTLS_KTLS_SEND;
+ } else {
+ _gnutls_record_log("Unable to set TCP_ULP for write socket: %d\n",
+ errno);
+ }
+ }
}
int _gnutls_ktls_set_keys(gnutls_session_t session)
--
2.36.1
From 2d3cba6bb21acb40141180298f3924c73c7de8f8 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 26 Jul 2022 11:38:41 +0900
Subject: [PATCH 1/2] handshake: do not enable KTLS if custom pull/push
functions are set
If gnutls_transport_set_pull_function or
gnutls_transport_set_push_function is used, we can't assume the
underlying transport handle is an FD.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/handshake.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/handshake.c b/lib/handshake.c
index 3886306eb4..cf025a84f6 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -2861,7 +2861,14 @@ int gnutls_handshake(gnutls_session_t session)
#ifdef ENABLE_KTLS
if (_gnutls_config_is_ktls_enabled()) {
- _gnutls_ktls_enable(session);
+ if (session->internals.pull_func ||
+ session->internals.push_func) {
+ _gnutls_audit_log(session,
+ "Not enabling KTLS with "
+ "custom pull/push function\n");
+ } else {
+ _gnutls_ktls_enable(session);
+ }
}
#endif
}
--
2.37.1
From f7160e4fb970b4ba6f96e85e21f8395eae735d95 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 26 Jul 2022 11:39:57 +0900
Subject: [PATCH 2/2] socket: only set pull/push functions when --save-*-trace
is used
This allows gnutls-cli to use KTLS for the transport, unless either
--save-client-trace or --save-server-trace is used.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
src/socket.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/socket.c b/src/socket.c
index 39f18dbe18..36ac292700 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -586,16 +586,16 @@ socket_open2(socket_st * hd, const char *hostname, const char *service,
gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size);
}
- if (server_trace)
+ if (client_trace || server_trace) {
hd->server_trace = server_trace;
-
- if (client_trace)
hd->client_trace = client_trace;
-
- gnutls_transport_set_push_function(hd->session, wrap_push);
- gnutls_transport_set_pull_function(hd->session, wrap_pull);
- gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func);
- gnutls_transport_set_ptr(hd->session, hd);
+ gnutls_transport_set_push_function(hd->session, wrap_push);
+ gnutls_transport_set_pull_function(hd->session, wrap_pull);
+ gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func);
+ gnutls_transport_set_ptr(hd->session, hd);
+ } else {
+ gnutls_transport_set_int(hd->session, hd->fd);
+ }
}
if (!(flags & SOCKET_FLAG_RAW) && !(flags & SOCKET_FLAG_SKIP_INIT)) {
--
2.37.1
From a5b671fc9105cb5dbe6e6a1c0f39fa787d862076 Mon Sep 17 00:00:00 2001
From: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
Date: Fri, 29 Jul 2022 10:38:42 +0200
Subject: [PATCH] KTLS: hotfix
session->internals.pull_func is set to system_read during gnutls_init()
so check for user set pull/push function added in commit mentioned
bellow will never pass.
source: 2d3cba6bb21acb40141180298f3924c73c7de8f8
Signed-off-by: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
---
lib/handshake.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/handshake.c b/lib/handshake.c
index cf025a84f6..21edc5ece9 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -2861,7 +2861,8 @@ int gnutls_handshake(gnutls_session_t session)
#ifdef ENABLE_KTLS
if (_gnutls_config_is_ktls_enabled()) {
- if (session->internals.pull_func ||
+ if ((session->internals.pull_func &&
+ session->internals.pull_func != system_read) ||
session->internals.push_func) {
_gnutls_audit_log(session,
"Not enabling KTLS with "
--
2.37.1

View File

@ -1,263 +0,0 @@
From 57afc290cd3ce2e9752a0ce5cba41ecc78fdc1bd Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Sun, 31 Jul 2022 10:39:53 +0900
Subject: [PATCH] gnutls-3.7.6-pkcs7-verify.patch
---
lib/x509/pkcs7.c | 3 +-
tests/Makefile.am | 2 +-
tests/pkcs7-verify-double-free.c | 215 +++++++++++++++++++++++++++++++
3 files changed, 218 insertions(+), 2 deletions(-)
create mode 100644 tests/pkcs7-verify-double-free.c
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index 1f35fab..d5be7f4 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -1318,7 +1318,8 @@ gnutls_x509_crt_t find_signer(gnutls_pkcs7_t pkcs7, gnutls_x509_trust_list_t tl,
issuer = find_verified_issuer_of(pkcs7, issuer, purpose, vflags);
if (issuer != NULL && gnutls_x509_crt_check_issuer(issuer, issuer)) {
- if (prev) gnutls_x509_crt_deinit(prev);
+ if (prev && prev != signer)
+ gnutls_x509_crt_deinit(prev);
prev = issuer;
break;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 26e39fb..7a7a4af 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
tls13-without-timeout-func buffer status-request-revoked \
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
- x509-upnconstraint
+ x509-upnconstraint pkcs7-verify-double-free
ctests += tls-channel-binding
diff --git a/tests/pkcs7-verify-double-free.c b/tests/pkcs7-verify-double-free.c
new file mode 100644
index 0000000..fadf307
--- /dev/null
+++ b/tests/pkcs7-verify-double-free.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Zoltan Fridrich
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <gnutls/pkcs7.h>
+#include <gnutls/x509.h>
+
+#include "utils.h"
+
+static char rca_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDCjCCAfKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQKDApFeGFt\n"
+ "cGxlIENBMCAXDTE3MDcyMTE0NDMzNloYDzIyMjIwNzIxMTQ0MzM2WjAVMRMwEQYD\n"
+ "VQQKDApFeGFtcGxlIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n"
+ "v8hnKPJ/IA0SQB/A/a0Uh+npZ67vsgIMrtTQo0r0kJkmkBz5323xO3DVuJfB3QmX\n"
+ "v9zvoeCQLuDvWar5Aixfxgm6s5Q+yPvJj9t3NebDrU+Y4+qyewBIJUF8EF/5iBPC\n"
+ "ZHONmzbfIRWvQWGGgb2CRcOHp2J7AY/QLB6LsWPaLjs/DHva28Q13JaTTHIpdu8v\n"
+ "t6vHr0nXf66DN4MvtoF3N+o+v3snJCMsfXOqASi4tbWR7gtOfCfiz9uBjh0W2Dut\n"
+ "/jclBQkJkLe6esNSM+f4YiOpctVDjmfj8yoHCp394vt0wFqhG38wsTFAyVP6qIcf\n"
+ "5zoSu9ovEt2cTkhnZHjiiwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\n"
+ "DwEB/wQEAwIBBjAdBgNVHQ4EFgQUhjeO6Uc5imbjOl2I2ltVA27Hu9YwHwYDVR0j\n"
+ "BBgwFoAUhjeO6Uc5imbjOl2I2ltVA27Hu9YwDQYJKoZIhvcNAQELBQADggEBAD+r\n"
+ "i/7FsbG0OFKGF2+JOnth6NjJQcMfM8LiglqAuBUijrv7vltoZ0Z3FJH1Vi4OeMXn\n"
+ "l7X/9tWUve0uFl75MfjDrf0+lCEdYRY1LCba2BrUgpbbkLywVUdnbsvndehegCgS\n"
+ "jss2/zys3Hlo3ZaHlTMQ/NQ4nrxcxkjOvkZSEOqgxJTLpzm6pr7YUts4k6c6lNiB\n"
+ "FSiJiDzsJCmWR9C3fBbUlfDfTJYGN3JwqX270KchXDElo8gNoDnF7jBMpLFFSEKm\n"
+ "MyfbNLX/srh+CEfZaN/OZV4A3MQ0L8vQEp6M4CJhvRLIuMVabZ2coJ0AzystrOMU\n"
+ "LirBWjg89RoAjFQ7bTE=\n"
+ "-----END CERTIFICATE-----\n";
+
+static char ca_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDFzCCAf+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQKDApFeGFt\n"
+ "cGxlIENBMCAXDTE3MDcyMTE0NDQzNFoYDzIyMjIwNzIxMTQ0NDM0WjAiMSAwHgYD\n"
+ "VQQKDBdFeGFtcGxlIGludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\n"
+ "ggEPADCCAQoCggEBAKb9ACB8u//sP6MfNU1OsVw68xz3eTPLgKxS0vpqexm6iGVg\n"
+ "ug/o9uYRLzqiEukv/eyz9WzHmY7sqlOJjOFdv92+SaNg79Jc51WHPFXgea4/qyfr\n"
+ "4y14PGs0SNxm6T44sXurUs7cXydQVUgnq2VCaWFOTUdxXoAWkV8r8GaUoPD/klVz\n"
+ "RqxSZVETmX1XBKhsMnnov41kRwVph2C+VfUspsbaUZaz/o/S1/nokhXRACzKsMBr\n"
+ "obqiGxbY35uVzsmbAW5ErhQz98AWJL3Bub1fsEMXg6OEMmPH4AtX888dTIYZNw0E\n"
+ "bUIESspz1kjJQTtVQDHTprhwz16YiSVeUonlLgMCAwEAAaNjMGEwDwYDVR0TAQH/\n"
+ "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPBjxDWjMhjXERirKF9O\n"
+ "o/5Cllc5MB8GA1UdIwQYMBaAFIY3julHOYpm4zpdiNpbVQNux7vWMA0GCSqGSIb3\n"
+ "DQEBCwUAA4IBAQCTm+vv3hBa6lL5IT+Fw8aTxQ2Ne7mZ5oyazhvXYwwfKNMX3SML\n"
+ "W2JdPaL64ZwbxxxYvW401o5Z0CEgru3YFrsqB/hEdl0Uf8UWWJmE1rRa+miTmbjt\n"
+ "lrLNCWdrs6CiwvsPITTHg7jevB4KyZYsTSxQFcyr3N3xF+6EmOTC4IkhPPnXYXcp\n"
+ "248ih+WOavSYoRvzgB/Dip1WnPYU2mfIV3O8JReRryngA0TzWCLPLUoWR3R4jwtC\n"
+ "+1uSLoqaenz3qv3F1WEbke37az9YJuXx/5D8CqFQiZ62TUUtI6fYd8mkMBM4Qfh6\n"
+ "NW9XrCkI9wlpL5K9HllhuW0BhKeJkuPpyQ2p\n"
+ "-----END CERTIFICATE-----\n";
+
+static char ee_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQKDBdFeGFt\n"
+ "cGxlIGludGVybWVkaWF0ZSBDQTAgFw0yMjA3MjExNDQ1MzdaGA8yMjIyMDcyMTE0\n"
+ "NDUzN1owFTETMBEGA1UEAwwKSm9obiBTbWl0aDCCASIwDQYJKoZIhvcNAQEBBQAD\n"
+ "ggEPADCCAQoCggEBAMb1uuxppBFY+WVD45iyHUq7DkIJNNOI/JRaybVJfPktWq2E\n"
+ "eNe7XhV05KKnqZTbDO2iYqNHqGhZ8pz/IstDRTZP3z/q1vXTG0P9Gx28rEy5TaUY\n"
+ "QjtD+ZoFUQm0ORMDBjd8jikqtJ87hKeuOPMH4rzdydotMaPQSm7KLzHBGBr6gg7z\n"
+ "g1IxPWkhMyHapoMqqrhjwjzoTY97UIXpZTEoIA+KpEC8f9CciBtL0i1MPBjWozB6\n"
+ "Jma9q5iEwZXuRr3cnPYeIPlK2drgDZCMuSFcYiT8ApLw5OhKqY1m2EvfZ2ox2s9R\n"
+ "68/HzYdPi3kZwiNEtlBvMlpt5yKBJAflp76d7DkCAwEAAaNuMGwwCwYDVR0PBAQD\n"
+ "AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAdBgNVHQ4EFgQUc+Mi\n"
+ "kr8WMCk00SQo+P2iggp/oQkwHwYDVR0jBBgwFoAU8GPENaMyGNcRGKsoX06j/kKW\n"
+ "VzkwDQYJKoZIhvcNAQELBQADggEBAKU9+CUR0Jcfybd1+8Aqgh1RH96yQygnVuyt\n"
+ "Na9rFz4fM3ij9tGXDHXrkZw8bW1dWLU9quu8zeTxKxc3aiDIw739Alz0tukttDo7\n"
+ "dW7YqIb77zsIsWB9p7G9dlxT6ieUy+5IKk69BbeK8KR0vAciAG4KVQxPhuPy/LGX\n"
+ "PzqlJIJ4h61s3UOroReHPB1keLZgpORqrvtpClOmABH9TLFRJA/WFg8Q2XYB/p0x\n"
+ "l/pWiaoBC+8wK9cDoMUK5yOwXeuCLffCb+UlAD0+z/qxJ2pisE8E9X8rRKRrWI+i\n"
+ "G7LtJCEn86EQK8KuRlJxKgj8lClZhoULB0oL4jbblBuNow9WRmM=\n"
+ "-----END CERTIFICATE-----\n";
+
+static char msg_pem[] =
+ "-----BEGIN PKCS7-----\n"
+ "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\n"
+ "-----END PKCS7-----\n";
+
+const gnutls_datum_t rca_datum = { (void *)rca_pem, sizeof(rca_pem) - 1 };
+const gnutls_datum_t ca_datum = { (void *)ca_pem, sizeof(ca_pem) - 1 };
+const gnutls_datum_t ee_datum = { (void *)ee_pem, sizeof(ee_pem) - 1 };
+const gnutls_datum_t msg_datum = { (void *)msg_pem, sizeof(msg_pem) - 1 };
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "%s |<%d>| %s", "err", level, str);
+}
+
+#define CHECK(X)\
+{\
+ r = X;\
+ if (r < 0)\
+ fail("error in %d: %s\n", __LINE__, gnutls_strerror(r));\
+}\
+
+void doit(void)
+{
+ int r;
+ gnutls_x509_crt_t rca_cert = NULL;
+ gnutls_x509_crt_t ca_cert = NULL;
+ gnutls_x509_crt_t ee_cert = NULL;
+ gnutls_x509_trust_list_t tlist = NULL;
+ gnutls_pkcs7_t pkcs7 = NULL;
+ gnutls_datum_t data = { (unsigned char *)"xxx", 3 };
+
+ if (debug) {
+ gnutls_global_set_log_function(tls_log_func);
+ gnutls_global_set_log_level(4711);
+ }
+
+ // Import certificates
+ CHECK(gnutls_x509_crt_init(&rca_cert));
+ CHECK(gnutls_x509_crt_import(rca_cert, &rca_datum, GNUTLS_X509_FMT_PEM));
+ CHECK(gnutls_x509_crt_init(&ca_cert));
+ CHECK(gnutls_x509_crt_import(ca_cert, &ca_datum, GNUTLS_X509_FMT_PEM));
+ CHECK(gnutls_x509_crt_init(&ee_cert));
+ CHECK(gnutls_x509_crt_import(ee_cert, &ee_datum, GNUTLS_X509_FMT_PEM));
+
+ // Setup trust store
+ CHECK(gnutls_x509_trust_list_init(&tlist, 0));
+ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, rca_cert, "rca", 3, 0));
+ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, ca_cert, "ca", 2, 0));
+ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, ee_cert, "ee", 2, 0));
+
+ // Setup pkcs7 structure
+ CHECK(gnutls_pkcs7_init(&pkcs7));
+ CHECK(gnutls_pkcs7_import(pkcs7, &msg_datum, GNUTLS_X509_FMT_PEM));
+
+ // Signature verification
+ gnutls_pkcs7_verify(pkcs7, tlist, NULL, 0, 0, &data, 0);
+
+ gnutls_x509_crt_deinit(rca_cert);
+ gnutls_x509_crt_deinit(ca_cert);
+ gnutls_x509_crt_deinit(ee_cert);
+ gnutls_x509_trust_list_deinit(tlist, 0);
+ gnutls_pkcs7_deinit(pkcs7);
+}
--
2.37.1

View File

@ -1,121 +0,0 @@
From a27c2e9574d2f29dbf674bd8863f29f7a0a9b9a0 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Wed, 10 Jan 2024 19:13:17 +0900
Subject: [PATCH] rsa-psk: minimize branching after decryption
This moves any non-trivial code between gnutls_privkey_decrypt_data2
and the function return in _gnutls_proc_rsa_psk_client_kx up until the
decryption. This also avoids an extra memcpy to session->key.key.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/auth/rsa_psk.c | 68 ++++++++++++++++++++++++----------------------
1 file changed, 35 insertions(+), 33 deletions(-)
diff --git a/lib/auth/rsa_psk.c b/lib/auth/rsa_psk.c
index 93c2dc9998..8f3fe5a4bd 100644
--- a/lib/auth/rsa_psk.c
+++ b/lib/auth/rsa_psk.c
@@ -269,7 +269,6 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data,
int ret, dsize;
ssize_t data_size = _data_size;
gnutls_psk_server_credentials_t cred;
- gnutls_datum_t premaster_secret = { NULL, 0 };
volatile uint8_t ver_maj, ver_min;
cred = (gnutls_psk_server_credentials_t)
@@ -329,24 +328,48 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data,
ver_maj = _gnutls_get_adv_version_major(session);
ver_min = _gnutls_get_adv_version_minor(session);
- premaster_secret.data = gnutls_malloc(GNUTLS_MASTER_SIZE);
- if (premaster_secret.data == NULL) {
+ /* Find the key of this username. A random value will be
+ * filled in if the key is not found.
+ */
+ ret =
+ _gnutls_psk_pwd_find_entry(session, info->username, strlen(info->username), &pwd_psk);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ /* Allocate memory for premaster secret, and fill in the
+ * fields except the decryption result.
+ */
+ session->key.key.size = 2 + GNUTLS_MASTER_SIZE + 2 + pwd_psk.size;
+ session->key.key.data = gnutls_malloc(session->key.key.size);
+ if (session->key.key.data == NULL) {
gnutls_assert();
+ _gnutls_free_key_datum(&pwd_psk);
+ /* No need to zeroize, as the secret is not copied in yet */
+ _gnutls_free_datum(&session->key.key);
return GNUTLS_E_MEMORY_ERROR;
}
- premaster_secret.size = GNUTLS_MASTER_SIZE;
/* Fallback value when decryption fails. Needs to be unpredictable. */
- ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data,
- premaster_secret.size);
+ ret = gnutls_rnd(GNUTLS_RND_NONCE, session->key.key.data + 2,
+ GNUTLS_MASTER_SIZE);
if (ret < 0) {
gnutls_assert();
- goto cleanup;
+ _gnutls_free_key_datum(&pwd_psk);
+ /* No need to zeroize, as the secret is not copied in yet */
+ _gnutls_free_datum(&session->key.key);
+ return ret;
}
+ _gnutls_write_uint16(GNUTLS_MASTER_SIZE, session->key.key.data);
+ _gnutls_write_uint16(pwd_psk.size,
+ &session->key.key.data[2 + GNUTLS_MASTER_SIZE]);
+ memcpy(&session->key.key.data[2 + GNUTLS_MASTER_SIZE + 2],
+ pwd_psk.data, pwd_psk.size);
+ _gnutls_free_key_datum(&pwd_psk);
+
gnutls_privkey_decrypt_data2(session->internals.selected_key, 0,
- &ciphertext, premaster_secret.data,
- premaster_secret.size);
+ &ciphertext, session->key.key.data + 2,
+ GNUTLS_MASTER_SIZE);
/* After this point, any conditional on failure that cause differences
* in execution may create a timing or cache access pattern side
* channel that can be used as an oracle, so tread carefully */
@@ -365,31 +388,10 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data,
/* This is here to avoid the version check attack
* discussed above.
*/
- premaster_secret.data[0] = ver_maj;
- premaster_secret.data[1] = ver_min;
-
- /* find the key of this username
- */
- ret =
- _gnutls_psk_pwd_find_entry(session, info->username, strlen(info->username), &pwd_psk);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
-
- ret =
- set_rsa_psk_session_key(session, &pwd_psk, &premaster_secret);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ session->key.key.data[2] = ver_maj;
+ session->key.key.data[3] = ver_min;
- ret = 0;
- cleanup:
- _gnutls_free_key_datum(&pwd_psk);
- _gnutls_free_temp_key_datum(&premaster_secret);
-
- return ret;
+ return 0;
}
static int
--
2.43.0

View File

@ -1,202 +0,0 @@
From 36b576644e4b90256bb485200ac6feca211f2b22 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 11 Dec 2023 10:47:04 +0900
Subject: [PATCH] gnutls-3.7.6-rsa-psk-timing.patch
Signed-off-by: rpm-build <rpm-build>
---
lib/auth/rsa.c | 2 +-
lib/auth/rsa_psk.c | 93 +++++++++++++++++-----------------------------
lib/gnutls_int.h | 4 --
lib/priority.c | 1 -
4 files changed, 35 insertions(+), 65 deletions(-)
diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c
index 858701f..02b6a34 100644
--- a/lib/auth/rsa.c
+++ b/lib/auth/rsa.c
@@ -207,7 +207,7 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
session->key.key.size);
/* After this point, any conditional on failure that cause differences
* in execution may create a timing or cache access pattern side
- * channel that can be used as an oracle, so treat very carefully */
+ * channel that can be used as an oracle, so tread carefully */
/* Error handling logic:
* In case decryption fails then don't inform the peer. Just use the
diff --git a/lib/auth/rsa_psk.c b/lib/auth/rsa_psk.c
index 1a9dab5..93c2dc9 100644
--- a/lib/auth/rsa_psk.c
+++ b/lib/auth/rsa_psk.c
@@ -264,14 +264,13 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data,
{
gnutls_datum_t username;
psk_auth_info_t info;
- gnutls_datum_t plaintext;
gnutls_datum_t ciphertext;
gnutls_datum_t pwd_psk = { NULL, 0 };
int ret, dsize;
- int randomize_key = 0;
ssize_t data_size = _data_size;
gnutls_psk_server_credentials_t cred;
gnutls_datum_t premaster_secret = { NULL, 0 };
+ volatile uint8_t ver_maj, ver_min;
cred = (gnutls_psk_server_credentials_t)
_gnutls_get_cred(session, GNUTLS_CRD_PSK);
@@ -327,71 +326,47 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data,
}
ciphertext.size = dsize;
- ret =
- gnutls_privkey_decrypt_data(session->internals.selected_key, 0,
- &ciphertext, &plaintext);
- if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE) {
- /* In case decryption fails then don't inform
- * the peer. Just use a random key. (in order to avoid
- * attack against pkcs-1 formatting).
- */
+ ver_maj = _gnutls_get_adv_version_major(session);
+ ver_min = _gnutls_get_adv_version_minor(session);
+
+ premaster_secret.data = gnutls_malloc(GNUTLS_MASTER_SIZE);
+ if (premaster_secret.data == NULL) {
gnutls_assert();
- _gnutls_debug_log
- ("auth_rsa_psk: Possible PKCS #1 format attack\n");
- if (ret >= 0) {
- gnutls_free(plaintext.data);
- }
- randomize_key = 1;
- } else {
- /* If the secret was properly formatted, then
- * check the version number.
- */
- if (_gnutls_get_adv_version_major(session) !=
- plaintext.data[0]
- || (session->internals.allow_wrong_pms == 0
- && _gnutls_get_adv_version_minor(session) !=
- plaintext.data[1])) {
- /* No error is returned here, if the version number check
- * fails. We proceed normally.
- * That is to defend against the attack described in the paper
- * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
- * Ondej Pokorny and Tomas Rosa.
- */
- gnutls_assert();
- _gnutls_debug_log
- ("auth_rsa: Possible PKCS #1 version check format attack\n");
- }
+ return GNUTLS_E_MEMORY_ERROR;
}
+ premaster_secret.size = GNUTLS_MASTER_SIZE;
-
- if (randomize_key != 0) {
- premaster_secret.size = GNUTLS_MASTER_SIZE;
- premaster_secret.data =
- gnutls_malloc(premaster_secret.size);
- if (premaster_secret.data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- /* we do not need strong random numbers here.
- */
- ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data,
- premaster_secret.size);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
- } else {
- premaster_secret.data = plaintext.data;
- premaster_secret.size = plaintext.size;
+ /* Fallback value when decryption fails. Needs to be unpredictable. */
+ ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data,
+ premaster_secret.size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
}
+ gnutls_privkey_decrypt_data2(session->internals.selected_key, 0,
+ &ciphertext, premaster_secret.data,
+ premaster_secret.size);
+ /* After this point, any conditional on failure that cause differences
+ * in execution may create a timing or cache access pattern side
+ * channel that can be used as an oracle, so tread carefully */
+
+ /* Error handling logic:
+ * In case decryption fails then don't inform the peer. Just use the
+ * random key previously generated. (in order to avoid attack against
+ * pkcs-1 formatting).
+ *
+ * If we get version mismatches no error is returned either. We
+ * proceed normally. This is to defend against the attack described
+ * in the paper "Attacking RSA-based sessions in SSL/TLS" by
+ * Vlastimil Klima, Ondej Pokorny and Tomas Rosa.
+ */
+
/* This is here to avoid the version check attack
* discussed above.
*/
-
- premaster_secret.data[0] = _gnutls_get_adv_version_major(session);
- premaster_secret.data[1] = _gnutls_get_adv_version_minor(session);
+ premaster_secret.data[0] = ver_maj;
+ premaster_secret.data[1] = ver_min;
/* find the key of this username
*/
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index c6bf154..b59fb7c 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -988,7 +988,6 @@ struct gnutls_priority_st {
bool _no_etm;
bool _no_ext_master_secret;
bool _allow_key_usage_violation;
- bool _allow_wrong_pms;
bool _dumbfw;
unsigned int _dh_prime_bits; /* old (deprecated) variable */
@@ -1006,7 +1005,6 @@ struct gnutls_priority_st {
(x)->no_etm = 1; \
(x)->no_ext_master_secret = 1; \
(x)->allow_key_usage_violation = 1; \
- (x)->allow_wrong_pms = 1; \
(x)->dumbfw = 1
#define ENABLE_PRIO_COMPAT(x) \
@@ -1015,7 +1013,6 @@ struct gnutls_priority_st {
(x)->_no_etm = 1; \
(x)->_no_ext_master_secret = 1; \
(x)->_allow_key_usage_violation = 1; \
- (x)->_allow_wrong_pms = 1; \
(x)->_dumbfw = 1
/* DH and RSA parameters types.
@@ -1140,7 +1137,6 @@ typedef struct {
bool no_etm;
bool no_ext_master_secret;
bool allow_key_usage_violation;
- bool allow_wrong_pms;
bool dumbfw;
/* old (deprecated) variable. This is used for both srp_prime_bits
diff --git a/lib/priority.c b/lib/priority.c
index 4adf4c7..423cbd3 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -701,7 +701,6 @@ gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority)
COPY_TO_INTERNALS(no_etm);
COPY_TO_INTERNALS(no_ext_master_secret);
COPY_TO_INTERNALS(allow_key_usage_violation);
- COPY_TO_INTERNALS(allow_wrong_pms);
COPY_TO_INTERNALS(dumbfw);
COPY_TO_INTERNALS(dh_prime_bits);
--
2.43.0

View File

@ -1,433 +0,0 @@
diff --color -ruNp a/doc/Makefile.am b/doc/Makefile.am
--- a/doc/Makefile.am 2022-11-15 14:14:10.632725399 +0100
+++ b/doc/Makefile.am 2022-11-15 14:14:40.252300863 +0100
@@ -575,6 +575,7 @@ ENUMS += enums/gnutls_certificate_verifi
ENUMS += enums/gnutls_certificate_verify_flags
ENUMS += enums/gnutls_channel_binding_t
ENUMS += enums/gnutls_cipher_algorithm_t
+ENUMS += enums/gnutls_cipher_flags_t
ENUMS += enums/gnutls_close_request_t
ENUMS += enums/gnutls_compression_method_t
ENUMS += enums/gnutls_credentials_type_t
@@ -882,12 +883,16 @@ FUNCS += functions/gnutls_cipher_decrypt
FUNCS += functions/gnutls_cipher_decrypt.short
FUNCS += functions/gnutls_cipher_decrypt2
FUNCS += functions/gnutls_cipher_decrypt2.short
+FUNCS += functions/gnutls_cipher_decrypt3
+FUNCS += functions/gnutls_cipher_decrypt3.short
FUNCS += functions/gnutls_cipher_deinit
FUNCS += functions/gnutls_cipher_deinit.short
FUNCS += functions/gnutls_cipher_encrypt
FUNCS += functions/gnutls_cipher_encrypt.short
FUNCS += functions/gnutls_cipher_encrypt2
FUNCS += functions/gnutls_cipher_encrypt2.short
+FUNCS += functions/gnutls_cipher_encrypt3
+FUNCS += functions/gnutls_cipher_encrypt3.short
FUNCS += functions/gnutls_cipher_get
FUNCS += functions/gnutls_cipher_get.short
FUNCS += functions/gnutls_cipher_get_block_size
diff --color -ruNp a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
--- a/doc/manpages/Makefile.am 2022-11-15 14:14:10.634725438 +0100
+++ b/doc/manpages/Makefile.am 2022-11-15 14:14:40.254300902 +0100
@@ -273,9 +273,11 @@ APIMANS += gnutls_check_version.3
APIMANS += gnutls_cipher_add_auth.3
APIMANS += gnutls_cipher_decrypt.3
APIMANS += gnutls_cipher_decrypt2.3
+APIMANS += gnutls_cipher_decrypt3.3
APIMANS += gnutls_cipher_deinit.3
APIMANS += gnutls_cipher_encrypt.3
APIMANS += gnutls_cipher_encrypt2.3
+APIMANS += gnutls_cipher_encrypt3.3
APIMANS += gnutls_cipher_get.3
APIMANS += gnutls_cipher_get_block_size.3
APIMANS += gnutls_cipher_get_id.3
diff --color -ruNp a/lib/crypto-api.c b/lib/crypto-api.c
--- a/lib/crypto-api.c 2022-11-15 14:14:11.036733248 +0100
+++ b/lib/crypto-api.c 2022-11-15 14:14:40.255300921 +0100
@@ -413,6 +413,166 @@ gnutls_cipher_decrypt2(gnutls_cipher_hd_
}
/**
+ * gnutls_cipher_encrypt3:
+ * @handle: is a #gnutls_cipher_hd_t type
+ * @ptext: the data to encrypt
+ * @ptext_len: the length of data to encrypt
+ * @ctext: the encrypted data
+ * @ctext_len: the length of encrypted data (initially must hold the maximum available size)
+ * @flags: flags for padding
+ *
+ * This function will encrypt the given data using the algorithm
+ * specified by the context. For block ciphers, @ptext_len is
+ * typically a multiple of the block size. If not, the caller can
+ * instruct the function to pad the last block according to @flags.
+ * Currently, the only available padding scheme is
+ * %GNUTLS_CIPHER_PADDING_PKCS7.
+ *
+ * If @ctext is not %NULL, it must hold enough space to store
+ * resulting cipher text. To check the required size, this function
+ * can be called with @ctext set to %NULL. Then @ctext_len will be
+ * updated without performing actual encryption.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.7.7
+ **/
+int
+gnutls_cipher_encrypt3(gnutls_cipher_hd_t handle,
+ const void *ptext, size_t ptext_len,
+ void *ctext, size_t *ctext_len,
+ unsigned flags)
+{
+ api_cipher_hd_st *h = handle;
+ const cipher_entry_st *e = h->ctx_enc.e;
+ int block_size = _gnutls_cipher_get_block_size(e);
+ int ret = 0;
+
+ if (unlikely(ctext_len == NULL)) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ if (_gnutls_cipher_type(e) == CIPHER_BLOCK &&
+ (flags & GNUTLS_CIPHER_PADDING_PKCS7)) {
+ size_t n, r;
+ uint8_t last_block[MAX_CIPHER_BLOCK_SIZE];
+ const uint8_t *p = ptext;
+ uint8_t *c = ctext;
+
+ if (!INT_ADD_OK(ptext_len, block_size, &n)) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ n = (n / block_size) * block_size;
+
+ if (!ctext) {
+ *ctext_len = n;
+ return 0;
+ }
+
+ if (*ctext_len < n) {
+ return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ }
+
+ /* Encrypt up to the last complete block */
+ r = ptext_len % block_size;
+
+ ret = _gnutls_cipher_encrypt2(&h->ctx_enc,
+ ptext, ptext_len - r,
+ ctext, ptext_len - r);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Encrypt the last block with padding */
+ gnutls_memset(last_block, block_size - r, sizeof(last_block));
+ if (r > 0) {
+ memcpy(last_block, &p[ptext_len - r], r);
+ }
+ ret = _gnutls_cipher_encrypt2(&h->ctx_enc,
+ last_block, block_size,
+ &c[ptext_len - r], block_size);
+ if (ret < 0) {
+ goto error;
+ }
+ *ctext_len = n;
+ } else {
+ if (!ctext) {
+ *ctext_len = ptext_len;
+ return 0;
+ }
+
+ ret = _gnutls_cipher_encrypt2(&h->ctx_enc, ptext, ptext_len,
+ ctext, *ctext_len);
+ if (ret < 0) {
+ goto error;
+ }
+ *ctext_len = ptext_len;
+ }
+
+ error:
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED);
+ }
+ return ret;
+}
+
+/**
+ * gnutls_cipher_decrypt3:
+ * @handle: is a #gnutls_cipher_hd_t type
+ * @ctext: the data to decrypt
+ * @ctext_len: the length of data to decrypt
+ * @ptext: the decrypted data
+ * @ptext_len: the available length for decrypted data
+ * @flags: flags for padding
+ *
+ * This function will decrypt the given data using the algorithm
+ * specified by the context. If @flags is specified, padding for the
+ * decrypted data will be removed accordingly and @ptext_len will be
+ * updated.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.7.7
+ **/
+int
+gnutls_cipher_decrypt3(gnutls_cipher_hd_t handle,
+ const void *ctext, size_t ctext_len,
+ void *ptext, size_t *ptext_len,
+ unsigned flags)
+{
+ api_cipher_hd_st *h = handle;
+ int ret;
+
+ ret = gnutls_cipher_decrypt2(handle,
+ ctext, ctext_len,
+ ptext, *ptext_len);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (_gnutls_cipher_type(h->ctx_enc.e) == CIPHER_BLOCK &&
+ (flags & GNUTLS_CIPHER_PADDING_PKCS7)) {
+ uint8_t *p = ptext;
+ uint8_t padding = p[*ptext_len - 1];
+ if (!padding || padding > _gnutls_cipher_get_block_size(h->ctx_enc.e)) {
+ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
+ }
+ /* Check that the prior bytes are all PADDING */
+ for (size_t i = *ptext_len - padding; i < *ptext_len; i++) {
+ if (padding != p[*ptext_len - 1]) {
+ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
+ }
+ }
+ *ptext_len -= padding;
+ }
+
+ return 0;
+}
+
+/**
* gnutls_cipher_deinit:
* @handle: is a #gnutls_cipher_hd_t type
*
diff --color -ruNp a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h
--- a/lib/includes/gnutls/crypto.h 2022-05-10 13:57:43.000000000 +0200
+++ b/lib/includes/gnutls/crypto.h 2022-11-15 14:14:40.256300941 +0100
@@ -49,6 +49,28 @@ int gnutls_cipher_encrypt2(gnutls_cipher
const void *text, size_t textlen,
void *ciphertext, size_t ciphertextlen);
+/**
+ * gnutls_cipher_flags_t:
+ * @GNUTLS_CIPHER_PADDING_PKCS7: Flag to indicate PKCS#7 padding
+ *
+ * Enumeration of flags to control block cipher padding, used by
+ * gnutls_cipher_encrypt3() and gnutls_cipher_decrypt3().
+ *
+ * Since: 3.7.7
+ */
+typedef enum gnutls_cipher_flags_t {
+ GNUTLS_CIPHER_PADDING_PKCS7 = 1
+} gnutls_cipher_flags_t;
+
+int gnutls_cipher_encrypt3(gnutls_cipher_hd_t handle,
+ const void *ptext, size_t ptext_len,
+ void *ctext, size_t *ctext_len,
+ unsigned flags);
+int gnutls_cipher_decrypt3(gnutls_cipher_hd_t handle,
+ const void *ctext, size_t ctext_len,
+ void *ptext, size_t *ptext_len,
+ unsigned flags);
+
void gnutls_cipher_set_iv(gnutls_cipher_hd_t handle, void *iv,
size_t ivlen);
diff --color -ruNp a/lib/libgnutls.map b/lib/libgnutls.map
--- a/lib/libgnutls.map 2022-11-15 14:14:11.142735308 +0100
+++ b/lib/libgnutls.map 2022-11-15 14:14:40.256300941 +0100
@@ -1403,6 +1403,8 @@ GNUTLS_3_7_7
{
global:
gnutls_fips140_run_self_tests;
+ gnutls_cipher_encrypt3;
+ gnutls_cipher_decrypt3;
local:
*;
} GNUTLS_3_7_5;
diff --color -ruNp a/tests/cipher-padding.c b/tests/cipher-padding.c
--- a/tests/cipher-padding.c 1970-01-01 01:00:00.000000000 +0100
+++ b/tests/cipher-padding.c 2022-11-15 14:14:40.258300980 +0100
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ *
+ */
+
+#include <config.h>
+
+#include <gnutls/crypto.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "utils.h"
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "<%d>| %s", level, str);
+}
+
+#define CLAMP(x, b) (((x) + (b)) / (b)) * (b)
+
+static void
+start(gnutls_cipher_algorithm_t algo, size_t plaintext_size, unsigned int flags)
+{
+ int ret;
+ gnutls_cipher_hd_t ch;
+ uint8_t key16[64];
+ uint8_t iv16[32];
+ uint8_t plaintext[128];
+ uint8_t ciphertext[128];
+ size_t block_size;
+ size_t size;
+ gnutls_datum_t key, iv;
+
+ success("%s %zu %u\n",
+ gnutls_cipher_get_name(algo), plaintext_size, flags);
+
+ block_size = gnutls_cipher_get_block_size(algo);
+
+ key.data = key16;
+ key.size = gnutls_cipher_get_key_size(algo);
+ assert(key.size <= sizeof(key16));
+
+ iv.data = iv16;
+ iv.size = gnutls_cipher_get_iv_size(algo);
+ assert(iv.size <= sizeof(iv16));
+
+ memset(iv.data, 0xff, iv.size);
+ memset(key.data, 0xfe, key.size);
+ memset(plaintext, 0xfa, sizeof(plaintext));
+
+ ret = gnutls_cipher_init(&ch, algo, &key, &iv);
+ if (ret < 0) {
+ fail("gnutls_cipher_init failed\n");
+ }
+
+ /* Check overflow if PKCS#7 is requested */
+ if (flags & GNUTLS_CIPHER_PADDING_PKCS7) {
+ ret = gnutls_cipher_encrypt3(ch,
+ plaintext, SIZE_MAX,
+ NULL, &size,
+ flags);
+ if (ret != GNUTLS_E_INVALID_REQUEST) {
+ fail("gnutls_cipher_encrypt3 succeeded\n");
+ }
+ }
+
+ /* Get the ciphertext size */
+ ret = gnutls_cipher_encrypt3(ch,
+ plaintext, plaintext_size,
+ NULL, &size,
+ flags);
+ if (ret < 0) {
+ fail("gnutls_cipher_encrypt3 failed\n");
+ }
+
+ if (flags & GNUTLS_CIPHER_PADDING_PKCS7) {
+ if (size <= plaintext_size) {
+ fail("no padding appended\n");
+ }
+ if (size != CLAMP(plaintext_size, block_size)) {
+ fail("size does not match: %zu (expected %zu)\n",
+ size, CLAMP(plaintext_size, block_size));
+ }
+ } else {
+ if (size != plaintext_size) {
+ fail("size does not match: %zu (expected %zu)\n",
+ size, plaintext_size);
+ }
+ }
+
+ /* Encrypt with padding */
+ ret = gnutls_cipher_encrypt3(ch,
+ plaintext, plaintext_size,
+ ciphertext, &size,
+ flags);
+ if (ret < 0) {
+ fail("gnutls_cipher_encrypt3 failed\n");
+ }
+
+ /* Decrypt with padding */
+ ret = gnutls_cipher_decrypt3(ch,
+ ciphertext, size,
+ ciphertext, &size,
+ flags);
+ if (ret < 0) {
+ fail("gnutls_cipher_encrypt3 failed\n");
+ }
+
+ if (size != plaintext_size) {
+ fail("size does not match: %zu (expected %zu)\n",
+ size, plaintext_size);
+ }
+
+ if (memcmp(ciphertext, plaintext, size) != 0) {
+ fail("plaintext does not match\n");
+ }
+
+ gnutls_cipher_deinit(ch);
+}
+
+void doit(void) {
+ int ret;
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug) {
+ gnutls_global_set_log_level(4711);
+ }
+
+ ret = global_init();
+ if (ret < 0) {
+ fail("Cannot initialize library\n");
+ }
+
+ start(GNUTLS_CIPHER_AES_128_CBC, 0, GNUTLS_CIPHER_PADDING_PKCS7);
+ start(GNUTLS_CIPHER_AES_128_CBC, 11, GNUTLS_CIPHER_PADDING_PKCS7);
+ start(GNUTLS_CIPHER_AES_128_CBC, 77, GNUTLS_CIPHER_PADDING_PKCS7);
+ start(GNUTLS_CIPHER_AES_128_CBC, 80, GNUTLS_CIPHER_PADDING_PKCS7);
+
+ start(GNUTLS_CIPHER_AES_128_CBC, 0, 0);
+ start(GNUTLS_CIPHER_AES_128_CBC, 80, 0);
+
+ gnutls_global_deinit();
+}
diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am
--- a/tests/Makefile.am 2022-11-15 14:14:11.144735347 +0100
+++ b/tests/Makefile.am 2022-11-15 14:14:40.257300960 +0100
@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hm
tls13-without-timeout-func buffer status-request-revoked \
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
- x509-upnconstraint xts-key-check pkcs7-verify-double-free \
+ x509-upnconstraint cipher-padding xts-key-check pkcs7-verify-double-free \
fips-rsa-sizes tls12-rehandshake-ticket
ctests += tls-channel-binding

View File

@ -1,215 +0,0 @@
diff --color -ruNp a/lib/ext/session_ticket.c b/lib/ext/session_ticket.c
--- a/lib/ext/session_ticket.c 2022-05-10 13:55:00.000000000 +0200
+++ b/lib/ext/session_ticket.c 2022-11-15 13:30:20.491830382 +0100
@@ -624,6 +624,12 @@ gnutls_session_ticket_enable_server(gnut
return 0;
}
+void
+_gnutls_session_ticket_disable_server(gnutls_session_t session)
+{
+ session->internals.flags |= GNUTLS_NO_TICKETS;
+}
+
/*
* Return zero if session tickets haven't been enabled.
*/
diff --color -ruNp a/lib/ext/session_ticket.h b/lib/ext/session_ticket.h
--- a/lib/ext/session_ticket.h 2022-02-22 15:34:48.000000000 +0100
+++ b/lib/ext/session_ticket.h 2022-11-15 13:30:20.491830382 +0100
@@ -36,5 +36,6 @@ int _gnutls_encrypt_session_ticket(gnutl
int _gnutls_decrypt_session_ticket(gnutls_session_t session,
const gnutls_datum_t *ticket_data,
gnutls_datum_t *state);
+void _gnutls_session_ticket_disable_server(gnutls_session_t session);
#endif /* GNUTLS_LIB_EXT_SESSION_TICKET_H */
diff --color -ruNp a/lib/libgnutls.map b/lib/libgnutls.map
--- a/lib/libgnutls.map 2022-11-15 13:12:57.781688194 +0100
+++ b/lib/libgnutls.map 2022-11-15 13:30:20.492830401 +0100
@@ -1510,4 +1510,6 @@ GNUTLS_PRIVATE_3_4 {
_gnutls_buffer_clear;
# needed by tests/cipher-alignment
_gnutls_crypto_register_cipher;
+ # needed by tests/tls12-rehandshake-cert-ticket
+ _gnutls_session_ticket_disable_server;
} GNUTLS_3_4;
diff --color -ruNp a/lib/state.c b/lib/state.c
--- a/lib/state.c 2022-05-16 17:10:08.000000000 +0200
+++ b/lib/state.c 2022-11-15 13:30:20.493830420 +0100
@@ -545,6 +545,7 @@ void _gnutls_handshake_internal_state_cl
session->internals.tfo.connect_addrlen = 0;
session->internals.tfo.connect_only = 0;
session->internals.early_data_received = 0;
+ session->internals.session_ticket_renew = 0;
}
/**
diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am
--- a/tests/Makefile.am 2022-11-15 13:12:58.209696462 +0100
+++ b/tests/Makefile.am 2022-11-15 13:30:20.494830440 +0100
@@ -234,7 +234,7 @@ ctests += mini-record-2 simple gnutls_hm
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
x509-upnconstraint xts-key-check pkcs7-verify-double-free \
- fips-rsa-sizes
+ fips-rsa-sizes tls12-rehandshake-ticket
ctests += tls-channel-binding
diff --color -ruNp a/tests/tls12-rehandshake-ticket.c b/tests/tls12-rehandshake-ticket.c
--- a/tests/tls12-rehandshake-ticket.c 1970-01-01 01:00:00.000000000 +0100
+++ b/tests/tls12-rehandshake-ticket.c 2022-11-15 13:30:20.495830459 +0100
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnutls/gnutls.h>
+#include <assert.h>
+#include "cert-common.h"
+
+#include "utils.h"
+#include "eagain-common.h"
+
+const char *side = "";
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "%s|<%d>| %s", side, level, str);
+}
+
+#define MAX_BUF 1024
+
+void _gnutls_session_ticket_disable_server(gnutls_session_t session);
+
+static void run(void)
+{
+ char buffer[MAX_BUF + 1];
+ /* Server stuff. */
+ gnutls_certificate_credentials_t scred;
+ gnutls_session_t server;
+ gnutls_datum_t session_ticket_key = { NULL, 0 };
+ int sret;
+ /* Client stuff. */
+ gnutls_certificate_credentials_t ccred;
+ gnutls_session_t client;
+ int cret;
+
+ /* General init. */
+ global_init();
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(9);
+
+ /* Init server */
+ assert(gnutls_certificate_allocate_credentials(&scred) >= 0);
+ assert(gnutls_certificate_set_x509_key_mem(scred,
+ &server_ca3_localhost_cert,
+ &server_ca3_key,
+ GNUTLS_X509_FMT_PEM) >= 0);
+ assert(gnutls_certificate_set_x509_trust_mem(scred,
+ &ca3_cert,
+ GNUTLS_X509_FMT_PEM) >= 0);
+
+ assert(gnutls_init(&server, GNUTLS_SERVER) >= 0);
+ gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
+ assert(gnutls_priority_set_direct(server,
+ "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.2",
+ NULL) >= 0);
+
+ gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, scred);
+ gnutls_transport_set_push_function(server, server_push);
+ gnutls_transport_set_pull_function(server, server_pull);
+ gnutls_transport_set_ptr(server, server);
+
+ gnutls_session_ticket_key_generate(&session_ticket_key);
+ gnutls_session_ticket_enable_server(server, &session_ticket_key);
+
+ /* Init client */
+ assert(gnutls_certificate_allocate_credentials(&ccred) >= 0);
+ assert(gnutls_certificate_set_x509_key_mem
+ (ccred, &cli_ca3_cert_chain, &cli_ca3_key, GNUTLS_X509_FMT_PEM) >= 0);
+ assert(gnutls_certificate_set_x509_trust_mem
+ (ccred, &ca3_cert, GNUTLS_X509_FMT_PEM) >= 0);
+
+ gnutls_init(&client, GNUTLS_CLIENT);
+ assert(gnutls_priority_set_direct(client,
+ "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.2",
+ NULL) >= 0);
+
+ assert(gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred) >= 0);
+
+ gnutls_transport_set_push_function(client, client_push);
+ gnutls_transport_set_pull_function(client, client_pull);
+ gnutls_transport_set_ptr(client, client);
+
+ HANDSHAKE(client, server);
+
+ /* Server initiates rehandshake */
+ switch_side("server");
+ sret = gnutls_rehandshake(server);
+ if (sret < 0) {
+ fail("Error sending %d byte packet: %s\n",
+ (int)sizeof(buffer), gnutls_strerror(sret));
+ } else if (debug)
+ success("server: starting rehandshake\n");
+
+ /* Stop sending session ticket */
+ _gnutls_session_ticket_disable_server(server);
+
+ /* Client gets notified with rehandshake */
+ switch_side("client");
+ do {
+ do {
+ cret = gnutls_record_recv(client, buffer, MAX_BUF);
+ } while (cret == GNUTLS_E_AGAIN || cret == GNUTLS_E_INTERRUPTED);
+ } while (cret > 0);
+
+ if (cret != GNUTLS_E_REHANDSHAKE) {
+ fail("client: Error receiving rehandshake: %s\n",
+ gnutls_strerror(cret));
+ }
+
+ HANDSHAKE(client, server);
+
+ gnutls_bye(client, GNUTLS_SHUT_WR);
+ gnutls_bye(server, GNUTLS_SHUT_WR);
+
+ gnutls_deinit(client);
+ gnutls_deinit(server);
+
+ gnutls_certificate_free_credentials(scred);
+ gnutls_certificate_free_credentials(ccred);
+
+ gnutls_free(session_ticket_key.data);
+
+ gnutls_global_deinit();
+ reset_buffers();
+}
+
+void doit(void)
+{
+ run();
+}

View File

@ -1,58 +0,0 @@
From 51b721b69fd08ef1c4c4989f5e12b643e170ff56 Mon Sep 17 00:00:00 2001
From: Pedro Monreal <pmgdeb@gmail.com>
Date: Thu, 16 Feb 2023 17:02:38 +0100
Subject: [PATCH] pk: extend pair-wise consistency to cover DH key generation
Perform SP800 56A (rev 3) 5.6.2.1.4 Owner Assurance of Pair-wise
Consistency check, even if we only support ephemeral DH, as it is
required by FIPS 140-3 IG 10.3.A.
Signed-off-by: Pedro Monreal <pmgdeb@gmail.com>
Co-authored-by: Daiki Ueno <ueno@gnu.org>
---
lib/nettle/pk.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index d30bca594f..bd9c1b4c74 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -2642,6 +2642,35 @@ static int pct_test(gnutls_pk_algorithm_t algo,
}
break;
case GNUTLS_PK_DH:
+ {
+ mpz_t y;
+
+ /* Perform SP800 56A (rev 3) 5.6.2.1.4 Owner Assurance
+ * of Pair-wise Consistency check, even if we only
+ * support ephemeral DH, as it is required by FIPS
+ * 140-3 IG 10.3.A.
+ *
+ * Use the private key, x, along with the generator g
+ * and prime modulus p included in the domain
+ * parameters associated with the key pair to compute
+ * g^x mod p. Compare the result to the public key, y.
+ */
+ mpz_init(y);
+ mpz_powm(y,
+ TOMPZ(params->params[DSA_G]),
+ TOMPZ(params->params[DSA_X]),
+ TOMPZ(params->params[DSA_P]));
+ if (unlikely
+ (mpz_cmp(y, TOMPZ(params->params[DSA_Y])) != 0)) {
+ ret =
+ gnutls_assert_val
+ (GNUTLS_E_PK_GENERATION_ERROR);
+ mpz_clear(y);
+ goto cleanup;
+ }
+ mpz_clear(y);
+ break;
+ }
case GNUTLS_PK_ECDH_X25519:
case GNUTLS_PK_ECDH_X448:
ret = 0;
--
2.39.2

View File

@ -1,54 +0,0 @@
diff --color -ruNp a/lib/fips.c b/lib/fips.c
--- a/lib/fips.c 2022-11-15 16:10:56.183185457 +0100
+++ b/lib/fips.c 2022-11-15 16:10:23.488530716 +0100
@@ -360,11 +360,6 @@ static int check_lib_hmac(struct hmac_en
return gnutls_assert_val(ret);
}
- if (strncmp(entry->path, path, GNUTLS_PATH_MAX)) {
- _gnutls_debug_log("Library path for %s does not match with HMAC file\n", lib);
- return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
- }
-
_gnutls_debug_log("Loading: %s\n", path);
ret = gnutls_load_file(path, &data);
if (ret < 0) {
diff --color -ruNp a/lib/fipshmac.c b/lib/fipshmac.c
--- a/lib/fipshmac.c 2022-11-15 16:10:56.183185457 +0100
+++ b/lib/fipshmac.c 2022-11-15 16:10:23.489530737 +0100
@@ -102,20 +102,30 @@ static int get_hmac(const char *path, ch
static int print_lib_path(const char *path)
{
int ret;
+ char *real_path = NULL;
char hmac[HMAC_STR_SIZE];
- ret = get_hmac(path, hmac, sizeof(hmac));
+ real_path = canonicalize_file_name(path);
+ if (real_path == NULL) {
+ fprintf(stderr, "Could not get realpath from %s\n", path);
+ ret = GNUTLS_E_FILE_ERROR;
+ goto cleanup;
+ }
+
+ ret = get_hmac(real_path, hmac, sizeof(hmac));
if (ret < 0) {
fprintf(stderr, "Could not calculate HMAC for %s: %s\n",
- last_component(path), gnutls_strerror(ret));
- return ret;
+ last_component(real_path), gnutls_strerror(ret));
+ goto cleanup;
}
printf("[%s]\n", last_component(path));
- printf("path = %s\n", path);
+ printf("path = %s\n", real_path);
printf("hmac = %s\n", hmac);
- return 0;
+cleanup:
+ free(real_path);
+ return ret;
}
static int print_lib_dl(const char *lib, const char *sym)

View File

@ -0,0 +1,27 @@
From 7d98e7768f3e4e1f981f76e27338ae7118ee2c39 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 22 Jan 2024 15:17:04 +0900
Subject: [PATCH] gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch
---
tests/gnutls_ktls.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c
index ccbe566..8b8992d 100644
--- a/tests/gnutls_ktls.c
+++ b/tests/gnutls_ktls.c
@@ -347,10 +347,8 @@ void doit(void)
{
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-GCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-256-GCM");
- run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+CHACHA20-POLY1305");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM");
- run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305");
#if defined(__linux__)
run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-CCM");
run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-CCM");
--
2.43.0

View File

@ -1,534 +0,0 @@
diff --color -ruNp a/configure.ac b/configure.ac
--- a/configure.ac 2022-05-27 09:17:26.000000000 +0200
+++ b/configure.ac 2022-12-15 11:00:18.830698584 +0100
@@ -619,6 +619,8 @@ if [ test "$enable_fips" = "yes" ];then
if test "x$fips_module_version" != xnone; then
AC_DEFINE_UNQUOTED([FIPS_MODULE_VERSION], ["$fips_module_version"], [The FIPS140 module version])
fi
+
+ AC_CHECK_FUNCS(dl_iterate_phdr)
else
enable_fips=no
AC_MSG_WARN([[
diff --color -ruNp a/lib/fips.c b/lib/fips.c
--- a/lib/fips.c 2022-12-15 10:59:57.460279029 +0100
+++ b/lib/fips.c 2022-12-15 11:00:18.831698604 +0100
@@ -23,9 +23,11 @@
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include <unistd.h>
+#include "dirname.h"
#include "errors.h"
#include "file.h"
#include "inih/ini.h"
+#include "str.h"
#include <fips.h>
#include <gnutls/self-test.h>
#include <stdio.h>
@@ -34,6 +36,10 @@
#include "gthreads.h"
+#ifdef HAVE_DL_ITERATE_PHDR
+#include <link.h>
+#endif
+
unsigned int _gnutls_lib_state = LIB_STATE_POWERON;
struct gnutls_fips140_context_st {
@@ -153,7 +159,6 @@ void _gnutls_fips_mode_reset_zombie(void
#define HMAC_SIZE 32
#define HMAC_ALGO GNUTLS_MAC_SHA256
-#define HMAC_FILE_NAME ".gnutls.hmac"
#define HMAC_FORMAT_VERSION 1
struct hmac_entry
@@ -162,51 +167,32 @@ struct hmac_entry
uint8_t hmac[HMAC_SIZE];
};
-typedef struct
+struct hmac_file
{
int version;
struct hmac_entry gnutls;
struct hmac_entry nettle;
struct hmac_entry hogweed;
struct hmac_entry gmp;
-} hmac_file;
+};
-static int get_library_path(const char* lib, const char* symbol, char* path, size_t path_size)
+struct lib_paths
{
- int ret;
- void *dl, *sym;
- Dl_info info;
-
- dl = dlopen(lib, RTLD_LAZY);
- if (dl == NULL)
- return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
-
- sym = dlsym(dl, symbol);
- if (sym == NULL) {
- ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
- goto cleanup;
- }
-
- ret = dladdr(sym, &info);
- if (ret == 0) {
- ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
- goto cleanup;
- }
-
- ret = snprintf(path, path_size, "%s", info.dli_fname);
- if ((size_t)ret >= path_size) {
- ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- goto cleanup;
- }
-
- ret = 0;
-cleanup:
- dlclose(dl);
- return ret;
-}
+ char gnutls[GNUTLS_PATH_MAX];
+ char nettle[GNUTLS_PATH_MAX];
+ char hogweed[GNUTLS_PATH_MAX];
+ char gmp[GNUTLS_PATH_MAX];
+};
-/* Parses hmac data and copies hex value into dest.
+/*
+ * get_hmac:
+ * @dest: buffer for the hex value
+ * @value: hmac value
+ *
+ * Parses hmac data and copies hex value into dest.
* dest must point to at least HMAC_SIZE amount of memory
+ *
+ * Returns: 0 on success, a negative error code otherwise
*/
static int get_hmac(uint8_t *dest, const char *value)
{
@@ -245,7 +231,7 @@ lib_handler(struct hmac_entry *entry,
static int handler(void *user, const char *section, const char *name, const char *value)
{
- hmac_file *p = (hmac_file *)user;
+ struct hmac_file *p = (struct hmac_file *)user;
if (!strcmp(section, "global")) {
if (!strcmp(name, "format-version")) {
@@ -267,24 +253,29 @@ static int handler(void *user, const cha
return 1;
}
-static int get_hmac_path(char *mac_file, size_t mac_file_size)
+/*
+ * get_hmac_path:
+ * @mac_file: buffer where the hmac file path will be written to
+ * @mac_file_size: size of the mac_file buffer
+ * @gnutls_path: path to the gnutls library, used to deduce hmac file path
+ *
+ * Deduces hmac file path from the gnutls library path.
+ *
+ * Returns: 0 on success, a negative error code otherwise
+ */
+static int get_hmac_path(char *mac_file, size_t mac_file_size, const char *gnutls_path)
{
int ret;
char *p;
- char file[GNUTLS_PATH_MAX];
- ret = get_library_path(GNUTLS_LIBRARY_NAME, "gnutls_global_init",
- file, sizeof(file));
- if (ret < 0)
- return ret;
-
- p = strrchr(file, '/');
+ p = strrchr(gnutls_path, '/');
if (p == NULL)
- ret = snprintf(mac_file, mac_file_size, HMAC_FILE_NAME);
+ ret = snprintf(mac_file, mac_file_size, ".%s.hmac", gnutls_path);
else
- ret = snprintf(mac_file, mac_file_size,
- "%.*s/"HMAC_FILE_NAME, (int)(p - file), file);
+ ret = snprintf(mac_file, mac_file_size, "%.*s/.%s.hmac",
+ (int)(p - gnutls_path), gnutls_path, p + 1);
+
if ((size_t)ret >= mac_file_size)
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
@@ -293,10 +284,11 @@ static int get_hmac_path(char *mac_file,
return GNUTLS_E_SUCCESS;
if (p == NULL)
- ret = snprintf(mac_file, mac_file_size, "fipscheck/"HMAC_FILE_NAME);
+ ret = snprintf(mac_file, mac_file_size, "fipscheck/.%s.hmac", gnutls_path);
else
- ret = snprintf(mac_file, mac_file_size,
- "%.*s/fipscheck/"HMAC_FILE_NAME, (int)(p - file), file);
+ ret = snprintf(mac_file, mac_file_size, "%.*s/fipscheck/.%s.hmac",
+ (int)(p - gnutls_path), gnutls_path, p + 1);
+
if ((size_t)ret >= mac_file_size)
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
@@ -307,51 +299,52 @@ static int get_hmac_path(char *mac_file,
return GNUTLS_E_FILE_ERROR;
}
-static int load_hmac_file(hmac_file *p)
+/*
+ * load_hmac_file:
+ * @hmac_file: hmac file structure
+ * @hmac_path: path to the hmac file
+ *
+ * Loads the hmac file into the hmac file structure.
+ *
+ * Returns: 0 on success, a negative error code otherwise
+ */
+static int load_hmac_file(struct hmac_file *hmac_file, const char *hmac_path)
{
int ret;
FILE *stream;
- char hmac_path[GNUTLS_PATH_MAX];
-
- ret = get_hmac_path(hmac_path, sizeof(hmac_path));
- if (ret < 0)
- return gnutls_assert_val(ret);
stream = fopen(hmac_path, "r");
if (stream == NULL)
return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
- gnutls_memset(p, 0, sizeof(*p));
- ret = ini_parse_file(stream, handler, p);
+ gnutls_memset(hmac_file, 0, sizeof(*hmac_file));
+ ret = ini_parse_file(stream, handler, hmac_file);
fclose(stream);
if (ret < 0)
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
- if (p->version != HMAC_FORMAT_VERSION)
+ if (hmac_file->version != HMAC_FORMAT_VERSION)
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
return 0;
}
-/* Run an HMAC using the key above on the library binary data.
- * Returns 0 on success and negative value on error.
+/*
+ * check_lib_hmac:
+ * @entry: hmac file entry
+ * @path: path to the library which hmac should be compared
+ *
+ * Verify that HMAC from hmac file entry matches HMAC of given library.
+ *
+ * Returns: 0 on successful HMAC verification, a negative error code otherwise
*/
-static int check_lib_hmac(struct hmac_entry *entry,
- const char *lib, const char *sym)
+static int check_lib_hmac(struct hmac_entry *entry, const char *path)
{
int ret;
unsigned prev;
- char path[GNUTLS_PATH_MAX];
uint8_t hmac[HMAC_SIZE];
gnutls_datum_t data;
- ret = get_library_path(lib, sym, path, sizeof(path));
- if (ret < 0) {
- _gnutls_debug_log("Could not get lib path for %s: %s\n",
- lib, gnutls_strerror(ret));
- return gnutls_assert_val(ret);
- }
-
_gnutls_debug_log("Loading: %s\n", path);
ret = gnutls_load_file(path, &data);
if (ret < 0) {
@@ -382,28 +375,99 @@ static int check_lib_hmac(struct hmac_en
return 0;
}
+#ifdef HAVE_DL_ITERATE_PHDR
+
+static int callback(struct dl_phdr_info *info, size_t size, void *data)
+{
+ const char *path = info->dlpi_name;
+ const char *soname = last_component(path);
+ struct lib_paths *paths = (struct lib_paths *)data;
+
+ if (!strcmp(soname, GNUTLS_LIBRARY_SONAME))
+ _gnutls_str_cpy(paths->gnutls, GNUTLS_PATH_MAX, path);
+ else if (!strcmp(soname, NETTLE_LIBRARY_SONAME))
+ _gnutls_str_cpy(paths->nettle, GNUTLS_PATH_MAX, path);
+ else if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
+ _gnutls_str_cpy(paths->hogweed, GNUTLS_PATH_MAX, path);
+ else if (!strcmp(soname, GMP_LIBRARY_SONAME))
+ _gnutls_str_cpy(paths->gmp, GNUTLS_PATH_MAX, path);
+ return 0;
+}
+
+static int load_lib_paths(struct lib_paths *paths)
+{
+ memset(paths, 0, sizeof(*paths));
+ dl_iterate_phdr(callback, paths);
+
+ if (paths->gnutls[0] == '\0') {
+ _gnutls_debug_log("Gnutls library path was not found\n");
+ return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+ }
+ if (paths->nettle[0] == '\0') {
+ _gnutls_debug_log("Nettle library path was not found\n");
+ return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+ }
+ if (paths->hogweed[0] == '\0') {
+ _gnutls_debug_log("Hogweed library path was not found\n");
+ return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+ }
+ if (paths->gmp[0] == '\0') {
+ _gnutls_debug_log("Gmp library path was not found\n");
+ return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+ }
+
+ return GNUTLS_E_SUCCESS;
+}
+
+#else
+
+static int load_lib_paths(struct lib_paths *paths)
+{
+ (void)paths;
+ _gnutls_debug_log("Function dl_iterate_phdr is missing\n");
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+}
+
+#endif /* HAVE_DL_ITERATE_PHDR */
+
static int check_binary_integrity(void)
{
int ret;
- hmac_file file;
+ struct lib_paths paths;
+ struct hmac_file hmac;
+ char hmac_path[GNUTLS_PATH_MAX];
+
+ ret = load_lib_paths(&paths);
+ if (ret < 0) {
+ _gnutls_debug_log("Could not load library paths: %s\n",
+ gnutls_strerror(ret));
+ return ret;
+ }
+
+ ret = get_hmac_path(hmac_path, sizeof(hmac_path), paths.gnutls);
+ if (ret < 0) {
+ _gnutls_debug_log("Could not get hmac file path: %s\n",
+ gnutls_strerror(ret));
+ return ret;
+ }
- ret = load_hmac_file(&file);
+ ret = load_hmac_file(&hmac, hmac_path);
if (ret < 0) {
_gnutls_debug_log("Could not load hmac file: %s\n",
gnutls_strerror(ret));
return ret;
}
- ret = check_lib_hmac(&file.gnutls, GNUTLS_LIBRARY_NAME, "gnutls_global_init");
+ ret = check_lib_hmac(&hmac.gnutls, paths.gnutls);
if (ret < 0)
return ret;
- ret = check_lib_hmac(&file.nettle, NETTLE_LIBRARY_NAME, "nettle_aes_set_encrypt_key");
+ ret = check_lib_hmac(&hmac.nettle, paths.nettle);
if (ret < 0)
return ret;
- ret = check_lib_hmac(&file.hogweed, HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u");
+ ret = check_lib_hmac(&hmac.hogweed, paths.hogweed);
if (ret < 0)
return ret;
- ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init");
+ ret = check_lib_hmac(&hmac.gmp, paths.gmp);
if (ret < 0)
return ret;
diff --color -ruNp a/lib/fipshmac.c b/lib/fipshmac.c
--- a/lib/fipshmac.c 2022-12-15 10:59:57.461279049 +0100
+++ b/lib/fipshmac.c 2022-12-15 11:00:18.832698623 +0100
@@ -22,12 +22,14 @@
#include "config.h"
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
-#include <dlfcn.h>
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+
+#ifdef HAVE_DL_ITERATE_PHDR
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include <link.h>
#include "dirname.h"
#include "errors.h"
@@ -36,40 +38,6 @@
#define HMAC_ALGO GNUTLS_MAC_SHA256
#define HMAC_STR_SIZE (2 * HMAC_SIZE + 1)
-static int get_path(const char *lib, const char *symbol, char *path, size_t path_size)
-{
- int ret;
- void *dl, *sym;
- Dl_info info;
-
- dl = dlopen(lib, RTLD_LAZY);
- if (dl == NULL)
- return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
-
- sym = dlsym(dl, symbol);
- if (sym == NULL) {
- ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
- goto cleanup;
- }
-
- ret = dladdr(sym, &info);
- if (ret == 0) {
- ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
- goto cleanup;
- }
-
- ret = snprintf(path, path_size, "%s", info.dli_fname);
- if ((size_t)ret >= path_size) {
- ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
- goto cleanup;
- }
-
- ret = 0;
-cleanup:
- dlclose(dl);
- return ret;
-}
-
static int get_hmac(const char *path, char *hmac, size_t hmac_size)
{
int ret;
@@ -99,7 +67,7 @@ static int get_hmac(const char *path, ch
return 0;
}
-static int print_lib_path(const char *path)
+static int print_lib(const char *path, const char *soname)
{
int ret;
char *real_path = NULL;
@@ -119,7 +87,7 @@ static int print_lib_path(const char *pa
goto cleanup;
}
- printf("[%s]\n", last_component(path));
+ printf("[%s]\n", soname);
printf("path = %s\n", real_path);
printf("hmac = %s\n", hmac);
@@ -128,25 +96,24 @@ cleanup:
return ret;
}
-static int print_lib_dl(const char *lib, const char *sym)
+static int callback(struct dl_phdr_info *info, size_t size, void *data)
{
- int ret;
- char path[GNUTLS_PATH_MAX];
-
- ret = get_path(lib, sym, path, sizeof(path));
- if (ret < 0) {
- fprintf(stderr, "Could not get lib path for %s: %s\n",
- lib, gnutls_strerror(ret));
- return ret;
- }
+ const char *path = info->dlpi_name;
+ const char *soname = last_component(path);
- return print_lib_path(path);
+ if (!strcmp(soname, GNUTLS_LIBRARY_SONAME))
+ return print_lib(data ? data : path, soname);
+ if (!strcmp(soname, NETTLE_LIBRARY_SONAME))
+ return print_lib(path, soname);
+ if (!strcmp(soname, HOGWEED_LIBRARY_SONAME))
+ return print_lib(path, soname);
+ if (!strcmp(soname, GMP_LIBRARY_SONAME))
+ return print_lib(path, soname);
+ return 0;
}
int main(int argc, char **argv)
{
- int ret;
-
if (argc != 1 && argc != 2) {
fprintf(stderr, "Usage: %s [gnutls_so_path]\n", last_component(argv[0]));
return EXIT_FAILURE;
@@ -155,24 +122,15 @@ int main(int argc, char **argv)
printf("[global]\n");
printf("format-version = %d\n", FORMAT_VERSION);
- if (argc == 2)
- ret = print_lib_path(argv[1]);
- else
- ret = print_lib_dl(GNUTLS_LIBRARY_SONAME, "gnutls_global_init");
- if (ret < 0)
- return EXIT_FAILURE;
+ return dl_iterate_phdr(callback, argc == 2 ? argv[1] : NULL);
+}
- ret = print_lib_dl(NETTLE_LIBRARY_SONAME, "nettle_aes_set_encrypt_key");
- if (ret < 0)
- return EXIT_FAILURE;
-
- ret = print_lib_dl(HOGWEED_LIBRARY_SONAME, "nettle_mpz_sizeinbase_256_u");
- if (ret < 0)
- return EXIT_FAILURE;
-
- ret = print_lib_dl(GMP_LIBRARY_SONAME, "__gmpz_init");
- if (ret < 0)
- return EXIT_FAILURE;
+#else
- return EXIT_SUCCESS;
+int main(void)
+{
+ fprintf(stderr, "Function dl_iterate_phdr is missing\n");
+ return EXIT_FAILURE;
}
+
+#endif /* HAVE_DL_ITERATE_PHDR */
diff --color -ruNp a/lib/Makefile.am b/lib/Makefile.am
--- a/lib/Makefile.am 2022-05-18 16:46:00.000000000 +0200
+++ b/lib/Makefile.am 2022-12-15 11:00:18.789697779 +0100
@@ -202,14 +202,14 @@ noinst_PROGRAMS = fipshmac
fipshmac_SOURCES = fipshmac.c
fipshmac_LDADD = libgnutls.la ../gl/libgnu.la
-hmac_files = .libs/.gnutls.hmac
+hmac_file = .libs/.$(gnutls_so).hmac
-all-local: $(hmac_files)
+all-local: $(hmac_file)
-.libs/.gnutls.hmac: libgnutls.la fipshmac
+$(hmac_file): libgnutls.la fipshmac
$(AM_V_GEN) $(builddir)/fipshmac > $@-t && mv $@-t $@
-CLEANFILES = $(hmac_files)
+CLEANFILES = $(hmac_file)
endif
if NEED_LTLIBDL

View File

@ -1,114 +0,0 @@
From c149dd0767f32789e391280cb1eb06b7eb7c6bce Mon Sep 17 00:00:00 2001
From: Alexander Sosedkin <asosedkin@redhat.com>
Date: Tue, 9 Aug 2022 16:05:53 +0200
Subject: [PATCH 1/2] auth/rsa: side-step potential side-channel
Remove branching that depends on secret data.
Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
Signed-off-by: Hubert Kario <hkario@redhat.com>
Tested-by: Hubert Kario <hkario@redhat.com>
---
lib/auth/rsa.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c
index 8108ee841d..6b158bacb2 100644
--- a/lib/auth/rsa.c
+++ b/lib/auth/rsa.c
@@ -155,7 +155,6 @@ static int
proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
size_t _data_size)
{
- const char attack_error[] = "auth_rsa: Possible PKCS #1 attack\n";
gnutls_datum_t ciphertext;
int ret, dsize;
ssize_t data_size = _data_size;
@@ -235,15 +234,6 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
ok &= CONSTCHECK_NOT_EQUAL(check_ver_min, 0) &
CONSTCHECK_EQUAL(session->key.key.data[1], ver_min);
- if (ok) {
- /* call logging function unconditionally so all branches are
- * indistinguishable for timing and cache access when debug
- * logging is disabled */
- _gnutls_no_log("%s", attack_error);
- } else {
- _gnutls_debug_log("%s", attack_error);
- }
-
/* This is here to avoid the version check attack
* discussed above.
*/
--
2.39.1
From 7c963102ec2119eecc1789b993aabe5edfd75f3b Mon Sep 17 00:00:00 2001
From: Hubert Kario <hkario@redhat.com>
Date: Wed, 8 Feb 2023 14:32:09 +0100
Subject: [PATCH 2/2] rsa: remove dead code
since the `ok` variable isn't used any more, we can remove all code
used to calculate it
Signed-off-by: Hubert Kario <hkario@redhat.com>
---
lib/auth/rsa.c | 20 +++-----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c
index 6b158bacb2..858701fe6e 100644
--- a/lib/auth/rsa.c
+++ b/lib/auth/rsa.c
@@ -159,8 +159,6 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
int ret, dsize;
ssize_t data_size = _data_size;
volatile uint8_t ver_maj, ver_min;
- volatile uint8_t check_ver_min;
- volatile uint32_t ok;
#ifdef ENABLE_SSL3
if (get_num_version(session) == GNUTLS_SSL3) {
@@ -186,7 +184,6 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
ver_maj = _gnutls_get_adv_version_major(session);
ver_min = _gnutls_get_adv_version_minor(session);
- check_ver_min = (session->internals.allow_wrong_pms == 0);
session->key.key.data = gnutls_malloc(GNUTLS_MASTER_SIZE);
if (session->key.key.data == NULL) {
@@ -205,10 +202,9 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
return ret;
}
- ret =
- gnutls_privkey_decrypt_data2(session->internals.selected_key,
- 0, &ciphertext, session->key.key.data,
- session->key.key.size);
+ gnutls_privkey_decrypt_data2(session->internals.selected_key,
+ 0, &ciphertext, session->key.key.data,
+ session->key.key.size);
/* After this point, any conditional on failure that cause differences
* in execution may create a timing or cache access pattern side
* channel that can be used as an oracle, so treat very carefully */
@@ -224,16 +220,6 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data,
* Vlastimil Klima, Ondej Pokorny and Tomas Rosa.
*/
- /* ok is 0 in case of error and 1 in case of success. */
-
- /* if ret < 0 */
- ok = CONSTCHECK_EQUAL(ret, 0);
- /* session->key.key.data[0] must equal ver_maj */
- ok &= CONSTCHECK_EQUAL(session->key.key.data[0], ver_maj);
- /* if check_ver_min then session->key.key.data[1] must equal ver_min */
- ok &= CONSTCHECK_NOT_EQUAL(check_ver_min, 0) &
- CONSTCHECK_EQUAL(session->key.key.data[1], ver_min);
-
/* This is here to avoid the version check attack
* discussed above.
*/
--
2.39.1

View File

@ -1,220 +0,0 @@
diff --color -ruNp a/lib/accelerated/x86/aes-xts-x86-aesni.c b/lib/accelerated/x86/aes-xts-x86-aesni.c
--- a/lib/accelerated/x86/aes-xts-x86-aesni.c 2022-03-02 12:38:09.000000000 +0100
+++ b/lib/accelerated/x86/aes-xts-x86-aesni.c 2022-11-07 14:12:38.476982750 +0100
@@ -73,7 +73,6 @@ x86_aes_xts_cipher_setkey(void *_ctx, co
/* Check key block according to FIPS-140-2 IG A.9 */
if (_gnutls_fips_mode_enabled()){
if (gnutls_memcmp(key, key + (keysize / 2), keysize / 2) == 0) {
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
}
diff --color -ruNp a/lib/nettle/cipher.c b/lib/nettle/cipher.c
--- a/lib/nettle/cipher.c 2022-11-07 14:10:13.672085930 +0100
+++ b/lib/nettle/cipher.c 2022-11-07 14:12:38.477982770 +0100
@@ -448,12 +448,14 @@ _gcm_decrypt(struct nettle_cipher_ctx *c
length, dst, src);
}
-static void _des_set_key(struct des_ctx *ctx, const uint8_t *key)
+static void
+_des_set_key(struct des_ctx *ctx, const uint8_t *key)
{
des_set_key(ctx, key);
}
-static void _des3_set_key(struct des3_ctx *ctx, const uint8_t *key)
+static void
+_des3_set_key(struct des3_ctx *ctx, const uint8_t *key)
{
des3_set_key(ctx, key);
}
@@ -477,50 +479,6 @@ _cfb8_decrypt(struct nettle_cipher_ctx *
}
static void
-_xts_aes128_set_encrypt_key(struct xts_aes128_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes128_set_encrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes128_set_decrypt_key(struct xts_aes128_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes128_set_decrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes256_set_encrypt_key(struct xts_aes256_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes256_set_encrypt_key(xts_key, key);
-}
-
-static void
-_xts_aes256_set_decrypt_key(struct xts_aes256_key *xts_key,
- const uint8_t *key)
-{
- if (_gnutls_fips_mode_enabled() &&
- gnutls_memcmp(key, key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
- _gnutls_switch_lib_state(LIB_STATE_ERROR);
-
- xts_aes256_set_decrypt_key(xts_key, key);
-}
-
-static void
_xts_aes128_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst,
const uint8_t * src)
{
@@ -1041,8 +999,8 @@ static const struct nettle_cipher_st bui
.ctx_size = sizeof(struct xts_aes128_key),
.encrypt = _xts_aes128_encrypt,
.decrypt = _xts_aes128_decrypt,
- .set_encrypt_key = (nettle_set_key_func*)_xts_aes128_set_encrypt_key,
- .set_decrypt_key = (nettle_set_key_func*)_xts_aes128_set_decrypt_key,
+ .set_encrypt_key = (nettle_set_key_func*)xts_aes128_set_encrypt_key,
+ .set_decrypt_key = (nettle_set_key_func*)xts_aes128_set_decrypt_key,
.max_iv_size = AES_BLOCK_SIZE,
},
{ .algo = GNUTLS_CIPHER_AES_256_XTS,
@@ -1052,8 +1010,8 @@ static const struct nettle_cipher_st bui
.ctx_size = sizeof(struct xts_aes256_key),
.encrypt = _xts_aes256_encrypt,
.decrypt = _xts_aes256_decrypt,
- .set_encrypt_key = (nettle_set_key_func*)_xts_aes256_set_encrypt_key,
- .set_decrypt_key = (nettle_set_key_func*)_xts_aes256_set_decrypt_key,
+ .set_encrypt_key = (nettle_set_key_func*)xts_aes256_set_encrypt_key,
+ .set_decrypt_key = (nettle_set_key_func*)xts_aes256_set_decrypt_key,
.max_iv_size = AES_BLOCK_SIZE,
},
{ .algo = GNUTLS_CIPHER_AES_128_SIV,
@@ -1144,6 +1102,21 @@ wrap_nettle_cipher_setkey(void *_ctx, co
return 0;
}
+ switch (ctx->cipher->algo) {
+ case GNUTLS_CIPHER_AES_128_XTS:
+ if (_gnutls_fips_mode_enabled() &&
+ gnutls_memcmp(key, (char *)key + AES128_KEY_SIZE, AES128_KEY_SIZE) == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ break;
+ case GNUTLS_CIPHER_AES_256_XTS:
+ if (_gnutls_fips_mode_enabled() &&
+ gnutls_memcmp(key, (char *)key + AES256_KEY_SIZE, AES256_KEY_SIZE) == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ break;
+ default:
+ break;
+ }
+
if (ctx->enc)
ctx->cipher->set_encrypt_key(ctx->ctx_ptr, key);
else
diff --color -ruNp a/tests/Makefile.am b/tests/Makefile.am
--- a/tests/Makefile.am 2022-11-07 14:10:13.836089211 +0100
+++ b/tests/Makefile.am 2022-11-07 14:12:38.478982790 +0100
@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hm
tls13-without-timeout-func buffer status-request-revoked \
set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \
x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \
- x509-upnconstraint pkcs7-verify-double-free \
+ x509-upnconstraint xts-key-check pkcs7-verify-double-free \
fips-rsa-sizes
ctests += tls-channel-binding
diff --color -ruNp a/tests/xts-key-check.c b/tests/xts-key-check.c
--- a/tests/xts-key-check.c 1970-01-01 01:00:00.000000000 +0100
+++ b/tests/xts-key-check.c 2022-11-07 14:12:38.478982790 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * Author: Zoltan Fridrich
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnutls/crypto.h>
+
+#include "utils.h"
+
+static void test_xts_check(gnutls_cipher_algorithm_t alg)
+{
+ int ret;
+ gnutls_cipher_hd_t ctx;
+ gnutls_datum_t key, iv;
+
+ iv.size = gnutls_cipher_get_iv_size(alg);
+ iv.data = gnutls_malloc(iv.size);
+ if (iv.data == NULL)
+ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
+ gnutls_memset(iv.data, 0xf0, iv.size);
+
+ key.size = gnutls_cipher_get_key_size(alg);
+ key.data = gnutls_malloc(key.size);
+ if (key.data == NULL) {
+ gnutls_free(iv.data);
+ fail("Error: %s\n", gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
+ }
+ gnutls_memset(key.data, 0xf0, key.size);
+
+ ret = gnutls_cipher_init(&ctx, alg, &key, &iv);
+ if (ret == GNUTLS_E_SUCCESS) {
+ gnutls_cipher_deinit(ctx);
+ gnutls_free(iv.data);
+ gnutls_free(key.data);
+ fail("cipher initialization should fail for key1 == key2\n");
+ }
+
+ key.data[0] = 0xff;
+
+ ret = gnutls_cipher_init(&ctx, alg, &key, &iv);
+ gnutls_free(iv.data);
+ gnutls_free(key.data);
+
+ if (ret == GNUTLS_E_SUCCESS)
+ gnutls_cipher_deinit(ctx);
+ else
+ fail("cipher initialization should succeed with key1 != key2"
+ "\n%s\n", gnutls_strerror(ret));
+}
+
+void doit(void)
+{
+ if (!gnutls_fips140_mode_enabled())
+ exit(77);
+
+ test_xts_check(GNUTLS_CIPHER_AES_128_XTS);
+ test_xts_check(GNUTLS_CIPHER_AES_256_XTS);
+}

View File

@ -1,4 +1,4 @@
From fae4203e1714c851507d19b27095a6dbc1803c44 Mon Sep 17 00:00:00 2001
From 1c4701ffc342259fc5965d5a0de90d87f780e3e5 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Fri, 12 Jan 2024 17:56:58 +0900
Subject: [PATCH] nettle: avoid normalization of mpz_t in deterministic ECDSA
@ -13,46 +13,34 @@ private key used to calculate a nonce in deterministic ECDSA. Namely:
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/nettle/int/dsa-compute-k.c | 84 +++++++++++++++++++------------
lib/nettle/int/dsa-compute-k.h | 31 +++++++++---
lib/nettle/int/ecdsa-compute-k.c | 33 +++---------
lib/nettle/int/ecdsa-compute-k.h | 8 +--
lib/nettle/pk.c | 79 ++++++++++++++++++++---------
lib/nettle/int/dsa-compute-k.c | 70 +++++++++++++++++++++----------
lib/nettle/int/dsa-compute-k.h | 23 +++++++++-
lib/nettle/int/ecdsa-compute-k.c | 28 +++----------
lib/nettle/int/ecdsa-compute-k.h | 4 +-
lib/nettle/pk.c | 65 +++++++++++++++++++++-------
tests/sign-verify-deterministic.c | 2 +-
6 files changed, 139 insertions(+), 98 deletions(-)
6 files changed, 127 insertions(+), 65 deletions(-)
diff --git a/lib/nettle/int/dsa-compute-k.c b/lib/nettle/int/dsa-compute-k.c
index 3f5105acd3..ddeb6f6d1e 100644
index 8ff5739c2b..2fcb2bb80e 100644
--- a/lib/nettle/int/dsa-compute-k.c
+++ b/lib/nettle/int/dsa-compute-k.c
@@ -31,33 +31,37 @@
@@ -31,19 +31,30 @@
#include "mpn-base256.h"
#include <string.h>
-#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
-
+/* For mini-gmp */
+#ifndef GMP_LIMB_BITS
+#define GMP_LIMB_BITS GMP_NUMB_BITS
+#endif
-/* The maximum size of q, chosen from the fact that we support
- * 521-bit elliptic curve generator and 512-bit DSA subgroup at
- * maximum. */
-#define MAX_Q_BITS 521
-#define MAX_Q_SIZE ((MAX_Q_BITS + 7) / 8)
-#define MAX_Q_LIMBS BITS_TO_LIMBS(MAX_Q_BITS)
-
-#define MAX_HASH_BITS (MAX_HASH_SIZE * 8)
-#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS)
-
-int
-_gnutls_dsa_compute_k(mpz_t k,
- const mpz_t q,
- const mpz_t x,
- gnutls_mac_algorithm_t mac,
- const uint8_t *digest,
- size_t length)
+/* For mini-gmp */
+#ifndef GMP_LIMB_BITS
+#define GMP_LIMB_BITS GMP_NUMB_BITS
+#endif
+
+static inline int is_zero_limb(mp_limb_t x)
+{
+ x |= (x << 1);
@ -63,29 +51,32 @@ index 3f5105acd3..ddeb6f6d1e 100644
+{
+ volatile mp_limb_t w;
+ mp_size_t i;
+
-#define MAX_HASH_BITS (MAX_HASH_SIZE * 8)
-#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS)
+ for (i = 0, w = 0; i < n; i++)
+ w |= ap[i];
+
-int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
+ return is_zero_limb(w);
+}
+
+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x,
+ mp_size_t qn, mp_bitcnt_t q_bits,
+ gnutls_mac_algorithm_t mac, const uint8_t *digest,
+ size_t length)
gnutls_mac_algorithm_t mac, const uint8_t *digest,
size_t length)
{
uint8_t V[MAX_HASH_SIZE];
@@ -51,9 +62,6 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
uint8_t K[MAX_HASH_SIZE];
uint8_t xp[MAX_Q_SIZE];
uint8_t tp[MAX_Q_SIZE];
- mp_limb_t h[MAX(MAX_Q_LIMBS, MAX_HASH_LIMBS)];
- mp_bitcnt_t q_bits = mpz_sizeinbase (q, 2);
- mp_bitcnt_t q_bits = mpz_sizeinbase(q, 2);
- mp_size_t qn = mpz_size(q);
mp_bitcnt_t h_bits = length * 8;
mp_size_t hn = BITS_TO_LIMBS(h_bits);
size_t nbytes = (q_bits + 7) / 8;
@@ -66,6 +70,7 @@ _gnutls_dsa_compute_k(mpz_t k,
@@ -62,6 +70,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
mp_limb_t cy;
gnutls_hmac_hd_t hd;
int ret = 0;
@ -93,7 +84,7 @@ index 3f5105acd3..ddeb6f6d1e 100644
if (unlikely(q_bits > MAX_Q_BITS))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -73,7 +78,7 @@ _gnutls_dsa_compute_k(mpz_t k,
@@ -69,7 +78,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
/* int2octets(x) */
@ -102,7 +93,7 @@ index 3f5105acd3..ddeb6f6d1e 100644
/* bits2octets(h) */
mpn_set_base256(h, hn, digest, length);
@@ -97,12 +102,12 @@ _gnutls_dsa_compute_k(mpz_t k,
@@ -93,12 +102,12 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
mpn_rshift(h, h, hn, shift % GMP_NUMB_BITS);
}
@ -118,12 +109,12 @@ index 3f5105acd3..ddeb6f6d1e 100644
#endif
mpn_get_base256(tp, nbytes, h, qn);
@@ -178,12 +183,8 @@ _gnutls_dsa_compute_k(mpz_t k,
@@ -174,12 +183,8 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
if (tlen * 8 > q_bits)
mpn_rshift (h, h, qn, tlen * 8 - q_bits);
mpn_rshift(h, h, qn, tlen * 8 - q_bits);
/* Check if k is in [1,q-1] */
- if (!mpn_zero_p (h, qn) &&
- mpn_cmp (h, mpz_limbs_read(q), qn) < 0) {
- if (!mpn_zero_p(h, qn) &&
- mpn_cmp(h, mpz_limbs_read(q), qn) < 0) {
- mpn_copyi(mpz_limbs_write(k, qn), h, qn);
- mpz_limbs_finish(k, qn);
+ if (!sec_zero_p(h, qn) && mpn_sub_n(scratch, h, q, qn))
@ -132,7 +123,7 @@ index 3f5105acd3..ddeb6f6d1e 100644
ret = gnutls_hmac_init(&hd, mac, K, length);
if (ret < 0)
@@ -207,3 +208,24 @@ _gnutls_dsa_compute_k(mpz_t k,
@@ -203,3 +208,24 @@ out:
return ret;
}
@ -158,20 +149,14 @@ index 3f5105acd3..ddeb6f6d1e 100644
+ mpn_get_base256(k, nbytes, h, n);
+}
diff --git a/lib/nettle/int/dsa-compute-k.h b/lib/nettle/int/dsa-compute-k.h
index 64e90e0ca2..e88fce0a6d 100644
index 49d243acb4..2f0667a01e 100644
--- a/lib/nettle/int/dsa-compute-k.h
+++ b/lib/nettle/int/dsa-compute-k.h
@@ -26,12 +26,29 @@
@@ -26,8 +26,29 @@
#include <gnutls/gnutls.h>
#include <nettle/bignum.h> /* includes gmp.h */
-int
-_gnutls_dsa_compute_k(mpz_t k,
- const mpz_t q,
- const mpz_t x,
- gnutls_mac_algorithm_t mac,
- const uint8_t *digest,
- size_t length);
-int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x,
+#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+
+/* The maximum size of q, chosen from the fact that we support
@ -188,26 +173,25 @@ index 64e90e0ca2..e88fce0a6d 100644
+
+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x,
+ mp_size_t qn, mp_bitcnt_t q_bits,
+ gnutls_mac_algorithm_t mac, const uint8_t *digest,
+ size_t length);
+
gnutls_mac_algorithm_t mac, const uint8_t *digest,
size_t length);
+void _gnutls_dsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n);
+
+void _gnutls_ecdsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h,
+ mp_size_t n);
+
#endif /* GNUTLS_LIB_NETTLE_INT_DSA_COMPUTE_K_H */
diff --git a/lib/nettle/int/ecdsa-compute-k.c b/lib/nettle/int/ecdsa-compute-k.c
index 94914ebdfa..d98f246c7d 100644
index 3b7f886160..4e25235c40 100644
--- a/lib/nettle/int/ecdsa-compute-k.c
+++ b/lib/nettle/int/ecdsa-compute-k.c
@@ -29,39 +29,38 @@
@@ -29,38 +29,38 @@
#include "dsa-compute-k.h"
#include "gnutls_int.h"
-static inline int
-_gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
-static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve)
{
switch (curve) {
@ -248,18 +232,14 @@ index 94914ebdfa..d98f246c7d 100644
"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFA51868783BF2F966B7FCC0148F709A"
@@ -73,23 +72,3 @@ _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
@@ -73,19 +73,3 @@ static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve)
GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
}
}
-
-int
-_gnutls_ecdsa_compute_k (mpz_t k,
- gnutls_ecc_curve_t curve,
- const mpz_t x,
- gnutls_mac_algorithm_t mac,
- const uint8_t *digest,
- size_t length)
-int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x,
- gnutls_mac_algorithm_t mac, const uint8_t *digest,
- size_t length)
-{
- mpz_t q;
- int ret;
@ -268,41 +248,37 @@ index 94914ebdfa..d98f246c7d 100644
- if (ret < 0)
- return gnutls_assert_val(ret);
-
- ret = _gnutls_dsa_compute_k (k, q, x, mac, digest, length);
- ret = _gnutls_dsa_compute_k(k, q, x, mac, digest, length);
- mpz_clear(q);
- return ret;
-}
diff --git a/lib/nettle/int/ecdsa-compute-k.h b/lib/nettle/int/ecdsa-compute-k.h
index 7ca401d6e4..a7e612bcab 100644
index be8beddb5d..207685763f 100644
--- a/lib/nettle/int/ecdsa-compute-k.h
+++ b/lib/nettle/int/ecdsa-compute-k.h
@@ -26,12 +26,6 @@
@@ -26,8 +26,6 @@
#include <gnutls/gnutls.h>
#include <nettle/bignum.h> /* includes gmp.h */
-int
-_gnutls_ecdsa_compute_k (mpz_t k,
- gnutls_ecc_curve_t curve,
- const mpz_t x,
- gnutls_mac_algorithm_t mac,
- const uint8_t *digest,
- size_t length);
-int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x,
- gnutls_mac_algorithm_t mac, const uint8_t *digest,
- size_t length);
+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve);
#endif /* GNUTLS_LIB_NETTLE_INT_ECDSA_COMPUTE_K_H */
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index c4a6001656..3d21bb818a 100644
index 305548f4d1..dd6b9936a8 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -97,10 +97,16 @@ static void rnd_nonce_func(void *_ctx, size_t length, uint8_t * data)
@@ -103,10 +103,16 @@ static void rnd_nonce_func(void *_ctx, size_t length, uint8_t *data)
}
}
-static void rnd_mpz_func(void *_ctx, size_t length, uint8_t * data)
-static void rnd_mpz_func(void *_ctx, size_t length, uint8_t *data)
+static void rnd_datum_func(void *ctx, size_t length, uint8_t *data)
{
- mpz_t *k = _ctx;
- nettle_mpz_get_str_256 (length, data, *k);
- nettle_mpz_get_str_256(length, data, *k);
+ gnutls_datum_t *d = ctx;
+
+ if (length > d->size) {
@ -313,132 +289,123 @@ index c4a6001656..3d21bb818a 100644
+ }
}
static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t * data)
@@ -1076,7 +1082,10 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_signature sig;
int curve_id = pk_params->curve;
const struct ecc_curve *curve;
- mpz_t k;
+ mpz_t q;
+ /* 521-bit elliptic curve generator at maximum */
+ uint8_t buf[(521 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t *data)
@@ -1403,7 +1409,10 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_signature sig;
int curve_id = pk_params->curve;
const struct ecc_curve *curve;
- mpz_t k;
+ mpz_t q;
+ /* 521-bit elliptic curve generator at maximum */
+ uint8_t buf[(521 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
@@ -1123,19 +1132,32 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
not_approved = true;
}
@@ -1447,17 +1456,32 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
not_approved = true;
}
- mpz_init(k);
+ mpz_init(q);
- mpz_init(k);
+ mpz_init(q);
+
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
- ret = _gnutls_ecdsa_compute_k(k,
- curve_id,
- pk_params->params[ECC_K],
- DIG_TO_MAC(sign_params->dsa_dig),
- vdata->data,
- vdata->size);
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
- ret = _gnutls_ecdsa_compute_k(
- k, curve_id, pk_params->params[ECC_K],
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
+
+ ret = _gnutls_ecc_curve_to_dsa_q(q, curve_id);
if (ret < 0)
goto ecdsa_cleanup;
+ ret = _gnutls_ecc_curve_to_dsa_q(q, curve_id);
+ if (ret < 0)
+ goto ecdsa_cleanup;
+
+ ret = _gnutls_dsa_compute_k(
+ h, mpz_limbs_read(q), priv.p,
+ ecc_size(priv.ecc), ecc_bit_size(priv.ecc),
+ DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
+ vdata->size);
+ if (ret < 0)
+ goto ecdsa_cleanup;
+ ret = _gnutls_dsa_compute_k(
+ h, mpz_limbs_read(q), priv.p,
+ ecc_size(priv.ecc), ecc_bit_size(priv.ecc),
DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
vdata->size);
if (ret < 0)
goto ecdsa_cleanup;
+
+ k.data = buf;
+ k.size = (ecc_bit_size(priv.ecc) + 7) / 8;
+ k.data = buf;
+ k.size = (ecc_bit_size(priv.ecc) + 7) / 8;
+
+ _gnutls_ecdsa_compute_k_finish(k.data, k.size, h,
+ ecc_size(priv.ecc));
+ _gnutls_ecdsa_compute_k_finish(k.data, k.size, h,
+ ecc_size(priv.ecc));
+
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1156,7 +1178,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
ecdsa_cleanup:
dsa_signature_clear(&sig);
ecc_scalar_zclear(&priv);
- mpz_clear(k);
+ mpz_clear(q);
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1476,7 +1500,7 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
ecdsa_cleanup:
dsa_signature_clear(&sig);
ecc_scalar_zclear(&priv);
- mpz_clear(k);
+ mpz_clear(q);
if (ret < 0) {
gnutls_assert();
@@ -1169,7 +1191,9 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_params pub;
bigint_t priv;
struct dsa_signature sig;
- mpz_t k;
+ /* 512-bit DSA subgroup at maximum */
+ uint8_t buf[(512 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
if (ret < 0) {
gnutls_assert();
@@ -1488,7 +1512,9 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
struct dsa_params pub;
bigint_t priv;
struct dsa_signature sig;
- mpz_t k;
+ /* 512-bit DSA subgroup at maximum */
+ uint8_t buf[(512 + 7) / 8];
+ gnutls_datum_t k = { NULL, 0 };
void *random_ctx;
nettle_random_func *random_func;
@@ -1196,21 +1220,27 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
hash_len = vdata->size;
}
@@ -1515,19 +1541,27 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
hash_len = vdata->size;
}
- mpz_init(k);
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
- ret = _gnutls_dsa_compute_k(k,
- pub.q,
- TOMPZ(priv),
- DIG_TO_MAC(sign_params->dsa_dig),
- vdata->data,
- vdata->size);
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
- mpz_init(k);
if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST ||
(sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) {
+ mp_limb_t h[DSA_COMPUTE_K_ITCH];
+
+ ret = _gnutls_dsa_compute_k(
+ h, mpz_limbs_read(pub.q),
+ mpz_limbs_read(TOMPZ(priv)), mpz_size(pub.q),
+ mpz_sizeinbase(pub.q, 2),
+ DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
+ vdata->size);
if (ret < 0)
goto dsa_fail;
- /* cancel-out dsa_sign's addition of 1 to random data */
- mpz_sub_ui (k, k, 1);
ret = _gnutls_dsa_compute_k(
- k, pub.q, TOMPZ(priv),
+ h, mpz_limbs_read(pub.q),
+ mpz_limbs_read(TOMPZ(priv)), mpz_size(pub.q),
+ mpz_sizeinbase(pub.q, 2),
DIG_TO_MAC(sign_params->dsa_dig), vdata->data,
vdata->size);
if (ret < 0)
goto dsa_fail;
- /* cancel-out dsa_sign's addition of 1 to random data */
- mpz_sub_ui(k, k, 1);
+
+ k.data = buf;
+ k.size = (mpz_sizeinbase(pub.q, 2) + 7) / 8;
+ k.data = buf;
+ k.size = (mpz_sizeinbase(pub.q, 2) + 7) / 8;
+
+ _gnutls_dsa_compute_k_finish(k.data, k.size, h,
+ mpz_size(pub.q));
+ _gnutls_dsa_compute_k_finish(k.data, k.size, h,
+ mpz_size(pub.q));
+
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1230,7 +1260,6 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
random_ctx = &k;
- random_func = rnd_mpz_func;
+ random_func = rnd_datum_func;
} else {
random_ctx = NULL;
random_func = rnd_nonce_func;
@@ -1544,7 +1578,6 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
dsa_fail:
dsa_signature_clear(&sig);
- mpz_clear(k);
dsa_fail:
dsa_signature_clear(&sig);
- mpz_clear(k);
if (ret < 0) {
gnutls_assert();
if (ret < 0) {
gnutls_assert();
diff --git a/tests/sign-verify-deterministic.c b/tests/sign-verify-deterministic.c
index 6e907288ee..25aa553a59 100644
index 6969b57a11..bdd5a49c7d 100644
--- a/tests/sign-verify-deterministic.c
+++ b/tests/sign-verify-deterministic.c
@@ -197,7 +197,7 @@ void doit(void)
&signature);
@@ -198,7 +198,7 @@ void doit(void)
&tests[i].msg, &signature);
if (ret < 0)
testfail("gnutls_pubkey_verify_data2\n");
- success(" - pass");

View File

@ -0,0 +1,36 @@
From 945c2f10eeda441f32404d1328761e311915add0 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 23 Jan 2024 11:54:32 +0900
Subject: [PATCH] ktls: fix kernel version checking using utsname
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/system/ktls.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/system/ktls.c b/lib/system/ktls.c
index 8efb913cda..432c70c5a2 100644
--- a/lib/system/ktls.c
+++ b/lib/system/ktls.c
@@ -482,7 +482,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session,
return GNUTLS_E_INTERNAL_ERROR;
}
- if (strcmp(utsname.sysname, "Linux") == 0) {
+ if (strcmp(utsname.sysname, "Linux") != 0) {
return GNUTLS_E_INTERNAL_ERROR;
}
@@ -495,6 +495,9 @@ int _gnutls_ktls_set_keys(gnutls_session_t session,
return GNUTLS_E_INTERNAL_ERROR;
}
+ _gnutls_debug_log("Linux kernel version %lu.%lu has been detected\n",
+ major, minor);
+
/* setsockopt(SOL_TLS, TLS_RX) support added in 5.10 */
if (major < 5 || (major == 5 && minor < 10)) {
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
--
2.43.0

View File

@ -1,4 +1,4 @@
From d6cd941425b1276a44269abb9742bef638562175 Mon Sep 17 00:00:00 2001
From e369e67a62f44561d417cb233acc566cc696d82d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Mon, 29 Jan 2024 13:52:46 +0900
Subject: [PATCH] gnutls_x509_trust_list_verify_crt2: remove length limit of
@ -13,15 +13,15 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
lib/gnutls_int.h | 5 +-
lib/x509/common.c | 10 +-
lib/x509/verify-high.c | 52 ++++++----
lib/x509/verify-high.c | 51 ++++++----
tests/test-chains.h | 211 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 256 insertions(+), 22 deletions(-)
4 files changed, 258 insertions(+), 19 deletions(-)
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 872188696b..1778659367 100644
index d8561ebe3a..8cf9a87157 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -221,7 +221,10 @@ typedef enum record_send_state_t {
@@ -232,7 +232,10 @@ typedef enum record_send_state_t {
#define MAX_PK_PARAM_SIZE 2048
@ -32,12 +32,12 @@ index 872188696b..1778659367 100644
+ * DEFAULT_MAX_VERIFY_DEPTH.
*/
#define DEFAULT_MAX_VERIFY_DEPTH 16
#define DEFAULT_MAX_VERIFY_BITS (MAX_PK_PARAM_SIZE*8)
#define DEFAULT_MAX_VERIFY_BITS (MAX_PK_PARAM_SIZE * 8)
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 1a022f91af..75c6a23ca0 100644
index 2cc83c9155..705aa868bc 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1755,7 +1755,15 @@ unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist,
@@ -1725,7 +1725,15 @@ unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist,
bool insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */
gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
@ -55,27 +55,19 @@ index 1a022f91af..75c6a23ca0 100644
for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
issuer[i] = -1;
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 5698d4f372..075f6105c2 100644
index 4e7361eb63..aacc24a7d8 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -24,11 +24,11 @@
#include "gnutls_int.h"
@@ -25,7 +25,7 @@
#include "errors.h"
#include <libtasn1.h>
-#include <global.h>
-#include <num.h> /* MAX */
-#include <tls-sig.h>
-#include <str.h>
-#include <datum.h>
+#include "global.h"
#include "global.h"
-#include "num.h" /* MAX */
+#include "num.h" /* MIN */
+#include "tls-sig.h"
+#include "str.h"
+#include "datum.h"
#include <hash-pjw-bare.h>
#include "x509_int.h"
#include <common.h>
@@ -1418,7 +1418,8 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
#include "tls-sig.h"
#include "str.h"
#include "datum.h"
@@ -1361,7 +1361,8 @@ int gnutls_x509_trust_list_verify_crt2(
int ret = 0;
unsigned int i;
size_t hash;
@ -85,7 +77,7 @@ index 5698d4f372..075f6105c2 100644
gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH];
unsigned int retrieved_size = 0;
const char *hostname = NULL, *purpose = NULL, *email = NULL;
@@ -1472,8 +1473,19 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
@@ -1421,16 +1422,28 @@ int gnutls_x509_trust_list_verify_crt2(
}
}
@ -105,20 +97,37 @@ index 5698d4f372..075f6105c2 100644
+ cert_list_size * sizeof(gnutls_x509_crt_t));
+ cert_list = cert_list_copy;
ret = cert_set_init(&cert_set, DEFAULT_MAX_VERIFY_DEPTH);
if (ret < 0) {
@@ -1536,19 +1548,18 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
continue;
}
records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq,
cert_hashcode, NULL, false);
- if (records == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ if (records == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto cleanup;
+ }
- ret = retrieve_issuers(list,
- cert_list[i - 1],
- &retrieved[retrieved_size],
- DEFAULT_MAX_VERIFY_DEPTH -
- MAX(retrieved_size,
- cert_list_size));
+ ret = retrieve_issuers(
+ list, cert_list[i - 1], &retrieved[retrieved_size],
- for (i = 0; i < cert_list_size &&
- cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH;) {
+ for (i = 0; i < cert_list_size;) {
unsigned int sorted_size = 1;
unsigned int j, k;
gnutls_x509_crt_t issuer;
@@ -1442,8 +1455,7 @@ int gnutls_x509_trust_list_verify_crt2(
assert(sorted_size > 0);
- /* Remove duplicates. Start with index 1, as the first element
- * may be re-checked after issuer retrieval. */
+ /* Remove duplicates. */
for (j = 0; j < sorted_size; j++) {
if (gl_list_search(records, cert_list[i + j])) {
if (i + j < cert_list_size - 1) {
@@ -1495,13 +1507,15 @@ int gnutls_x509_trust_list_verify_crt2(
ret = retrieve_issuers(
list, cert_list[i - 1], &retrieved[retrieved_size],
- DEFAULT_MAX_VERIFY_DEPTH -
- MAX(retrieved_size, cert_list_size));
+ MIN(DEFAULT_MAX_VERIFY_DEPTH - retrieved_size,
+ cert_list_max_size - cert_list_size));
if (ret < 0) {
@ -126,16 +135,13 @@ index 5698d4f372..075f6105c2 100644
} else if (ret > 0) {
assert((unsigned int)ret <=
- DEFAULT_MAX_VERIFY_DEPTH - cert_list_size);
- memmove(&cert_list[i + ret],
- &cert_list[i],
+ DEFAULT_MAX_VERIFY_DEPTH - retrieved_size);
+ assert((unsigned int)ret <=
+ cert_list_max_size - cert_list_size);
+ memmove(&cert_list[i + ret], &cert_list[i],
memmove(&cert_list[i + ret], &cert_list[i],
(cert_list_size - i) *
sizeof(gnutls_x509_crt_t));
memcpy(&cert_list[i],
@@ -1563,8 +1574,10 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
sizeof(gnutls_x509_crt_t));
@@ -1517,8 +1531,10 @@ int gnutls_x509_trust_list_verify_crt2(
}
cert_list_size = shorten_clist(list, cert_list, cert_list_size);
@ -146,30 +152,37 @@ index 5698d4f372..075f6105c2 100644
+ goto cleanup;
+ }
hash =
hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.
@@ -1715,6 +1728,7 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
hash = hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.data,
cert_list[cert_list_size - 1]->raw_issuer_dn.size);
@@ -1661,10 +1677,13 @@ int gnutls_x509_trust_list_verify_crt2(
}
cleanup:
cleanup:
+ gnutls_free(cert_list_copy);
for (i = 0; i < retrieved_size; i++) {
gnutls_x509_crt_deinit(retrieved[i]);
}
- gl_list_free(records);
+ if (records) {
+ gl_list_free(records);
+ }
return ret;
}
diff --git a/tests/test-chains.h b/tests/test-chains.h
index 09a5461ebf..dd872a9685 100644
index 3e559fecd5..a7fe1cdecc 100644
--- a/tests/test-chains.h
+++ b/tests/test-chains.h
@@ -25,7 +25,7 @@
/* *INDENT-OFF* */
@@ -23,7 +23,7 @@
#ifndef GNUTLS_TESTS_TEST_CHAINS_H
#define GNUTLS_TESTS_TEST_CHAINS_H
-#define MAX_CHAIN 10
+#define MAX_CHAIN 17
static const char *chain_with_no_subject_id_in_ca_ok[] = {
"-----BEGIN CERTIFICATE-----\n"
@@ -4386,6 +4386,213 @@ static const char *cross_signed_ca[] = {
@@ -4383,6 +4383,213 @@ static const char *cross_signed_ca[] = {
NULL
};
@ -381,15 +394,15 @@ index 09a5461ebf..dd872a9685 100644
+};
+
#if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4567,6 +4774,8 @@ static struct
GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1620118136, 1},
{ "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0,
1704955300 },
+ { "many intermediates - ok", many_icas, many_icas_ca, 0, 0, 0,
+ 1710284400 },
{ NULL, NULL, NULL, 0, 0}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4696,6 +4903,8 @@ static struct {
1620118136, 1 },
{ "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0,
1704955300 },
+ { "many intermediates - ok", many_icas, many_icas_ca, 0, 0, 0,
+ 1710284400 },
{ NULL, NULL, NULL, 0, 0 }
};
--

View File

@ -0,0 +1,226 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
wNTn8cXhFYi0Of02Vt4nNiXryBL/zneXgb37qiI=
=8Avy
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -12,49 +12,23 @@ sha256sum:close()
print(string.sub(hash, 0, 16))
}
Version: 3.7.6
Release: 23%{?dist}.4
Version: 3.8.3
Release: 4%{?dist}
# not upstreamed
Patch: gnutls-3.6.7-no-now-guile.patch
Patch: gnutls-3.2.7-rpath.patch
Patch: gnutls-3.7.2-enable-intel-cet.patch
Patch: gnutls-3.7.2-no-explicit-init.patch
# upstreamed
Patch: gnutls-3.7.6-fips-run-selftests.patch
Patch: gnutls-3.7.6-ktls-disable-by-default.patch
Patch: gnutls-3.7.6-ktls-fixes.patch
Patch: gnutls-3.7.6-aes-gcm-pt-limit.patch
Patch: gnutls-3.7.6-pkcs7-verify.patch
Patch: gnutls-3.7.6-fips-pkcs12-des-cbc.patch
Patch: gnutls-3.7.6-fips-rsa-key-sizes.patch
Patch: gnutls-3.7.6-fips-symkey-limit.patch
Patch: gnutls-3.7.6-fips-ecdsa-hash-check.patch
Patch: gnutls-3.7.8-xts-key-check.patch
Patch: gnutls-3.7.8-clear-session-ticket.patch
Patch: gnutls-3.7.7-aes-cbc-padding-support.patch
Patch: gnutls-3.7.8-integrity-check.patch
Patch: gnutls-3.7.6-fips-service-indicator-test-functions.patch
Patch: gnutls-3.7.6-fips-ccm-taglen.patch
Patch: gnutls-3.7.6-fips-rsa-pss-saltlen.patch
Patch: gnutls-3.7.8-revert-hmac-name.patch
Patch: gnutls-3.7.8-rsa-kx-timing.patch
Patch: gnutls-3.7.8-fips-pct-dh.patch
Patch: gnutls-3.7.6-fips-ems.patch
Patch: gnutls-3.7.6-fips-sha1-sigver.patch
Patch: gnutls-3.7.6-rsa-psk-timing.patch
Patch: gnutls-3.7.6-rsa-psk-timing-followup.patch
Patch: gnutls-3.7.6-ca-xsigned.patch
Patch: gnutls-3.7.6-fips-integrity-zeroize.patch
Patch: gnutls-3.7.6-deterministic-ecdsa-fixes.patch
Patch: gnutls-3.7.6-verify-chain.patch
# not upstreamed
Patch: gnutls-3.7.3-disable-config-reload.patch
Patch: gnutls-3.7.3-fips-dsa-post.patch
Patch: gnutls-3.7.6-drbg-reseed.patch
Patch: gnutls-3.7.6-cpuid-fixes.patch
Patch: gnutls-3.7.6-fips-sha1-sigver.patch
Patch: gnutls-3.7.6-gmp-static.patch
Patch: gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch
# upstreamed
Patch: gnutls-3.8.3-ktls-utsname.patch
Patch: gnutls-3.8.3-deterministic-ecdsa-fixes.patch
Patch: gnutls-3.8.3-verify-chain.patch
%bcond_without bootstrap
%bcond_without dane
@ -70,6 +44,8 @@ Patch: gnutls-3.7.6-gmp-static.patch
%bcond_with gost
%bcond_with certificate_compression
%bcond_without tests
%bcond_without srp
%bcond_without heartbeat
Summary: A TLS protocol implementation
Name: gnutls
@ -84,7 +60,7 @@ BuildRequires: zlib-devel, brotli-devel, libzstd-devel
BuildRequires: automake, autoconf, gperf, libtool
%endif
BuildRequires: texinfo
BuildRequires: nettle-devel >= 3.5.1
BuildRequires: nettle-devel >= 3.9.1
%if %{with tpm12}
BuildRequires: trousers-devel >= 0.3.11.2
%endif
@ -102,7 +78,7 @@ BuildRequires: p11-kit-trust, ca-certificates
Requires: crypto-policies
Requires: p11-kit-trust
Requires: libtasn1 >= 4.3
Requires: nettle >= 3.4.1
Requires: nettle >= 3.9.1
%if %{with tpm12}
Recommends: trousers >= 0.3.11.2
%endif
@ -115,9 +91,9 @@ BuildRequires: guile22-devel
%endif
BuildRequires: make
URL: http://www.gnutls.org/
Source0: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.7/%{name}-%{version}.tar.xz
Source1: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.7/%{name}-%{version}.tar.xz.sig
Source2: gnutls-release-keyring.gpg
Source0: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8/%{name}-%{version}.tar.xz
Source1: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8/%{name}-%{version}.tar.xz.sig
Source2: gnutls-release-keyring.pgp
Source100: gmp-6.2.1.tar.xz
# Taken from the main gmp package
@ -275,6 +251,16 @@ export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name"
--enable-gost \
%else
--disable-gost \
%endif
%if %{with srp}
--enable-srp-authentication \
%else
--disable-srp-authentication \
%endif
%if %{with heartbeat}
--enable-heartbeat-support \
%else
--disable-heartbeat-support \
%endif
--enable-sha1-support \
--disable-static \
@ -361,17 +347,19 @@ ln -s ".$fname.hmac" "$RPM_BUILD_ROOT%{_libdir}/.libgnutls.so.30.hmac"
%check
%if %{with tests}
xfail_tests=
# This test shouldn't work until the kernel gets support for KeyUpdate
xfail_tests=ktls_keyupdate.sh
# The ktls.sh test currently only supports kernel 5.11+. This needs to
# be checked at run time, as the koji builder might be using a different
# version of kernel on the host than the one indicated by the
# kernel-devel package.
# With older kernel, key installation fails if the host is x86_64 and
# the package is built with -m32:
%ifarch %{ix86}
case "$(uname -r)" in
4.*.x86_64)
4.* | 5.[0-9].* | 5.10.* )
xfail_tests="$xfail_tests ktls.sh"
;;
esac
%endif
make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null XFAIL_TESTS="$xfail_tests"
%endif
@ -427,19 +415,28 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null XFAIL_TESTS="$x
%endif
%changelog
* Fri Mar 29 2024 Daiki Ueno <dueno@redhat.com> - 3.7.6-23.4
- Fix timing side-channel in deterministic ECDSA (RHEL-28958)
- Fix potential crash during chain building/verification (RHEL-28953)
* Fri Apr 5 2024 Daiki Ueno <dueno@redhat.com> - 3.8.3-4
- Bump release to ensure el9 package is greater than el9_* packages
* Wed Jan 17 2024 Daiki Ueno <dueno@redhat.com> - 3.7.6-23.3
- x509: detect loop in certificate chain (RHEL-21759)
- fips: Zeroize temporary values in integrity check (RHEL-21870)
* Fri Mar 22 2024 Daiki Ueno <dueno@redhat.com> - 3.8.3-3
- Bump release to ensure el9 package is greater than el9_* packages
* Wed Jan 10 2024 Daiki Ueno <dueno@redhat.com> - 3.7.6-23.2
- auth/rsa_psk: minimize branching after decryption
* Thu Mar 21 2024 Daiki Ueno <dueno@redhat.com> - 3.8.3-2
- Fix timing side-channel in deterministic ECDSA (RHEL-28959)
- Fix potential crash during chain building/verification (RHEL-28954)
* Mon Dec 11 2023 Daiki Ueno <dueno@redhat.com> - 3.7.6-23.1
- auth/rsa_psk: side-step potential side-channel (RHEL-16755)
* Tue Jan 23 2024 Daiki Ueno <dueno@redhat.com> - 3.8.3-1
- Update to gnutls 3.8.3 (RHEL-14891)
* Mon Jan 22 2024 Daiki Ueno <dueno@redhat.com> - 3.8.2-3
- Skip KTLS test exercising ChaCha20-Poly1305 in TLS 1.3 as well (RHEL-18498)
* Fri Dec 8 2023 Daiki Ueno <dueno@redhat.com> - 3.8.2-2
- Bump nettle dependency to 3.9.1
- Skip KTLS test exercising ChaCha20-Poly1305 in TLS 1.2 (RHEL-18498)
* Thu Nov 16 2023 Daiki Ueno <dueno@redhat.com> - 3.8.2-1
- Update to gnutls 3.8.2 (RHEL-14891)
* Sat Jul 29 2023 Daiki Ueno <dueno@redhat.com> - 3.7.6-23
- Mark SHA-1 signature verification non-approved in FIPS (#2102751)